Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
898 user890104 3
//    Copyright 2013 user890104
770 user890104 4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
#include "global.h"
24
 
25
#include "emcore.h"
26
#include "util.h"
27
#include "usb.h"
28
 
916 user890104 29
libusb_context *usb_ctx;
30
libusb_device_handle *usb_handle;
31
uint8_t usb_iface_num;
770 user890104 32
 
898 user890104 33
int32_t usb_init(void) {
34
    int32_t res;
770 user890104 35
 
36
#ifdef DEBUG
37
    fprintf(stderr, "Initialising USB library...\n");
38
#endif
39
 
40
    res = libusb_init(&usb_ctx);
41
 
898 user890104 42
    if (res != LIBUSB_SUCCESS) {
770 user890104 43
        return res;
44
    }
45
 
46
#ifdef DEBUG
47
    fprintf(stderr, "USB library initialized!\n");
48
    libusb_set_debug(usb_ctx, 3);
49
#endif
50
 
51
    return LIBUSB_SUCCESS;
52
}
53
 
898 user890104 54
int32_t usb_find(uint16_t vendor_id, uint16_t product_id, uint8_t *reattach) {
55
    libusb_device **devs, *dev = NULL;
916 user890104 56
    ssize_t devs_cnt, i;
57
    uint8_t found = 0, j, k;
58
    int l;
898 user890104 59
    int32_t res;
770 user890104 60
    struct libusb_device_descriptor dev_desc;
898 user890104 61
    struct libusb_config_descriptor *cfg_desc;
62
    const struct libusb_interface *iface;
63
    const struct libusb_interface_descriptor *iface_desc;
770 user890104 64
 
65
#ifdef DEBUG
66
    fprintf(stderr, "Getting USB device list...\n");
67
#endif
68
 
69
    devs_cnt = libusb_get_device_list(usb_ctx, &devs);
70
 
898 user890104 71
    if (devs_cnt < 0) {
770 user890104 72
        return devs_cnt;
73
    }
74
 
75
#ifdef DEBUG
916 user890104 76
    fprintf(stderr, "Found %zd USB devices!\n", devs_cnt);
770 user890104 77
#endif
898 user890104 78
    for (i = 0; i < devs_cnt; ++i) {
770 user890104 79
        dev = devs[i];
80
#ifdef DEBUG
916 user890104 81
        fprintf(stderr, "Getting device descriptor of USB device %zd...\n", i);
770 user890104 82
#endif
83
        res = libusb_get_device_descriptor(dev, &dev_desc);
84
 
898 user890104 85
        if (res != LIBUSB_SUCCESS) {
770 user890104 86
#ifdef DEBUG
916 user890104 87
            fprintf(stderr, "Unable to get device descriptor of device %zd!\n", i);
770 user890104 88
#endif
89
            continue;
90
        }
91
 
92
#ifdef DEBUG
93
        fprintf(stderr, "[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
94
            dev_desc.idProduct, libusb_get_bus_number(dev),
95
            libusb_get_device_address(dev), dev_desc.bcdUSB);
96
#endif
898 user890104 97
        if (dev_desc.idVendor != vendor_id || dev_desc.idProduct != product_id) {
98
            continue;
99
        }
100
 
770 user890104 101
#ifdef DEBUG
898 user890104 102
        fprintf(stderr, "Found emCORE USB device!\n");
770 user890104 103
#endif
898 user890104 104
        if (!dev_desc.bNumConfigurations) {
770 user890104 105
#ifdef DEBUG
898 user890104 106
            fprintf(stderr, "No configs found...\n");
770 user890104 107
#endif
898 user890104 108
            continue;
109
        }
770 user890104 110
 
111
#ifdef DEBUG
916 user890104 112
        fprintf(stderr, "Found %u configs...\n", dev_desc.bNumConfigurations);
770 user890104 113
#endif
114
 
898 user890104 115
        for (j = 0; j < dev_desc.bNumConfigurations; ++j) {
770 user890104 116
#ifdef DEBUG
916 user890104 117
            fprintf(stderr, "Getting config descriptor %u of device...\n", j);
770 user890104 118
#endif
119
 
898 user890104 120
            res = libusb_get_config_descriptor(dev, j, &cfg_desc);
121
 
122
            if (res != LIBUSB_SUCCESS) {
123
                return res;
770 user890104 124
            }
125
 
898 user890104 126
            if (!cfg_desc->bNumInterfaces) {
770 user890104 127
#ifdef DEBUG
898 user890104 128
                fprintf(stderr, "No interfaces found...\n");
770 user890104 129
#endif
130
                continue;
131
            }
132
 
898 user890104 133
            for (k = 0; k < cfg_desc->bNumInterfaces; ++k) {
134
                iface = &cfg_desc->interface[k];
770 user890104 135
 
898 user890104 136
                if (!iface->num_altsetting) {
770 user890104 137
#ifdef DEBUG
898 user890104 138
                    fprintf(stderr, "No altsettings found...\n");
770 user890104 139
#endif
898 user890104 140
                    continue;
141
                }
770 user890104 142
 
898 user890104 143
                for (l = 0; l < iface->num_altsetting; ++l) {
144
                    iface_desc = &iface->altsetting[l];
770 user890104 145
 
898 user890104 146
                    if (
147
                        iface_desc->bInterfaceClass    != EMCORE_USB_INTERFACE_CLASS ||
148
                        iface_desc->bInterfaceSubClass != EMCORE_USB_INTERFACE_SUB_CLASS ||
149
                        iface_desc->bInterfaceProtocol != EMCORE_USB_INTERFACE_PROTOCOL
150
                    ) {
770 user890104 151
#ifdef DEBUG
898 user890104 152
                        fprintf(stderr, "Wrong interface class (%02X %02X %02X), trying next device...\n", iface_desc->bInterfaceClass, iface_desc->bInterfaceSubClass, iface_desc->bInterfaceProtocol);
770 user890104 153
#endif
154
 
898 user890104 155
                        continue;
156
                    }
157
 
770 user890104 158
#ifdef DEBUG
916 user890104 159
                    fprintf(stderr, "emCORE Debugger interface at %u\n", iface_desc->bInterfaceNumber);
770 user890104 160
#endif
161
 
898 user890104 162
                    usb_iface_num = iface_desc->bInterfaceNumber;
163
                    found = 1;
164
                    goto outside_search_loop;
770 user890104 165
                }
166
            }
167
        }
168
    }
898 user890104 169
 
170
    outside_search_loop:
770 user890104 171
 
898 user890104 172
    if (found) {
770 user890104 173
        res = usb_open(dev, reattach);
174
    }
898 user890104 175
    else {
176
        fprintf(stderr, "emCORE Debugger interface not found!\n");
770 user890104 177
 
178
        res = EMCORE_ERROR_NO_DEVICE;
179
    }
180
 
181
#ifdef DEBUG
182
    fprintf(stderr, "Freeing device list...\n");
183
#endif
184
    libusb_free_device_list(devs, 1);
185
 
186
    return res;
187
}
188
 
