/[pcsclite]/trunk/Drivers/ccid/src/ccid_usb.c
ViewVC logotype

Diff of /trunk/Drivers/ccid/src/ccid_usb.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1804 by rousseau, Tue Jan 17 19:57:11 2006 UTC revision 2871 by rousseau, Tue Apr 8 09:34:13 2008 UTC
# Line 1  Line 1 
1  /*  /*
2      ccid_usb.c: USB access routines using the libusb library      ccid_usb.c: USB access routines using the libusb library
3      Copyright (C) 2003-2004   Ludovic Rousseau      Copyright (C) 2003-2008   Ludovic Rousseau
4    
5      This library is free software; you can redistribute it and/or      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Lesser General Public      modify it under the terms of the GNU Lesser General Public
# Line 24  Line 24 
24  #define __CCID_USB__  #define __CCID_USB__
25    
26  #include <stdio.h>  #include <stdio.h>
27  #include <string.h>  #include <string.h>
28  #include <errno.h>  #include <errno.h>
29  # ifdef S_SPLINT_S  # ifdef S_SPLINT_S
30  # include <sys/types.h>  # include <sys/types.h>
31  # endif  # endif
32  #include <usb.h>  #include <usb.h>
33    #include <ifdhandler.h>
34    
35    #include "misc.h"
36  #include "ccid.h"  #include "ccid.h"
37  #include "config.h"  #include "config.h"
38  #include "debug.h"  #include "debug.h"
# Line 52  Line 54 
54   * Manufacturer and Product ID are also used to identify the device */   * Manufacturer and Product ID are also used to identify the device */
55  #define ALLOW_PROPRIETARY_CLASS  #define ALLOW_PROPRIETARY_CLASS
56    
 /*  
  * The O2Micro OZ776S reader has a wrong USB descriptor  
  * The extra[] field is associated with the last endpoint instead of the  
  * main USB descriptor  
  */  
 #define O2MICRO_OZ776_PATCH  
   
