Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
3
//    Copyright 2011 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
 
24
#include "global.h"
25
 
26
#include "emcore.h"
27
#include "util.h"
28
#include "usb.h"
29
 
30
 
31
libusb_context* usb_ctx = NULL;
32
libusb_device_handle* usb_handle = NULL;
33
 
34
extern struct emcore_usb_endpoints_addr emcore_usb_eps_addr;
35
extern struct emcore_usb_endpoints_max_packet_size emcore_usb_eps_mps;
36
 
37
int usb_init(void)
38
{
39
    int res;
40
 
41
#ifdef DEBUG
42
    fprintf(stderr, "Initialising USB library...\n");
43
#endif
44
 
45
    res = libusb_init(&usb_ctx);
46
 
47
    if (LIBUSB_SUCCESS != res)
48
    {
49
        return res;
50
    }
51
 
52
#ifdef DEBUG
53
    fprintf(stderr, "USB library initialized!\n");
54
    libusb_set_debug(usb_ctx, 3);
55
 
56
#endif
57
 
58
    return LIBUSB_SUCCESS;
59
}
60
 
785 user890104 61
int usb_find(uint16_t vendor_id, uint16_t product_id, uint8_t* reattach)
770 user890104 62
{
63
    libusb_device **devs, *dev;
64
    ssize_t devs_cnt;
790 user890104 65
    int res, i, j;
770 user890104 66
    struct libusb_device_descriptor dev_desc;
67
    uint8_t found = 0;
68
    struct libusb_config_descriptor* cfg_desc;
69
    const struct libusb_interface* iface;
70
    const struct libusb_interface_descriptor* iface_desc;
71
    const struct libusb_endpoint_descriptor* ep_desc;
72
 
73
#ifdef DEBUG
74
    fprintf(stderr, "Getting USB device list...\n");
75
#endif
76
 
77
    devs_cnt = libusb_get_device_list(usb_ctx, &devs);
78
 
79
    if (devs_cnt < 0)
80
    {
81
        return devs_cnt;
82
    }
83
 
84
#ifdef DEBUG
790 user890104 85
    fprintf(stderr, "Found %Zd USB devices!\n", devs_cnt);
770 user890104 86
#endif
87
    for (i = 0; i < devs_cnt; ++i)
88
    {
89
        dev = devs[i];
90
#ifdef DEBUG
91
        fprintf(stderr, "Getting device descriptor of USB device %d...\n", i);
92
#endif
93
        res = libusb_get_device_descriptor(dev, &dev_desc);
94
 
95
        if (LIBUSB_SUCCESS != res)
96
        {
97
#ifdef DEBUG
98
            fprintf(stderr, "Unable to get device descriptor of device %d!\n", i);
99
#endif
100
            continue;
101
        }
102
 
103
#ifdef DEBUG
104
        fprintf(stderr, "[%04x:%04x] bus %d, device %d, USB ver. %04x\n", dev_desc.idVendor,
105
            dev_desc.idProduct, libusb_get_bus_number(dev),
106
            libusb_get_device_address(dev), dev_desc.bcdUSB);
107
#endif
108
        if (vendor_id == dev_desc.idVendor && product_id == dev_desc.idProduct)
109
        {
110
#ifdef DEBUG
111
            fprintf(stderr, "Found emCORE USB device!\n");
112
#endif
113
            if (1 != dev_desc.bNumConfigurations)
114
            {
115
#ifdef DEBUG
116
                fprintf(stderr, "Number of configs is different than 1, not the right device...\n");
117
#endif
118
                continue;
119
            }
120
 
121
#ifdef DEBUG
122
            fprintf(stderr, "Getting config descriptor 0 of device...\n");
123
#endif
124
 
125
            res = libusb_get_config_descriptor(dev, 0, &cfg_desc);
126
 
127
            if (LIBUSB_SUCCESS != res)
128
            {
129
                return res;
130
            }
131
 
132
            if (1 != cfg_desc->bNumInterfaces)
133
            {
134
#ifdef DEBUG
135
                fprintf(stderr, "Wrong USB device, it should have exactly 1 interface\n");
136
#endif
137
 
138
                continue;
139
            }
140
 
141
            iface = &cfg_desc->interface[0];
142
 
143
            if (1 != iface->num_altsetting)
144
            {
145
#ifdef DEBUG
146
                fprintf(stderr, "Wrong USB device, it should have exactly 1 altsetting\n");
147
#endif
148
 
149
                continue;
150
            }
151
 
152
            iface_desc = &iface->altsetting[0];
153
 
154
            if (4 != iface_desc->bNumEndpoints)
155
            {
156
#ifdef DEBUG
157
                fprintf(stderr, "Wrong USB device, it should have exactly 4 endpoints\n");
158
#endif
159
 
160
                continue;
161
            }
162
 
163
#ifdef DEBUG
164
           fprintf(stderr, "Endpoints:");
165
#endif
166
 
790 user890104 167
            for (j = 0; j < 4; ++j)
770 user890104 168
            {
790 user890104 169
                ep_desc = &iface_desc->endpoint[j];
770 user890104 170
 
171
#ifdef DEBUG
790 user890104 172
                fprintf(stderr, " %d at 0x%02x", j, ep_desc->bEndpointAddress);
770 user890104 173
#endif
174
 
790 user890104 175
                switch (j) {
770 user890104 176
                    case 0:
177
                        emcore_usb_eps_addr.cout = ep_desc->bEndpointAddress;
178
                    break;
179
                    case 1:
180
                        emcore_usb_eps_addr.cin = ep_desc->bEndpointAddress;
181
                    break;
182
                    case 2:
183
                        emcore_usb_eps_addr.dout = ep_desc->bEndpointAddress;
184
                    break;
185
                    case 3:
186
                        emcore_usb_eps_addr.din = ep_desc->bEndpointAddress;
187
                    break;
188
                }
189
            }
190
 
191
#ifdef DEBUG
192
            fprintf(stderr, "\n");
193
#endif
194
 
195
            found = 1;
799 user890104 196
            break;
770 user890104 197
        }
198
    }
199
 
200
    if (found)
201
    {
202
        res = usb_open(dev, reattach);
203
    }
204
    else
205
    {
206
        fprintf(stderr, "USB device with VID=%4x and PID=%4x not found!\n",
207
            vendor_id, product_id);
208
 
209
        res = EMCORE_ERROR_NO_DEVICE;
210
    }
211
 
212
#ifdef DEBUG
213
    fprintf(stderr, "Freeing device list...\n");
214
#endif
215
    libusb_free_device_list(devs, 1);
216
 
217
    return res;
218
}
219
 
