| 238 |
dev_handle = usb_open(dev); |
dev_handle = usb_open(dev); |
| 239 |
if (dev_handle) |
if (dev_handle) |
| 240 |
{ |
{ |
| 241 |
|
struct usb_interface *usb_interface = NULL; |
| 242 |
int interface; |
int interface; |
| 243 |
|
|
| 244 |
if (dev->config == NULL) |
if (dev->config == NULL) |
| 248 |
return STATUS_UNSUCCESSFUL; |
return STATUS_UNSUCCESSFUL; |
| 249 |
} |
} |
| 250 |
|
|
| 251 |
if (dev->config->interface->altsetting->extralen != 54) |
usb_interface = get_ccid_usb_interface(dev); |
| 252 |
|
if (usb_interface == NULL) |
| 253 |
{ |
{ |
| 254 |
DEBUG_CRITICAL3("Extra field for %s has a wrong length: %d", device_name, dev->config->interface->altsetting->extralen); |
DEBUG_CRITICAL("Can't find a CCID interface on %s", device_name); |
| 255 |
|
return STATUS_UNSUCCESSFUL; |
| 256 |
|
} |
| 257 |
|
|
| 258 |
|
if (usb_interface->altsetting->extralen != 54) |
| 259 |
|
{ |
| 260 |
|
DEBUG_CRITICAL3("Extra field for %s has a wrong length: %d", device_name, usb_interface->altsetting->extralen); |
| 261 |
return STATUS_UNSUCCESSFUL; |
return STATUS_UNSUCCESSFUL; |
| 262 |
} |
} |
| 263 |
|
|
| 264 |
interface = dev->config->interface->altsetting->bInterfaceNumber; |
interface = usb_interface->altsetting->bInterfaceNumber; |
| 265 |
if (usb_claim_interface(dev_handle, interface) < 0) |
if (usb_claim_interface(dev_handle, interface) < 0) |
| 266 |
{ |
{ |
| 267 |
DEBUG_CRITICAL3("Can't claim interface %s: %s", |
DEBUG_CRITICAL3("Can't claim interface %s: %s", |
| 289 |
usbDevice[reader].ccid.readerID = |
usbDevice[reader].ccid.readerID = |
| 290 |
(dev->descriptor.idVendor << 16) + |
(dev->descriptor.idVendor << 16) + |
| 291 |
dev->descriptor.idProduct; |
dev->descriptor.idProduct; |
| 292 |
usbDevice[reader].ccid.dwFeatures = dw2i(dev->config->interface->altsetting->extra, 40); |
usbDevice[reader].ccid.dwFeatures = dw2i(usb_interface->altsetting->extra, 40); |
| 293 |
usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(dev->config->interface->altsetting->extra, 44); |
usbDevice[reader].ccid.dwMaxCCIDMessageLength = dw2i(usb_interface->altsetting->extra, 44); |
| 294 |
|
|
| 295 |
goto end; |
goto end; |
| 296 |
} |
} |
| 392 |
****************************************************************************/ |
****************************************************************************/ |
| 393 |
status_t CloseUSB(int lun) |
status_t CloseUSB(int lun) |
| 394 |
{ |
{ |
| 395 |
|
struct usb_interface *usb_interface; |
| 396 |
|
int interface; |
| 397 |
int reader = LunToReaderIndex(lun); |
int reader = LunToReaderIndex(lun); |
| 398 |
|
|
| 399 |
/* device not opened */ |
/* device not opened */ |
| 402 |
|
|
| 403 |
DEBUG_COMM2("Closing USB device: %s", usbDevice[reader].device_name); |
DEBUG_COMM2("Closing USB device: %s", usbDevice[reader].device_name); |
| 404 |
|
|
| 405 |
usb_release_interface(usbDevice[reader].handle, usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber); |
usb_interface = get_ccid_usb_interface(usbDevice[reader].dev); |
| 406 |
|
interface = usb_interface ? |
| 407 |
|
usb_interface->altsetting->bInterfaceNumber : |
| 408 |
|
usbDevice[reader].dev->config->interface->altsetting->bInterfaceNumber; |
| 409 |
|
|
| 410 |
|
usb_release_interface(usbDevice[reader].handle, interface); |
| 411 |
|
|
| 412 |
usb_close(usbDevice[reader].handle); |
usb_close(usbDevice[reader].handle); |
| 413 |
|
|
| 459 |
{ |
{ |
| 460 |
int i; |
int i; |
| 461 |
int bEndpointAddress; |
int bEndpointAddress; |
| 462 |
|
struct usb_interface *usb_interface = get_ccid_usb_interface(dev); |
| 463 |
|
|
| 464 |
/* |
/* |
| 465 |
* 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out |
* 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out |
| 466 |
*/ |
*/ |
| 467 |
for (i=0; i<3; i++) |
for (i=0; i<3; i++) |
| 468 |
{ |
{ |
| 469 |
if (dev->config->interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK) |
if (usb_interface->altsetting->endpoint[i].bmAttributes != USB_ENDPOINT_TYPE_BULK) |
| 470 |
continue; |
continue; |
| 471 |
|
|
| 472 |
bEndpointAddress = dev->config->interface->altsetting->endpoint[i].bEndpointAddress; |
bEndpointAddress = usb_interface->altsetting->endpoint[i].bEndpointAddress; |
| 473 |
|
|
| 474 |
if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN) |
if ((bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_IN) |
| 475 |
usb_device->bulk_in = bEndpointAddress; |
usb_device->bulk_in = bEndpointAddress; |
| 481 |
return 0; |
return 0; |
| 482 |
} /* get_end_points */ |
} /* get_end_points */ |
| 483 |
|
|
| 484 |
|
|
| 485 |
|
/***************************************************************************** |
| 486 |
|
* |
| 487 |
|
* get_ccid_usb_interface |
| 488 |
|
* |
| 489 |
|
****************************************************************************/ |
| 490 |
|
struct usb_interface * get_ccid_usb_interface(struct usb_device *dev) |
| 491 |
|
{ |
| 492 |
|
struct usb_interface *usb_interface = NULL; |
| 493 |
|
|
| 494 |
|
/* if multiple interfaces use the first one with CCID class type */ |
| 495 |
|
if (dev->config->bNumInterfaces > 1) |
| 496 |
|
{ |
| 497 |
|
int ii; |
| 498 |
|
for (ii=0; ii<dev->config->bNumInterfaces; ii++) |
| 499 |
|
{ |
| 500 |
|
if (dev->config->interface[ii].altsetting->bInterfaceClass == 0xb) |
| 501 |
|
{ |
| 502 |
|
usb_interface = &dev->config->interface[ii]; |
| 503 |
|
break; |
| 504 |
|
} |
| 505 |
|
} |
| 506 |
|
} |
| 507 |
|
else |
| 508 |
|
/* we keep this in case a reader reports a bad class value */ |
| 509 |
|
usb_interface = dev->config->interface; |
| 510 |
|
|
| 511 |
|
return usb_interface; |
| 512 |
|
} /* get_ccid_usb_interface */ |
| 513 |
|
|