diff -urN libusb_0.1.10a.orig/bsd.c libusb-0.1.10a/bsd.c --- libusb_0.1.10a.orig/bsd.c 2004-02-18 08:34:52.000000000 +0100 +++ libusb-0.1.10a/bsd.c 2005-06-30 19:40:00.000000000 +0200 @@ -25,6 +25,10 @@ * for both read and write. */ +#if defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) +#define __FreeBSD_kernel__ __FreeBSD__ +#endif + #include #include #include @@ -142,7 +146,7 @@ USB_ERROR(-ENOMEM); dev->impl_info = info; -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ snprintf(ctlpath, PATH_MAX, "%s", dev->device->filename); #else snprintf(ctlpath, PATH_MAX, "%s.00", dev->device->filename); @@ -255,7 +259,7 @@ ep = UE_GET_ADDR(ep); if (info->ep_fd[ep] < 0) { -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->device->filename, ep); #else snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->device->filename, ep); @@ -286,7 +290,7 @@ fd = ensure_ep_open(dev, ep, O_WRONLY); if (fd < 0) { if (usb_debug >= 2) { -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep)); #else fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep)); @@ -302,7 +306,7 @@ ret = write(fd, bytes, size); if (ret < 0) -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error writing to bulk endpoint %s.%d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #else @@ -324,7 +328,7 @@ fd = ensure_ep_open(dev, ep, O_RDONLY); if (fd < 0) { if (usb_debug >= 2) { -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ fprintf (stderr, "usb_bulk_read: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep)); #else fprintf (stderr, "usb_bulk_read: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep)); @@ -343,7 +347,7 @@ ret = read(fd, bytes, size); if (ret < 0) -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error reading from bulk endpoint %s.%d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #else @@ -365,7 +369,7 @@ fd = ensure_ep_open(dev, ep, O_WRONLY); if (fd < 0) { if (usb_debug >= 2) { -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ fprintf (stderr, "usb_interrupt_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep)); #else fprintf (stderr, "usb_interrupt_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep)); @@ -382,7 +386,7 @@ do { ret = write(fd, bytes+sent, size-sent); if (ret < 0) -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error writing to interrupt endpoint %s.%d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #else @@ -407,7 +411,7 @@ fd = ensure_ep_open(dev, ep, O_RDONLY); if (fd < 0) { if (usb_debug >= 2) { -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ fprintf (stderr, "usb_interrupt_read: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep)); #else fprintf (stderr, "usb_interrupt_read: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep)); @@ -427,7 +431,7 @@ do { ret = read(fd, bytes+retrieved, size-retrieved); if (ret < 0) -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ USB_ERROR_STR(-errno, "error reading from interrupt endpoint %s.%d: %s", dev->device->filename, UE_GET_ADDR(ep), strerror(errno)); #else @@ -543,7 +547,7 @@ /* best not to play with things we don't understand */ continue; -#if __FreeBSD__ +#ifdef __FreeBSD_kernel__ snprintf(buf, sizeof(buf) - 1, "/dev/%s", di.udi_devnames[0]); #else snprintf(buf, sizeof(buf) - 1, "/dev/%s.00", di.udi_devnames[0]); diff -urN libusb_0.1.10a.orig/linux.c libusb-0.1.10a/linux.c --- libusb_0.1.10a.orig/linux.c 2005-02-11 03:16:10.000000000 +0100 +++ libusb-0.1.10a/linux.c 2005-06-30 19:40:00.000000000 +0200 @@ -156,6 +156,8 @@ return ret; } +#define URB_USERCONTEXT_COOKIE ((void *)0x1) + /* Reading and writing are the same except for the endpoint */ static int usb_urb_transfer(usb_dev_handle *dev, int ep, int urbtype, char *bytes, int size, int timeout) @@ -163,14 +165,16 @@ struct usb_urb urb; unsigned int bytesdone = 0, requested; struct timeval tv, tv_ref, tv_now; - void *context; + struct usb_urb *context; int ret, waiting; /* - * FIXME: The use of the URB interface is incorrect here if there are - * multiple callers at the same time. We assume we're the only caller - * and if we get completions from another caller, this code will fail - * in interesting ways. + * HACK: The use of urb.usercontext is a hack to get threaded applications + * sort of working again. Threaded support is still not recommended, but + * this should allow applications to work in the common cases. Basically, + * if we get the completion for an URB we're not waiting for, then we update + * the usercontext pointer to 1 for the other threads URB and it will see + * the change after it wakes up from the the timeout. Ugly, but it works. */ /* @@ -198,10 +202,10 @@ urb.flags = 0; urb.buffer = bytes + bytesdone; urb.buffer_length = requested; - urb.usercontext = (void *)ep; urb.signr = 0; urb.actual_length = 0; urb.number_of_packets = 0; /* don't do isochronous yet */ + urb.usercontext = NULL; ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urb); if (ret < 0) { @@ -212,18 +216,28 @@ FD_ZERO(&writefds); FD_SET(dev->fd, &writefds); +restart: waiting = 1; - while (((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) { + context = NULL; + while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) { tv.tv_sec = 0; tv.tv_usec = 1000; // 1 msec select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait - /* compare with actual time, as the select timeout is not that precise */ - gettimeofday(&tv_now, NULL); + if (timeout) { + /* compare with actual time, as the select timeout is not that precise */ + gettimeofday(&tv_now, NULL); + + if ((tv_now.tv_sec > tv_ref.tv_sec) || + ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec))) + waiting = 0; + } + } - if ((tv_now.tv_sec > tv_ref.tv_sec) || - ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec))) - waiting = 0; + if (context && context != &urb) { + context->usercontext = URB_USERCONTEXT_COOKIE; + /* We need to restart since we got a successful URB, but not ours */ + goto restart; } /* @@ -231,14 +245,14 @@ * something happened during the reaping and we should return that * error now */ - if (ret < 0 && errno != EAGAIN) + if (ret < 0 && !urb.usercontext && errno != EAGAIN) USB_ERROR_STR(-errno, "error reaping URB: %s", strerror(errno)); bytesdone += urb.actual_length; - } while (ret == 0 && bytesdone < size && urb.actual_length == requested); + } while ((ret == 0 || urb.usercontext) && bytesdone < size && urb.actual_length == requested); /* If the URB didn't complete in success or error, then let's unlink it */ - if (ret < 0) { + if (ret < 0 && !urb.usercontext) { int rc; if (!waiting) diff -urN libusb_0.1.10a.orig/usb.h.in libusb-0.1.10a/usb.h.in --- libusb_0.1.10a.orig/usb.h.in 2004-08-03 20:20:38.000000000 +0200 +++ libusb-0.1.10a/usb.h.in 2005-06-30 19:40:00.000000000 +0200 @@ -13,8 +13,9 @@ #include #include +#include #include - +#include #include /* @@ -63,40 +64,40 @@ /* All standard descriptors have these 2 fields in common */ struct usb_descriptor_header { - u_int8_t bLength; - u_int8_t bDescriptorType; -}; + uint8_t bLength; + uint8_t bDescriptorType; +} __attribute__ ((packed)); /* String descriptor */ struct usb_string_descriptor { - u_int8_t bLength; - u_int8_t bDescriptorType; - u_int16_t wData[1]; -}; + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wData[1]; +} __attribute__ ((packed)); /* HID descriptor */ struct usb_hid_descriptor { - u_int8_t bLength; - u_int8_t bDescriptorType; - u_int16_t bcdHID; - u_int8_t bCountryCode; - u_int8_t bNumDescriptors; - /* u_int8_t bReportDescriptorType; */ - /* u_int16_t wDescriptorLength; */ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; + uint8_t bCountryCode; + uint8_t bNumDescriptors; + /* uint8_t bReportDescriptorType; */ + /* uint16_t wDescriptorLength; */ /* ... */ -}; +} __attribute__ ((packed)); /* Endpoint descriptor */ #define USB_MAXENDPOINTS 32 struct usb_endpoint_descriptor { - u_int8_t bLength; - u_int8_t bDescriptorType; - u_int8_t bEndpointAddress; - u_int8_t bmAttributes; - u_int16_t wMaxPacketSize; - u_int8_t bInterval; - u_int8_t bRefresh; - u_int8_t bSynchAddress; + uint8_t bLength __attribute__ ((packed)); + uint8_t bDescriptorType __attribute__ ((packed)); + uint8_t bEndpointAddress __attribute__ ((packed)); + uint8_t bmAttributes __attribute__ ((packed)); + uint16_t wMaxPacketSize __attribute__ ((packed)); + uint8_t bInterval __attribute__ ((packed)); + uint8_t bRefresh __attribute__ ((packed)); + uint8_t bSynchAddress __attribute__ ((packed)); unsigned char *extra; /* Extra descriptors */ int extralen; @@ -114,15 +115,15 @@ /* Interface descriptor */ #define USB_MAXINTERFACES 32 struct usb_interface_descriptor { - u_int8_t bLength; - u_int8_t bDescriptorType; - u_int8_t bInterfaceNumber; - u_int8_t bAlternateSetting; - u_int8_t bNumEndpoints; - u_int8_t bInterfaceClass; - u_int8_t bInterfaceSubClass; - u_int8_t bInterfaceProtocol; - u_int8_t iInterface; + uint8_t bLength __attribute__ ((packed));; + uint8_t bDescriptorType __attribute__ ((packed));; + uint8_t bInterfaceNumber __attribute__ ((packed));; + uint8_t bAlternateSetting __attribute__ ((packed));; + uint8_t bNumEndpoints __attribute__ ((packed));; + uint8_t bInterfaceClass __attribute__ ((packed));; + uint8_t bInterfaceSubClass __attribute__ ((packed));; + uint8_t bInterfaceProtocol __attribute__ ((packed));; + uint8_t iInterface __attribute__ ((packed));; struct usb_endpoint_descriptor *endpoint; @@ -140,14 +141,14 @@ /* Configuration descriptor information.. */ #define USB_MAXCONFIG 8 struct usb_config_descriptor { - u_int8_t bLength; - u_int8_t bDescriptorType; - u_int16_t wTotalLength; - u_int8_t bNumInterfaces; - u_int8_t bConfigurationValue; - u_int8_t iConfiguration; - u_int8_t bmAttributes; - u_int8_t MaxPower; + uint8_t bLength __attribute__ ((packed)); + uint8_t bDescriptorType __attribute__ ((packed)); + uint16_t wTotalLength __attribute__ ((packed)); + uint8_t bNumInterfaces __attribute__ ((packed)); + uint8_t bConfigurationValue __attribute__ ((packed)); + uint8_t iConfiguration __attribute__ ((packed)); + uint8_t bmAttributes __attribute__ ((packed)); + uint8_t MaxPower __attribute__ ((packed)); struct usb_interface *interface; @@ -157,29 +158,29 @@ /* Device descriptor */ struct usb_device_descriptor { - u_int8_t bLength; - u_int8_t bDescriptorType; - u_int16_t bcdUSB; - u_int8_t bDeviceClass; - u_int8_t bDeviceSubClass; - u_int8_t bDeviceProtocol; - u_int8_t bMaxPacketSize0; - u_int16_t idVendor; - u_int16_t idProduct; - u_int16_t bcdDevice; - u_int8_t iManufacturer; - u_int8_t iProduct; - u_int8_t iSerialNumber; - u_int8_t bNumConfigurations; -}; + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __attribute__ ((packed)); struct usb_ctrl_setup { - u_int8_t bRequestType; - u_int8_t bRequest; - u_int16_t wValue; - u_int16_t wIndex; - u_int16_t wLength; -}; + uint8_t bRequestType; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} __attribute__ ((packed)); /* * Standard requests @@ -249,7 +250,7 @@ void *dev; /* Darwin support */ - u_int8_t devnum; + uint8_t devnum; unsigned char num_children; struct usb_device **children; @@ -261,7 +262,7 @@ char dirname[PATH_MAX + 1]; struct usb_device *devices; - u_int32_t location; + uint32_t location; struct usb_device *root_dev; };