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
 
898 user890104 29
libusb_context *usb_ctx = NULL;
30
libusb_device_handle *usb_handle = NULL;
31
uint8_t usb_iface_num = 0;
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;
56
    ssize_t devs_cnt, i, j, k, l;
57
    int32_t res;
901 user890104 58
    uint8_t found = 0;
770 user890104 59
    struct libusb_device_descriptor dev_desc;
898 user890104 60
    struct libusb_config_descriptor *cfg_desc;
61
    const struct libusb_interface *iface;
62
    const struct libusb_interface_descriptor *iface_desc;
770 user890104 63
 
64
#ifdef DEBUG
65
    fprintf(stderr, "Getting USB device list...\n");
66
#endif
67
 
68
    devs_cnt = libusb_get_device_list(usb_ctx, &devs);
69
 
898 user890104 70
    if (devs_cnt < 0) {
770 user890104 71
        return devs_cnt;
72
    }
73
 
74
#ifdef DEBUG
790 user890104 75
    fprintf(stderr, "Found %Zd USB devices!\n", devs_cnt);
770 user890104 76
#endif
898 user890104 77
    for (i = 0; i < devs_cnt; ++i) {
770 user890104 78
        dev = devs[i];
79
#ifdef DEBUG
80
        fprintf(stderr, "Getting device descriptor of USB device %d...\n", i);
81
#endif
82
        res = libusb_get_device_descriptor(dev, &dev_desc);
83
 
898 user890104 84
        if (res != LIBUSB_SUCCESS) {
770 user890104 85
#ifdef DEBUG
86
            fprintf(stderr, "Unable to get device descriptor of device %d!\n", i);
87
#endif
88
            continue;
89
        }
90
 
91
#ifdef DEBUG
92
        fprintf(stderr, "[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
93
            dev_desc.idProduct, libusb_get_bus_number(dev),
94
            libusb_get_device_address(dev), dev_desc.bcdUSB);
95
#endif
898 user890104 96
        if (dev_desc.idVendor != vendor_id || dev_desc.idProduct != product_id) {
97
            continue;
98
        }
99
 
770 user890104 100
#ifdef DEBUG
898 user890104 101
        fprintf(stderr, "Found emCORE USB device!\n");
770 user890104 102
#endif
898 user890104 103
        if (!dev_desc.bNumConfigurations) {
770 user890104 104
#ifdef DEBUG
898 user890104 105
            fprintf(stderr, "No configs found...\n");
770 user890104 106
#endif
898 user890104 107
            continue;
108
        }
770 user890104 109
 
110
#ifdef DEBUG
898 user890104 111
        fprintf(stderr, "Found %Zd configs...\n", dev_desc.bNumConfigurations);
770 user890104 112
#endif
113
 
898 user890104 114
        for (j = 0; j < dev_desc.bNumConfigurations; ++j) {
770 user890104 115
#ifdef DEBUG
898 user890104 116
            fprintf(stderr, "Getting config descriptor %Zd of device...\n", j);
770 user890104 117
#endif
118
 
898 user890104 119
            res = libusb_get_config_descriptor(dev, j, &cfg_desc);
120
 
121
            if (res != LIBUSB_SUCCESS) {
122
                return res;
770 user890104 123
            }
124
 
898 user890104 125
            if (!cfg_desc->bNumInterfaces) {
770 user890104 126
#ifdef DEBUG
898 user890104 127
                fprintf(stderr, "No interfaces found...\n");
770 user890104 128
#endif
129
                continue;
130
            }
131
 
898 user890104 132
            for (k = 0; k < cfg_desc->bNumInterfaces; ++k) {
133
                iface = &cfg_desc->interface[k];
770 user890104 134
 
898 user890104 135
                if (!iface->num_altsetting) {
770 user890104 136
#ifdef DEBUG
898 user890104 137
                    fprintf(stderr, "No altsettings found...\n");
770 user890104 138
#endif
898 user890104 139
                    continue;
140
                }
770 user890104 141
 
898 user890104 142
                for (l = 0; l < iface->num_altsetting; ++l) {
143
                    iface_desc = &iface->altsetting[l];
770 user890104 144
 
898 user890104 145
                    if (
146
                        iface_desc->bInterfaceClass    != EMCORE_USB_INTERFACE_CLASS ||
147
                        iface_desc->bInterfaceSubClass != EMCORE_USB_INTERFACE_SUB_CLASS ||
148
                        iface_desc->bInterfaceProtocol != EMCORE_USB_INTERFACE_PROTOCOL
149
                    ) {
770 user890104 150
#ifdef DEBUG
898 user890104 151
                        fprintf(stderr, "Wrong interface class (%02X %02X %02X), trying next device...\n", iface_desc->bInterfaceClass, iface_desc->bInterfaceSubClass, iface_desc->bInterfaceProtocol);
770 user890104 152
#endif
153
 
898 user890104 154
                        continue;
155
                    }
156
 
770 user890104 157
#ifdef DEBUG
898 user890104 158
                    fprintf(stderr, "emCORE Debugger interface at %Zd\n", iface_desc->bInterfaceNumber);
770 user890104 159
#endif
160
 
898 user890104 161
                    usb_iface_num = iface_desc->bInterfaceNumber;
162
                    found = 1;
163
                    goto outside_search_loop;
770 user890104 164
                }
165
            }
166
        }
167
    }