57  #define BUS_DEVICE_STRSIZE 32  #define BUS_DEVICE_STRSIZE 32
58    
59  typedef struct  typedef struct
60  {  {
61          usb_dev_handle *handle;          usb_dev_handle *handle;
62          struct usb_device *dev;          char *dirname;
63            char *filename;
64          int interface;          int interface;
65    
66          /*          /*
# Line 72  typedef struct Line 68  typedef struct
68           */           */
69          int bulk_in;          int bulk_in;
70          int bulk_out;          int bulk_out;
71            int interrupt;
72    
73          /* Number of slots using the same device */          /* Number of slots using the same device */
74          int real_nb_opened_slots;          int real_nb_opened_slots;
# Line 87  typedef struct Line 84  typedef struct
84  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
85  #include "ccid_usb.h"  #include "ccid_usb.h"
86    
87  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice);
88  int ccid_check_firmware(struct usb_device *dev);  int ccid_check_firmware(struct usb_device *dev);
89  static unsigned int *get_data_rates(unsigned int reader_index);  static unsigned int *get_data_rates(unsigned int reader_index,
90            struct usb_device *dev);
91    
92  /* ne need to initialize to 0 since it is static */  /* ne need to initialize to 0 since it is static */
93  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];  static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
# Line 106  struct _bogus_firmware Line 104  struct _bogus_firmware
104  };  };
105    
106  static struct _bogus_firmware Bogus_firmwares[] = {  static struct _bogus_firmware Bogus_firmwares[] = {
         { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */ /* the firmware version if not correct since I don't have received a working reader yet */  
107          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */          { 0x04e6, 0xe001, 0x0516 },     /* SCR 331 */
108          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */          { 0x04e6, 0x5111, 0x0620 },     /* SCR 331-DI */
109          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */          { 0x04e6, 0x5115, 0x0514 },     /* SCR 335 */
110          { 0x04e6, 0xe003, 0x0504 },     /* SPR 532 */          { 0x04e6, 0xe003, 0x0510 },     /* SPR 532 */
111          { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */          { 0x0D46, 0x3001, 0x0037 },     /* KAAN Base */
112          { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */          { 0x0D46, 0x3002, 0x0037 },     /* KAAN Advanced */
113            { 0x09C3, 0x0008, 0x0203 },     /* ActivCard V2 */
114            { 0x0DC3, 0x1004, 0x0502 },     /* ASE IIIe USBv2 */
115            { 0x0DC3, 0x1102, 0x0607 },     /* ASE IIIe KB USB */
116            { 0x058F, 0x9520, 0x0102 },     /* Alcor AU9520-G */
117    
118            /* the firmware version is not correct since I do not have received a
119             * working reader yet */
120    #ifndef O2MICRO_OZ776_PATCH
121            { 0x0b97, 0x7762, 0x0111 },     /* Oz776S */
122    #endif
123  };  };
124    
125    /* data rates supported by the secondary slots on the GemCore Pos Pro & SIM Pro */
126    unsigned int SerialCustomDataRates[] = { GEMPLUS_CUSTOM_DATA_RATES, 0 };
127    
128    
129  /*****************************************************************************  /*****************************************************************************
130   *   *
# Line 147  status_t OpenUSBByName(unsigned int read Line 157  status_t OpenUSBByName(unsigned int read
157    
158          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);          DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);
159    
160    #ifndef __APPLE__
161          /* device name specified */          /* device name specified */
162          if (device)          if (device)
163          {          {
# Line 191  status_t OpenUSBByName(unsigned int read Line 202  status_t OpenUSBByName(unsigned int read
202                          }                          }
203                  }                  }
204          }          }
205    #endif
206    
207          if (busses == NULL)          if (busses == NULL)
208                  usb_init();                  usb_init();
# Line 242  status_t OpenUSBByName(unsigned int read Line 254  status_t OpenUSBByName(unsigned int read
254          else          else
255                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
256          vendorID = strlen(keyValue);          vendorID = strlen(keyValue);
257          alias = 0x1D;          alias = 0x1C;
258          for (; vendorID--;)          for (; vendorID--;)
259                  alias ^= keyValue[vendorID];                  alias ^= keyValue[vendorID];
260    
# Line 261  status_t OpenUSBByName(unsigned int read Line 273  status_t OpenUSBByName(unsigned int read
273                  /* go to next supported reader for next round */                  /* go to next supported reader for next round */
274                  alias++;                  alias++;
275    
276    #ifndef __APPLE__
277                  /* the device was specified but is not the one we are trying to find */                  /* the device was specified but is not the one we are trying to find */
278                  if (device                  if (device
279                          && (vendorID != device_vendor || productID != device_product))                          && (vendorID != device_vendor || productID != device_product))
280                          continue;                          continue;
281    #else
282                    /* Leopard puts the friendlyname in the device argument */
283                    if (device && strcmp(device, keyValue))
284                            continue;
285    #endif
286    
287                  /* on any USB buses */                  /* on any USB buses */
288                  for (bus = busses; bus; bus = bus->next)                  for (bus = busses; bus; bus = bus->next)
# Line 289  status_t OpenUSBByName(unsigned int read Line 307  status_t OpenUSBByName(unsigned int read
307                                          /* is it already opened? */                                          /* is it already opened? */
308                                          already_used = FALSE;                                          already_used = FALSE;
309    
310                                            DEBUG_COMM3("Checking device: %s/%s",
311                                                    bus->dirname, dev->filename);
312                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)                                          for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
313                                          {                                          {
314                                                  if (usbDevice[r].dev)                                                  if (usbDevice[r].handle)
315                                                  {                                                  {
                                                         DEBUG_COMM3("Checking device: %s/%s",  
                                                                 bus->dirname, dev->filename);  
316                                                          /* same busname, same filename */                                                          /* same busname, same filename */
317                                                          if (strcmp(usbDevice[r].dev->bus->dirname, bus->dirname) == 0 && strcmp(usbDevice[r].dev->filename, dev->filename) == 0)                                                          if (strcmp(usbDevice[r].dirname, bus->dirname) == 0 && strcmp(usbDevice[r].filename, dev->filename) == 0)
318                                                                  already_used = TRUE;                                                                  already_used = TRUE;
319                                                  }                                                  }
320                                          }                                          }
# Line 305  status_t OpenUSBByName(unsigned int read Line 323  status_t OpenUSBByName(unsigned int read
323                                          if (already_used)                                          if (already_used)
324                                          {                                          {
325                                                  if ((previous_reader_index != -1)                                                  if ((previous_reader_index != -1)
326                                                          && usbDevice[previous_reader_index].dev                                                          && usbDevice[previous_reader_index].handle
327                                                          && (strcmp(usbDevice[previous_reader_index].dev->bus->dirname, bus->dirname)  == 0)                                                          && (strcmp(usbDevice[previous_reader_index].dirname, bus->dirname)  == 0)
328                                                          && (strcmp(usbDevice[previous_reader_index].dev->filename, dev->filename) == 0)                                                          && (strcmp(usbDevice[previous_reader_index].filename, dev->filename) == 0)
329                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)                                                          && usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
330                                                  {                                                  {
331                                                          /* we reuse the same device                                                          /* we reuse the same device
332                                                           * and the reader is multi-slot */                                                           * and the reader is multi-slot */
333                                                          usbDevice[reader_index] = usbDevice[previous_reader_index];                                                          usbDevice[reader_index] = usbDevice[previous_reader_index];
334                                                            /* the other slots do not have the same data rates */
335                                                            if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
336                                                                    || (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
337                                                            {
338                                                                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
339                                                                    usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
340                                                            }
341    
342                                                          *usbDevice[reader_index].nb_opened_slots += 1;                                                          *usbDevice[reader_index].nb_opened_slots += 1;
343                                                          usbDevice[reader_index].ccid.bCurrentSlotIndex++;                                                          usbDevice[reader_index].ccid.bCurrentSlotIndex++;
344                                                            usbDevice[reader_index].ccid.dwSlotStatus =
345                                                                    IFD_ICC_PRESENT;
346                                                          DEBUG_INFO2("Opening slot: %d",                                                          DEBUG_INFO2("Opening slot: %d",
347                                                                  usbDevice[reader_index].ccid.bCurrentSlotIndex);                                                                  usbDevice[reader_index].ccid.bCurrentSlotIndex);
348                                                          goto end;                                                          goto end;
# Line 357  status_t OpenUSBByName(unsigned int read Line 385  status_t OpenUSBByName(unsigned int read
385                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",                                                  DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
386                                                          bus->dirname, dev->filename);                                                          bus->dirname, dev->filename);
387                                                  return STATUS_UNSUCCESSFUL;                                                  return STATUS_UNSUCCESSFUL;
388                                          }                                          }
389    
390                                          if (usb_interface->altsetting->extralen != 54)                                          if (usb_interface->altsetting->extralen != 54)
391                                          {                                          {
# Line 393  status_t OpenUSBByName(unsigned int read Line 421  status_t OpenUSBByName(unsigned int read
421    
422                                          /* store device information */                                          /* store device information */
423                                          usbDevice[reader_index].handle = dev_handle;                                          usbDevice[reader_index].handle = dev_handle;
424                                          usbDevice[reader_index].dev = dev;                                          usbDevice[reader_index].dirname = strdup(bus->dirname);
425                                            usbDevice[reader_index].filename = strdup(dev->filename);
426                                          usbDevice[reader_index].interface = interface;                                          usbDevice[reader_index].interface = interface;
427                                          usbDevice[reader_index].real_nb_opened_slots = 1;                                          usbDevice[reader_index].real_nb_opened_slots = 1;
428                                          usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;                                          usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
# Line 413  status_t OpenUSBByName(unsigned int read Line 442  status_t OpenUSBByName(unsigned int read
442                                          usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];                                          usbDevice[reader_index].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
443                                          usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;                                          usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
444                                          usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;                                          usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
445                                          usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index);                                          usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, dev);
446                                            usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
447                                            usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
448                                            usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
449                                          goto end;                                          goto end;
450                                  }                                  }
451                          }                          }
# Line 452  status_t WriteUSB(unsigned int reader_in Line 484  status_t WriteUSB(unsigned int reader_in
484    
485          if (rv < 0)          if (rv < 0)
486          {          {
487                  if (usbDevice[reader_index].dev->bus)                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
488                  {                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
489                          DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",                          strerror(errno));
490                                  usbDevice[reader_index].dev->bus->dirname,  
491                                  usbDevice[reader_index].dev->filename, strerror(errno));                  if (ENODEV == errno)
492                  }                          return STATUS_NO_SUCH_DEVICE;
                 else  
                         DEBUG_CRITICAL2("usb_bulk_write(no device): %s", strerror(errno));  
493    
494                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
495          }          }
# Line 478  status_t ReadUSB(unsigned int reader_ind Line 508  status_t ReadUSB(unsigned int reader_ind
508  {  {
509          int rv;          int rv;
510          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
511            _ccid_descriptor *ccid_descriptor = get_ccid_descriptor(reader_index);
512            int duplicate_frame = 0;
513    
514    read_again:
515          sprintf(debug_header, "<- %06X ", (int)reader_index);          sprintf(debug_header, "<- %06X ", (int)reader_index);
516    
517          rv = usb_bulk_read(usbDevice[reader_index].handle,          rv = usb_bulk_read(usbDevice[reader_index].handle,
# Line 489  status_t ReadUSB(unsigned int reader_ind Line 522  status_t ReadUSB(unsigned int reader_ind
522          {          {
523                  *length = 0;                  *length = 0;
524                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
525                          usbDevice[reader_index].dev->bus->dirname,                          usbDevice[reader_index].dirname, usbDevice[reader_index].filename,
526                          usbDevice[reader_index].dev->filename, strerror(errno));                          strerror(errno));
527    
528                    if (ENODEV == errno)
529                            return STATUS_NO_SUCH_DEVICE;
530    
531                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
532          }          }
533    
# Line 498  status_t ReadUSB(unsigned int reader_ind Line 535  status_t ReadUSB(unsigned int reader_ind
535    
536          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
537    
538    #define BSEQ_OFFSET 6
539            if ((*length >= BSEQ_OFFSET)
540                    && (buffer[BSEQ_OFFSET] < *ccid_descriptor->pbSeq -1))
541            {
542                    duplicate_frame++;
543                    if (duplicate_frame > 10)
544                    {
545                            DEBUG_CRITICAL("Too many duplicate frame detected");
546                            return STATUS_UNSUCCESSFUL;
547                    }
548                    DEBUG_INFO("Duplicate frame detected");
549                    goto read_again;
550            }
551    
552          return STATUS_SUCCESS;          return STATUS_SUCCESS;
553  } /* ReadUSB */  } /* ReadUSB */
554    
# Line 510  status_t ReadUSB(unsigned int reader_ind Line 561  status_t ReadUSB(unsigned int reader_ind
561  status_t CloseUSB(unsigned int reader_index)  status_t CloseUSB(unsigned int reader_index)
562  {  {
563          /* device not opened */          /* device not opened */
564          if (usbDevice[reader_index].dev == NULL)          if (usbDevice[reader_index].handle == NULL)
565                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
566    
567          DEBUG_COMM3("Closing USB device: %s/%s",          DEBUG_COMM3("Closing USB device: %s/%s",
568                  usbDevice[reader_index].dev->bus->dirname,                  usbDevice[reader_index].dirname,
569                  usbDevice[reader_index].dev->filename);                  usbDevice[reader_index].filename);
570    
571            if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates
572                    && (usbDevice[reader_index].ccid.bCurrentSlotIndex == 0))
573            {
574                    free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);
575                    usbDevice[reader_index].ccid.arrayOfSupportedDataRates = NULL;
576            }
577    
578          /* one slot closed */          /* one slot closed */
579          (*usbDevice[reader_index].nb_opened_slots)--;          (*usbDevice[reader_index].nb_opened_slots)--;
# Line 525  status_t CloseUSB(unsigned int reader_in Line 583  status_t CloseUSB(unsigned int reader_in
583          {          {
584                  DEBUG_COMM("Last slot closed. Release resources");                  DEBUG_COMM("Last slot closed. Release resources");
585    
                 if (usbDevice[reader_index].ccid.arrayOfSupportedDataRates)  
                         free(usbDevice[reader_index].ccid.arrayOfSupportedDataRates);  
   
586                  /* reset so that bSeq starts at 0 again */                  /* reset so that bSeq starts at 0 again */
587                  if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)                  if (DriverOptions & DRIVER_OPTION_RESET_ON_CLOSE)
588                          usb_reset(usbDevice[reader_index].handle);                          usb_reset(usbDevice[reader_index].handle);
# Line 535  status_t CloseUSB(unsigned int reader_in Line 590  status_t CloseUSB(unsigned int reader_in
590                  usb_release_interface(usbDevice[reader_index].handle,                  usb_release_interface(usbDevice[reader_index].handle,
591                          usbDevice[reader_index].interface);                          usbDevice[reader_index].interface);
592                  usb_close(usbDevice[reader_index].handle);                  usb_close(usbDevice[reader_index].handle);
593    
594                    free(usbDevice[reader_index].dirname);
595                    free(usbDevice[reader_index].filename);
596          }          }
597    
598          /* mark the resource unused */          /* mark the resource unused */
599          usbDevice[reader_index].handle = NULL;          usbDevice[reader_index].handle = NULL;
600          usbDevice[reader_index].dev = NULL;          usbDevice[reader_index].dirname = NULL;
601            usbDevice[reader_index].filename = NULL;
602          usbDevice[reader_index].interface = 0;          usbDevice[reader_index].interface = 0;
603    
604          return STATUS_SUCCESS;          return STATUS_SUCCESS;
# Line 559  _ccid_descriptor *get_ccid_descriptor(un Line 618  _ccid_descriptor *get_ccid_descriptor(un
618    
619  /*****************************************************************************  /*****************************************************************************
620   *   *
  *                                      get_desc  
  *  
  ****************************************************************************/  
 int get_desc(int lun, usb_dev_handle **handle, struct  
         usb_device **dev)  
 {  
         int reader_index;  
   
         if (-1 == (reader_index = LunToReaderIndex(lun)))  
                 return FALSE;  
   
         *handle = usbDevice[reader_index].handle;  
         *dev = usbDevice[reader_index].dev;  
   
         return TRUE;  
 } /* get_desc */  
   
   
 /*****************************************************************************  
  *  
621   *                                      get_end_points   *                                      get_end_points
622   *   *
623   ****************************************************************************/   ****************************************************************************/
624  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  static int get_end_points(struct usb_device *dev, _usbDevice *usbdevice)
625  {  {
626          int i;          int i;
627          int bEndpointAddress;          int bEndpointAddress;
628          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);          struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
629    
630          /*          /*
631           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
632           */           */
633          for (i=0; i<3; i++)          for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
634          {          {
635                    /* interrupt end point (if available) */
636                    if (usb_interface->altsetting->endpoint[i].bmAttributes == USB_ENDPOINT_TYPE_INTERRUPT)
637                    {
638                            usbdevice->interrupt = usb_interface->altsetting->endpoint[i].bEndpointAddress;
639                            continue;
640                    }
641    
642                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
643                          continue;                          continue;
644    
645                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
646    
647                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
648                          usb_device->bulk_in = bEndpointAddress;                          usbdevice->bulk_in = bEndpointAddress;
649    
650                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT)
651                          usb_device->bulk_out = bEndpointAddress;                          usbdevice->bulk_out = bEndpointAddress;
652          }          }
653    
654          return 0;          return 0;
# Line 614  static int get_end_points(struct usb_dev Line 660  static int get_end_points(struct usb_dev
660   *                                      get_ccid_usb_interface   *                                      get_ccid_usb_interface
661   *   *
662   ****************************************************************************/   ****************************************************************************/
663  /*@null@*/ struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)  /*@null@*/ EXTERNAL struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
664  {  {
665          struct usb_interface *usb_interface = NULL;          struct usb_interface *usb_interface = NULL;
666            int i;
667    #ifdef O2MICRO_OZ776_PATCH
668            int readerID;
669    #endif
670    
671          /* if multiple interfaces use the first one with CCID class type */          /* if multiple interfaces use the first one with CCID class type */
672          if (dev->config->bNumInterfaces > 1)          for (i=0; dev->config && i<dev->config->bNumInterfaces; i++)
673          {          {
674                  int ii;                  /* CCID Class? */
675                  for (ii=0; ii<dev->config->bNumInterfaces; ii++)                  if (dev->config->interface[i].altsetting->bInterfaceClass == 0xb
                 {  
                         /* CCID Class? */  
                         if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb  
676  #ifdef ALLOW_PROPRIETARY_CLASS  #ifdef ALLOW_PROPRIETARY_CLASS
677                                  || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff                          || dev->config->interface[i].altsetting->bInterfaceClass == 0xff
678  #endif  #endif
679                                  )                          )
680                          {                  {
681                                  usb_interface = &dev->config->interface[ii];                          usb_interface = &dev->config->interface[i];
682                                  break;                          break;
                         }  
683                  }                  }
684          }          }
         else  
                 /* only one interface found */  
                 usb_interface = dev->config->interface;  
685    
686  #ifdef O2MICRO_OZ776_PATCH  #ifdef O2MICRO_OZ776_PATCH
687            readerID = (dev->descriptor.idVendor << 16) + dev->descriptor.idProduct;
688          if (usb_interface != NULL          if (usb_interface != NULL
689                  && (OZ776 == (dev->descriptor.idVendor << 16)                  && ((OZ776 == readerID) || (OZ776_7772 == readerID)
690                  + dev->descriptor.idProduct)                  || (REINER_SCT == readerID) || (BLUDRIVEII_CCID == readerID))
691                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */                  && (0 == usb_interface->altsetting->extralen)) /* this is the bug */
692          {          {
                 int i;  
   
693                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)                  for (i=0; i<usb_interface->altsetting->bNumEndpoints; i++)
694                  {                  {
695                          /* find the extra[] array */                          /* find the extra[] array */
# Line 657  static int get_end_points(struct usb_dev Line 699  static int get_end_points(struct usb_dev
699                                  usb_interface->altsetting->extralen = 54;                                  usb_interface->altsetting->extralen = 54;
700                                  usb_interface->altsetting->extra =                                  usb_interface->altsetting->extra =
701                                          usb_interface->altsetting->endpoint[i].extra;                                          usb_interface->altsetting->endpoint[i].extra;
702                                    /* avoid double free on close */
703                                    usb_interface->altsetting->endpoint[i].extra = NULL;
704                                    usb_interface->altsetting->endpoint[i].extralen = 0;
705                                  break;                                  break;
706                          }                          }
707                  }                  }
# Line 674  static int get_end_points(struct usb_dev Line 719  static int get_end_points(struct usb_dev
719   ****************************************************************************/   ****************************************************************************/
720  int ccid_check_firmware(struct usb_device *dev)  int ccid_check_firmware(struct usb_device *dev)
721  {  {
722          int i;          unsigned int i;
723    
724          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)          for (i=0; i<sizeof(Bogus_firmwares)/sizeof(Bogus_firmwares[0]); i++)
725          {          {
# Line 708  int ccid_check_firmware(struct usb_devic Line 753  int ccid_check_firmware(struct usb_devic
753          return FALSE;          return FALSE;
754  } /* ccid_check_firmware */  } /* ccid_check_firmware */
755    
756    
757  /*****************************************************************************  /*****************************************************************************
758   *   *
759   *                                      get_data_rates   *                                      get_data_rates
760   *   *
761   ****************************************************************************/   ****************************************************************************/
762  static unsigned int *get_data_rates(unsigned int reader_index)  static unsigned int *get_data_rates(unsigned int reader_index,
763            struct usb_device *dev)
764  {  {
765          int n, i, len;          int n, i, len;
766          unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */          unsigned char buffer[256*sizeof(int)];  /* maximum is 256 records */
767          unsigned int *int_array;          unsigned int *int_array;
768    
769          /* See CCID 3.7.3 page 25 */          /* See CCID 3.7.3 page 25 */
770          n = usb_control_msg(usbDevice[reader_index].handle,          n = ControlUSB(reader_index,
771                  0xA1, /* request type */                  0xA1, /* request type */
772                  0x03, /* GET_DATA_RATES */                  0x03, /* GET_DATA_RATES */
773                  0x00, /* value */                  0x00, /* value */
774                  usbDevice[reader_index].interface, /* interface */                  buffer, sizeof(buffer));
                 (char *)buffer,  
                 sizeof(buffer),  
                 usbDevice[reader_index].ccid.readTimeout * 1000);  
775    
776          /* we got an error? */          /* we got an error? */
777          if (n <= 0)          if (n <= 0)
# Line 748  static unsigned int *get_data_rates(unsi Line 792  static unsigned int *get_data_rates(unsi
792          n /= sizeof(int);          n /= sizeof(int);
793    
794          /* we do not get the expected number of data rates */          /* we do not get the expected number of data rates */
795          len = get_ccid_usb_interface(usbDevice[reader_index].dev)          len = get_ccid_usb_interface(dev)->altsetting->extra[27]; /* bNumDataRatesSupported */
                 ->altsetting->extra[27]; /* bNumDataRatesSupported */  
796          if ((n != len) && len)          if ((n != len) && len)
797          {          {
798                  DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);                  DEBUG_INFO3("Got %d data rates but was expecting %d", n, len);
# Line 777  static unsigned int *get_data_rates(unsi Line 820  static unsigned int *get_data_rates(unsi
820          int_array[i] = 0;          int_array[i] = 0;
821    
822          return int_array;          return int_array;
823  }  } /* get_data_rates */
824    
825    
826    /*****************************************************************************
827     *
828     *                                      ControlUSB
829     *
830     ****************************************************************************/
831    int ControlUSB(int reader_index, int requesttype, int request, int value,
832            unsigned char *bytes, unsigned int size)
833    {
834            int ret;
835    
836            DEBUG_COMM2("request: 0x%02X", request);
837    
838            if (0 == (requesttype & 0x80))
839                    DEBUG_XXD("send: ", bytes, size);
840    
841            ret = usb_control_msg(usbDevice[reader_index].handle, requesttype,
842                    request, value, usbDevice[reader_index].interface, (char *)bytes, size,
843                    usbDevice[reader_index].ccid.readTimeout * 1000);
844    
845            if (requesttype & 0x80)
846                    DEBUG_XXD("receive: ", bytes, ret);
847    
848            return ret;
849    } /* ControlUSB */
850    
851    /*****************************************************************************
852     *
853     *                                      InterruptRead
854     *
855     *
856     ****************************************************************************/
857    int InterruptRead(int reader_index)
858    {
859            int ret;
860            char buffer[8];
861            int timeout = 60*60*1000; /* 60 minutes */
862            static int hasfailed = FALSE;
863    
864            if (hasfailed)
865            {
866                    DEBUG_COMM("driver has failed");
867                    return 0;
868            }
869    
870            DEBUG_COMM("before");
871            ret = usb_interrupt_read(usbDevice[reader_index].handle,
872                    usbDevice[reader_index].interrupt, buffer, sizeof(buffer), timeout);
873            DEBUG_COMM2("after %d\n", ret);
874    
875            if (0 == ret)
876                    hasfailed = TRUE;
877    
878            if (ret < 0)
879            {
880                    /* if usb_interrupt_read() times out we get EILSEQ or EAGAIN */
881                    if ((errno != EILSEQ) && (errno != EAGAIN))
882                            DEBUG_CRITICAL4("usb_interrupt_read(%s/%s): %s",
883                                            usbDevice[reader_index].dirname,
884                                            usbDevice[reader_index].filename, strerror(errno));
885            }
886            else
887                    DEBUG_XXD("NotifySlotChange: ", buffer, ret);
888    
889            return ret;
890    } /* InterruptRead */
891    

Legend:
Removed from v.1804  
changed lines
  Added in v.2871

  ViewVC Help
Powered by ViewVC 1.1.5