898 user890104 189
int32_t usb_open(libusb_device *dev, uint8_t *reattach) {
190
    int32_t res;
770 user890104 191
 
192
#ifdef DEBUG
193
    fprintf(stderr, "Opening USB device...\n");
194
#endif
195
    res = libusb_open(dev, &usb_handle);
196
 
898 user890104 197
    if (res != LIBUSB_SUCCESS) {
770 user890104 198
        return res;
199
    }
200
#ifdef DEBUG
201
    fprintf(stderr, "USB device opened!\n");
202
    fprintf(stderr, "Setting USB configuration 1...\n");
203
#endif
204
 
205
    res = libusb_set_configuration(usb_handle, 1);
206
 
898 user890104 207
    if (res != LIBUSB_SUCCESS) {
770 user890104 208
        return res;
209
    }
898 user890104 210
 
770 user890104 211
#ifdef DEBUG
212
    fprintf(stderr, "USB configuration set!\n");
213
#endif
214
    res = libusb_kernel_driver_active(usb_handle, 0);
215
 
898 user890104 216
    if (res < 0) {
217
        return res;
218
    }
219
 
220
    if (res == 1) {
770 user890104 221
        *reattach = 1;
222
 
223
        res = libusb_detach_kernel_driver(usb_handle, 0);
224
    }
225
 
898 user890104 226
    if (res != LIBUSB_SUCCESS) {
770 user890104 227
        return res;
228
    }
229
 
230
#ifdef DEBUG
231
    fprintf(stderr, "Claiming interface 0...\n");
232
#endif
233
    res = libusb_claim_interface(usb_handle, 0);
234
 
898 user890104 235
    if (res != LIBUSB_SUCCESS) {
770 user890104 236
        return res;
237
    }
238
 
239
#ifdef DEBUG
240
    fprintf(stderr, "Interface claimed successfully!\n");
241
#endif
242
 
243
    return LIBUSB_SUCCESS;
244
}
245
 
