1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

scd: Migrate to new API of libusb 1.0.

* configure.ac (LIBUSB_CPPFLAGS): New.
* scd/Makefile.am (AM_CPPFLAGS): Add LIBUSB_CPPFLAGS.
* scd/ccid-driver.c: Use libusb 1.0 API.
--

Changes are straightforward, not use any new features.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
NIIBE Yutaka 2016-01-27 12:24:05 +09:00
parent 167558a67e
commit d0d9708970
3 changed files with 194 additions and 187 deletions

View File

@ -783,15 +783,52 @@ AM_PATH_KSBA("$NEED_KSBA_API:$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no)
# #
# FiXME: Use GNUPG_CHECK_LIBUSB and modify to use separate AC_SUBSTs. # FiXME: Use GNUPG_CHECK_LIBUSB and modify to use separate AC_SUBSTs.
if test "$use_ccid_driver" = yes ; then if test "$use_ccid_driver" = yes ; then
AC_CHECK_LIB(usb, usb_bulk_write, case $target in
[ LIBUSB_LIBS="$LIBUSB_LIBS -lusb" *-*-darwin*)
AC_DEFINE(HAVE_LIBUSB,1, LIBUSB_LIBS="-lusb-1.0 -Wl,-framework,CoreFoundation -Wl,-framework,IOKit"
[defined if libusb is available]) ;;
*-*-freebsd*)
# FreeBSD has a native 1.0 compatible library by -lusb.
LIBUSB_LIBS="-lusb"
;;
*)
LIBUSB_LIBS="-lusb-1.0"
;;
esac
AC_CHECK_LIB(usb-1.0, libusb_init,
[ LIBUSB_LIBS="$LIBUSB_LIBS"
AC_DEFINE(HAVE_LIBUSB,1, [defined if libusb is available])
have_libusb=yes have_libusb=yes
]) ])
AC_CHECK_FUNCS(usb_create_match) AC_DEFINE([HAVE_LIBUSB])
AC_MSG_CHECKING([libusb include dir])
usb_incdir_found="no"
for _incdir in "" "/usr/include/libusb-1.0" "/usr/local/include/libusb-1.0"; do
_libusb_save_cppflags=$CPPFLAGS
if test -n "${_incdir}"; then
CPPFLAGS="-I${_incdir} ${CPPFLAGS}"
fi
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[@%:@include <libusb.h>]])],
[usb_incdir=${_incdir}; usb_incdir_found="yes"], [])
CPPFLAGS=${_libusb_save_cppflags}
if test "$usb_incdir_found" = "yes"; then
break
fi
done
if test "$usb_incdir_found" = "yes"; then
AC_MSG_RESULT([${usb_incdir}])
else
AC_MSG_RESULT([not found])
use_ccid_driver=no
fi
if test "$usb_incdir" = ""; then
LIBUSB_CPPFLAGS=""
else
LIBUSB_CPPFLAGS="-I${usb_incdir}"
fi
fi fi
AC_SUBST(LIBUSB_LIBS) AC_SUBST(LIBUSB_LIBS)
AC_SUBST(LIBUSB_CPPFLAGS)
# #
# Check wether it is necessary to link against libdl. # Check wether it is necessary to link against libdl.

View File

@ -21,7 +21,7 @@ EXTRA_DIST = ChangeLog-2011 scdaemon-w32info.rc
libexec_PROGRAMS = scdaemon libexec_PROGRAMS = scdaemon
AM_CPPFLAGS = -I$(top_srcdir)/common AM_CPPFLAGS = -I$(top_srcdir)/common $(LIBUSB_CPPFLAGS)
include $(top_srcdir)/am/cmacros.am include $(top_srcdir)/am/cmacros.am

View File

