1 diff -urN libusb_0.1.10a.orig/bsd.c libusb-0.1.10a/bsd.c
2 --- libusb_0.1.10a.orig/bsd.c 2004-02-18 08:34:52.000000000 +0100
3 +++ libusb-0.1.10a/bsd.c 2005-06-30 19:40:00.000000000 +0200
5 * for both read and write.
8 +#if defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
9 +#define __FreeBSD_kernel__ __FreeBSD__
17 dev->impl_info = info;
20 +#ifdef __FreeBSD_kernel__
21 snprintf(ctlpath, PATH_MAX, "%s", dev->device->filename);
23 snprintf(ctlpath, PATH_MAX, "%s.00", dev->device->filename);
27 if (info->ep_fd[ep] < 0) {
29 +#ifdef __FreeBSD_kernel__
30 snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->device->filename, ep);
32 snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->device->filename, ep);
34 fd = ensure_ep_open(dev, ep, O_WRONLY);
38 +#ifdef __FreeBSD_kernel__
39 fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep));
41 fprintf (stderr, "usb_bulk_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep));
44 ret = write(fd, bytes, size);
47 +#ifdef __FreeBSD_kernel__
48 USB_ERROR_STR(-errno, "error writing to bulk endpoint %s.%d: %s",
49 dev->device->filename, UE_GET_ADDR(ep), strerror(errno));
52 fd = ensure_ep_open(dev, ep, O_RDONLY);
56 +#ifdef __FreeBSD_kernel__
57 fprintf (stderr, "usb_bulk_read: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep));
59 fprintf (stderr, "usb_bulk_read: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep));
62 ret = read(fd, bytes, size);
65 +#ifdef __FreeBSD_kernel__
66 USB_ERROR_STR(-errno, "error reading from bulk endpoint %s.%d: %s",
67 dev->device->filename, UE_GET_ADDR(ep), strerror(errno));
70 fd = ensure_ep_open(dev, ep, O_WRONLY);
74 +#ifdef __FreeBSD_kernel__
75 fprintf (stderr, "usb_interrupt_write: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep));
77 fprintf (stderr, "usb_interrupt_write: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep));
80 ret = write(fd, bytes+sent, size-sent);
83 +#ifdef __FreeBSD_kernel__
84 USB_ERROR_STR(-errno, "error writing to interrupt endpoint %s.%d: %s",
85 dev->device->filename, UE_GET_ADDR(ep), strerror(errno));
88 fd = ensure_ep_open(dev, ep, O_RDONLY);
92 +#ifdef __FreeBSD_kernel__
93 fprintf (stderr, "usb_interrupt_read: got negative open file descriptor for endpoint %d\n", UE_GET_ADDR(ep));
95 fprintf (stderr, "usb_interrupt_read: got negative open file descriptor for endpoint %02d\n", UE_GET_ADDR(ep));
98 ret = read(fd, bytes+retrieved, size-retrieved);
101 +#ifdef __FreeBSD_kernel__
102 USB_ERROR_STR(-errno, "error reading from interrupt endpoint %s.%d: %s",
103 dev->device->filename, UE_GET_ADDR(ep), strerror(errno));
106 /* best not to play with things we don't understand */
110 +#ifdef __FreeBSD_kernel__
111 snprintf(buf, sizeof(buf) - 1, "/dev/%s", di.udi_devnames[0]);
113 snprintf(buf, sizeof(buf) - 1, "/dev/%s.00", di.udi_devnames[0]);
114 diff -urN libusb_0.1.10a.orig/linux.c libusb-0.1.10a/linux.c
115 --- libusb_0.1.10a.orig/linux.c 2005-02-11 03:16:10.000000000 +0100
116 +++ libusb-0.1.10a/linux.c 2005-06-30 19:40:00.000000000 +0200
121 +#define URB_USERCONTEXT_COOKIE ((void *)0x1)
123 /* Reading and writing are the same except for the endpoint */
124 static int usb_urb_transfer(usb_dev_handle *dev, int ep, int urbtype,
125 char *bytes, int size, int timeout)
126 @@ -163,14 +165,16 @@
128 unsigned int bytesdone = 0, requested;
129 struct timeval tv, tv_ref, tv_now;
131 + struct usb_urb *context;
135 - * FIXME: The use of the URB interface is incorrect here if there are
136 - * multiple callers at the same time. We assume we're the only caller
137 - * and if we get completions from another caller, this code will fail
138 - * in interesting ways.
139 + * HACK: The use of urb.usercontext is a hack to get threaded applications
140 + * sort of working again. Threaded support is still not recommended, but
141 + * this should allow applications to work in the common cases. Basically,
142 + * if we get the completion for an URB we're not waiting for, then we update
143 + * the usercontext pointer to 1 for the other threads URB and it will see
144 + * the change after it wakes up from the the timeout. Ugly, but it works.
148 @@ -198,10 +202,10 @@
150 urb.buffer = bytes + bytesdone;
151 urb.buffer_length = requested;
152 - urb.usercontext = (void *)ep;
154 urb.actual_length = 0;
155 urb.number_of_packets = 0; /* don't do isochronous yet */
156 + urb.usercontext = NULL;
158 ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urb);
160 @@ -212,18 +216,28 @@
162 FD_SET(dev->fd, &writefds);
166 - while (((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
168 + while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
170 tv.tv_usec = 1000; // 1 msec
171 select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait
173 - /* compare with actual time, as the select timeout is not that precise */
174 - gettimeofday(&tv_now, NULL);
176 + /* compare with actual time, as the select timeout is not that precise */
177 + gettimeofday(&tv_now, NULL);
179 + if ((tv_now.tv_sec > tv_ref.tv_sec) ||
180 + ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
185 - if ((tv_now.tv_sec > tv_ref.tv_sec) ||
186 - ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
188 + if (context && context != &urb) {
189 + context->usercontext = URB_USERCONTEXT_COOKIE;
190 + /* We need to restart since we got a successful URB, but not ours */
195 @@ -231,14 +245,14 @@
196 * something happened during the reaping and we should return that
199 - if (ret < 0 && errno != EAGAIN)
200 + if (ret < 0 && !urb.usercontext && errno != EAGAIN)
201 USB_ERROR_STR(-errno, "error reaping URB: %s", strerror(errno));
203 bytesdone += urb.actual_length;
204 - } while (ret == 0 && bytesdone < size && urb.actual_length == requested);
205 + } while ((ret == 0 || urb.usercontext) && bytesdone < size && urb.actual_length == requested);
207 /* If the URB didn't complete in success or error, then let's unlink it */
209 + if (ret < 0 && !urb.usercontext) {
213 diff -urN libusb_0.1.10a.orig/usb.h.in libusb-0.1.10a/usb.h.in
214 --- libusb_0.1.10a.orig/usb.h.in 2004-08-03 20:20:38.000000000 +0200
215 +++ libusb-0.1.10a/usb.h.in 2005-06-30 19:40:00.000000000 +0200
223 +#include <sys/param.h>
229 /* All standard descriptors have these 2 fields in common */
230 struct usb_descriptor_header {
232 - u_int8_t bDescriptorType;
235 + uint8_t bDescriptorType;
236 +} __attribute__ ((packed));
238 /* String descriptor */
239 struct usb_string_descriptor {
241 - u_int8_t bDescriptorType;
242 - u_int16_t wData[1];
245 + uint8_t bDescriptorType;
247 +} __attribute__ ((packed));
250 struct usb_hid_descriptor {
252 - u_int8_t bDescriptorType;
254 - u_int8_t bCountryCode;
255 - u_int8_t bNumDescriptors;
256 - /* u_int8_t bReportDescriptorType; */
257 - /* u_int16_t wDescriptorLength; */
259 + uint8_t bDescriptorType;
261 + uint8_t bCountryCode;
262 + uint8_t bNumDescriptors;
263 + /* uint8_t bReportDescriptorType; */
264 + /* uint16_t wDescriptorLength; */
267 +} __attribute__ ((packed));
269 /* Endpoint descriptor */
270 #define USB_MAXENDPOINTS 32
271 struct usb_endpoint_descriptor {
273 - u_int8_t bDescriptorType;
274 - u_int8_t bEndpointAddress;
275 - u_int8_t bmAttributes;
276 - u_int16_t wMaxPacketSize;
277 - u_int8_t bInterval;
279 - u_int8_t bSynchAddress;
280 + uint8_t bLength __attribute__ ((packed));
281 + uint8_t bDescriptorType __attribute__ ((packed));
282 + uint8_t bEndpointAddress __attribute__ ((packed));
283 + uint8_t bmAttributes __attribute__ ((packed));
284 + uint16_t wMaxPacketSize __attribute__ ((packed));
285 + uint8_t bInterval __attribute__ ((packed));
286 + uint8_t bRefresh __attribute__ ((packed));
287 + uint8_t bSynchAddress __attribute__ ((packed));
289 unsigned char *extra; /* Extra descriptors */
291 @@ -114,15 +115,15 @@
292 /* Interface descriptor */
293 #define USB_MAXINTERFACES 32
294 struct usb_interface_descriptor {
296 - u_int8_t bDescriptorType;
297 - u_int8_t bInterfaceNumber;
298 - u_int8_t bAlternateSetting;
299 - u_int8_t bNumEndpoints;
300 - u_int8_t bInterfaceClass;
301 - u_int8_t bInterfaceSubClass;
302 - u_int8_t bInterfaceProtocol;
303 - u_int8_t iInterface;
304 + uint8_t bLength __attribute__ ((packed));;
305 + uint8_t bDescriptorType __attribute__ ((packed));;
306 + uint8_t bInterfaceNumber __attribute__ ((packed));;
307 + uint8_t bAlternateSetting __attribute__ ((packed));;
308 + uint8_t bNumEndpoints __attribute__ ((packed));;
309 + uint8_t bInterfaceClass __attribute__ ((packed));;
310 + uint8_t bInterfaceSubClass __attribute__ ((packed));;
311 + uint8_t bInterfaceProtocol __attribute__ ((packed));;
312 + uint8_t iInterface __attribute__ ((packed));;
314 struct usb_endpoint_descriptor *endpoint;
316 @@ -140,14 +141,14 @@
317 /* Configuration descriptor information.. */
318 #define USB_MAXCONFIG 8
319 struct usb_config_descriptor {
321 - u_int8_t bDescriptorType;
322 - u_int16_t wTotalLength;
323 - u_int8_t bNumInterfaces;
324 - u_int8_t bConfigurationValue;
325 - u_int8_t iConfiguration;
326 - u_int8_t bmAttributes;
328 + uint8_t bLength __attribute__ ((packed));
329 + uint8_t bDescriptorType __attribute__ ((packed));
330 + uint16_t wTotalLength __attribute__ ((packed));
331 + uint8_t bNumInterfaces __attribute__ ((packed));
332 + uint8_t bConfigurationValue __attribute__ ((packed));
333 + uint8_t iConfiguration __attribute__ ((packed));
334 + uint8_t bmAttributes __attribute__ ((packed));
335 + uint8_t MaxPower __attribute__ ((packed));
337 struct usb_interface *interface;
339 @@ -157,29 +158,29 @@
341 /* Device descriptor */
342 struct usb_device_descriptor {
344 - u_int8_t bDescriptorType;
346 - u_int8_t bDeviceClass;
347 - u_int8_t bDeviceSubClass;
348 - u_int8_t bDeviceProtocol;
349 - u_int8_t bMaxPacketSize0;
350 - u_int16_t idVendor;
351 - u_int16_t idProduct;
352 - u_int16_t bcdDevice;
353 - u_int8_t iManufacturer;
355 - u_int8_t iSerialNumber;
356 - u_int8_t bNumConfigurations;
359 + uint8_t bDescriptorType;
361 + uint8_t bDeviceClass;
362 + uint8_t bDeviceSubClass;
363 + uint8_t bDeviceProtocol;
364 + uint8_t bMaxPacketSize0;
366 + uint16_t idProduct;
367 + uint16_t bcdDevice;
368 + uint8_t iManufacturer;
370 + uint8_t iSerialNumber;
371 + uint8_t bNumConfigurations;
372 +} __attribute__ ((packed));
374 struct usb_ctrl_setup {
375 - u_int8_t bRequestType;
381 + uint8_t bRequestType;
386 +} __attribute__ ((packed));
392 void *dev; /* Darwin support */
397 unsigned char num_children;
398 struct usb_device **children;
400 char dirname[PATH_MAX + 1];
402 struct usb_device *devices;
403 - u_int32_t location;
406 struct usb_device *root_dev;