Subversion Repositories f9daq

Rev

Rev 197 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
195 f9daq 1
/********************************************************************\
2
 
3
  Name:         musbstd.c
4
  Created by:   Konstantin Olchanski, Stefan Ritt
5
 
6
  Contents:     Midas USB access
7
 
8
  $Id$
9
 
10
\********************************************************************/
11
 
12
#include <stdio.h>
13
#include <assert.h>
14
#include "musbstd.h"
15
 
16
#ifdef _MSC_VER                 // Windows includes
17
 
18
#include <windows.h>
19
#include <conio.h>
20
#include <winioctl.h>
21
 
22
#include <setupapi.h>
23
#include <initguid.h>           /* Required for GUID definition */
24
 
25
// link with SetupAPI.Lib.
26
#pragma comment (lib, "setupapi.lib")
27
 
28
// disable "deprecated" warning
29
#pragma warning( disable: 4996)
30
 
31
// {CBEB3FB1-AE9F-471c-9016-9B6AC6DCD323}
32
DEFINE_GUID(GUID_CLASS_MSCB_BULK, 0xcbeb3fb1, 0xae9f, 0x471c, 0x90, 0x16, 0x9b, 0x6a, 0xc6, 0xdc, 0xd3, 0x23);
33
 
34
#elif defined(OS_DARWIN)
35
 
36
#include <unistd.h>
37
#include <string.h>
38
#include <stdlib.h>
39
#include <ctype.h>
40
#include <sys/types.h>
41
#include <sys/ioctl.h>
42
#include <sys/time.h>
43
#include <fcntl.h>
44
 
45
#include <assert.h>
46
#include <mach/mach.h>
47
#include <IOKit/IOKitLib.h>
48
#include <IOKit/IOCFPlugIn.h>
49
#include <IOKit/usb/IOUSBLib.h>
50
 
51
#elif defined(OS_LINUX)         // Linux includes
52
 
53
#include <unistd.h>
54
#include <string.h>
55
#include <stdlib.h>
56
 
57
#endif
58
 
59
#ifdef HAVE_LIBUSB
60
#include <errno.h>
61
#include "usb.h"
62
#endif
63
 
64
#ifdef HAVE_LIBUSB10
65
#include <errno.h>
66
#include <libusb-1.0/libusb.h>
67
#endif
68
 
69
#if !defined(HAVE_LIBUSB) && !defined(HAVE_LIBUSB10)
70
#ifdef OS_DARWIN
71
 
72
IOReturn darwin_configure_device(MUSB_INTERFACE* musb)
73
{
74
   IOReturn status;
75
   io_iterator_t iter;
76
   io_service_t service;
77
   IOCFPlugInInterface **plugin;
78
   SInt32 score;
79
   IOUSBInterfaceInterface **uinterface;
80
   UInt8 numend;
81
 
82
   IOUSBDeviceInterface **device = (IOUSBDeviceInterface **)musb->device;
83
 
84
   status = (*device)->SetConfiguration(device, musb->usb_configuration);
85
   assert(status == kIOReturnSuccess);
86
 
87
   IOUSBFindInterfaceRequest request;
88
 
89
   request.bInterfaceClass = kIOUSBFindInterfaceDontCare;
90
   request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
91
   request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
92
   request.bAlternateSetting = kIOUSBFindInterfaceDontCare;
93
 
94
   status = (*device)->CreateInterfaceIterator(device, &request, &iter);
95
   assert(status == kIOReturnSuccess);
96
 
97
   while ((service = IOIteratorNext(iter))) {
98
      int i;
99
      status =
100
        IOCreatePlugInInterfaceForService(service, kIOUSBInterfaceUserClientTypeID,
101
                                          kIOCFPlugInInterfaceID, &plugin, &score);
102
      assert(status == kIOReturnSuccess);
103
 
104
      status =
105
        (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
106
                                  (void *) &uinterface);
107
      assert(status == kIOReturnSuccess);
108
 
109
 
110
      status = (*uinterface)->USBInterfaceOpen(uinterface);
111
      fprintf(stderr, "musb_open: USBInterfaceOpen status 0x%x\n", status);
112
      assert(status == kIOReturnSuccess);
113
 
114
      status = (*uinterface)->GetNumEndpoints(uinterface, &numend);
115
      assert(status == kIOReturnSuccess);
116
 
117
      fprintf(stderr, "musb_open: endpoints: %d\n", numend);
118
 
119
      for (i=1; i<=numend; i++) {
120
         status = (*uinterface)->GetPipeStatus(uinterface, i);
121
         fprintf(stderr, "musb_open: pipe %d status: 0x%x\n", i, status);
122
 
123
#if 0
124
         status = (*uinterface)->ClearPipeStall(uinterface, i);
125
         fprintf(stderr, "musb_open: pipe %d ClearPipeStall() status: 0x%x\n", i, status);
126
         status = (*uinterface)->ResetPipe(uinterface, i);
127
         fprintf(stderr, "musb_open: pipe %d ResetPipe() status: 0x%x\n", i, status);
128
         status = (*uinterface)->AbortPipe(uinterface, i);
129
         fprintf(stderr, "musb_open: pipe %d AbortPipe() status: 0x%x\n", i, status);
130
#endif
131
      }
132
 
133
      musb->interface = uinterface;
134
      return kIOReturnSuccess;
135
   }
136
 
137
   assert(!"Should never be reached!");
138
   return -1;
139
}
140
 
