/[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 581 by rousseau, Tue Jan 6 07:21:27 2004 UTC revision 1091 by rousseau, Wed Jul 21 08:59:28 2004 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   Ludovic Rousseau      Copyright (C) 2003-2004   Ludovic Rousseau
4    
5      This program is free software; you can redistribute it and/or modify      This program is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published by      it under the terms of the GNU General Public License as published by
# Line 26  Line 26 
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
30    # include <sys/types.h>
31    # endif
32  #include <usb.h>  #include <usb.h>
33    
34  #include "pcscdefines.h"  #include "ccid.h"
35  #include "config.h"  #include "config.h"
36  #include "debug.h"  #include "debug.h"
37    #include "defs.h"
38  #include "utils.h"  #include "utils.h"
39  #include "parser.h"  #include "parser.h"
40  #include "ccid.h"  #include "ccid_ifdhandler.h"
41    
42    
43  /* read timeout  /* read timeout
# Line 46  Line 50 
50   * we don't have to wait a long time since the card was doing nothing */   * we don't have to wait a long time since the card was doing nothing */
51  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */  #define USB_WRITE_TIMEOUT (5 * 1000)  /* 5 seconds timeout */
52    
53    /*
54     * Proprietary USB Class (0xFF) are (or are not) accepted
55     * A proprietary class is used for devices released before the final CCID
56     * specifications were ready.
57     * We should not have problems with non CCID devices becasue the
58     * Manufacturer and Product ID are also used to identify the device */
59    #define ALLOW_PROPRIETARY_CLASS
60    
61  #define BUS_DEVICE_STRSIZE 32  #define BUS_DEVICE_STRSIZE 32
62    
# Line 55  typedef struct Line 66  typedef struct
66          struct usb_device *dev;          struct usb_device *dev;
67    
68          /*          /*
          * Used to store device name string %s/%s like:  
          * 001/002 (Linux)  
          * /dev/usb0//dev/ (FreeBSD)  
          * /dev/usb0//dev/ugen0 (OpenBSD)  
          */  
         char device_name[BUS_DEVICE_STRSIZE];  
   
         /*  
69           * Endpoints           * Endpoints
70           */           */
71          int bulk_in;          int bulk_in;
# Line 78  typedef struct Line 81  typedef struct
81  /* The _usbDevice structure must be defined before including ccid_usb.h */  /* The _usbDevice structure must be defined before including ccid_usb.h */
82  #include "ccid_usb.h"  #include "ccid_usb.h"
83    
84  static _usbDevice usbDevice[PCSCLITE_MAX_READERS] = {  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device);
85          [ 0 ... (PCSCLITE_MAX_READERS-1) ] = { NULL, NULL, "", 0, 0 }  
86  };  /* ne need to initialize to 0 since it is static */
87    static _usbDevice usbDevice[CCID_DRIVER_MAX_READERS];
88    
89  #define PCSCLITE_MANUKEY_NAME                   "ifdVendorID"  #define PCSCLITE_MANUKEY_NAME                   "ifdVendorID"
90  #define PCSCLITE_PRODKEY_NAME                   "ifdProductID"  #define PCSCLITE_PRODKEY_NAME                   "ifdProductID"
91  #define PCSCLITE_NAMEKEY_NAME                   "ifdFriendlyName"  #define PCSCLITE_NAMEKEY_NAME                   "ifdFriendlyName"
92    
93    
94  /*****************************************************************************  /*****************************************************************************
95   *   *
96   *                                      OpenUSB   *                                      OpenUSB
97   *   *
98   ****************************************************************************/   ****************************************************************************/
99  status_t OpenUSB(int lun, int Channel)  status_t OpenUSB(unsigned int lun, /*@unused@*/ int Channel)
100    {
101            return OpenUSBByName(lun, NULL);
102    } /* OpenUSB */
103    
104    
105    /*****************************************************************************
106     *
107     *                                      OpenUSBByName
108     *
109     ****************************************************************************/
110    status_t OpenUSBByName(unsigned int lun, /*@null@*/ char *device)
111  {  {
112          static struct usb_bus *busses = NULL;          static struct usb_bus *busses = NULL;
113          int reader = LunToReaderIndex(lun);          unsigned int reader = LunToReaderIndex(lun);
114          int alias = 0;          int alias = 0;
115          struct usb_bus *bus;          struct usb_bus *bus;
116          struct usb_dev_handle *dev_handle;          struct usb_dev_handle *dev_handle;
117          char keyValue[TOKEN_MAX_VALUE_SIZE];          char keyValue[TOKEN_MAX_VALUE_SIZE];
118          int vendorID, productID;          int vendorID, productID;
119          char infofile[FILENAME_MAX];          char infofile[FILENAME_MAX];
120            unsigned int device_vendor, device_product;
121            char *dirname = NULL, *filename = NULL;
122    
123            DEBUG_COMM3("Lun: %X, Device: %s", lun, device);
124    
125            /* device name specified */
126            if (device)
127            {
128                    /* format: usb:%04x/%04x, vendor, product */
129                    if (strncmp("usb:", device, 4) != 0)
130                    {
131                            DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",
132                                    device);
133                            return STATUS_UNSUCCESSFUL;
134                    }
135    
136                    if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2)
137                    {
138                            DEBUG_CRITICAL2("device name can't be parsed: %s", device);
139                            return STATUS_UNSUCCESSFUL;
140                    }
141    
142          DEBUG_COMM3("OpenUSB: Lun: %X, Channel: %X", lun, Channel);                  /* format usb:%04x/%04x:libusb:%s
143                     * with %s set to %s:%s, dirname, filename */
144                    if ((dirname = strstr(device, "libusb:")) != NULL)
145                    {
146                            /* dirname points to the first char after libusb: */
147                            dirname += strlen("libusb:");
148    
149                            /* search the : (separation) char */
150                            filename = strchr(dirname, ':');
151    
152                            if (filename)
153                            {
154                                    /* end the dirname string */
155                                    *filename = '\0';
156    
157                                    /* filename points to the first char after : */
158                                    filename++;
159                            }
160                            else
161                            {
162                                    /* parse failed */
163                                    dirname = NULL;
164    
165                                    DEBUG_CRITICAL2("can't parse using libusb scheme: %s", device);
166                            }
167                    }
168            }
169    
170          if (busses == NULL)          if (busses == NULL)
171                  usb_init();                  usb_init();
# Line 131  status_t OpenUSB(int lun, int Channel) Line 194  status_t OpenUSB(int lun, int Channel)
194    
195          /* general driver info */          /* general driver info */
196          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdManufacturerString", keyValue, 0))
197            {
198                  DEBUG_CRITICAL2("Manufacturer: %s", keyValue);                  DEBUG_CRITICAL2("Manufacturer: %s", keyValue);
199            }
200          else          else
201          {          {
202                  DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",                  DEBUG_CRITICAL2("LTPBundleFindValueWithKey error. Can't find %s?",
# Line 139  status_t OpenUSB(int lun, int Channel) Line 204  status_t OpenUSB(int lun, int Channel)
204                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
205          }          }
206          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "ifdProductString", keyValue, 0))
207            {
208                  DEBUG_CRITICAL2("ProductString: %s", keyValue);                  DEBUG_CRITICAL2("ProductString: %s", keyValue);
209            }
210          else          else
211                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
212          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))          if (!LTPBundleFindValueWithKey(infofile, "Copyright", keyValue, 0))
213            {
214                  DEBUG_CRITICAL2("Copyright: %s", keyValue);                  DEBUG_CRITICAL2("Copyright: %s", keyValue);
215            }
216          else          else
217                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
218          vendorID = strlen(keyValue);          vendorID = strlen(keyValue);
# Line 154  status_t OpenUSB(int lun, int Channel) Line 223  status_t OpenUSB(int lun, int Channel)
223          /* for any supported reader */          /* for any supported reader */
224          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)          while (LTPBundleFindValueWithKey(infofile, PCSCLITE_MANUKEY_NAME, keyValue, alias) == 0)
225          {          {
226                  vendorID = strtoul(keyValue, 0, 16);                  vendorID = strtoul(keyValue, NULL, 0);
227    
228                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_PRODKEY_NAME, keyValue, alias))
229                          goto end;                          goto end;
230                  productID = strtoul(keyValue, 0, 16);                  productID = strtoul(keyValue, NULL, 0);
231    
232                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))                  if (LTPBundleFindValueWithKey(infofile, PCSCLITE_NAMEKEY_NAME, keyValue, alias))
233                          goto end;                          goto end;
234    
235                    /* go to next supported reader for next round */
236                    alias++;
237    
238                    /* the device was specified but is not the one we are trying to find */
239                    if (device
240                            && (vendorID != device_vendor || productID != device_product))
241                            continue;
242    
243                  /* on any USB buses */                  /* on any USB buses */
244                  for (bus = busses; bus; bus = bus->next)                  for (bus = busses; bus; bus = bus->next)
245                  {                  {
# Line 171  status_t OpenUSB(int lun, int Channel) Line 248  status_t OpenUSB(int lun, int Channel)
248                          /* any device on this bus */                          /* any device on this bus */
249                          for (dev = bus->devices; dev; dev = dev->next)                          for (dev = bus->devices; dev; dev = dev->next)
250                          {                          {
251                                    /* device defined by name? */
252                                    if (dirname && (strcmp(dirname, bus->dirname)
253                                            || strcmp(filename, dev->filename)))
254                                            continue;
255    
256                                  if (dev->descriptor.idVendor == vendorID                                  if (dev->descriptor.idVendor == vendorID
257                                          && dev->descriptor.idProduct == productID)                                          && dev->descriptor.idProduct == productID)
258                                  {                                  {
259                                          int r, already_used;                                          int r, already_used;
260                                          char device_name[BUS_DEVICE_STRSIZE];                                          struct usb_interface *usb_interface = NULL;
261                                            int interface;
                                         if (snprintf(device_name, BUS_DEVICE_STRSIZE, "%s/%s",  
                                                 bus->dirname, dev->filename) < 0)  
                                         {  
                                                 DEBUG_CRITICAL2("Device name too long: %s", device_name);  
                                                 return STATUS_UNSUCCESSFUL;  
                                         }  
262    
263                                          /* is it already opened? */                                          /* is it already opened? */
264                                          already_used = FALSE;                                          already_used = FALSE;
265                                          for (r=0; r<PCSCLITE_MAX_READERS; r++)  
266                                            for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
267                                          {                                          {
268                                                  if (usbDevice[r].dev)                                                  if (usbDevice[r].dev)
269                                                  {                                                  {
270                                                          DEBUG_COMM3("Checking new device '%s' against old '%s'",                                                          DEBUG_COMM3("Checking device: %s/%s",
271                                                                  device_name, usbDevice[r].device_name);                                                                  bus->dirname, dev->filename);
272                                                          if (strcmp(usbDevice[r].device_name, device_name) == 0)                                                          /* same busname, same filename */
273                                                            if (strcmp(usbDevice[r].dev->bus->dirname, bus->dirname) == 0 && strcmp(usbDevice[r].dev->filename, dev->filename) == 0)
274                                                                  already_used = TRUE;                                                                  already_used = TRUE;
275                                                  }                                                  }
276                                          }                                          }
277    
278                                          if (!already_used)                                          /* this reader is already managed by us */
279                                            if (already_used)
280                                          {                                          {
281                                                  DEBUG_COMM2("Trying to open USB bus/device: %s",                                                  DEBUG_INFO3("USB device %s/%s already in use. Checking next one.",
282                                                           device_name);                                                          bus->dirname, dev->filename);
283    
284                                                  dev_handle = usb_open(dev);                                                  continue;
285                                                  if (dev_handle)                                          }
                                                 {  
                                                         int interface;  
286    
287                                                          if (dev->config == NULL)                                          DEBUG_COMM3("Trying to open USB bus/device: %s/%s",
288                                                          {                                                   bus->dirname, dev->filename);
                                                                 DEBUG_CRITICAL2("No dev->config found for %s",  
                                                                          device_name);  
                                                                 return STATUS_UNSUCCESSFUL;  
                                                         }  
   
                                                         if (dev->config->interface->altsetting->extralen != 54)  
                                                         {  
                                                                 DEBUG_CRITICAL3("Extra field for %s has a wrong length: %d", device_name, dev->config->interface->altsetting->extralen);  
                                                                 return STATUS_UNSUCCESSFUL;  
                                                         }  
   
                                                         interface = dev->config->interface->altsetting->bInterfaceNumber;  
                                                         if (usb_claim_interface(dev_handle, interface) < 0)  
                                                         {  
                                                                 DEBUG_CRITICAL3("Can't claim interface %s: %s",  
                                                                         device_name, strerror(errno));  
                                                                 return STATUS_UNSUCCESSFUL;  
                                                         }  
   
                                                         DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",  
                                                                 dev->descriptor.idVendor,  
                                                                 dev->descriptor.idProduct, keyValue);  
                                                         DEBUG_INFO2("Using USB bus/device: %s",  
                                                                  device_name);  
   
                                                         /* Get Endpoints values*/  
                                                         get_end_points(dev, &usbDevice[reader]);  
   
                                                         /* store device information */  
                                                         usbDevice[reader].handle = dev_handle;  
                                                         usbDevice[reader].dev = dev;  
                                                         strncpy(usbDevice[reader].device_name,  
                                                                 device_name, BUS_DEVICE_STRSIZE);  
   
                                                         /* CCID common informations */  
                                                         usbDevice[reader].ccid.bSeq = 1;  
                                                         usbDevice[reader].ccid.readerID =  
                                                                 (dev->descriptor.idVendor << 16) +  
                                                                 dev->descriptor.idProduct;  
                                                         usbDevice[reader].ccid.dwFeatures = dw2i(dev->config->interface->altsetting->extra, 40);  
                                                         usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(dev->config->interface->altsetting->extra, 44);  
   
                                                         /* Maybe we have a special treatment  
                                                          * for this reader */  
                                                         ccid_open_hack(lun);  
289    
290                                                          goto end;                                          dev_handle = usb_open(dev);
291                                                  }                                          if (dev_handle == NULL)
292                                                  else                                          {
293                                                          DEBUG_CRITICAL3("Can't usb_open(%s): %s",                                                  DEBUG_CRITICAL4("Can't usb_open(%s/%s): %s",
294                                                                  device_name,                                                          bus->dirname, dev->filename, strerror(errno));
295                                                                  strerror(errno));  
296                                                    continue;
297                                            }
298    
299                                            /* now we found a free reader and we try to use it */
300                                            if (dev->config == NULL)
301                                            {
302                                                    DEBUG_CRITICAL3("No dev->config found for %s/%s",
303                                                             bus->dirname, dev->filename);
304                                                    return STATUS_UNSUCCESSFUL;
305                                            }
306    
307                                            usb_interface = get_ccid_usb_interface(dev);
308                                            if (usb_interface == NULL)
309                                            {
310                                                    DEBUG_CRITICAL3("Can't find a CCID interface on %s/%s",
311                                                            bus->dirname, dev->filename);
312                                                    return STATUS_UNSUCCESSFUL;
313                                            }
314    
315                                            if (usb_interface->altsetting->extralen != 54)
316                                            {
317                                                    DEBUG_CRITICAL4("Extra field for %s/%s has a wrong length: %d", bus->dirname, dev->filename, usb_interface->altsetting->extralen);
318                                                    return STATUS_UNSUCCESSFUL;
319                                          }                                          }
320                                          else  
321                                            interface = usb_interface->altsetting->bInterfaceNumber;
322                                            if (usb_claim_interface(dev_handle, interface) < 0)
323                                          {                                          {
324                                                  DEBUG_INFO2("USB device %s already in use. Checking next one.",                                                  DEBUG_CRITICAL4("Can't claim interface %s/%s: %s",
325                                                          device_name);                                                          bus->dirname, dev->filename, strerror(errno));
326                                                    return STATUS_UNSUCCESSFUL;
327                                          }                                          }
328    
329                                            DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
330                                                    dev->descriptor.idVendor,
331                                                    dev->descriptor.idProduct, keyValue);
332                                            DEBUG_INFO3("Using USB bus/device: %s/%s",
333                                                     bus->dirname, dev->filename);
334    
335                                            /* Get Endpoints values*/
336                                            get_end_points(dev, &usbDevice[reader]);
337    
338                                            /* store device information */
339                                            usbDevice[reader].handle = dev_handle;
340                                            usbDevice[reader].dev = dev;
341    
342                                            /* CCID common informations */
343                                            usbDevice[reader].ccid.bSeq = 0;
344                                            usbDevice[reader].ccid.readerID =
345                                                    (dev->descriptor.idVendor << 16) +
346                                                    dev->descriptor.idProduct;
347                                            usbDevice[reader].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40);
348                                            usbDevice[reader].ccid.bPINSupport = usb_interface->altsetting->extra[52];
349                                            usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44);
350                                            usbDevice[reader].ccid.dwMaxIFSD = dw2i(usb_interface->altsetting->extra, 28);
351                                            usbDevice[reader].ccid.dwDefaultClock = dw2i(usb_interface->altsetting->extra, 10);
352                                            usbDevice[reader].ccid.dwMaxDataRate = dw2i(usb_interface->altsetting->extra, 23);
353                                            usbDevice[reader].ccid.bMaxSlotIndex = usb_interface->altsetting->extra[4];
354                                            usbDevice[reader].ccid.bCurrentSlotIndex = 0;
355    
356                                            goto end;
357                                  }                                  }
358                          }                          }
359                  }                  }
   
                 /* go to next supported reader */  
                 alias++;  
