Update TODO list
[trut64.git] / libusb / linux.c
blobebea43d848292e68bfcf4a81823a32b667a1e84a
1 /*
2 * Linux USB support
4 * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
6 * This library is covered by the LGPL, read LICENSE for details.
7 */
9 #include <stdlib.h> /* getenv, etc */
10 #include <unistd.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <errno.h>
15 #include <sys/time.h>
16 #include <dirent.h>
18 #include "linux.h"
19 #include "usbi.h"
21 struct usb_async
23 usb_dev_handle *dev;
24 int ep;
25 struct usb_urb urb;
26 int urbs_in_flight;
27 int urb_start;
28 int urbtype;
29 int bytes_done;
32 static char usb_path[PATH_MAX + 1] = "";
34 static int device_open(struct usb_device *dev)
36 char filename[PATH_MAX + 1];
37 int fd;
39 snprintf(filename, sizeof(filename) - 1, "%s/%s/%s",
40 usb_path, dev->bus->dirname, dev->filename);
42 fd = open(filename, O_RDWR);
43 if (fd < 0) {
44 fd = open(filename, O_RDONLY);
45 if (fd < 0)
46 USB_ERROR_STR(-errno, "failed to open %s: %s",
47 filename, strerror(errno));
50 return fd;
53 int usb_os_open(usb_dev_handle *dev)
55 dev->fd = device_open(dev->device);
57 return 0;
60 int usb_os_close(usb_dev_handle *dev)
62 if (dev->fd < 0)
63 return 0;
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,
68 strerror(errno));
70 return 0;
73 int usb_set_configuration(usb_dev_handle *dev, int configuration)
75 int ret;
77 ret = ioctl(dev->fd, IOCTL_USB_SETCONFIG, &configuration);
78 if (ret < 0)
79 USB_ERROR_STR(-errno, "could not set config %d: %s", configuration,
80 strerror(errno));
82 dev->config = configuration;
84 return 0;
87 int usb_claim_interface(usb_dev_handle *dev, int interface)
89 int ret;
91 ret = ioctl(dev->fd, IOCTL_USB_CLAIMINTF, &interface);
92 if (ret < 0) {
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,
97 strerror(errno));
100 dev->interface = interface;
102 return 0;
105 int usb_release_interface(usb_dev_handle *dev, int interface)
107 int ret;
109 ret = ioctl(dev->fd, IOCTL_USB_RELEASEINTF, &interface);
110 if (ret < 0)
111 USB_ERROR_STR(-errno, "could not release intf %d: %s", interface,
112 strerror(errno));
114 dev->interface = -1;
116 return 0;
119 int usb_set_altinterface(usb_dev_handle *dev, int alternate)
121 int ret;
122 struct usb_setinterface setintf;
124 if (dev->interface < 0)
125 USB_ERROR(-EINVAL);
127 setintf.interface = dev->interface;
128 setintf.altsetting = alternate;
130 ret = ioctl(dev->fd, IOCTL_USB_SETINTF, &setintf);
131 if (ret < 0)
132 USB_ERROR_STR(-errno, "could not set alt intf %d/%d: %s",
133 dev->interface, alternate, strerror(errno));
135 dev->altsetting = alternate;
137 return 0;
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;
152 int ret;
154 ctrl.bRequestType = requesttype;
155 ctrl.bRequest = request;
156 ctrl.wValue = value;
157 ctrl.wIndex = index;
158 ctrl.wLength = size;
160 ctrl.data = bytes;
161 ctrl.timeout = timeout;
163 ret = ioctl(dev->fd, IOCTL_USB_CONTROL, &ctrl);
164 if (ret < 0)
165 USB_ERROR_STR(-errno, "error sending control message: %s", strerror(errno));
167 return ret;
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)
176 struct usb_urb urb;
177 int bytesdone = 0, requested;
178 struct timeval tv, tv_ref, tv_now;
179 struct usb_urb *context;
180 int ret, waiting;
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;
201 tv_ref.tv_sec++;
204 do {
205 fd_set writefds;
207 requested = size - bytesdone;
208 if (requested > MAX_READ_WRITE)
209 requested = MAX_READ_WRITE;
211 urb.type = urbtype;
212 urb.endpoint = ep;
213 urb.flags = 0;
214 urb.buffer = bytes + bytesdone;
215 urb.buffer_length = requested;
216 urb.signr = 0;
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);
222 if (ret < 0) {
223 USB_ERROR_STR(-errno, "error submitting URB: %s", strerror(errno));
226 restart:
227 waiting = 1;
228 context = NULL;
229 while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
230 tv.tv_sec = 0;
231 tv.tv_usec = 1000; // 1 msec
232 FD_ZERO(&writefds);
233 FD_SET(dev->fd, &writefds);
234 select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait
236 if (timeout) {
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)))
242 waiting = 0;
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 */
249 goto restart;
253 * If there was an error, that wasn't EAGAIN (no completion), then
254 * something happened during the reaping and we should return that
255 * error now
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) {
265 int rc;
267 if (!waiting)
268 rc = -ETIMEDOUT;
269 else
270 rc = urb.status;
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;
286 return bytesdone;
289 return rc;
292 return bytesdone;
295 static int submit_urb(int fd, struct usb_urb* urb, int urbtype, int ep, void* data, int data_len)
297 urb->type = urbtype;
298 urb->endpoint = ep;
299 urb->flags = 0;
300 urb->buffer = data;
301 urb->buffer_length = data_len;
302 urb->signr = 0;
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));
312 if(!async) {
313 USB_ERROR(-ENOMEM);
314 return -1;
317 *context = async;
319 async->dev = dev;
320 async->ep = ep;
321 async->bytes_done = 0;
322 async->urbtype = urbtype;
323 async->urbs_in_flight = 0;
325 return 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)
343 return 0;
345 int ret = ioctl(async->dev->fd, IOCTL_USB_REAPURBNDELAY, &context);
347 if(ret < 0) {
348 if(errno == EAGAIN)
349 return 0;
350 else
351 USB_ERROR_STR(-errno, "failed to reap URB: %s", strerror(errno));
352 } else {
353 if(usb_debug >= 1)
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;
361 return 0;
364 int usb_async_is_done(void* context)
366 struct usb_async* async = context;
367 if(reap_urbs(async) < 0)
368 return -1;
370 if(async->urbs_in_flight == 0)
371 return 1;
372 else
373 return 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;
385 int ret;
387 ret = reap_urbs(async);
388 if(ret < 0)
389 return -1;
391 if(async->urbs_in_flight == 0)
392 return 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;
400 tv_ref.tv_sec++;
403 again:
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;
408 if(usec < 0) {
409 sec--;
410 usec += 1000000;
412 if(sec < 0) {
413 sec = 0;
414 usec = 0;
416 tv.tv_sec = sec;
417 tv.tv_usec = usec;
419 fd_set readfds;
420 FD_ZERO(&readfds);
421 FD_SET(async->dev->fd, &readfds);
422 ret = select(async->dev->fd + 1, &readfds, NULL, NULL, &tv);
423 if(ret == -1 && errno == EINTR)
424 goto again;
426 if(ret == -1)
427 USB_ERROR_STR(-errno, "select failed: %s", strerror(errno));
429 if(cancel)
430 return usb_cancel_async(async);
431 else
432 return 0;
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)
442 return ret;
443 else
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)
454 return ret;
455 else
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;
465 reap_urbs(async);
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
476 * exit early
478 ret = ioctl(async->dev->fd, IOCTL_USB_REAPURB, &context);
479 if(ret < 0) {
480 if(prev_done == async->bytes_done)
481 USB_ERROR_STR(-errno, "error reaping URB after discard: %s",
482 strerror(errno));
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)
493 free(context);
494 return 0;
497 int usb_submit_async(void *context, char *bytes, int size)
499 struct usb_async *async = context;
501 if(reap_urbs(async) < 0)
502 return -1;
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.");
511 if(usb_debug >= 2)
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,
515 bytes, size);
516 if (ret != 0) {
517 USB_ERROR_STR(-errno, "error submitting URB: %s", strerror(errno));
518 } else {
519 async->urbs_in_flight = 1;
520 return size;
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];
536 int urb_start = 0;
537 int urbs_in_flight = 0;
538 int ret = 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;
554 tv_ref.tv_sec++;
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;
563 if(usb_debug >= 2)
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);
569 if (ret != 0) {
570 first_fail = errno;
571 if(usb_debug >= 1)
572 fprintf(stderr, "error submitting URB: %s", strerror(errno));
573 goto cleanup;
574 } else {
575 if(usb_debug >= 2)
576 fprintf(stderr, "actual length: %d\n", urbs[urb_start].actual_length);
577 urbs_in_flight++;
578 urb_start = (urb_start + 1) % MAX_NUM_URBS;
579 bytessent += requested;
583 while (((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) < 0) &&
584 waiting) {
586 * If there was an error, that wasn't EAGAIN (no completion), then
587 * something happened during the reaping and we should return that
588 * error now
590 if (ret < 0 && errno != EAGAIN) {
591 first_fail = errno;
592 if(usb_debug >= 1)
593 fprintf(stderr, "error reaping URB: %s", strerror(errno));
594 goto cleanup;
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;
602 if(usec < 0) {
603 sec--;
604 usec += 1000000;
606 if(sec < 0) {
607 sec = 0;
608 usec = 0;
609 waiting = 0;
611 tv.tv_sec = sec;
612 tv.tv_usec = usec;
614 if(usb_debug >= 2)
615 fprintf(stderr, "Going to sleep\n");
616 fd_set writefds;
617 FD_ZERO(&writefds);
618 FD_SET(dev->fd, &writefds);
619 select(dev->fd + 1, NULL, &writefds, NULL, &tv);
620 if(usb_debug >= 2)
621 fprintf(stderr, "Wakeup\n");
623 if(ret == 0) {
624 bytesdone += context->actual_length;
625 if(usb_debug >= 2)
626 fprintf(stderr, "Reaping urb context: %p actual length: %d\n",
627 context, context->actual_length);
628 urbs_in_flight--;
631 if(usb_debug >= 2)
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. */
636 cleanup:
637 if (!waiting && !first_fail)
638 first_fail = ETIMEDOUT;
640 while(urbs_in_flight > 0) {
641 urbs_in_flight--;
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
651 * exit early
653 ret = ioctl(dev->fd, IOCTL_USB_REAPURB, &context);
654 if(ret < 0) {
655 if(!first_fail)
656 first_fail = errno;
658 if(usb_debug >= 1)
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)
666 return first_fail;
667 else
668 return bytesdone;
671 int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
672 int timeout)
674 /* Ensure the endpoint address is correct */
675 return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
676 timeout);
679 int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
680 int timeout)
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,
685 timeout);
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,
693 timeout);
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,
702 int timeout)
704 /* Ensure the endpoint address is correct */
705 return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
706 timeout);
709 int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
710 int timeout)
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,
715 timeout);
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,
723 size, timeout);
726 int usb_os_find_busses(struct usb_bus **busses)
728 struct usb_bus *fbus = NULL;
729 DIR *dir;
730 struct dirent *entry;
732 dir = opendir(usb_path);
733 if (!dir)
734 USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", usb_path,
735 strerror(errno));
737 while ((entry = readdir(dir)) != NULL) {
738 struct usb_bus *bus;
740 /* Skip anything starting with a . */
741 if (entry->d_name[0] == '.')
742 continue;
744 if (!strchr("0123456789", entry->d_name[strlen(entry->d_name) - 1])) {
745 if (usb_debug >= 2)
746 fprintf(stderr, "usb_os_find_busses: Skipping non bus directory %s\n",
747 entry->d_name);
748 continue;
751 bus = malloc(sizeof(*bus));
752 if (!bus)
753 USB_ERROR(-ENOMEM);
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;
760 LIST_ADD(fbus, bus);
762 if (usb_debug >= 2)
763 fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
766 closedir(dir);
768 *busses = fbus;
770 return 0;
773 int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
775 struct usb_device *fdev = NULL;
776 DIR *dir;
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);
783 if (!dir)
784 USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", dirpath,
785 strerror(errno));
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;
792 int i, fd, ret;
794 /* Skip anything starting with a . */
795 if (entry->d_name[0] == '.')
796 continue;
798 dev = malloc(sizeof(*dev));
799 if (!dev)
800 USB_ERROR(-ENOMEM);
802 memset((void *)dev, 0, sizeof(*dev));
804 dev->bus = bus;
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);
811 if (fd < 0) {
812 fd = open(filename, O_RDONLY);
813 if (fd < 0) {
814 if (usb_debug >= 2)
815 fprintf(stderr, "usb_os_find_devices: Couldn't open %s\n",
816 filename);
818 free(dev);
819 continue;
823 /* Get the device number */
824 ret = ioctl(fd, IOCTL_USB_CONNECTINFO, &connectinfo);
825 if (ret < 0) {
826 if (usb_debug)
827 fprintf(stderr, "usb_os_find_devices: couldn't get connect info\n");
828 } else
829 dev->devnum = connectinfo.devnum;
831 ret = read(fd, (void *)device_desc, DEVICE_DESC_LENGTH);
832 if (ret < 0) {
833 if (usb_debug)
834 fprintf(stderr, "usb_os_find_devices: Couldn't read descriptor\n");
836 free(dev);
838 goto err;
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);
848 LIST_ADD(fdev, dev);
850 if (usb_debug >= 2)
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 */
857 goto err;
859 if (dev->descriptor.bNumConfigurations < 1)
860 /* Silent since we'll try again later */
861 goto err;
863 dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor));
864 if (!dev->config)
865 /* Silent since we'll try again later */
866 goto err;
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);
877 if (ret < 8) {
878 if (usb_debug >= 1) {
879 if (ret < 0)
880 fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
881 else
882 fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", 8, ret);
885 goto err;
888 usb_parse_descriptor(buffer, "bbw", &config);
890 bigbuffer = malloc(config.wTotalLength);
891 if (!bigbuffer) {
892 if (usb_debug >= 1)
893 fprintf(stderr, "Unable to allocate memory for descriptors\n");
894 goto err;
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) {
903 if (ret < 0)
904 fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
905 else
906 fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, ret);
909 free(bigbuffer);
910 goto err;
913 ret = usb_parse_configuration(&dev->config[i], bigbuffer);
914 if (usb_debug >= 2) {
915 if (ret > 0)
916 fprintf(stderr, "Descriptor data still left\n");
917 else if (ret < 0)
918 fprintf(stderr, "Unable to parse descriptors\n");
921 free(bigbuffer);
924 err:
925 close(fd);
928 closedir(dir);
930 *devices = fdev;
932 return 0;
935 int usb_os_determine_children(struct usb_bus *bus)
937 struct usb_device *dev, *devices[256];
938 struct usb_ioctl command;
939 int ret, i, i1;
941 /* Create a list of devices first */
942 memset(devices, 0, sizeof(devices));
943 for (dev = bus->devices; dev; dev = dev->next)
944 if (dev->devnum)
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;
950 int fd;
952 fd = device_open(dev);
953 if (fd < 0)
954 continue;
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;
959 else
960 command.ifno = 0;
961 command.ioctl_code = IOCTL_USB_HUB_PORTINFO;
962 command.data = &portinfo;
963 ret = ioctl(fd, IOCTL_USB_IOCTL, &command);
964 if (ret < 0) {
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",
968 strerror(errno));
970 close(fd);
971 continue;
974 dev->num_children = 0;
975 for (i = 0; i < portinfo.numports; i++)
976 if (portinfo.port[i])
977 dev->num_children++;
979 /* Free any old children first */
980 free(dev->children);
982 dev->children = malloc(sizeof(struct usb_device *) * dev->num_children);
983 if (!dev->children) {
984 if (usb_debug > 1)
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;
989 close(fd);
990 continue;
993 for (i = 0, i1 = 0; i < portinfo.numports; i++) {
994 if (!portinfo.port[i])
995 continue;
997 dev->children[i1++] = devices[portinfo.port[i]];
999 devices[portinfo.port[i]] = NULL;
1002 close(fd);
1006 * There should be one device left in the devices list and that should be
1007 * the root device
1009 for (i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
1010 if (devices[i])
1011 bus->root_dev = devices[i];
1014 return 0;
1017 static int check_usb_vfs(const char *dirname)
1019 DIR *dir;
1020 struct dirent *entry;
1021 int found = 0;
1023 dir = opendir(dirname);
1024 if (!dir)
1025 return 0;
1027 while ((entry = readdir(dir)) != NULL) {
1028 /* Skip anything starting with a . */
1029 if (entry->d_name[0] == '.')
1030 continue;
1032 /* We assume if we find any files that it must be the right place */
1033 found = 1;
1034 break;
1037 closedir(dir);
1039 return found;
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");
1053 if (!usb_path[0]) {
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;
1060 } else
1061 usb_path[0] = 0; /* No path, no USB support */
1064 if (usb_debug) {
1065 if (usb_path[0])
1066 fprintf(stderr, "usb_os_init: Found USB VFS at %s\n", usb_path);
1067 else
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)
1074 int ret;
1076 ret = ioctl(dev->fd, IOCTL_USB_RESETEP, &ep);
1077 if (ret)
1078 USB_ERROR_STR(-errno, "could not reset ep %d: %s", ep,
1079 strerror(errno));
1081 return 0;
1084 int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
1086 int ret;
1088 ret = ioctl(dev->fd, IOCTL_USB_CLEAR_HALT, &ep);
1089 if (ret)
1090 USB_ERROR_STR(-errno, "could not clear/halt ep %d: %s", ep,
1091 strerror(errno));
1093 return 0;
1096 int usb_reset(usb_dev_handle *dev)
1098 int ret;
1100 ret = ioctl(dev->fd, IOCTL_USB_RESET, NULL);
1101 if (ret)
1102 USB_ERROR_STR(-errno, "could not reset: %s", strerror(errno));
1104 return 0;
1107 int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name,
1108 unsigned int namelen)
1110 struct usb_getdriver getdrv;
1111 int ret;
1113 getdrv.interface = interface;
1114 ret = ioctl(dev->fd, IOCTL_USB_GETDRIVER, &getdrv);
1115 if (ret)
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;
1121 return 0;
1124 int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
1126 struct usb_ioctl command;
1127 int ret;
1129 command.ifno = interface;
1130 command.ioctl_code = IOCTL_USB_DISCONNECT;
1131 command.data = NULL;
1133 ret = ioctl(dev->fd, IOCTL_USB_IOCTL, &command);
1134 if (ret)
1135 USB_ERROR_STR(-errno, "could not detach kernel driver from interface %d: %s",
1136 interface, strerror(errno));
1138 return 0;