141
#endif
142
 
143
#endif
144
 
145
int musb_open(MUSB_INTERFACE **musb_interface, int vendor, int product, int instance, int configuration, int usbinterface)
146
{
147
#if defined(HAVE_LIBUSB)
148
 
149
   struct usb_bus *bus;
150
   struct usb_device *dev;
151
   int count = 0;
152
 
153
   usb_init();
154
   usb_find_busses();
155
   usb_find_devices();
156
   usb_set_debug(3);
157
 
158
   for (bus = usb_get_busses(); bus; bus = bus->next)
159
      for (dev = bus->devices; dev; dev = dev->next)
160
         if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) {
161
            if (count == instance) {
162
               int status;
163
               usb_dev_handle *udev;
164
 
165
               udev = usb_open(dev);
166
               if (!udev) {
167
                  fprintf(stderr, "musb_open: usb_open() error\n");
168
                  return MUSB_ACCESS_ERROR;
169
               }
170
 
171
               status = usb_set_configuration(udev, configuration);
172
               if (status < 0) {
173
                  fprintf(stderr, "musb_open: usb_set_configuration() error %d (%s)\n", status,
174
                     strerror(-status));
175
                  fprintf(stderr,
176
                     "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\" and \"/dev/bus/usb/%s/%s\"\n",
177
                     vendor, product, instance, bus->dirname, dev->filename, bus->dirname, dev->filename);
178
                  return MUSB_ACCESS_ERROR;
179
               }
180
 
181
               /* see if we have write access */
182
               status = usb_claim_interface(udev, usbinterface);
183
               if (status < 0) {
184
                  fprintf(stderr, "musb_open: usb_claim_interface() error %d (%s)\n", status,
185
                     strerror(-status));
186
 
187
#ifdef _MSC_VER
188
                  fprintf(stderr,
189
                     "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n",
190
                     vendor, product, instance);
191
#else
192
                  fprintf(stderr,
193
                     "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\"\n",
194
                     vendor, product, instance, bus->dirname, dev->filename);
195
#endif
196
 
197
                  return MUSB_ACCESS_ERROR;
198
               }
199
 
200
               *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE));
201
               (*musb_interface)->dev = udev;
202
               (*musb_interface)->usb_configuration = configuration;
203
               (*musb_interface)->usb_interface     = usbinterface;
204
               return MUSB_SUCCESS;
205
            }
206
 
207
            count++;
208
         }
209
 
210
   return MUSB_NOT_FOUND;
211
 