@ -83,11 +83,12 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#ifdef HAVE_NPTH #ifdef HAVE_NPTH
# include <npth.h> # include <npth.h>
#endif /*HAVE_NPTH*/ #endif /*HAVE_NPTH*/
#include <usb.h> #include <libusb.h>
#include "scdaemon.h" #include "scdaemon.h"
#include "iso7816.h" #include "iso7816.h"
@ -237,7 +238,7 @@ static struct
structure is used as handle for most functions. */ structure is used as handle for most functions. */
struct ccid_driver_s struct ccid_driver_s
{ {
usb_dev_handle *idev; libusb_device_handle *idev;
char *rid; char *rid;
int dev_fd; /* -1 for USB transport or file descriptor of the int dev_fd; /* -1 for USB transport or file descriptor of the
transport device. */ transport device. */
@ -985,7 +986,7 @@ parse_ccid_descriptor (ccid_driver_t handle,
static char * static char *
get_escaped_usb_string (usb_dev_handle *idev, int idx, get_escaped_usb_string (libusb_device_handle *idev, int idx,
const char *prefix, const char *suffix) const char *prefix, const char *suffix)
{ {
int rc; int rc;
@ -1005,18 +1006,20 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx,
/* First get the list of supported languages and use the first one. /* First get the list of supported languages and use the first one.
If we do don't find it we try to use English. Note that this is If we do don't find it we try to use English. Note that this is
all in a 2 bute Unicode encoding using little endian. */ all in a 2 bute Unicode encoding using little endian. */
rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN,
(USB_DT_STRING << 8), 0, LIBUSB_REQUEST_GET_DESCRIPTOR,
(char*)buf, sizeof buf, 1000 /* ms timeout */); (LIBUSB_DT_STRING << 8), 0,
(char*)buf, sizeof buf, 1000 /* ms timeout */);
if (rc < 4) if (rc < 4)
langid = 0x0409; /* English. */ langid = 0x0409; /* English. */
else else
langid = (buf[3] << 8) | buf[2]; langid = (buf[3] << 8) | buf[2];
rc = usb_control_msg (idev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, rc = libusb_control_transfer (idev, LIBUSB_ENDPOINT_IN,
(USB_DT_STRING << 8) + idx, langid, LIBUSB_REQUEST_GET_DESCRIPTOR,
(char*)buf, sizeof buf, 1000 /* ms timeout */); (LIBUSB_DT_STRING << 8) + idx, langid,
if (rc < 2 || buf[1] != USB_DT_STRING) (char*)buf, sizeof buf, 1000 /* ms timeout */);
if (rc < 2 || buf[1] != LIBUSB_DT_STRING)
return NULL; /* Error or not a string. */ return NULL; /* Error or not a string. */
len = buf[0]; len = buf[0];
if (len > rc) if (len > rc)
@ -1059,7 +1062,7 @@ get_escaped_usb_string (usb_dev_handle *idev, int idx,
physical reader after a reset. It returns an allocated and possibly physical reader after a reset. It returns an allocated and possibly
percent escaped string or NULL if not enough memory is available. */ percent escaped string or NULL if not enough memory is available. */
static char * static char *
make_reader_id (usb_dev_handle *idev, make_reader_id (libusb_device_handle *idev,
unsigned int vendor, unsigned int product, unsigned int vendor, unsigned int product,
unsigned char serialno_index) unsigned char serialno_index)
{ {
@ -1082,7 +1085,7 @@ make_reader_id (usb_dev_handle *idev,
/* Helper to find the endpoint from an interface descriptor. */ /* Helper to find the endpoint from an interface descriptor. */
static int static int
find_endpoint (struct usb_interface_descriptor *ifcdesc, int mode) find_endpoint (const struct libusb_interface_descriptor *ifcdesc, int mode)
{ {
int no; int no;
int want_bulk_in = 0; int want_bulk_in = 0;
@ -1091,21 +1094,21 @@ find_endpoint (struct usb_interface_descriptor *ifcdesc, int mode)
want_bulk_in = 0x80; want_bulk_in = 0x80;
for (no=0; no < ifcdesc->bNumEndpoints; no++) for (no=0; no < ifcdesc->bNumEndpoints; no++)
{ {
struct usb_endpoint_descriptor *ep = ifcdesc->endpoint + no; const struct libusb_endpoint_descriptor *ep = ifcdesc->endpoint + no;
if (ep->bDescriptorType != USB_DT_ENDPOINT) if (ep->bDescriptorType != LIBUSB_DT_ENDPOINT)
; ;
else if (mode == 2 else if (mode == 2
&& ((ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) && ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
== USB_ENDPOINT_TYPE_INTERRUPT) == LIBUSB_TRANSFER_TYPE_INTERRUPT)
&& (ep->bEndpointAddress & 0x80)) && (ep->bEndpointAddress & 0x80))
return (ep->bEndpointAddress & 0x0f); return ep->bEndpointAddress;
else if (((ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) else if (((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
== USB_ENDPOINT_TYPE_BULK) == LIBUSB_TRANSFER_TYPE_BULK)
&& (ep->bEndpointAddress & 0x80) == want_bulk_in) && (ep->bEndpointAddress & 0x80) == want_bulk_in)
return (ep->bEndpointAddress & 0x0f); return ep->bEndpointAddress;
} }
/* Should never happen. */
return mode == 2? 0x83 : mode == 1? 0x82 :1; return -1;
} }
@ -1116,10 +1119,10 @@ static int
scan_or_find_usb_device (int scan_mode, scan_or_find_usb_device (int scan_mode,
int *readerno, int *count, char **rid_list, int *readerno, int *count, char **rid_list,
const char *readerid, const char *readerid,
struct usb_device *dev, struct libusb_device *dev,
char **r_rid, char **r_rid,
struct usb_device **r_dev, struct libusb_device_descriptor *desc,
usb_dev_handle **r_idev, libusb_device_handle **r_idev,
unsigned char **ifcdesc_extra, unsigned char **ifcdesc_extra,
size_t *ifcdesc_extra_len, size_t *ifcdesc_extra_len,
int *interface_number, int *interface_number,
@ -1128,29 +1131,33 @@ scan_or_find_usb_device (int scan_mode,
int cfg_no; int cfg_no;
int ifc_no; int ifc_no;
int set_no; int set_no;
struct usb_config_descriptor *config; const struct libusb_interface_descriptor *ifcdesc;
struct usb_interface *interface;
struct usb_interface_descriptor *ifcdesc;
char *rid; char *rid;
usb_dev_handle *idev; libusb_device_handle *idev;
int err;
err = libusb_get_device_descriptor (dev, desc);
if (err < 0)
return err;
*r_idev = NULL; *r_idev = NULL;
for (cfg_no=0; cfg_no < dev->descriptor.bNumConfigurations; cfg_no++) for (cfg_no=0; cfg_no < desc->bNumConfigurations; cfg_no++)
{ {
config = dev->config + cfg_no; struct libusb_config_descriptor *config;
if(!config)
continue; err = libusb_get_config_descriptor (dev, cfg_no, &config);
if (err < 0)
{
libusb_free_config_descriptor (config);
continue;
}
for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++) for (ifc_no=0; ifc_no < config->bNumInterfaces; ifc_no++)
{ {
interface = config->interface + ifc_no; for (set_no=0; set_no < config->interface->num_altsetting; set_no++)
if (!interface)
continue;
for (set_no=0; set_no < interface->num_altsetting; set_no++)
{ {
ifcdesc = (interface->altsetting + set_no); ifcdesc = (config->interface->altsetting + set_no);
/* The second condition is for older SCM SPR 532 who did /* The second condition is for older SCM SPR 532 who did
not know about the assigned CCID class. The third not know about the assigned CCID class. The third
condition does the same for a Cherry SmartTerminal condition does the same for a Cherry SmartTerminal
@ -1161,24 +1168,24 @@ scan_or_find_usb_device (int scan_mode,
&& ifcdesc->bInterfaceSubClass == 0 && ifcdesc->bInterfaceSubClass == 0
&& ifcdesc->bInterfaceProtocol == 0) && ifcdesc->bInterfaceProtocol == 0)
|| (ifcdesc->bInterfaceClass == 255 || (ifcdesc->bInterfaceClass == 255
&& dev->descriptor.idVendor == VENDOR_SCM && desc->idVendor == VENDOR_SCM
&& dev->descriptor.idProduct == SCM_SPR532) && desc->idProduct == SCM_SPR532)
|| (ifcdesc->bInterfaceClass == 255 || (ifcdesc->bInterfaceClass == 255
&& dev->descriptor.idVendor == VENDOR_CHERRY && desc->idVendor == VENDOR_CHERRY
&& dev->descriptor.idProduct == CHERRY_ST2000))) && desc->idProduct == CHERRY_ST2000)))
{ {
idev = usb_open (dev); err = libusb_open (dev, &idev);
if (!idev) if (err < 0)
{ {
DEBUGOUT_1 ("usb_open failed: %s\n", DEBUGOUT_1 ("usb_open failed: %s\n",
strerror (errno)); libusb_error_name (err));
continue; /* with next setting. */ continue; /* with next setting. */
} }
rid = make_reader_id (idev, rid = make_reader_id (idev,
dev->descriptor.idVendor, desc->idVendor,
dev->descriptor.idProduct, desc->idProduct,
dev->descriptor.iSerialNumber); desc->iSerialNumber);
if (rid) if (rid)
{ {
if (scan_mode) if (scan_mode)
@ -1219,16 +1226,16 @@ scan_or_find_usb_device (int scan_mode,
if (ifcdesc_extra && ifcdesc_extra_len) if (ifcdesc_extra && ifcdesc_extra_len)
{ {
*ifcdesc_extra = malloc (ifcdesc *ifcdesc_extra = malloc (ifcdesc
->extralen); ->extra_length);
if (!*ifcdesc_extra) if (!*ifcdesc_extra)
{ {
usb_close (idev); libusb_close (idev);
free (rid); free (rid);
return 1; /* Out of core. */ return 1; /* Out of core. */
} }
memcpy (*ifcdesc_extra, ifcdesc->extra, memcpy (*ifcdesc_extra, ifcdesc->extra,
ifcdesc->extralen); ifcdesc->extra_length);
*ifcdesc_extra_len = ifcdesc->extralen; *ifcdesc_extra_len = ifcdesc->extra_length;
} }
if (interface_number) if (interface_number)
@ -1241,8 +1248,6 @@ scan_or_find_usb_device (int scan_mode,
if (ep_intr) if (ep_intr)
*ep_intr = find_endpoint (ifcdesc, 2); *ep_intr = find_endpoint (ifcdesc, 2);
if (r_dev)
*r_dev = dev;
if (r_rid) if (r_rid)
{ {
*r_rid = rid; *r_rid = rid;
@ -1265,7 +1270,7 @@ scan_or_find_usb_device (int scan_mode,
free (rid); free (rid);
} }
usb_close (idev); libusb_close (idev);
idev = NULL; idev = NULL;
return 0; return 0;
} }
@ -1316,27 +1321,27 @@ scan_or_find_usb_device (int scan_mode,
static int static int
scan_or_find_devices (int readerno, const char *readerid, scan_or_find_devices (int readerno, const char *readerid,
char **r_rid, char **r_rid,
struct usb_device **r_dev, struct libusb_device_descriptor *r_desc,
unsigned char **ifcdesc_extra, unsigned char **ifcdesc_extra,
size_t *ifcdesc_extra_len, size_t *ifcdesc_extra_len,
int *interface_number, int *interface_number,
int *ep_bulk_out, int *ep_bulk_in, int *ep_intr, int *ep_bulk_out, int *ep_bulk_in, int *ep_intr,
usb_dev_handle **r_idev, libusb_device_handle **r_idev,
int *r_fd) int *r_fd)
{ {
char *rid_list = NULL; char *rid_list = NULL;
int count = 0; int count = 0;
struct usb_bus *busses, *bus; libusb_device **dev_list = NULL;
struct usb_device *dev = NULL; libusb_device *dev;
usb_dev_handle *idev = NULL; libusb_device_handle *idev = NULL;
int scan_mode = (readerno == -1 && !readerid); int scan_mode = (readerno == -1 && !readerid);
int i; int i;
ssize_t n;
struct libusb_device_descriptor desc;
/* Set return values to a default. */ /* Set return values to a default. */
if (r_rid) if (r_rid)
*r_rid = NULL; *r_rid = NULL;
if (r_dev)
*r_dev = NULL;
if (ifcdesc_extra) if (ifcdesc_extra)
*ifcdesc_extra = NULL; *ifcdesc_extra = NULL;
if (ifcdesc_extra_len) if (ifcdesc_extra_len)
@ -1354,39 +1359,32 @@ scan_or_find_devices (int readerno, const char *readerid,
assert (r_rid); assert (r_rid);
} }
usb_find_busses(); n = libusb_get_device_list (NULL, &dev_list);
usb_find_devices();
#ifdef HAVE_USB_GET_BUSSES for (i = 0; i < n; i++)
busses = usb_get_busses();
#else
busses = usb_busses;
#endif
for (bus = busses; bus; bus = bus->next)
{ {
for (dev = bus->devices; dev; dev = dev->next) dev = dev_list[i];
if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list,
readerid,
dev,
r_rid,
&desc,
&idev,
ifcdesc_extra,
ifcdesc_extra_len,
interface_number,
ep_bulk_out, ep_bulk_in, ep_intr))
{ {
if (scan_or_find_usb_device (scan_mode, &readerno, &count, &rid_list, /* Found requested device or out of core. */
readerid, if (!idev)
dev,
r_rid,
r_dev,
&idev,
ifcdesc_extra,
ifcdesc_extra_len,
interface_number,
ep_bulk_out, ep_bulk_in, ep_intr))
{ {
/* Found requested device or out of core. */ free (rid_list);
if (!idev) return -1; /* error */
{
free (rid_list);
return -1; /* error */
}
*r_idev = idev;
return 0;
} }
*r_idev = idev;
if (r_desc)
memcpy (r_desc, &desc, sizeof (struct libusb_device_descriptor));
return 0;
} }
} }
@ -1501,7 +1499,7 @@ ccid_get_reader_list (void)
if (!initialized_usb) if (!initialized_usb)
{ {
usb_init (); libusb_init (NULL);
initialized_usb = 1; initialized_usb = 1;
} }
@ -1546,20 +1544,20 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid,
const char **rdrname_p) const char **rdrname_p)
{ {
int rc = 0; int rc = 0;
struct usb_device *dev = NULL; libusb_device_handle *idev = NULL;
usb_dev_handle *idev = NULL;
int dev_fd = -1; int dev_fd = -1;
char *rid = NULL; char *rid = NULL;
unsigned char *ifcdesc_extra = NULL; unsigned char *ifcdesc_extra = NULL;
size_t ifcdesc_extra_len; size_t ifcdesc_extra_len;
int readerno; int readerno;
int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr; int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr;
struct libusb_device_descriptor desc;
*handle = NULL; *handle = NULL;
if (!initialized_usb) if (!initialized_usb)
{ {
usb_init (); libusb_init (NULL);
initialized_usb = 1; initialized_usb = 1;
} }
@ -1581,7 +1579,7 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid,
else else
readerno = 0; /* Default. */ readerno = 0; /* Default. */
if (scan_or_find_devices (readerno, readerid, &rid, &dev, if (scan_or_find_devices (readerno, readerid, &rid, &desc,
&ifcdesc_extra, &ifcdesc_extra_len, &ifcdesc_extra, &ifcdesc_extra_len,
&ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr, &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr,
&idev, &dev_fd) ) &idev, &dev_fd) )
@ -1607,9 +1605,9 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid,
{ {
(*handle)->idev = idev; (*handle)->idev = idev;
(*handle)->dev_fd = -1; (*handle)->dev_fd = -1;
(*handle)->id_vendor = dev->descriptor.idVendor; (*handle)->id_vendor = desc.idVendor;
(*handle)->id_product = dev->descriptor.idProduct; (*handle)->id_product = desc.idProduct;
(*handle)->bcd_device = dev->descriptor.bcdDevice; (*handle)->bcd_device = desc.bcdDevice;
(*handle)->ifc_no = ifc_no; (*handle)->ifc_no = ifc_no;
(*handle)->ep_bulk_out = ep_bulk_out; (*handle)->ep_bulk_out = ep_bulk_out;
(*handle)->ep_bulk_in = ep_bulk_in; (*handle)->ep_bulk_in = ep_bulk_in;
@ -1639,8 +1637,8 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid,
goto leave; goto leave;
} }
rc = usb_claim_interface (idev, ifc_no); rc = libusb_claim_interface (idev, ifc_no);
if (rc) if (rc < 0)
{ {
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
rc = CCID_DRIVER_ERR_CARD_IO_ERROR; rc = CCID_DRIVER_ERR_CARD_IO_ERROR;
@ -1656,7 +1654,7 @@ ccid_open_reader (ccid_driver_t *handle, const char *readerid,
{ {
free (rid); free (rid);
if (idev) if (idev)
usb_close (idev); libusb_close (idev);
if (dev_fd != -1) if (dev_fd != -1)
close (dev_fd); close (dev_fd);
free (*handle); free (*handle);
@ -1697,8 +1695,8 @@ do_close_reader (ccid_driver_t handle)
} }
if (handle->idev) if (handle->idev)
{ {
usb_release_interface (handle->idev, handle->ifc_no); libusb_release_interface (handle->idev, handle->ifc_no);
usb_close (handle->idev); libusb_close (handle->idev);
handle->idev = NULL; handle->idev = NULL;
} }
if (handle->dev_fd != -1) if (handle->dev_fd != -1)
@ -1721,8 +1719,7 @@ int
ccid_shutdown_reader (ccid_driver_t handle) ccid_shutdown_reader (ccid_driver_t handle)
{ {
int rc = 0; int rc = 0;
struct usb_device *dev = NULL; libusb_device_handle *idev = NULL;
usb_dev_handle *idev = NULL;
unsigned char *ifcdesc_extra = NULL; unsigned char *ifcdesc_extra = NULL;
size_t ifcdesc_extra_len; size_t ifcdesc_extra_len;
int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr; int ifc_no, ep_bulk_out, ep_bulk_in, ep_intr;
@ -1732,7 +1729,7 @@ ccid_shutdown_reader (ccid_driver_t handle)
do_close_reader (handle); do_close_reader (handle);
if (scan_or_find_devices (-1, handle->rid, NULL, &dev, if (scan_or_find_devices (-1, handle->rid, NULL, NULL,
&ifcdesc_extra, &ifcdesc_extra_len, &ifcdesc_extra, &ifcdesc_extra_len,
&ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr, &ifc_no, &ep_bulk_out, &ep_bulk_in, &ep_intr,
&idev, NULL) || !idev) &idev, NULL) || !idev)
@ -1756,7 +1753,7 @@ ccid_shutdown_reader (ccid_driver_t handle)
goto leave; goto leave;
} }
rc = usb_claim_interface (idev, ifc_no); rc = libusb_claim_interface (idev, ifc_no);
if (rc) if (rc)
{ {
DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc); DEBUGOUT_1 ("usb_claim_interface failed: %d\n", rc);
@ -1770,7 +1767,7 @@ ccid_shutdown_reader (ccid_driver_t handle)
if (rc) if (rc)
{ {
if (handle->idev) if (handle->idev)
usb_close (handle->idev); libusb_close (handle->idev);
handle->idev = NULL; handle->idev = NULL;
if (handle->dev_fd != -1) if (handle->dev_fd != -1)
close (handle->dev_fd); close (handle->dev_fd);
@ -1843,11 +1840,6 @@ writen (int fd, const void *buf, size_t nbytes)
return 0; return 0;
} }
#if defined(ENXIO) && !defined(LIBUSB_PATH_MAX) && defined(__GNU_LIBRARY__)
#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENXIO /* libusb-compat */
#elif defined(ENODEV)
#define LIBUSB_ERRNO_NO_SUCH_DEVICE ENODEV /* Original libusb */
#endif
/* Write a MSG of length MSGLEN to the designated bulk out endpoint. /* Write a MSG of length MSGLEN to the designated bulk out endpoint.
Returns 0 on success. */ Returns 0 on success. */
@ -1916,35 +1908,23 @@ bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen,
if (handle->idev) if (handle->idev)
{ {
rc = usb_bulk_write (handle->idev, int transferred;
handle->ep_bulk_out,
(char*)msg, msglen,
5000 /* ms timeout */);
if (rc == msglen)
return 0;
#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE
if (rc == -(LIBUSB_ERRNO_NO_SUCH_DEVICE))
{
/* The Linux libusb returns a negative error value. Catch
the most important one. */
errno = LIBUSB_ERRNO_NO_SUCH_DEVICE;
rc = -1;
}
#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/
if (rc == -1) rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out,
(char*)msg, msglen, &transferred,
5000 /* ms timeout */);
if (rc == 0 && transferred == msglen)
return 0;
if (rc < 0)
{ {
DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno)); DEBUGOUT_1 ("usb_bulk_write error: %s\n", libusb_error_name (rc));
#ifdef LIBUSB_ERRNO_NO_SUCH_DEVICE if (rc == LIBUSB_ERROR_NO_DEVICE)
if (errno == LIBUSB_ERRNO_NO_SUCH_DEVICE)
{ {
handle->enodev_seen = 1; handle->enodev_seen = 1;
return CCID_DRIVER_ERR_NO_READER; return CCID_DRIVER_ERR_NO_READER;
} }
#endif /*LIBUSB_ERRNO_NO_SUCH_DEVICE*/
} }
else
DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc);
} }
else else
{ {
@ -1981,14 +1961,11 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
retry: retry:
if (handle->idev) if (handle->idev)
{ {
rc = usb_bulk_read (handle->idev, rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in,
handle->ep_bulk_in, (char*)buffer, length, &msglen, timeout);
(char*)buffer, length,
timeout);
if (rc < 0) if (rc < 0)
{ {
rc = errno; DEBUGOUT_1 ("usb_bulk_read error: %s\n", libusb_error_name (rc));
DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (rc));
if (rc == EAGAIN && eagain_retries++ < 3) if (rc == EAGAIN && eagain_retries++ < 3)
{ {
my_sleep (1); my_sleep (1);
@ -1996,7 +1973,7 @@ bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length,
} }
return CCID_DRIVER_ERR_CARD_IO_ERROR; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
*nread = msglen = rc; *nread = msglen;
} }
else else
{ {
@ -2117,17 +2094,17 @@ abort_cmd (ccid_driver_t handle, int seqno)
/* Send the abort command to the control pipe. Note that we don't /* Send the abort command to the control pipe. Note that we don't
need to keep track of sent abort commands because there should need to keep track of sent abort commands because there should
never be another thread using the same slot concurrently. */ never be another thread using the same slot concurrently. */
rc = usb_control_msg (handle->idev, rc = libusb_control_transfer (handle->idev,
0x21,/* bmRequestType: host-to-device, 0x21,/* bmRequestType: host-to-device,
class specific, to interface. */ class specific, to interface. */
1, /* ABORT */ 1, /* ABORT */
(seqno << 8 | 0 /* slot */), (seqno << 8 | 0 /* slot */),
handle->ifc_no, handle->ifc_no,
dummybuf, 0, dummybuf, 0,
1000 /* ms timeout */); 1000 /* ms timeout */);
if (rc < 0) if (rc < 0)
{ {
DEBUGOUT_1 ("usb_control_msg error: %s\n", strerror (errno)); DEBUGOUT_1 ("usb_control_msg error: %s\n", libusb_error_name (rc));
return CCID_DRIVER_ERR_CARD_IO_ERROR; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
@ -2137,6 +2114,8 @@ abort_cmd (ccid_driver_t handle, int seqno)
seqno--; /* Adjust for next increment. */ seqno--; /* Adjust for next increment. */
do do
{ {
int transferred;
seqno++; seqno++;
msg[0] = PC_to_RDR_Abort; msg[0] = PC_to_RDR_Abort;
msg[5] = 0; /* slot */ msg[5] = 0; /* slot */
@ -2147,32 +2126,27 @@ abort_cmd (ccid_driver_t handle, int seqno)
msglen = 10; msglen = 10;
set_msg_len (msg, 0); set_msg_len (msg, 0);
rc = usb_bulk_write (handle->idev, rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_out,
handle->ep_bulk_out, (char*)msg, msglen, &transferred,
(char*)msg, msglen, 5000 /* ms timeout */);
5000 /* ms timeout */); if (rc == 0 && transferred == msglen)
if (rc == msglen)
rc = 0; rc = 0;
else if (rc == -1) else if (rc < 0)
DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n", DEBUGOUT_1 ("usb_bulk_write error in abort_cmd: %s\n",
strerror (errno)); libusb_error_name (rc));
else
DEBUGOUT_1 ("usb_bulk_write failed in abort_cmd: %d\n", rc);
if (rc) if (rc)
return rc; return rc;
rc = usb_bulk_read (handle->idev, rc = libusb_bulk_transfer (handle->idev, handle->ep_bulk_in,
handle->ep_bulk_in, (char*)msg, sizeof msg, &msglen,
(char*)msg, sizeof msg, 5000 /*ms timeout*/);
5000 /*ms timeout*/);
if (rc < 0) if (rc < 0)
{ {
DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n", DEBUGOUT_1 ("usb_bulk_read error in abort_cmd: %s\n",
strerror (errno)); libusb_error_name (rc));
return CCID_DRIVER_ERR_CARD_IO_ERROR; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
msglen = rc;
if (msglen < 10) if (msglen < 10)
{ {
@ -2283,11 +2257,10 @@ ccid_poll (ccid_driver_t handle)
if (handle->idev) if (handle->idev)
{ {
rc = usb_bulk_read (handle->idev, rc = libusb_bulk_transfer (handle->idev, handle->ep_intr,
handle->ep_intr, (char*)msg, sizeof msg, &msglen,
(char*)msg, sizeof msg, 0 /* ms timeout */ );
0 /* ms timeout */ ); if (rc == LIBUSB_ERROR_TIMEOUT)
if (rc < 0 && errno == ETIMEDOUT)
return 0; return 0;
} }
else else
@ -2295,13 +2268,10 @@ ccid_poll (ccid_driver_t handle)
if (rc < 0) if (rc < 0)
{ {
DEBUGOUT_1 ("usb_intr_read error: %s\n", strerror (errno)); DEBUGOUT_1 ("usb_intr_read error: %s\n", libusb_error_name (rc));
return CCID_DRIVER_ERR_CARD_IO_ERROR; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
msglen = rc;
rc = 0;
if (msglen < 1) if (msglen < 1)
{ {
DEBUGOUT ("intr-in msg too short\n"); DEBUGOUT ("intr-in msg too short\n");
@ -2365,8 +2335,8 @@ ccid_slot_status (ccid_driver_t handle, int *statusbits)
if (!retries) if (!retries)
{ {
DEBUGOUT ("USB: CALLING USB_CLEAR_HALT\n"); DEBUGOUT ("USB: CALLING USB_CLEAR_HALT\n");
usb_clear_halt (handle->idev, handle->ep_bulk_in); libusb_clear_halt (handle->idev, handle->ep_bulk_in);
usb_clear_halt (handle->idev, handle->ep_bulk_out); libusb_clear_halt (handle->idev, handle->ep_bulk_out);
} }
else else
DEBUGOUT ("USB: RETRYING bulk_in AGAIN\n"); DEBUGOUT ("USB: RETRYING bulk_in AGAIN\n");
@ -3112,7 +3082,7 @@ ccid_transceive (ccid_driver_t handle,
if (tpdulen < 4) if (tpdulen < 4)
{ {
usb_clear_halt (handle->idev, handle->ep_bulk_in); libusb_clear_halt (handle->idev, handle->ep_bulk_in);
return CCID_DRIVER_ERR_ABORTED; return CCID_DRIVER_ERR_ABORTED;
} }
@ -3546,7 +3516,7 @@ ccid_transceive_secure (ccid_driver_t handle,
if (tpdulen < 4) if (tpdulen < 4)
{ {
usb_clear_halt (handle->idev, handle->ep_bulk_in); libusb_clear_halt (handle->idev, handle->ep_bulk_in);
return CCID_DRIVER_ERR_ABORTED; return CCID_DRIVER_ERR_ABORTED;
} }
if (debug_level > 1) if (debug_level > 1)