360          }          }
361  end:  end:
362          if (usbDevice[reader].handle == NULL)          if (usbDevice[reader].handle == NULL)
363                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
364    
365          return STATUS_SUCCESS;          return STATUS_SUCCESS;
366  } /* OpenUSB */  } /* OpenUSBByName */
367    
368    
369  /*****************************************************************************  /*****************************************************************************
# Line 287  end: Line 371  end:
371   *                                      WriteUSB   *                                      WriteUSB
372   *   *
373   ****************************************************************************/   ****************************************************************************/
374  status_t WriteUSB(int lun, int length, unsigned char *buffer)  status_t WriteUSB(unsigned int lun, unsigned int length, unsigned char *buffer)
375  {  {
376          int rv;          int rv;
377          int reader = LunToReaderIndex(lun);          unsigned int reader = LunToReaderIndex(lun);
378  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
379          char debug_header[] = "-> 121234 ";          char debug_header[] = "-> 121234 ";
380    
# Line 301  status_t WriteUSB(int lun, int length, u Line 385  status_t WriteUSB(int lun, int length, u
385          DEBUG_XXD(debug_header, buffer, length);          DEBUG_XXD(debug_header, buffer, length);
386  #endif  #endif
387    
388          rv = usb_bulk_write(usbDevice[reader].handle, usbDevice[reader].bulk_out, buffer, length, USB_WRITE_TIMEOUT);          rv = usb_bulk_write(usbDevice[reader].handle, usbDevice[reader].bulk_out,
389                    (char *)buffer, length, USB_WRITE_TIMEOUT);
390    
391          if (rv < 0)          if (rv < 0)
392          {          {
393                  DEBUG_CRITICAL3("usb_bulk_write(%s): %s",                  DEBUG_CRITICAL4("usb_bulk_write(%s/%s): %s",
394                          usbDevice[reader].device_name, strerror(errno));                          usbDevice[reader].dev->bus->dirname,
395                            usbDevice[reader].dev->filename, strerror(errno));
396                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
397          }          }
398    
# Line 319  status_t WriteUSB(int lun, int length, u Line 405  status_t WriteUSB(int lun, int length, u
405   *                                      ReadUSB   *                                      ReadUSB
406   *   *
407   ****************************************************************************/   ****************************************************************************/
408  status_t ReadUSB(int lun, int * length, unsigned char *buffer)  status_t ReadUSB(unsigned int lun, unsigned int * length, unsigned char *buffer)
409  {  {
410          int rv;          int rv;
411          int reader = LunToReaderIndex(lun);          unsigned int reader = LunToReaderIndex(lun);
412  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
413          char debug_header[] = "<- 121234 ";          char debug_header[] = "<- 121234 ";
414    
415          sprintf(debug_header, "<- %06X ", (int)lun);          sprintf(debug_header, "<- %06X ", (int)lun);
416  #endif  #endif
417    
418            rv = usb_bulk_read(usbDevice[reader].handle, usbDevice[reader].bulk_in,
419          rv = usb_bulk_read(usbDevice[reader].handle, usbDevice[reader].bulk_in, buffer, *length, USB_READ_TIMEOUT);                  (char *)buffer, *length, USB_READ_TIMEOUT);
         *length = rv;  
420    
421          if (rv < 0)          if (rv < 0)
422          {          {
423                  DEBUG_CRITICAL3("usb_bulk_read(%s): %s",                  *length = 0;
424                          usbDevice[reader].device_name, strerror(errno));                  DEBUG_CRITICAL4("usb_bulk_read(%s/%s): %s",
425                            usbDevice[reader].dev->bus->dirname,
426                            usbDevice[reader].dev->filename, strerror(errno));
427                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
428          }          }
429    
430            *length = rv;
431    
432  #ifdef DEBUG_LEVEL_COMM  #ifdef DEBUG_LEVEL_COMM
433          DEBUG_XXD(debug_header, buffer, *length);          DEBUG_XXD(debug_header, buffer, *length);
434  #endif  #endif
# Line 353  status_t ReadUSB(int lun, int * length, Line 442  status_t ReadUSB(int lun, int * length,
442   *                                      CloseUSB   *                                      CloseUSB
443   *   *
444   ****************************************************************************/   ****************************************************************************/
445  status_t CloseUSB(int lun)  status_t CloseUSB(unsigned int lun)
446  {  {
447          int reader = LunToReaderIndex(lun);          struct usb_interface *usb_interface;
448            int interface;
449            unsigned int reader = LunToReaderIndex(lun);
450    
451          /* device not opened */          /* device not opened */
452          if (usbDevice[reader].dev == NULL)          if (usbDevice[reader].dev == NULL)
453                  return STATUS_UNSUCCESSFUL;                  return STATUS_UNSUCCESSFUL;
454    
455          DEBUG_COMM2("Closing USB device: %s", usbDevice[reader].device_name);          DEBUG_COMM3("Closing USB device: %s/%s",
456                    usbDevice[reader].dev->bus->dirname, usbDevice[reader].dev->filename);
457    
458          usb_release_interface(usbDevice[reader].handle, usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber);          usb_interface = get_ccid_usb_interface(usbDevice[reader].dev);
459            interface = usb_interface ?
460                    usb_interface->altsetting->bInterfaceNumber :
461                    usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber;
462    
463            /* reset so that bSeq starts at 0 again */
464            usb_reset(usbDevice[reader].handle);
465    
466            usb_release_interface(usbDevice[reader].handle, interface);
467          usb_close(usbDevice[reader].handle);          usb_close(usbDevice[reader].handle);
468    
469          /* mark the resource unused */          /* mark the resource unused */
470          usbDevice[reader].handle = NULL;          usbDevice[reader].handle = NULL;
471          usbDevice[reader].dev = NULL;          usbDevice[reader].dev = NULL;
         usbDevice[reader].device_name[0] = '\0';  
472    
473          return STATUS_SUCCESS;          return STATUS_SUCCESS;
474  } /* CloseUSB */  } /* CloseUSB */
# Line 381  status_t CloseUSB(int lun) Line 479  status_t CloseUSB(int lun)
479   *                                      get_ccid_descriptor   *                                      get_ccid_descriptor
480   *   *
481   ****************************************************************************/   ****************************************************************************/
482  _ccid_descriptor *get_ccid_descriptor(int lun)  _ccid_descriptor *get_ccid_descriptor(unsigned int lun)
483  {  {
484          return &usbDevice[LunToReaderIndex(lun)].ccid;          return &usbDevice[LunToReaderIndex(lun)].ccid;
485  } /* get_ccid_descriptor */  } /* get_ccid_descriptor */
# Line 392  _ccid_descriptor *get_ccid_descriptor(in Line 490  _ccid_descriptor *get_ccid_descriptor(in
490   *                                      get_desc   *                                      get_desc
491   *   *
492   ****************************************************************************/   ****************************************************************************/
493  int get_desc(int channel, char *device_name[], usb_dev_handle **handle, struct  int get_desc(int channel, usb_dev_handle **handle, struct
494          usb_device **dev)          usb_device **dev)
495  {  {
496          if (channel < 0 || channel > PCSCLITE_MAX_READERS)          if (channel < 0 || channel > CCID_DRIVER_MAX_READERS)
497                  return 1;                  return 1;
498    
         *device_name = usbDevice[channel].device_name;  
499          *handle = usbDevice[channel].handle;          *handle = usbDevice[channel].handle;
500          *dev = usbDevice[channel].dev;          *dev = usbDevice[channel].dev;
501    
502          return 0;          return 0;
503  } /* get_desc */  } /* get_desc */
504    
505    
506  /*****************************************************************************  /*****************************************************************************
507   *   *
508   *                                      get_end_points   *                                      get_end_points
509   *   *
510   ****************************************************************************/   ****************************************************************************/
511  int get_end_points(struct usb_device *dev, _usbDevice *usb_device)  static int get_end_points(struct usb_device *dev, _usbDevice *usb_device)
512  {  {
513          int i;          int i;
514          int bEndpointAddress;          int bEndpointAddress;
515            struct usb_interface *usb_interface = get_ccid_usb_interface(dev);
516    
517          /*          /*
518           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out           * 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
519           */           */
520          for (i=0; i<3; i++)          for (i=0; i<3; i++)
521          {          {
522                  if (dev->config->interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)                  if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK)
523                          continue;                          continue;
524    
525                  bEndpointAddress = dev->config->interface->altsetting->endpoint[i].bEndpointAddress;                  bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress;
526    
527                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)                  if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN)
528                          usb_device->bulk_in = bEndpointAddress;                          usb_device->bulk_in = bEndpointAddress;
# Line 435  int get_end_points(struct usb_device *de Line 534  int get_end_points(struct usb_device *de
534          return 0;          return 0;
535  } /* get_end_points */  } /* get_end_points */
536    
537    
538    /*****************************************************************************
539     *
540     *                                      get_ccid_usb_interface
541     *
542     ****************************************************************************/
543    /*@null@*/ struct usb_interface * get_ccid_usb_interface(struct usb_device *dev)
544    {
545            struct usb_interface *usb_interface = NULL;
546    
547            /* if multiple interfaces use the first one with CCID class type */
548            if (dev->config->bNumInterfaces > 1)
549            {
550                    int ii;
551                    for (ii=0; ii<dev->config->bNumInterfaces; ii++)
552                    {
553                            /* CCID Class? */
554                            if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb
555    #ifdef ALLOW_PROPRIETARY_CLASS
556                                    || dev->config->interface[ii].altsetting->bInterfaceClass == 0xff
557    #endif
558                                    )
559                            {
560                                    usb_interface = &dev->config->interface[ii];
561                                    break;
562                            }
563                    }
564            }
565            else
566                    /* we keep this in case a reader reports a bad class value */
567                    usb_interface = dev->config->interface;
568    
569            return usb_interface;
570    } /* get_ccid_usb_interface */
571    

Legend:
Removed from v.581  
changed lines
  Added in v.1091

  ViewVC Help
Powered by ViewVC 1.1.5