212
#elif defined(HAVE_LIBUSB10)
213
 
214
   static int first_call = 1;
215
 
216
   libusb_device **dev_list;
217
   libusb_device_handle *dev;
218
   struct libusb_device_descriptor desc;
219
 
220
   int status, i, n;
221
   int count = 0;
222
 
223
   if (first_call) {
224
      first_call = 0;
225
      libusb_init(NULL);
226
      // libusb_set_debug(NULL, 3);
227
   }
228
 
229
   n = libusb_get_device_list(NULL, &dev_list);
230
 
231
   for (i=0 ; i<n ; i++) {
232
      status = libusb_get_device_descriptor(dev_list[i], &desc);
233
      if (desc.idVendor == vendor && desc.idProduct == product) {
234
         if (count == instance) {
235
            status = libusb_open(dev_list[i], &dev);
236
            if (status < 0) {
237
               fprintf(stderr, "musb_open: libusb_open() error %d\n", status);
238
               return MUSB_ACCESS_ERROR;
239
            }
240
 
241
            status = libusb_set_configuration(dev, configuration);
242
            if (status < 0) {
243
               fprintf(stderr, "musb_open: usb_set_configuration() error %d\n", status);
244
               fprintf(stderr,
245
                       "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\" and \"/dev/bus/usb/%d/%d\"\n",
246
                       vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]), libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]));
247
               return MUSB_ACCESS_ERROR;
248
            }
249
 
250
            /* see if we have write access */
251
            status = libusb_claim_interface(dev, usbinterface);
252
            if (status < 0) {
253
               fprintf(stderr, "musb_open: libusb_claim_interface() error %d\n", status);
254
 
255
#ifdef _MSC_VER
256
               fprintf(stderr,
257
                       "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n",
258
                       vendor, product, instance);
259
#else
260
               fprintf(stderr,
261
                       "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\"\n",
262
                       vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]));
263
#endif
264
 
265
               return MUSB_ACCESS_ERROR;
266
            }
267
 
268
            *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE));
269
            (*musb_interface)->dev = dev;
270
            (*musb_interface)->usb_configuration = configuration;
271
            (*musb_interface)->usb_interface     = usbinterface;
272
            return MUSB_SUCCESS;
273
 
274
         }
275
         count++;
276
      }
277
   }
278
 
279
   libusb_free_device_list(dev_list, 1);
280
 
281
   return MUSB_NOT_FOUND;
282
 
283
#elif defined(OS_DARWIN)
284
 
285
   kern_return_t status;
286
   io_iterator_t iter;
287
   io_service_t service;
288
   IOCFPlugInInterface **plugin;
289
   SInt32 score;
290
   IOUSBDeviceInterface **device;
291
   UInt16 xvendor, xproduct;
292
   int count = 0;
293
 
294
   *musb_interface = calloc(1, sizeof(MUSB_INTERFACE));
295
 
296
   status = IORegistryCreateIterator(kIOMasterPortDefault, kIOUSBPlane, kIORegistryIterateRecursively, &iter);
297
   assert(status == kIOReturnSuccess);
298
 
299
   while ((service = IOIteratorNext(iter))) {
300
      status =
301
          IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID,
302
                                            &plugin, &score);
303
      assert(status == kIOReturnSuccess);
304
 
305
      status = IOObjectRelease(service);
306
      assert(status == kIOReturnSuccess);
307
 
308
      status =
309
          (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (void *) &device);
310
      assert(status == kIOReturnSuccess);
311
 
312
      status = (*plugin)->Release(plugin);
313
 
314
      status = (*device)->GetDeviceVendor(device, &xvendor);
315
      assert(status == kIOReturnSuccess);
316
      status = (*device)->GetDeviceProduct(device, &xproduct);
317
      assert(status == kIOReturnSuccess);
318
 
319
      //fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x\n", xvendor, xproduct);
320
 