898 user890104 168
 
169
    outside_search_loop:
770 user890104 170
 
898 user890104 171
    if (found) {
770 user890104 172
        res = usb_open(dev, reattach);
173
    }
898 user890104 174
    else {
175
        fprintf(stderr, "emCORE Debugger interface not found!\n");
770 user890104 176
 
177
        res = EMCORE_ERROR_NO_DEVICE;
178
    }
179
 
180
#ifdef DEBUG
181
    fprintf(stderr, "Freeing device list...\n");
182
#endif
183
    libusb_free_device_list(devs, 1);
184
 
185
    return res;
186
}
187
 
898 user890104 188
int32_t usb_open(libusb_device *dev, uint8_t *reattach) {
189
    int32_t res;
770 user890104 190
 
191
#ifdef DEBUG
192
    fprintf(stderr, "Opening USB device...\n");
193
#endif
194
    res = libusb_open(dev, &usb_handle);
195
 
898 user890104 196
    if (res != LIBUSB_SUCCESS) {
770 user890104 197
        return res;
198
    }
199
#ifdef DEBUG
200
    fprintf(stderr, "USB device opened!\n");
201
    fprintf(stderr, "Setting USB configuration 1...\n");
202
#endif
203
 
204
    res = libusb_set_configuration(usb_handle, 1);
205
 
898 user890104 206
    if (res != LIBUSB_SUCCESS) {
770 user890104 207
        return res;
208
    }
898 user890104 209
 
770 user890104 210
#ifdef DEBUG
211
    fprintf(stderr, "USB configuration set!\n");
212
#endif
213
    res = libusb_kernel_driver_active(usb_handle, 0);
214
 
898 user890104 215
    if (res < 0) {
216
        return res;
217
    }
218
 
219
    if (res == 1) {
770 user890104 220
        *reattach = 1;
221
 
222
        res = libusb_detach_kernel_driver(usb_handle, 0);
223
    }
224
 
898 user890104 225
    if (res != LIBUSB_SUCCESS) {
770 user890104 226
        return res;
227
    }
228
 
229
#ifdef DEBUG
230
    fprintf(stderr, "Claiming interface 0...\n");
231
#endif
232
    res = libusb_claim_interface(usb_handle, 0);
233
 
898 user890104 234
    if (res != LIBUSB_SUCCESS) {
770 user890104 235
        return res;
236
    }
237
 
238
#ifdef DEBUG
239
    fprintf(stderr, "Interface claimed successfully!\n");
240
#endif
241
 
242
    return LIBUSB_SUCCESS;
243
}
244
 
898 user890104 245
int32_t usb_control_transfer(uint8_t rq_type, void *data, size_t length) {
246
    int32_t res;
770 user890104 247
 
898 user890104 248
    res = libusb_control_transfer(usb_handle, rq_type, 0, 0, usb_iface_num, (unsigned char *)data, length, 10000);
770 user890104 249
 
898 user890104 250
    if (res < 0) {
770 user890104 251
        return res;
252
    }
253
 
898 user890104 254
    if ((size_t)res != length) {
770 user890104 255
        return EMCORE_ERROR_INCOMPLETE;
256
    }
257
 
258
    return LIBUSB_SUCCESS;
259
}
260
 
898 user890104 261
int32_t usb_close(uint8_t reattach) {
262
    int32_t res;
770 user890104 263
 
264
#ifdef DEBUG
265
    fprintf(stderr, "Releasing USB interface...\n");
266
#endif
267
    res = libusb_release_interface(usb_handle, 0);
268
 
898 user890104 269
    if (res != LIBUSB_SUCCESS) {
770 user890104 270
        return res;
271
    }
272
 
273
#ifdef DEBUG
274
    fprintf(stderr, "Released interface successfully!\n");
275
#endif
276
 
898 user890104 277
    if (reattach) {
770 user890104 278
#ifdef DEBUG
279
        fprintf(stderr, "Reattaching kernel driver...\n");
280
#endif
281
 
282
        res = libusb_attach_kernel_driver(usb_handle, 0);
283
 
898 user890104 284
        if (res == LIBUSB_SUCCESS) {
770 user890104 285
#ifdef DEBUG
286
            fprintf(stderr, "Reattached successfully!\n");
287
#endif
288
        }
898 user890104 289
        else {
770 user890104 290
            print_error(res);
291
 
292
            res = LIBUSB_SUCCESS;
293
        }
294
    }
295
#ifdef DEBUG
296
    fprintf(stderr, "Closing USB device handle...\n");
297
#endif
298
    libusb_close(usb_handle);
299
 
300
    return res;
301
}
302
 
898 user890104 303
void usb_exit(void) {
770 user890104 304
#ifdef DEBUG
305
    fprintf(stderr, "Deinitializing USB library...\n");
306
#endif
307
 
308
    libusb_exit(usb_ctx);
309
}
310
 
898 user890104 311
int32_t usb_destroy(uint8_t reattach) {
312
    int32_t res = LIBUSB_SUCCESS;
770 user890104 313
 
898 user890104 314
    if (usb_handle) {
770 user890104 315
        res = usb_close(reattach);
316
    }
317
 
898 user890104 318
    if (usb_ctx) {
770 user890104 319
        usb_exit();
320
    }
321
 
322
    return res;
323
}