220
int usb_open(libusb_device* dev, uint8_t* reattach)
221
{
222
    int res;
223
 
224
#ifdef DEBUG
225
    fprintf(stderr, "Opening USB device...\n");
226
#endif
227
    res = libusb_open(dev, &usb_handle);
228
 
229
    if (LIBUSB_SUCCESS != res)
230
    {
231
        return res;
232
    }
233
#ifdef DEBUG
234
    fprintf(stderr, "USB device opened!\n");
235
    fprintf(stderr, "Setting USB configuration 1...\n");
236
#endif
237
 
238
    res = libusb_set_configuration(usb_handle, 1);
239
 
240
    if (LIBUSB_SUCCESS != res)
241
    {
242
        return res;
243
    }
244
#ifdef DEBUG
245
    fprintf(stderr, "USB configuration set!\n");
246
#endif
247
    res = libusb_kernel_driver_active(usb_handle, 0);
248
 
249
    if (1 == res)
250
    {
251
        *reattach = 1;
252
 
253
        res = libusb_detach_kernel_driver(usb_handle, 0);
254
    }
255
 
256
    if (LIBUSB_SUCCESS != res)
257
    {
258
        return res;
259
    }
260
 
261
#ifdef DEBUG
262
    fprintf(stderr, "Claiming interface 0...\n");
263
#endif
264
    res = libusb_claim_interface(usb_handle, 0);
265
 
266
    if (LIBUSB_SUCCESS != res)
267
    {
268
        return res;
269
    }
270
 
271
#ifdef DEBUG
272
    fprintf(stderr, "Interface claimed successfully!\n");
273
    fprintf(stderr, "Getting endpoints max size...\n");
274
#endif
275
 
276
    res = emcore_get_packet_info(&emcore_usb_eps_mps);
277
 
278
    if (EMCORE_SUCCESS != res)
279
    {
280
        return res;
281
    }
282
 
283
#ifdef DEBUG
284
    fprintf(stderr, "Got endpoint max size!\n");
285
    fprintf(stderr, "COUT max pckt: %d, CIN max pckt: %d, DOUT max pckt: %d, DIN max pckt: %d\n",
286
        emcore_usb_eps_mps.cout, emcore_usb_eps_mps.cin, emcore_usb_eps_mps.dout, emcore_usb_eps_mps.din
287
    );
288
#endif
289
 
290
    return LIBUSB_SUCCESS;
291
}
292
 