321
      if (xvendor == vendor && xproduct == product) {
322
         if (count == instance) {
323
 
324
            fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x, instance %d\n", xvendor, xproduct, instance);
325
 
326
            status = (*device)->USBDeviceOpen(device);
327
            fprintf(stderr, "musb_open: USBDeviceOpen status 0x%x\n", status);
328
 
329
            assert(status == kIOReturnSuccess);
330
 
331
            (*musb_interface)->usb_configuration = configuration;
332
            (*musb_interface)->usb_interface     = usbinterface;
333
            (*musb_interface)->device = (void*)device;
334
            (*musb_interface)->interface = NULL;
335
 
336
            status = darwin_configure_device(*musb_interface);
337
 
338
            if (status == kIOReturnSuccess)
339
               return MUSB_SUCCESS;
340
 
341
            fprintf(stderr, "musb_open: USB device exists, but configuration fails!");
342
            return MUSB_NOT_FOUND;
343
         }
344
 
345
         count++;
346
      }
347
 
348
      (*device)->Release(device);
349
   }
350
 
351
   return MUSB_NOT_FOUND;
352
#elif defined(_MSC_VER)
353
   GUID guid;
354
   HDEVINFO hDevInfoList;
355
   SP_DEVICE_INTERFACE_DATA deviceInfoData;
356
   PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData;
357
   ULONG predictedLength, requiredLength;
358
   int status;
359
   char device_name[256], str[256];
360
 
361
   *musb_interface = (MUSB_INTERFACE *)calloc(1, sizeof(MUSB_INTERFACE));
362
 
363
   guid = GUID_CLASS_MSCB_BULK;
364
 
365
   // Retrieve device list for GUID that has been specified.