898 user890104 246
int32_t usb_control_transfer(uint8_t rq_type, void *data, size_t length) {
247
    int32_t res;
770 user890104 248
 
898 user890104 249
    res = libusb_control_transfer(usb_handle, rq_type, 0, 0, usb_iface_num, (unsigned char *)data, length, 10000);
770 user890104 250
 
898 user890104 251
    if (res < 0) {
770 user890104 252
        return res;
253
    }
254
 
898 user890104 255
    if ((size_t)res != length) {
770 user890104 256
        return EMCORE_ERROR_INCOMPLETE;
257
    }
258
 
259
    return LIBUSB_SUCCESS;
260
}
261
 
898 user890104 262
int32_t usb_close(uint8_t reattach) {
263
    int32_t res;
770 user890104 264
 
265
#ifdef DEBUG
266
    fprintf(stderr, "Releasing USB interface...\n");
267
#endif
268
    res = libusb_release_interface(usb_handle, 0);
269
 
898 user890104 270
    if (res != LIBUSB_SUCCESS) {
770 user890104 271
        return res;
272
    }
273
 
274
#ifdef DEBUG
275
    fprintf(stderr, "Released interface successfully!\n");
276
#endif
277
 
898 user890104 278
    if (reattach) {
770 user890104 279
#ifdef DEBUG
280
        fprintf(stderr, "Reattaching kernel driver...\n");
281
#endif
282
 
283
        res = libusb_attach_kernel_driver(usb_handle, 0);
284
 
898 user890104 285
        if (res == LIBUSB_SUCCESS) {
770 user890104 286
#ifdef DEBUG
287
            fprintf(stderr, "Reattached successfully!\n");
288
#endif
289
        }
898 user890104 290
        else {
770 user890104 291
            print_error(res);
292
 
293
            res = LIBUSB_SUCCESS;
294
        }
295
    }
296
#ifdef DEBUG
297
    fprintf(stderr, "Closing USB device handle...\n");
298
#endif
299
    libusb_close(usb_handle);
300
 
301
    return res;
302
}
303
 
898 user890104 304
void usb_exit(void) {
770 user890104 305
#ifdef DEBUG
306
    fprintf(stderr, "Deinitializing USB library...\n");
307
#endif
308
 
309
    libusb_exit(usb_ctx);
310
}
311
 
898 user890104 312
int32_t usb_destroy(uint8_t reattach) {
313
    int32_t res = LIBUSB_SUCCESS;
770 user890104 314
 
898 user890104 315
    if (usb_handle) {
770 user890104 316
        res = usb_close(reattach);
317
    }
318
 
898 user890104 319
    if (usb_ctx) {
770 user890104 320
        usb_exit();
321
    }
322
 
323
    return res;
324
}