785 user890104 293
int usb_bulk_transfer(unsigned char endpoint, void* data, int length)
770 user890104 294
{
295
    int transferred;
296
    int res;
297
 
298
    res = libusb_bulk_transfer(usb_handle, endpoint, (unsigned char*)data, length, &transferred, 30000);
299
 
300
    if (LIBUSB_SUCCESS != res)
301
    {
302
        return res;
303
    }
304
 
305
    if (transferred != length)
306
    {
307
        return EMCORE_ERROR_INCOMPLETE;
308
    }
309
 
310
    return LIBUSB_SUCCESS;
311
}
312
 
785 user890104 313
int usb_close(uint8_t reattach) {
770 user890104 314
    int res;
315
 
316
#ifdef DEBUG
317
    fprintf(stderr, "Releasing USB interface...\n");
318
#endif
319
    res = libusb_release_interface(usb_handle, 0);
320
 
321
    if (LIBUSB_SUCCESS != res)
322
    {
323
        return res;
324
    }
325
 
326
#ifdef DEBUG
327
    fprintf(stderr, "Released interface successfully!\n");
328
#endif
329
 
330
    if (reattach)
331
    {
332
#ifdef DEBUG
333
        fprintf(stderr, "Reattaching kernel driver...\n");
334
#endif
335
 
336
        res = libusb_attach_kernel_driver(usb_handle, 0);
337
 
338
        if (LIBUSB_SUCCESS == res)
339
        {
340
#ifdef DEBUG
341
            fprintf(stderr, "Reattached successfully!\n");
342
#endif
343
        }
344
        else
345
        {
346
            print_error(res);
347
 
348
            res = LIBUSB_SUCCESS;
349
        }
350
    }
351
#ifdef DEBUG
352
    fprintf(stderr, "Closing USB device handle...\n");
353
#endif
354
    libusb_close(usb_handle);
355
 
356
    return res;
357
}
358
 
359
void usb_exit(void)
360
{
361
#ifdef DEBUG
362
    fprintf(stderr, "Deinitializing USB library...\n");
363
#endif
364
 
365
    libusb_exit(usb_ctx);
366
}
367
 
785 user890104 368
int usb_destroy(uint8_t reattach)
770 user890104 369
{
370
    int res = LIBUSB_SUCCESS;
371
 
372
    if (usb_handle)
373
    {
374
        res = usb_close(reattach);
375
    }
376
 
377
    if (usb_ctx)
378
    {
379
        usb_exit();
380
    }
381
 
382
    return res;
383
}