366
   hDevInfoList = SetupDiGetClassDevs(&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
367
 
368
   status = FALSE;
369
   if (hDevInfoList != NULL) {
370
 
371
      // Clear data structure
372
      memset(&deviceInfoData, 0, sizeof(deviceInfoData));
373
      deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
374
 
375
      // retrieves a context structure for a device interface of a device information set.
376
      if (SetupDiEnumDeviceInterfaces(hDevInfoList, 0, &guid, instance, &deviceInfoData)) {
377
         // Must get the detailed information in two steps
378
         // First get the length of the detailed information and allocate the buffer
379
         // retrieves detailed information about a specified device interface.
380
         functionClassDeviceData = NULL;
381
 
382
         predictedLength = requiredLength = 0;
383
 
384
         SetupDiGetDeviceInterfaceDetail(hDevInfoList, &deviceInfoData, NULL,   // Not yet allocated
385
                                         0,     // Set output buffer length to zero
386
                                         &requiredLength,       // Find out memory requirement
387
                                         NULL);
388
 
389
         predictedLength = requiredLength;
390
         functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(predictedLength);
391
         functionClassDeviceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
392
 
393
         // Second, get the detailed information
394
         if (SetupDiGetDeviceInterfaceDetail(hDevInfoList,
395
                                             &deviceInfoData, functionClassDeviceData,
396
                                             predictedLength, &requiredLength, NULL)) {
397
 
398
            // Save the device name for subsequent pipe open calls
399
            strcpy(device_name, functionClassDeviceData->DevicePath);
400
            free(functionClassDeviceData);
401
 
402
            // Signal device found
403
            status = TRUE;
404
         } else
405
            free(functionClassDeviceData);
406
      }
407
   }
408
   // SetupDiDestroyDeviceInfoList() destroys a device information set
409
   // and frees all associated memory.
410
   SetupDiDestroyDeviceInfoList(hDevInfoList);
411
 
412
   if (status) {
413
 
414
      // Get the read handle
415
      sprintf(str, "%s\\PIPE00", device_name);
416
      (*musb_interface)->rhandle = CreateFile(str,
417
                                    GENERIC_WRITE | GENERIC_READ,
418
                                    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
419
                                    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
420
 
421
      if ((*musb_interface)->rhandle == INVALID_HANDLE_VALUE)
422
         return MUSB_ACCESS_ERROR;
423
 
424
      // Get the write handle
425
      sprintf(str, "%s\\PIPE01", device_name);
426
      (*musb_interface)->whandle = CreateFile(str,
427
                                    GENERIC_WRITE | GENERIC_READ,
428
                                    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
429
 
430
      if ((*musb_interface)->whandle == INVALID_HANDLE_VALUE)
431
         return MUSB_ACCESS_ERROR;
432
 
433
      return MUSB_SUCCESS;
434
   }
435
 
436
   return MUSB_NOT_FOUND;
437
#endif
438
}
439
 
440
int musb_set_altinterface(MUSB_INTERFACE *musb_interface, int index)
441
{
442
#if defined (HAVE_LIBUSB)
443
   int status;
444
 
445
   status = usb_set_altinterface(musb_interface->dev, index);
446
   if (status < 0)
447
      fprintf(stderr, "musb_set_altinterface: usb_set_altinterface() error %d\n", status);
448
 
449
   return status;
450
#else
451
   return -1;
452
#endif
453
}
454
 
455
int musb_close(MUSB_INTERFACE *musb_interface)
456
{
457
#if defined(HAVE_LIBUSB)
458
 
459
   int status;
460
   status = usb_release_interface(musb_interface->dev, musb_interface->usb_interface);
461
   if (status < 0)
462
      fprintf(stderr, "musb_close: usb_release_interface() error %d\n", status);
463
 
464
#ifdef OS_LINUX   // linux wants a reset, otherwise the device cannot be accessed next time
465
   musb_reset(musb_interface);
466
#endif
467
 
468
   status = usb_close(musb_interface->dev);
469
   if (status < 0)
470
      fprintf(stderr, "musb_close: usb_close() error %d\n", status);
471
 
472
#elif defined(HAVE_LIBUSB10)   
473
 
474
   int status;
475
   status = libusb_release_interface(musb_interface->dev, musb_interface->usb_interface);
476
   if (status < 0)
477
      fprintf(stderr, "musb_close: libusb_release_interface() error %d\n", status);
478
 
479
#ifdef OS_LINUX   // linux wants a reset, otherwise the device cannot be accessed next time
480
   musb_reset(musb_interface);
481
#endif
482
 
483
   libusb_close(musb_interface->dev);
484
 
485
#elif defined(OS_DARWIN)
486
 
487
   IOReturn status;
488
   IOUSBInterfaceInterface **interface = (IOUSBInterfaceInterface **)musb_interface->interface;
489
 
490
   status = (*interface)->USBInterfaceClose(interface);
491
   if (status != kIOReturnSuccess)
492
      fprintf(stderr, "musb_close: USBInterfaceClose() status %d 0x%x\n", status, status);
493
 
494
   status = (*interface)->Release(interface);
495
   if (status != kIOReturnSuccess)
496
      fprintf(stderr, "musb_close: USB Interface Release() status %d 0x%x\n", status, status);
497
 
498
   IOUSBDeviceInterface **device = (IOUSBDeviceInterface**)musb_interface->device;
499
   status = (*device)->USBDeviceClose(device);
500
   if (status != kIOReturnSuccess)
501
      fprintf(stderr, "musb_close: USBDeviceClose() status %d 0x%x\n", status, status);
502
 
503
   status = (*device)->Release(device);
504
   if (status != kIOReturnSuccess)
505
      fprintf(stderr, "musb_close: USB Device Release() status %d 0x%x\n", status, status);
506
 
507
#elif defined(_MSC_VER)
508
 
509
   CloseHandle(musb_interface->rhandle);
510
   CloseHandle(musb_interface->whandle);
511
 
512
#else
513
   assert(!"musb_close() is not implemented");
514
#endif
515
 
516
   /* free memory allocated in musb_open() */
517
   free(musb_interface);
518
   return 0;
519
}
520
 
521
int musb_write(MUSB_INTERFACE *musb_interface, int endpoint, const void *buf, int count, int timeout)
522
{
523
   int n_written;
524
 
525
#if defined(HAVE_LIBUSB)
526
   n_written = usb_bulk_write(musb_interface->dev, endpoint, (char*)buf, count, timeout);
527
   if (n_written != count) {
528
      fprintf(stderr, "musb_write: requested %d, wrote %d, errno %d (%s)\n", count, n_written, errno, strerror(errno));
529
   }
530
#elif defined(HAVE_LIBUSB10)
531
   int status = libusb_bulk_transfer(musb_interface->dev, endpoint, (unsigned char*)buf, count, &n_written, timeout);
532
   if (n_written != count) {
533
      fprintf(stderr, "musb_write: requested %d, wrote %d, errno %d (%s)\n", count, n_written, status, strerror(status));
534
   }
535
#elif defined(OS_DARWIN)
536
   IOReturn status;
537
   IOUSBInterfaceInterface182 **interface = (IOUSBInterfaceInterface182 **)musb_interface->interface;
538
   status = (*interface)->WritePipeTO(interface, endpoint, buf, count, 0, timeout);
539
   if (status != 0) {
540
      fprintf(stderr, "musb_write: WritePipe() status %d 0x%x\n", status, status);
541
      return -1;
542
   }
543
   n_written = count;
544
#elif defined(_MSC_VER)
545
   WriteFile(musb_interface->whandle, buf, count, &n_written, NULL);
546
#endif
547
 
548
   //fprintf(stderr, "musb_write(ep %d, %d bytes) (%s) returns %d\n", endpoint, count, buf, n_written); 
549
 
550
   return n_written;
551
}
552
 
553
int musb_read(MUSB_INTERFACE *musb_interface, int endpoint, void *buf, int count, int timeout)
554
{
555
   int n_read = 0;
556
 
557
#if defined(HAVE_LIBUSB)
558
 
559
   n_read = usb_bulk_read(musb_interface->dev, endpoint | 0x80, (char*)buf, count, timeout);
560
   /* errors should be handled in upper layer ....
561
   if (n_read <= 0) {
562
      fprintf(stderr, "musb_read: requested %d, read %d, errno %d (%s)\n", count, n_read, errno, strerror(errno));
563
   }
564
   */
565
 
566
#elif defined(HAVE_LIBUSB10)
567
 
568
   libusb_bulk_transfer(musb_interface->dev, endpoint | 0x80, (unsigned char*)buf, count, &n_read, timeout);
569
   /* errors should be handled in upper layer ....
570
    if (n_read <= 0) {
571
    fprintf(stderr, "musb_read: requested %d, read %d, errno %d (%s)\n", count, n_read, status, strerror(status));
572
    }
573
    */
574
 
575
#elif defined(OS_DARWIN)
576
 
577
   UInt32 xcount = count;
578
   IOReturn status;
579
   IOUSBInterfaceInterface182 **interface = (IOUSBInterfaceInterface182 **)musb_interface->interface;
580
 
581
   status = (*interface)->ReadPipeTO(interface, endpoint, buf, &xcount, 0, timeout);
582
   if (status != kIOReturnSuccess) {
583
      fprintf(stderr, "musb_read: requested %d, read %d, ReadPipe() status %d 0x%x (%s)\n", count, n_read, status, status, strerror(status));
584
      return -1;
585
   }
586
 
587
   n_read = xcount;
588
 
589
#elif defined(_MSC_VER)
590
 
591
   OVERLAPPED overlapped;
592
   int status;
593
 
594
   memset(&overlapped, 0, sizeof(overlapped));
595
   overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
596
   n_read = 0;
597
 
598
   status = ReadFile(musb_interface->rhandle, buf, count, &n_read, &overlapped);
599
 
600
   if (!status) {
601
 
602
      status = GetLastError();
603
      if (status != ERROR_IO_PENDING)
604
         return 0;
605
 
606
      /* wait for completion with timeout */
607
      status = WaitForSingleObject(overlapped.hEvent, timeout);
608
      if (status == WAIT_TIMEOUT)
609
         CancelIo(musb_interface->rhandle);
610
      else
611
         GetOverlappedResult(musb_interface->rhandle, &overlapped, &n_read, FALSE);
612
   }
613
 
614
   CloseHandle(overlapped.hEvent);
615
 
616
#endif
617
 
618
   //fprintf(stderr, "musb_read(ep %d, %d bytes) returns %d (%s)\n", endpoint, count, n_read, buf); 
619
 
620
   return n_read;
621
}
622
 
623
int musb_reset(MUSB_INTERFACE *musb_interface)
624
{
625
#if defined(HAVE_LIBUSB)
626
 
627
   /* Causes re-enumeration: After calling usb_reset, the device will need
628
      to re-enumerate and thusly, requires you to find the new device and
629
      open a new handle. The handle used to call usb_reset will no longer work */
630
 
631
   int status;
632
   status = usb_reset(musb_interface->dev);
633
   if (status < 0)
634
      fprintf(stderr, "musb_reset: usb_reset() status %d\n", status);
635
 
636
#elif defined(HAVE_LIBUSB10)
637
 
638
   int status;
639
   status = libusb_reset_device(musb_interface->dev);
640
   if (status < 0)
641
      fprintf(stderr, "musb_reset: usb_reset() status %d\n", status);
642
 
643
#elif defined(OS_DARWIN)
644
 
645
   IOReturn status;
646
   IOUSBDeviceInterface **device = (IOUSBDeviceInterface**)musb_interface->device;
647
 
648
   status = (*device)->ResetDevice(device);
649
   fprintf(stderr, "musb_reset: ResetDevice() status 0x%x\n", status);
650
 
651
   status = darwin_configure_device(musb_interface);
652
   assert(status == kIOReturnSuccess);
653
 
654
#elif defined(_MSC_VER)
655
 
656
#define IOCTL_BULKUSB_RESET_DEVICE          CTL_CODE(FILE_DEVICE_UNKNOWN,     \
657
                                                     1,                       \
658
                                                     METHOD_BUFFERED,         \
659
                                                     FILE_ANY_ACCESS)
660
#define IOCTL_BULKUSB_RESET_PIPE            CTL_CODE(FILE_DEVICE_UNKNOWN,     \
661
                                                     2,                       \
662
                                                     METHOD_BUFFERED,         \
663
                                                     FILE_ANY_ACCESS)
664
 
665
   int status, n_bytes;
666
 
667
   status =  DeviceIoControl(musb_interface->rhandle,
668
                  IOCTL_BULKUSB_RESET_DEVICE,
669
                  NULL, 0, NULL, 0, &n_bytes, NULL);
670
   status =  DeviceIoControl(musb_interface->whandle,
671
                  IOCTL_BULKUSB_RESET_DEVICE,
672
                  NULL, 0, NULL, 0, &n_bytes, NULL);
673
   status =  DeviceIoControl(musb_interface->rhandle,
674
                  IOCTL_BULKUSB_RESET_PIPE,
675
                  NULL, 0, NULL, 0, &n_bytes, NULL);
676
   status =  DeviceIoControl(musb_interface->whandle,
677
                  IOCTL_BULKUSB_RESET_PIPE,
678
                  NULL, 0, NULL, 0, &n_bytes, NULL);
679
   return status;
680
 
681
#endif
682
   return 0;
683
}
684
 
685
int musb_get_device(MUSB_INTERFACE *usb_interface)
686
{
687
#ifdef HAVE_LIBUSB
688
   struct usb_device_descriptor d;
689
   usb_get_descriptor(usb_interface->dev, USB_DT_DEVICE, 0, &d, sizeof(d));
690
   return d.bcdDevice;
691
#elif HAVE_LIBUSB10
692
   struct libusb_device_descriptor d;
693
   libusb_get_descriptor(usb_interface->dev, LIBUSB_DT_DEVICE, 0, (unsigned char *)&d, sizeof(d));
694
   return d.bcdDevice;
695
#else
696
   return 0;
697
#endif
698
}
699
 
700
/* end */