4 * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
6 * This library is covered by the LGPL, read LICENSE for details.
9 #include <stdlib.h> /* getenv, etc */
32 static char usb_path
[PATH_MAX
+ 1] = "";
34 static int device_open(struct usb_device
*dev
)
36 char filename
[PATH_MAX
+ 1];
39 snprintf(filename
, sizeof(filename
) - 1, "%s/%s/%s",
40 usb_path
, dev
->bus
->dirname
, dev
->filename
);
42 fd
= open(filename
, O_RDWR
);
44 fd
= open(filename
, O_RDONLY
);
46 USB_ERROR_STR(-errno
, "failed to open %s: %s",
47 filename
, strerror(errno
));
53 int usb_os_open(usb_dev_handle
*dev
)
55 dev
->fd
= device_open(dev
->device
);
60 int usb_os_close(usb_dev_handle
*dev
)
65 if (close(dev
->fd
) == -1)
66 /* Failing trying to close a file really isn't an error, so return 0 */
67 USB_ERROR_STR(0, "tried to close device fd %d: %s", dev
->fd
,
73 int usb_set_configuration(usb_dev_handle
*dev
, int configuration
)
77 ret
= ioctl(dev
->fd
, IOCTL_USB_SETCONFIG
, &configuration
);
79 USB_ERROR_STR(-errno
, "could not set config %d: %s", configuration
,
82 dev
->config
= configuration
;
87 int usb_claim_interface(usb_dev_handle
*dev
, int interface
)
91 ret
= ioctl(dev
->fd
, IOCTL_USB_CLAIMINTF
, &interface
);
93 if (errno
== EBUSY
&& usb_debug
> 0)
94 fprintf(stderr
, "Check that you have permissions to write to %s/%s and, if you don't, that you set up hotplug (http://linux-hotplug.sourceforge.net/) correctly.\n", dev
->bus
->dirname
, dev
->device
->filename
);
96 USB_ERROR_STR(-errno
, "could not claim interface %d: %s", interface
,
100 dev
->interface
= interface
;
105 int usb_release_interface(usb_dev_handle
*dev
, int interface
)
109 ret
= ioctl(dev
->fd
, IOCTL_USB_RELEASEINTF
, &interface
);
111 USB_ERROR_STR(-errno
, "could not release intf %d: %s", interface
,
119 int usb_set_altinterface(usb_dev_handle
*dev
, int alternate
)
122 struct usb_setinterface setintf
;
124 if (dev
->interface
< 0)
127 setintf
.interface
= dev
->interface
;
128 setintf
.altsetting
= alternate
;
130 ret
= ioctl(dev
->fd
, IOCTL_USB_SETINTF
, &setintf
);
132 USB_ERROR_STR(-errno
, "could not set alt intf %d/%d: %s",
133 dev
->interface
, alternate
, strerror(errno
));
135 dev
->altsetting
= alternate
;
141 * Linux usbfs has a limit of one page size for synchronous bulk read/write.
142 * 4096 is the most portable maximum we can do for now.
143 * Linux usbfs has a limit of 16KB for the URB interface. We use this now
144 * to get better performance for USB 2.0 devices.
146 #define MAX_READ_WRITE (16 * 1024)
148 int usb_control_msg(usb_dev_handle
*dev
, int requesttype
, int request
,
149 int value
, int index
, char *bytes
, int size
, int timeout
)
151 struct usb_ctrltransfer ctrl
;
154 ctrl
.bRequestType
= requesttype
;
155 ctrl
.bRequest
= request
;
161 ctrl
.timeout
= timeout
;
163 ret
= ioctl(dev
->fd
, IOCTL_USB_CONTROL
, &ctrl
);
165 USB_ERROR_STR(-errno
, "error sending control message: %s", strerror(errno
));
170 #define URB_USERCONTEXT_COOKIE ((void *)0x1)
172 /* Reading and writing are the same except for the endpoint */
173 static int usb_urb_transfer(usb_dev_handle
*dev
, int ep
, int urbtype
,
174 char *bytes
, int size
, int timeout
)
177 int bytesdone
= 0, requested
;
178 struct timeval tv
, tv_ref
, tv_now
;
179 struct usb_urb
*context
;
183 * HACK: The use of urb.usercontext is a hack to get threaded applications
184 * sort of working again. Threaded support is still not recommended, but
185 * this should allow applications to work in the common cases. Basically,
186 * if we get the completion for an URB we're not waiting for, then we update
187 * the usercontext pointer to 1 for the other threads URB and it will see
188 * the change after it wakes up from the the timeout. Ugly, but it works.
192 * Get actual time, and add the timeout value. The result is the absolute
193 * time where we have to quit waiting for an message.
195 gettimeofday(&tv_ref
, NULL
);
196 tv_ref
.tv_sec
= tv_ref
.tv_sec
+ timeout
/ 1000;
197 tv_ref
.tv_usec
= tv_ref
.tv_usec
+ (timeout
% 1000) * 1000;
199 if (tv_ref
.tv_usec
> 1000000) {
200 tv_ref
.tv_usec
-= 1000000;
207 requested
= size
- bytesdone
;
208 if (requested
> MAX_READ_WRITE
)
209 requested
= MAX_READ_WRITE
;
214 urb
.buffer
= bytes
+ bytesdone
;
215 urb
.buffer_length
= requested
;
217 urb
.actual_length
= 0;
218 urb
.number_of_packets
= 0; /* don't do isochronous yet */
219 urb
.usercontext
= NULL
;
221 ret
= ioctl(dev
->fd
, IOCTL_USB_SUBMITURB
, &urb
);
223 USB_ERROR_STR(-errno
, "error submitting URB: %s", strerror(errno
));
229 while (!urb
.usercontext
&& ((ret
= ioctl(dev
->fd
, IOCTL_USB_REAPURBNDELAY
, &context
)) == -1) && waiting
) {
231 tv
.tv_usec
= 1000; // 1 msec
233 FD_SET(dev
->fd
, &writefds
);
234 select(dev
->fd
+ 1, NULL
, &writefds
, NULL
, &tv
); //sub second wait
237 /* compare with actual time, as the select timeout is not that precise */
238 gettimeofday(&tv_now
, NULL
);
240 if ((tv_now
.tv_sec
> tv_ref
.tv_sec
) ||
241 ((tv_now
.tv_sec
== tv_ref
.tv_sec
) && (tv_now
.tv_usec
>= tv_ref
.tv_usec
)))
246 if (context
&& context
!= &urb
) {
247 context
->usercontext
= URB_USERCONTEXT_COOKIE
;
248 /* We need to restart since we got a successful URB, but not ours */
253 * If there was an error, that wasn't EAGAIN (no completion), then
254 * something happened during the reaping and we should return that
257 if (ret
< 0 && !urb
.usercontext
&& errno
!= EAGAIN
)
258 USB_ERROR_STR(-errno
, "error reaping URB: %s", strerror(errno
));
260 bytesdone
+= urb
.actual_length
;
261 } while ((ret
== 0 || urb
.usercontext
) && bytesdone
< size
&& urb
.actual_length
== requested
);
263 /* If the URB didn't complete in success or error, then let's unlink it */
264 if (ret
< 0 && !urb
.usercontext
) {
272 ret
= ioctl(dev
->fd
, IOCTL_USB_DISCARDURB
, &urb
);
273 if (ret
< 0 && errno
!= EINVAL
&& usb_debug
>= 1)
274 fprintf(stderr
, "error discarding URB: %s", strerror(errno
));
277 * When the URB is unlinked, it gets moved to the completed list and
278 * then we need to reap it or else the next time we call this function,
279 * we'll get the previous completion and exit early
281 ret
= ioctl(dev
->fd
, IOCTL_USB_REAPURB
, &context
);
282 if(ret
< 0 && usb_debug
>= 1)
283 fprintf(stderr
, "error reaping URB (after discard): %s", strerror(errno
));
284 else if(context
->actual_length
> 0) {
285 bytesdone
+= urb
.actual_length
;
295 static int submit_urb(int fd
, struct usb_urb
* urb
, int urbtype
, int ep
, void* data
, int data_len
)
301 urb
->buffer_length
= data_len
;
303 urb
->actual_length
= 0;
304 urb
->number_of_packets
= 0; /* don't do isochronous yet */
305 urb
->usercontext
= NULL
;
306 return ioctl(fd
, IOCTL_USB_SUBMITURB
, urb
);
309 static int usb_setup_async(usb_dev_handle
*dev
, void **context
, unsigned char ep
, int urbtype
)
311 struct usb_async
* async
= malloc(sizeof(struct usb_async
));
321 async
->bytes_done
= 0;
322 async
->urbtype
= urbtype
;
323 async
->urbs_in_flight
= 0;
328 int usb_bulk_setup_async(usb_dev_handle
*dev
, void **context
, unsigned char ep
)
330 return usb_setup_async(dev
, context
, ep
, USB_URB_TYPE_BULK
);
333 int usb_interrupt_setup_async(usb_dev_handle
*dev
, void **context
, unsigned char ep
)
335 return usb_setup_async(dev
, context
, ep
, USB_URB_TYPE_INTERRUPT
);
338 static int reap_urbs(struct usb_async
*async
)
340 struct usb_urb
* context
;
342 if(async
->urbs_in_flight
== 0)
345 int ret
= ioctl(async
->dev
->fd
, IOCTL_USB_REAPURBNDELAY
, &context
);
351 USB_ERROR_STR(-errno
, "failed to reap URB: %s", strerror(errno
));
354 fprintf(stderr
, "Reaping URB %p actual length: %d\n",
355 context
, context
->actual_length
);
357 async
->bytes_done
+= context
->actual_length
;
358 async
->urbs_in_flight
= 0;
364 int usb_async_is_done(void* context
)
366 struct usb_async
* async
= context
;
367 if(reap_urbs(async
) < 0)
370 if(async
->urbs_in_flight
== 0)
376 int usb_async_get_fd(void *context
)
378 struct usb_async
* async
= context
;
379 return async
->dev
->fd
;
382 static int usb_reap_async_impl(struct usb_async
* async
, int timeout
, int cancel
)
384 struct timeval tv
, tv_now
, tv_ref
;
387 ret
= reap_urbs(async
);
391 if(async
->urbs_in_flight
== 0)
394 gettimeofday(&tv_ref
, NULL
);
395 tv_ref
.tv_sec
= tv_ref
.tv_sec
+ timeout
/ 1000;
396 tv_ref
.tv_usec
= tv_ref
.tv_usec
+ (timeout
% 1000) * 1000;
398 if (tv_ref
.tv_usec
> 1000000) {
399 tv_ref
.tv_usec
-= 1000000;
404 gettimeofday(&tv_now
, NULL
);
405 int sec
= tv_ref
.tv_sec
- tv_now
.tv_sec
;
406 int usec
= tv_ref
.tv_usec
- tv_now
.tv_usec
;
421 FD_SET(async
->dev
->fd
, &readfds
);
422 ret
= select(async
->dev
->fd
+ 1, &readfds
, NULL
, NULL
, &tv
);
423 if(ret
== -1 && errno
== EINTR
)
427 USB_ERROR_STR(-errno
, "select failed: %s", strerror(errno
));
430 return usb_cancel_async(async
);
435 int usb_reap_async(void *async_context
, int timeout
)
437 struct usb_async
* async
= async_context
;
438 int prev_done
= async
->bytes_done
;
439 int ret
= usb_reap_async_impl(async
, timeout
, 1);
441 if(ret
< 0 && prev_done
== async
->bytes_done
)
444 return async
->bytes_done
- prev_done
;
447 int usb_reap_async_nocancel(void *async_context
, int timeout
)
449 struct usb_async
* async
= async_context
;
450 int prev_done
= async
->bytes_done
;
451 int ret
= usb_reap_async_impl(async
, timeout
, 0);
453 if(ret
< 0 && prev_done
== async
->bytes_done
)
456 return async
->bytes_done
- prev_done
;
459 int usb_cancel_async(void *async_context
)
461 struct usb_async
* async
= async_context
;
462 struct usb_urb
* context
;
463 int prev_done
= async
->bytes_done
;
467 if(async
->urbs_in_flight
> 0) {
468 int ret
= ioctl(async
->dev
->fd
, IOCTL_USB_DISCARDURB
, &context
);
469 if (ret
< 0 && errno
!= EINVAL
&& usb_debug
>= 1)
470 fprintf(stderr
, "error discarding URB: %s", strerror(errno
));
473 * When the URB is unlinked, it gets moved to the completed
474 * list and then we need to reap it or else the next time we
475 * call this function, we'll get the previous completion and
478 ret
= ioctl(async
->dev
->fd
, IOCTL_USB_REAPURB
, &context
);
480 if(prev_done
== async
->bytes_done
)
481 USB_ERROR_STR(-errno
, "error reaping URB after discard: %s",
483 } else if(context
->actual_length
> 0) {
484 async
->bytes_done
+= context
->actual_length
;
488 return async
->bytes_done
- prev_done
;
491 int usb_free_async(void *context
)
497 int usb_submit_async(void *context
, char *bytes
, int size
)
499 struct usb_async
*async
= context
;
501 if(reap_urbs(async
) < 0)
504 if(async
->urbs_in_flight
> 0)
505 USB_ERROR_STR(-EINVAL
, "Cannot submit new request before the "
506 "previous request is completed.");
508 if(size
> MAX_READ_WRITE
)
509 USB_ERROR_STR(-EINVAL
, "Request too large.");
512 fprintf(stderr
, "Submitting urb %p size: %d\n", &async
->urb
, size
);
513 int ret
= submit_urb(async
->dev
->fd
, &async
->urb
,
514 async
->urbtype
, async
->ep
,
517 USB_ERROR_STR(-errno
, "error submitting URB: %s", strerror(errno
));
519 async
->urbs_in_flight
= 1;
524 int usb_max_read_write()
526 return MAX_READ_WRITE
;
529 #define MAX_NUM_URBS 2
530 static int usb_urb_transfer_low_latency(usb_dev_handle
*dev
, int ep
, int urbtype
,
531 char *bytes
, int size
, int timeout
)
533 struct timeval tv_ref
;
534 struct usb_urb
*context
;
535 struct usb_urb urbs
[MAX_NUM_URBS
];
537 int urbs_in_flight
= 0;
539 int first_fail
= 0; /* errno of first USB failure, otherwise 0. */
540 int waiting
= 1; /* 0 if we have passed the timeout deadline, otherwise 1 */
541 int bytessent
= 0; /* Bytes submitted */
542 int bytesdone
= 0; /* Bytes done, i.e., submitted and reaped */
545 * Get actual time, and add the timeout value. The result is the absolute
546 * time where we have to quit waiting for an message.
548 gettimeofday(&tv_ref
, NULL
);
549 tv_ref
.tv_sec
= tv_ref
.tv_sec
+ timeout
/ 1000;
550 tv_ref
.tv_usec
= tv_ref
.tv_usec
+ (timeout
% 1000) * 1000;
552 if (tv_ref
.tv_usec
> 1000000) {
553 tv_ref
.tv_usec
-= 1000000;
557 while (bytesdone
< size
) {
558 while(urbs_in_flight
< MAX_NUM_URBS
&& bytessent
< size
) {
559 int requested
= size
- bytessent
;
560 if (requested
> MAX_READ_WRITE
)
561 requested
= MAX_READ_WRITE
;
564 fprintf(stderr
, "Submitting urb %p urbs_in_flight: %d " \
565 "urb_start: %d requested: %d\n",
566 &urbs
[urb_start
], urbs_in_flight
, urb_start
, requested
);
567 ret
= submit_urb(dev
->fd
, &urbs
[urb_start
], urbtype
, ep
,
568 bytes
+ bytessent
, requested
);
572 fprintf(stderr
, "error submitting URB: %s", strerror(errno
));
576 fprintf(stderr
, "actual length: %d\n", urbs
[urb_start
].actual_length
);
578 urb_start
= (urb_start
+ 1) % MAX_NUM_URBS
;
579 bytessent
+= requested
;
583 while (((ret
= ioctl(dev
->fd
, IOCTL_USB_REAPURBNDELAY
, &context
)) < 0) &&
586 * If there was an error, that wasn't EAGAIN (no completion), then
587 * something happened during the reaping and we should return that
590 if (ret
< 0 && errno
!= EAGAIN
) {
593 fprintf(stderr
, "error reaping URB: %s", strerror(errno
));
597 struct timeval tv
, tv_now
;
598 gettimeofday(&tv_now
, NULL
);
599 int sec
= tv_ref
.tv_sec
- tv_now
.tv_sec
;
600 int usec
= tv_ref
.tv_usec
- tv_now
.tv_usec
;
615 fprintf(stderr
, "Going to sleep\n");
618 FD_SET(dev
->fd
, &writefds
);
619 select(dev
->fd
+ 1, NULL
, &writefds
, NULL
, &tv
);
621 fprintf(stderr
, "Wakeup\n");
624 bytesdone
+= context
->actual_length
;
626 fprintf(stderr
, "Reaping urb context: %p actual length: %d\n",
627 context
, context
->actual_length
);
632 fprintf(stderr
, "End. ret: %d bytesdone: %d bytessent: %d size: %d\n",
633 ret
, bytesdone
, bytessent
, size
);
635 /* Unlink and reap any remaining URBs. */
637 if (!waiting
&& !first_fail
)
638 first_fail
= ETIMEDOUT
;
640 while(urbs_in_flight
> 0) {
643 ret
= ioctl(dev
->fd
, IOCTL_USB_DISCARDURB
, &context
);
644 if (ret
< 0 && errno
!= EINVAL
&& usb_debug
>= 1)
645 fprintf(stderr
, "error discarding URB: %s", strerror(errno
));
648 * When the URB is unlinked, it gets moved to the completed
649 * list and then we need to reap it or else the next time we
650 * call this function, we'll get the previous completion and
653 ret
= ioctl(dev
->fd
, IOCTL_USB_REAPURB
, &context
);
659 fprintf(stderr
, "error reaping URB (after discard): %s", strerror(errno
));
660 } else if(context
->actual_length
> 0) {
661 bytesdone
+= context
->actual_length
;
665 if(first_fail
&& bytesdone
== 0)
671 int usb_bulk_write(usb_dev_handle
*dev
, int ep
, char *bytes
, int size
,
674 /* Ensure the endpoint address is correct */
675 return usb_urb_transfer(dev
, ep
, USB_URB_TYPE_BULK
, bytes
, size
,
679 int usb_bulk_read(usb_dev_handle
*dev
, int ep
, char *bytes
, int size
,
682 /* Ensure the endpoint address is correct */
683 ep
|= USB_ENDPOINT_IN
;
684 return usb_urb_transfer(dev
, ep
, USB_URB_TYPE_BULK
, bytes
, size
,
688 int usb_bulk_write_low_latency(usb_dev_handle
*dev
, int ep
, char *bytes
,
689 int size
, int timeout
)
691 /* Ensure the endpoint address is correct */
692 return usb_urb_transfer_low_latency(dev
, ep
, USB_URB_TYPE_BULK
, bytes
, size
,
697 * FIXME: Packetize large buffers here. 2.4 HCDs (atleast, haven't checked
698 * 2.5 HCDs yet) don't handle multi-packet Interrupt transfers. So we need
699 * to lookup the endpoint packet size and packetize appropriately here.
701 int usb_interrupt_write(usb_dev_handle
*dev
, int ep
, char *bytes
, int size
,
704 /* Ensure the endpoint address is correct */
705 return usb_urb_transfer(dev
, ep
, USB_URB_TYPE_INTERRUPT
, bytes
, size
,
709 int usb_interrupt_read(usb_dev_handle
*dev
, int ep
, char *bytes
, int size
,
712 /* Ensure the endpoint address is correct */
713 ep
|= USB_ENDPOINT_IN
;
714 return usb_urb_transfer(dev
, ep
, USB_URB_TYPE_INTERRUPT
, bytes
, size
,
718 int usb_interrupt_write_low_latency(usb_dev_handle
*dev
, int ep
, char *bytes
,
719 int size
, int timeout
)
721 /* Ensure the endpoint address is correct */
722 return usb_urb_transfer_low_latency(dev
, ep
, USB_URB_TYPE_INTERRUPT
, bytes
,
726 int usb_os_find_busses(struct usb_bus
**busses
)
728 struct usb_bus
*fbus
= NULL
;
730 struct dirent
*entry
;
732 dir
= opendir(usb_path
);
734 USB_ERROR_STR(-errno
, "couldn't opendir(%s): %s", usb_path
,
737 while ((entry
= readdir(dir
)) != NULL
) {
740 /* Skip anything starting with a . */
741 if (entry
->d_name
[0] == '.')
744 if (!strchr("0123456789", entry
->d_name
[strlen(entry
->d_name
) - 1])) {
746 fprintf(stderr
, "usb_os_find_busses: Skipping non bus directory %s\n",
751 bus
= malloc(sizeof(*bus
));
755 memset((void *)bus
, 0, sizeof(*bus
));
757 strncpy(bus
->dirname
, entry
->d_name
, sizeof(bus
->dirname
) - 1);
758 bus
->dirname
[sizeof(bus
->dirname
) - 1] = 0;
763 fprintf(stderr
, "usb_os_find_busses: Found %s\n", bus
->dirname
);
773 int usb_os_find_devices(struct usb_bus
*bus
, struct usb_device
**devices
)
775 struct usb_device
*fdev
= NULL
;
777 struct dirent
*entry
;
778 char dirpath
[PATH_MAX
+ 1];
780 snprintf(dirpath
, PATH_MAX
, "%s/%s", usb_path
, bus
->dirname
);
782 dir
= opendir(dirpath
);
784 USB_ERROR_STR(-errno
, "couldn't opendir(%s): %s", dirpath
,
787 while ((entry
= readdir(dir
)) != NULL
) {
788 unsigned char device_desc
[DEVICE_DESC_LENGTH
];
789 char filename
[PATH_MAX
+ 1];
790 struct usb_device
*dev
;
791 struct usb_connectinfo connectinfo
;
794 /* Skip anything starting with a . */
795 if (entry
->d_name
[0] == '.')
798 dev
= malloc(sizeof(*dev
));
802 memset((void *)dev
, 0, sizeof(*dev
));
806 strncpy(dev
->filename
, entry
->d_name
, sizeof(dev
->filename
) - 1);
807 dev
->filename
[sizeof(dev
->filename
) - 1] = 0;
809 snprintf(filename
, sizeof(filename
) - 1, "%s/%s", dirpath
, entry
->d_name
);
810 fd
= open(filename
, O_RDWR
);
812 fd
= open(filename
, O_RDONLY
);
815 fprintf(stderr
, "usb_os_find_devices: Couldn't open %s\n",
823 /* Get the device number */
824 ret
= ioctl(fd
, IOCTL_USB_CONNECTINFO
, &connectinfo
);
827 fprintf(stderr
, "usb_os_find_devices: couldn't get connect info\n");
829 dev
->devnum
= connectinfo
.devnum
;
831 ret
= read(fd
, (void *)device_desc
, DEVICE_DESC_LENGTH
);
834 fprintf(stderr
, "usb_os_find_devices: Couldn't read descriptor\n");
842 * Linux kernel converts the words in this descriptor to CPU endian, so
843 * we use the undocumented W character for usb_parse_descriptor() that
844 * doesn't convert endianess when parsing the descriptor
846 usb_parse_descriptor(device_desc
, "bbWbbbbWWWbbbb", &dev
->descriptor
);
851 fprintf(stderr
, "usb_os_find_devices: Found %s on %s\n",
852 dev
->filename
, bus
->dirname
);
854 /* Now try to fetch the rest of the descriptors */
855 if (dev
->descriptor
.bNumConfigurations
> USB_MAXCONFIG
)
856 /* Silent since we'll try again later */
859 if (dev
->descriptor
.bNumConfigurations
< 1)
860 /* Silent since we'll try again later */
863 dev
->config
= (struct usb_config_descriptor
*)malloc(dev
->descriptor
.bNumConfigurations
* sizeof(struct usb_config_descriptor
));
865 /* Silent since we'll try again later */
868 memset(dev
->config
, 0, dev
->descriptor
.bNumConfigurations
*
869 sizeof(struct usb_config_descriptor
));
871 for (i
= 0; i
< dev
->descriptor
.bNumConfigurations
; i
++) {
872 unsigned char buffer
[8], *bigbuffer
;
873 struct usb_config_descriptor config
;
875 /* Get the first 8 bytes so we can figure out what the total length is */
876 ret
= read(fd
, (void *)buffer
, 8);
878 if (usb_debug
>= 1) {
880 fprintf(stderr
, "Unable to get descriptor (%d)\n", ret
);
882 fprintf(stderr
, "Config descriptor too short (expected %d, got %d)\n", 8, ret
);
888 usb_parse_descriptor(buffer
, "bbw", &config
);
890 bigbuffer
= malloc(config
.wTotalLength
);
893 fprintf(stderr
, "Unable to allocate memory for descriptors\n");
897 /* Read the rest of the config descriptor */
898 memcpy(bigbuffer
, buffer
, 8);
900 ret
= read(fd
, (void *)(bigbuffer
+ 8), config
.wTotalLength
- 8);
901 if (ret
< config
.wTotalLength
- 8) {
902 if (usb_debug
>= 1) {
904 fprintf(stderr
, "Unable to get descriptor (%d)\n", ret
);
906 fprintf(stderr
, "Config descriptor too short (expected %d, got %d)\n", config
.wTotalLength
, ret
);
913 ret
= usb_parse_configuration(&dev
->config
[i
], bigbuffer
);
914 if (usb_debug
>= 2) {
916 fprintf(stderr
, "Descriptor data still left\n");
918 fprintf(stderr
, "Unable to parse descriptors\n");
935 int usb_os_determine_children(struct usb_bus
*bus
)
937 struct usb_device
*dev
, *devices
[256];
938 struct usb_ioctl command
;
941 /* Create a list of devices first */
942 memset(devices
, 0, sizeof(devices
));
943 for (dev
= bus
->devices
; dev
; dev
= dev
->next
)
945 devices
[dev
->devnum
] = dev
;
947 /* Now fetch the children for each device */
948 for (dev
= bus
->devices
; dev
; dev
= dev
->next
) {
949 struct usb_hub_portinfo portinfo
;
952 fd
= device_open(dev
);
956 /* Query the hub driver for the children of this device */
957 if (dev
->config
&& dev
->config
->interface
&& dev
->config
->interface
->altsetting
)
958 command
.ifno
= dev
->config
->interface
->altsetting
->bInterfaceNumber
;
961 command
.ioctl_code
= IOCTL_USB_HUB_PORTINFO
;
962 command
.data
= &portinfo
;
963 ret
= ioctl(fd
, IOCTL_USB_IOCTL
, &command
);
965 /* errno == ENOSYS means the device probably wasn't a hub */
966 if (errno
!= ENOSYS
&& usb_debug
> 1)
967 fprintf(stderr
, "error obtaining child information: %s\n",
974 dev
->num_children
= 0;
975 for (i
= 0; i
< portinfo
.numports
; i
++)
976 if (portinfo
.port
[i
])
979 /* Free any old children first */
982 dev
->children
= malloc(sizeof(struct usb_device
*) * dev
->num_children
);
983 if (!dev
->children
) {
985 fprintf(stderr
, "error allocating %zu bytes memory for dev->children\n",
986 sizeof(struct usb_device
*) * dev
->num_children
);
988 dev
->num_children
= 0;
993 for (i
= 0, i1
= 0; i
< portinfo
.numports
; i
++) {
994 if (!portinfo
.port
[i
])
997 dev
->children
[i1
++] = devices
[portinfo
.port
[i
]];
999 devices
[portinfo
.port
[i
]] = NULL
;
1006 * There should be one device left in the devices list and that should be
1009 for (i
= 0; i
< sizeof(devices
) / sizeof(devices
[0]); i
++) {
1011 bus
->root_dev
= devices
[i
];
1017 static int check_usb_vfs(const char *dirname
)
1020 struct dirent
*entry
;
1023 dir
= opendir(dirname
);
1027 while ((entry
= readdir(dir
)) != NULL
) {
1028 /* Skip anything starting with a . */
1029 if (entry
->d_name
[0] == '.')
1032 /* We assume if we find any files that it must be the right place */
1042 void usb_os_init(void)
1044 /* Find the path to the virtual filesystem */
1045 if (getenv("USB_DEVFS_PATH")) {
1046 if (check_usb_vfs(getenv("USB_DEVFS_PATH"))) {
1047 strncpy(usb_path
, getenv("USB_DEVFS_PATH"), sizeof(usb_path
) - 1);
1048 usb_path
[sizeof(usb_path
) - 1] = 0;
1049 } else if (usb_debug
)
1050 fprintf(stderr
, "usb_os_init: couldn't find USB VFS in USB_DEVFS_PATH\n");
1054 if (check_usb_vfs("/dev/bus/usb")) {
1055 strncpy(usb_path
, "/dev/bus/usb", sizeof(usb_path
) - 1);
1056 usb_path
[sizeof(usb_path
) - 1] = 0;
1057 } else if (check_usb_vfs("/proc/bus/usb")) {
1058 strncpy(usb_path
, "/proc/bus/usb", sizeof(usb_path
) - 1);
1059 usb_path
[sizeof(usb_path
) - 1] = 0;
1061 usb_path
[0] = 0; /* No path, no USB support */
1066 fprintf(stderr
, "usb_os_init: Found USB VFS at %s\n", usb_path
);
1068 fprintf(stderr
, "usb_os_init: No USB VFS found, is it mounted?\n");
1072 int usb_resetep(usb_dev_handle
*dev
, unsigned int ep
)
1076 ret
= ioctl(dev
->fd
, IOCTL_USB_RESETEP
, &ep
);
1078 USB_ERROR_STR(-errno
, "could not reset ep %d: %s", ep
,
1084 int usb_clear_halt(usb_dev_handle
*dev
, unsigned int ep
)
1088 ret
= ioctl(dev
->fd
, IOCTL_USB_CLEAR_HALT
, &ep
);
1090 USB_ERROR_STR(-errno
, "could not clear/halt ep %d: %s", ep
,
1096 int usb_reset(usb_dev_handle
*dev
)
1100 ret
= ioctl(dev
->fd
, IOCTL_USB_RESET
, NULL
);
1102 USB_ERROR_STR(-errno
, "could not reset: %s", strerror(errno
));
1107 int usb_get_driver_np(usb_dev_handle
*dev
, int interface
, char *name
,
1108 unsigned int namelen
)
1110 struct usb_getdriver getdrv
;
1113 getdrv
.interface
= interface
;
1114 ret
= ioctl(dev
->fd
, IOCTL_USB_GETDRIVER
, &getdrv
);
1116 USB_ERROR_STR(-errno
, "could not get bound driver: %s", strerror(errno
));
1118 strncpy(name
, getdrv
.driver
, namelen
- 1);
1119 name
[namelen
- 1] = 0;
1124 int usb_detach_kernel_driver_np(usb_dev_handle
*dev
, int interface
)
1126 struct usb_ioctl command
;
1129 command
.ifno
= interface
;
1130 command
.ioctl_code
= IOCTL_USB_DISCONNECT
;
1131 command
.data
= NULL
;
1133 ret
= ioctl(dev
->fd
, IOCTL_USB_IOCTL
, &command
);
1135 USB_ERROR_STR(-errno
, "could not detach kernel driver from interface %d: %s",
1136 interface
, strerror(errno
));