1/*
2 * Linux USB support
3 *
4 * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
5 *
6 * This library is covered by the LGPL, read LICENSE for details.
7 */
8
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>
17
18#include "linux.h"
19#include "usbi.h"
20
21static char usb_path[PATH_MAX + 1] = "";
22
23static int device_open(struct usb_device *dev)
24{
25  char filename[PATH_MAX + 1];
26  int fd;
27
28  snprintf(filename, sizeof(filename) - 1, "%s/%s/%s",
29    usb_path, dev->bus->dirname, dev->filename);
30
31  fd = open(filename, O_RDWR);
32  if (fd < 0) {
33    fd = open(filename, O_RDONLY);
34    if (fd < 0)
35      USB_ERROR_STR(-errno, "failed to open %s: %s",
36	filename, strerror(errno));
37  }
38
39  return fd;
40}
41
42int usb_os_open(usb_dev_handle *dev)
43{
44  dev->fd = device_open(dev->device);
45
46  return 0;
47}
48
49int usb_os_close(usb_dev_handle *dev)
50{
51  if (dev->fd < 0)
52    return 0;
53
54  if (close(dev->fd) == -1)
55    /* Failing trying to close a file really isn't an error, so return 0 */
56    USB_ERROR_STR(0, "tried to close device fd %d: %s", dev->fd,
57	strerror(errno));
58
59  return 0;
60}
61
62int usb_set_configuration(usb_dev_handle *dev, int configuration)
63{
64  int ret;
65
66  ret = ioctl(dev->fd, IOCTL_USB_SETCONFIG, &configuration);
67  if (ret < 0)
68    USB_ERROR_STR(-errno, "could not set config %d: %s", configuration,
69	strerror(errno));
70
71  dev->config = configuration;
72
73  return 0;
74}
75
76int usb_claim_interface(usb_dev_handle *dev, int interface)
77{
78  int ret;
79
80  ret = ioctl(dev->fd, IOCTL_USB_CLAIMINTF, &interface);
81  if (ret < 0) {
82    if (errno == EBUSY && usb_debug > 0)
83      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);
84
85    USB_ERROR_STR(-errno, "could not claim interface %d: %s", interface,
86	strerror(errno));
87  }
88
89  dev->interface = interface;
90
91  return 0;
92}
93
94int usb_release_interface(usb_dev_handle *dev, int interface)
95{
96  int ret;
97
98  ret = ioctl(dev->fd, IOCTL_USB_RELEASEINTF, &interface);
99  if (ret < 0)
100    USB_ERROR_STR(-errno, "could not release intf %d: %s", interface,
101    	strerror(errno));
102
103  dev->interface = -1;
104
105  return 0;
106}
107
108int usb_set_altinterface(usb_dev_handle *dev, int alternate)
109{
110  int ret;
111  struct usb_setinterface setintf;
112
113  if (dev->interface < 0)
114    USB_ERROR(-EINVAL);
115
116  setintf.interface = dev->interface;
117  setintf.altsetting = alternate;
118
119  ret = ioctl(dev->fd, IOCTL_USB_SETINTF, &setintf);
120  if (ret < 0)
121    USB_ERROR_STR(-errno, "could not set alt intf %d/%d: %s",
122	dev->interface, alternate, strerror(errno));
123
124  dev->altsetting = alternate;
125
126  return 0;
127}
128
129/*
130 * Linux usbfs has a limit of one page size for synchronous bulk read/write.
131 * 4096 is the most portable maximum we can do for now.
132 * Linux usbfs has a limit of 16KB for the URB interface. We use this now
133 * to get better performance for USB 2.0 devices.
134 */
135#define MAX_READ_WRITE	(16 * 1024)
136
137int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
138	int value, int index, char *bytes, int size, int timeout)
139{
140  struct usb_ctrltransfer ctrl;
141  int ret;
142
143  ctrl.bRequestType = requesttype;
144  ctrl.bRequest = request;
145  ctrl.wValue = value;
146  ctrl.wIndex = index;
147  ctrl.wLength = size;
148
149  ctrl.data = bytes;
150  ctrl.timeout = timeout;
151
152  ret = ioctl(dev->fd, IOCTL_USB_CONTROL, &ctrl);
153  if (ret < 0)
154    USB_ERROR_STR(-errno, "error sending control message: %s", strerror(errno));
155
156  return ret;
157}
158
159#define URB_USERCONTEXT_COOKIE		((void *)0x1)
160
161/* Reading and writing are the same except for the endpoint */
162static int usb_urb_transfer(usb_dev_handle *dev, int ep, int urbtype,
163	char *bytes, int size, int timeout)
164{
165  struct usb_urb urb;
166  int bytesdone = 0, requested;
167  struct timeval tv, tv_ref, tv_now;
168  struct usb_urb *context;
169  int ret, waiting;
170
171  /*
172   * HACK: The use of urb.usercontext is a hack to get threaded applications
173   * sort of working again. Threaded support is still not recommended, but
174   * this should allow applications to work in the common cases. Basically,
175   * if we get the completion for an URB we're not waiting for, then we update
176   * the usercontext pointer to 1 for the other threads URB and it will see
177   * the change after it wakes up from the the timeout. Ugly, but it works.
178   */
179
180  /*
181   * Get actual time, and add the timeout value. The result is the absolute
182   * time where we have to quit waiting for an message.
183   */
184  gettimeofday(&tv_ref, NULL);
185  tv_ref.tv_sec = tv_ref.tv_sec + timeout / 1000;
186  tv_ref.tv_usec = tv_ref.tv_usec + (timeout % 1000) * 1000;
187
188  if (tv_ref.tv_usec > 1000000) {
189    tv_ref.tv_usec -= 1000000;
190    tv_ref.tv_sec++;
191  }
192
193  do {
194    fd_set writefds;
195
196    requested = size - bytesdone;
197    if (requested > MAX_READ_WRITE)
198      requested = MAX_READ_WRITE;
199
200    urb.type = urbtype;
201    urb.endpoint = ep;
202    urb.flags = 0;
203    urb.buffer = bytes + bytesdone;
204    urb.buffer_length = requested;
205    urb.signr = 0;
206    urb.actual_length = 0;
207    urb.number_of_packets = 0;	/* don't do isochronous yet */
208    urb.usercontext = NULL;
209
210    ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urb);
211    if (ret < 0) {
212      USB_ERROR_STR(-errno, "error submitting URB: %s", strerror(errno));
213      return ret;
214    }
215
216    FD_ZERO(&writefds);
217    FD_SET(dev->fd, &writefds);
218
219restart:
220    waiting = 1;
221    context = NULL;
222    while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
223      tv.tv_sec = 0;
224      tv.tv_usec = 1000; // 1 msec
225      select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait
226      /* 32767 is a magic number for no timeout */
227      if (timeout && timeout != 32767) {
228        /* compare with actual time, as the select timeout is not that precise */
229        gettimeofday(&tv_now, NULL);
230
231        if ((tv_now.tv_sec > tv_ref.tv_sec) ||
232            ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
233          waiting = 0;
234      }
235    }
236
237    if (context && context != &urb) {
238      context->usercontext = URB_USERCONTEXT_COOKIE;
239      /* We need to restart since we got a successful URB, but not ours */
240      goto restart;
241    }
242
243    /*
244     * If there was an error, that wasn't EAGAIN (no completion), then
245     * something happened during the reaping and we should return that
246     * error now
247     */
248    if (ret < 0 && !urb.usercontext && errno != EAGAIN)
249      USB_ERROR_STR(-errno, "error reaping URB: %s", strerror(errno));
250
251    bytesdone += urb.actual_length;
252  } while ((ret == 0 || urb.usercontext) && bytesdone < size && urb.actual_length == requested);
253
254  /* If the URB didn't complete in success or error, then let's unlink it */
255  if (ret < 0 && !urb.usercontext) {
256    int rc;
257
258    if (!waiting)
259      rc = -ETIMEDOUT;
260    else
261      rc = urb.status;
262
263    ret = ioctl(dev->fd, IOCTL_USB_DISCARDURB, &urb);
264    if (ret < 0 && errno != EINVAL && usb_debug >= 1)
265      fprintf(stderr, "error discarding URB: %s", strerror(errno));
266
267    /*
268     * When the URB is unlinked, it gets moved to the completed list and
269     * then we need to reap it or else the next time we call this function,
270     * we'll get the previous completion and exit early
271     */
272    ioctl(dev->fd, IOCTL_USB_REAPURB, &context);
273
274    return rc;
275  }
276
277  return bytesdone;
278}
279
280/* Reading and writing are the same except for the endpoint */
281static int usb_urb_transfer_sp(usb_dev_handle *dev, int ep, int urbtype,
282	char *bytes, int size, int timeout, int *actual_length, int max_rw)
283{
284  struct usb_urb urb;
285  int bytesdone = 0, requested;
286  struct timeval tv, tv_ref, tv_now;
287  struct usb_urb *context;
288  int ret, waiting;
289
290  /*
291   * HACK: The use of urb.usercontext is a hack to get threaded applications
292   * sort of working again. Threaded support is still not recommended, but
293   * this should allow applications to work in the common cases. Basically,
294   * if we get the completion for an URB we're not waiting for, then we update
295   * the usercontext pointer to 1 for the other threads URB and it will see
296   * the change after it wakes up from the the timeout. Ugly, but it works.
297   */
298
299  /*
300   * Get actual time, and add the timeout value. The result is the absolute
301   * time where we have to quit waiting for an message.
302   */
303  gettimeofday(&tv_ref, NULL);
304  tv_ref.tv_sec = tv_ref.tv_sec + timeout / 1000;
305  tv_ref.tv_usec = tv_ref.tv_usec + (timeout % 1000) * 1000;
306
307  if (tv_ref.tv_usec > 1000000) {
308    tv_ref.tv_usec -= 1000000;
309    tv_ref.tv_sec++;
310  }
311
312  do {
313    fd_set writefds;
314
315    requested = size - bytesdone;
316    if (requested > max_rw)
317      requested = max_rw;
318
319    urb.type = urbtype;
320    urb.endpoint = ep;
321    urb.flags = 0;
322    urb.buffer = bytes + bytesdone;
323    urb.buffer_length = requested;
324    urb.signr = 0;
325    urb.actual_length = 0;
326    urb.number_of_packets = 0;	/* don't do isochronous yet */
327    urb.usercontext = NULL;
328
329    ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urb);
330    if (ret < 0) {
331      USB_ERROR_STR(-errno, "error submitting URB: %s", strerror(errno));
332      return ret;
333    }
334
335    FD_ZERO(&writefds);
336    FD_SET(dev->fd, &writefds);
337
338restart:
339    waiting = 1;
340    context = NULL;
341    while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
342      tv.tv_sec = 0;
343      tv.tv_usec = 1000; // 1 msec
344      select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait
345#if 0
346      if (timeout) {
347#else /* 32767 is a magic number for no timeout */
348      if (timeout && timeout != 32767) {
349#endif
350        /* compare with actual time, as the select timeout is not that precise */
351        gettimeofday(&tv_now, NULL);
352
353        if ((tv_now.tv_sec > tv_ref.tv_sec) ||
354            ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
355          waiting = 0;
356      }
357    }
358
359    if (context && context != &urb) {
360      context->usercontext = URB_USERCONTEXT_COOKIE;
361      /* We need to restart since we got a successful URB, but not ours */
362      goto restart;
363    }
364
365    /*
366     * If there was an error, that wasn't EAGAIN (no completion), then
367     * something happened during the reaping and we should return that
368     * error now
369     */
370    if (ret < 0 && !urb.usercontext && errno != EAGAIN)
371      USB_ERROR_STR(-errno, "error reaping URB: %s", strerror(errno));
372
373    bytesdone += urb.actual_length;
374    *actual_length = bytesdone;
375  } while ((ret == 0 || urb.usercontext) && bytesdone < size && urb.actual_length == requested);
376
377  /* If the URB didn't complete in success or error, then let's unlink it */
378  if (ret < 0 && !urb.usercontext) {
379    int rc;
380
381    if (!waiting)
382      rc = -ETIMEDOUT;
383    else
384      rc = urb.status;
385
386    ret = ioctl(dev->fd, IOCTL_USB_DISCARDURB, &urb);
387    if (ret < 0 && errno != EINVAL && usb_debug >= 1)
388      fprintf(stderr, "error discarding URB: %s", strerror(errno));
389
390    /*
391     * When the URB is unlinked, it gets moved to the completed list and
392     * then we need to reap it or else the next time we call this function,
393     * we'll get the previous completion and exit early
394     */
395    ioctl(dev->fd, IOCTL_USB_REAPURB, &context);
396
397    return rc;
398  }
399
400  return bytesdone;
401}
402
403int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
404	int timeout)
405{
406  /* Ensure the endpoint address is correct */
407  return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
408		timeout);
409}
410
411int usb_bulk_write_sp(usb_dev_handle *dev, int ep, char *bytes, int size,
412	int timeout, int *actual_length, int max_rw)
413{
414  /* Ensure the endpoint address is correct */
415  return usb_urb_transfer_sp(dev, ep, USB_URB_TYPE_BULK, bytes, size,
416		timeout, actual_length, max_rw);
417}
418
419int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
420	int timeout)
421{
422  /* Ensure the endpoint address is correct */
423  ep |= USB_ENDPOINT_IN;
424  return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
425		timeout);
426}
427
428/*
429 * FIXME: Packetize large buffers here. 2.4 HCDs (atleast, haven't checked
430 * 2.5 HCDs yet) don't handle multi-packet Interrupt transfers. So we need
431 * to lookup the endpoint packet size and packetize appropriately here.
432 */
433int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
434	int timeout)
435{
436  /* Ensure the endpoint address is correct */
437  return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
438		timeout);
439}
440
441int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
442	int timeout)
443{
444  /* Ensure the endpoint address is correct */
445  ep |= USB_ENDPOINT_IN;
446  return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
447		timeout);
448}
449
450int usb_os_find_busses(struct usb_bus **busses)
451{
452  struct usb_bus *fbus = NULL;
453  DIR *dir;
454  struct dirent *entry;
455
456  dir = opendir(usb_path);
457  if (!dir)
458    USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", usb_path,
459	strerror(errno));
460
461  while ((entry = readdir(dir)) != NULL) {
462    struct usb_bus *bus;
463
464    /* Skip anything starting with a . */
465    if (entry->d_name[0] == '.')
466      continue;
467
468    if (!strchr("0123456789", entry->d_name[strlen(entry->d_name) - 1])) {
469      if (usb_debug >= 2)
470        fprintf(stderr, "usb_os_find_busses: Skipping non bus directory %s\n",
471		entry->d_name);
472      continue;
473    }
474
475    bus = malloc(sizeof(*bus));
476    if (!bus)
477      USB_ERROR(-ENOMEM);
478
479    memset((void *)bus, 0, sizeof(*bus));
480
481    strncpy(bus->dirname, entry->d_name, sizeof(bus->dirname) - 1);
482    bus->dirname[sizeof(bus->dirname) - 1] = 0;
483
484    LIST_ADD(fbus, bus);
485
486    if (usb_debug >= 2)
487       fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
488  }
489
490  closedir(dir);
491
492  *busses = fbus;
493
494  return 0;
495}
496
497int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
498{
499  struct usb_device *fdev = NULL;
500  DIR *dir;
501  struct dirent *entry;
502  char dirpath[PATH_MAX + 1];
503
504  snprintf(dirpath, PATH_MAX, "%s/%s", usb_path, bus->dirname);
505
506  dir = opendir(dirpath);
507  if (!dir)
508    USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", dirpath,
509	strerror(errno));
510
511  while ((entry = readdir(dir)) != NULL) {
512    unsigned char device_desc[DEVICE_DESC_LENGTH];
513    char filename[PATH_MAX + 1];
514    struct usb_device *dev;
515    struct usb_connectinfo connectinfo;
516    int i, fd, ret;
517
518    /* Skip anything starting with a . */
519    if (entry->d_name[0] == '.')
520      continue;
521
522    dev = malloc(sizeof(*dev));
523    if (!dev)
524      USB_ERROR(-ENOMEM);
525
526    memset((void *)dev, 0, sizeof(*dev));
527
528    dev->bus = bus;
529
530    strncpy(dev->filename, entry->d_name, sizeof(dev->filename) - 1);
531    dev->filename[sizeof(dev->filename) - 1] = 0;
532
533    snprintf(filename, sizeof(filename) - 1, "%s/%s", dirpath, entry->d_name);
534    fd = open(filename, O_RDWR);
535    if (fd < 0) {
536      fd = open(filename, O_RDONLY);
537      if (fd < 0) {
538        if (usb_debug >= 2)
539          fprintf(stderr, "usb_os_find_devices: Couldn't open %s\n",
540                  filename);
541
542        free(dev);
543        continue;
544      }
545    }
546
547    /* Get the device number */
548    ret = ioctl(fd, IOCTL_USB_CONNECTINFO, &connectinfo);
549    if (ret < 0) {
550      if (usb_debug)
551        fprintf(stderr, "usb_os_find_devices: couldn't get connect info\n");
552    } else
553      dev->devnum = connectinfo.devnum;
554
555    ret = read(fd, (void *)device_desc, DEVICE_DESC_LENGTH);
556    if (ret < 0) {
557      if (usb_debug)
558        fprintf(stderr, "usb_os_find_devices: Couldn't read descriptor\n");
559
560      free(dev);
561
562      goto err;
563    }
564
565    /*
566     * Linux kernel converts the words in this descriptor to CPU endian, so
567     * we use the undocumented W character for usb_parse_descriptor() that
568     * doesn't convert endianess when parsing the descriptor
569     */
570    usb_parse_descriptor(device_desc, "bbWbbbbWWWbbbb", &dev->descriptor);
571
572    LIST_ADD(fdev, dev);
573
574    if (usb_debug >= 2)
575      fprintf(stderr, "usb_os_find_devices: Found %s on %s\n",
576		dev->filename, bus->dirname);
577
578    /* Now try to fetch the rest of the descriptors */
579    if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG)
580      /* Silent since we'll try again later */
581      goto err;
582
583    if (dev->descriptor.bNumConfigurations < 1)
584      /* Silent since we'll try again later */
585      goto err;
586
587    dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor));
588    if (!dev->config)
589      /* Silent since we'll try again later */
590      goto err;
591
592    memset(dev->config, 0, dev->descriptor.bNumConfigurations *
593          sizeof(struct usb_config_descriptor));
594
595    for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
596      unsigned char buffer[8], *bigbuffer;
597      struct usb_config_descriptor config;
598
599      /* Get the first 8 bytes so we can figure out what the total length is */
600      ret = read(fd, (void *)buffer, 8);
601      if (ret < 8) {
602        if (usb_debug >= 1) {
603          if (ret < 0)
604            fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
605          else
606            fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", 8, ret);
607        }
608
609        goto err;
610      }
611
612      usb_parse_descriptor(buffer, "bbw", &config);
613
614      bigbuffer = malloc(config.wTotalLength);
615      if (!bigbuffer) {
616        if (usb_debug >= 1)
617          fprintf(stderr, "Unable to allocate memory for descriptors\n");
618        goto err;
619      }
620
621      /* Read the rest of the config descriptor */
622      memcpy(bigbuffer, buffer, 8);
623
624      ret = read(fd, (void *)(bigbuffer + 8), config.wTotalLength - 8);
625      if (ret < config.wTotalLength - 8) {
626        if (usb_debug >= 1) {
627          if (ret < 0)
628            fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
629          else
630            fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, ret);
631        }
632
633        free(bigbuffer);
634        goto err;
635      }
636
637      ret = usb_parse_configuration(&dev->config[i], bigbuffer);
638      if (usb_debug >= 2) {
639        if (ret > 0)
640          fprintf(stderr, "Descriptor data still left\n");
641        else if (ret < 0)
642          fprintf(stderr, "Unable to parse descriptors\n");
643      }
644
645      free(bigbuffer);
646    }
647
648err:
649    close(fd);
650  }
651
652  closedir(dir);
653
654  *devices = fdev;
655
656  return 0;
657}
658
659int usb_os_determine_children(struct usb_bus *bus)
660{
661  struct usb_device *dev, *devices[256];
662  struct usb_ioctl command;
663  int ret, i, i1;
664
665  /* Create a list of devices first */
666  memset(devices, 0, sizeof(devices));
667  for (dev = bus->devices; dev; dev = dev->next)
668    if (dev->devnum)
669      devices[dev->devnum] = dev;
670
671  /* Now fetch the children for each device */
672  for (dev = bus->devices; dev; dev = dev->next) {
673    struct usb_hub_portinfo portinfo;
674    int fd;
675
676    fd = device_open(dev);
677    if (fd < 0)
678      continue;
679
680    /* Query the hub driver for the children of this device */
681    if (dev->config && dev->config->interface && dev->config->interface->altsetting)
682      command.ifno = dev->config->interface->altsetting->bInterfaceNumber;
683    else
684      command.ifno = 0;
685    command.ioctl_code = IOCTL_USB_HUB_PORTINFO;
686    command.data = &portinfo;
687    ret = ioctl(fd, IOCTL_USB_IOCTL, &command);
688    if (ret < 0) {
689      /* errno == ENOSYS means the device probably wasn't a hub */
690      if (errno != ENOSYS && usb_debug > 1)
691        fprintf(stderr, "error obtaining child information: %s\n",
692		strerror(errno));
693
694      close(fd);
695      continue;
696    }
697
698    dev->num_children = 0;
699    for (i = 0; i < portinfo.numports; i++)
700      if (portinfo.port[i])
701        dev->num_children++;
702
703    /* Free any old children first */
704    free(dev->children);
705
706    dev->children = malloc(sizeof(struct usb_device *) * dev->num_children);
707    if (!dev->children) {
708      if (usb_debug > 1)
709        fprintf(stderr, "error allocating %zu bytes memory for dev->children\n",
710                sizeof(struct usb_device *) * dev->num_children);
711
712      dev->num_children = 0;
713      close(fd);
714      continue;
715    }
716
717    for (i = 0, i1 = 0; i < portinfo.numports; i++) {
718      if (!portinfo.port[i])
719        continue;
720
721      dev->children[i1++] = devices[portinfo.port[i]];
722
723      devices[portinfo.port[i]] = NULL;
724    }
725
726    close(fd);
727  }
728
729  /*
730   * There should be one device left in the devices list and that should be
731   * the root device
732   */
733  for (i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
734    if (devices[i])
735      bus->root_dev = devices[i];
736  }
737
738  return 0;
739}
740
741static int check_usb_vfs(const char *dirname)
742{
743  DIR *dir;
744  struct dirent *entry;
745  int found = 0;
746
747  dir = opendir(dirname);
748  if (!dir)
749    return 0;
750
751  while ((entry = readdir(dir)) != NULL) {
752    /* Skip anything starting with a . */
753    if (entry->d_name[0] == '.')
754      continue;
755
756    /* We assume if we find any files that it must be the right place */
757    found = 1;
758    break;
759  }
760
761  closedir(dir);
762
763  return found;
764}
765
766void usb_os_init(void)
767{
768  /* Find the path to the virtual filesystem */
769  if (getenv("USB_DEVFS_PATH")) {
770    if (check_usb_vfs(getenv("USB_DEVFS_PATH"))) {
771      strncpy(usb_path, getenv("USB_DEVFS_PATH"), sizeof(usb_path) - 1);
772      usb_path[sizeof(usb_path) - 1] = 0;
773    } else if (usb_debug)
774      fprintf(stderr, "usb_os_init: couldn't find USB VFS in USB_DEVFS_PATH\n");
775  }
776
777  if (!usb_path[0]) {
778    if (check_usb_vfs("/dev/bus/usb")) {
779      strncpy(usb_path, "/dev/bus/usb", sizeof(usb_path) - 1);
780      usb_path[sizeof(usb_path) - 1] = 0;
781    } else if (check_usb_vfs("/proc/bus/usb")) {
782      strncpy(usb_path, "/proc/bus/usb", sizeof(usb_path) - 1);
783      usb_path[sizeof(usb_path) - 1] = 0;
784    } else
785      usb_path[0] = 0;	/* No path, no USB support */
786  }
787
788  if (usb_debug) {
789    if (usb_path[0])
790      fprintf(stderr, "usb_os_init: Found USB VFS at %s\n", usb_path);
791    else
792      fprintf(stderr, "usb_os_init: No USB VFS found, is it mounted?\n");
793  }
794}
795
796int usb_resetep(usb_dev_handle *dev, unsigned int ep)
797{
798  int ret;
799
800  ret = ioctl(dev->fd, IOCTL_USB_RESETEP, &ep);
801  if (ret)
802    USB_ERROR_STR(-errno, "could not reset ep %d: %s", ep,
803    	strerror(errno));
804
805  return 0;
806}
807
808int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
809{
810  int ret;
811
812  ret = ioctl(dev->fd, IOCTL_USB_CLEAR_HALT, &ep);
813  if (ret)
814    USB_ERROR_STR(-errno, "could not clear/halt ep %d: %s", ep,
815    	strerror(errno));
816
817  return 0;
818}
819
820int usb_reset(usb_dev_handle *dev)
821{
822  int ret;
823
824  ret = ioctl(dev->fd, IOCTL_USB_RESET, NULL);
825  if (ret)
826     USB_ERROR_STR(-errno, "could not reset: %s", strerror(errno));
827
828  return 0;
829}
830
831int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name,
832	unsigned int namelen)
833{
834  struct usb_getdriver getdrv;
835  int ret;
836
837  getdrv.interface = interface;
838  ret = ioctl(dev->fd, IOCTL_USB_GETDRIVER, &getdrv);
839  if (ret)
840    USB_ERROR_STR(-errno, "could not get bound driver: %s", strerror(errno));
841
842  strncpy(name, getdrv.driver, namelen - 1);
843  name[namelen - 1] = 0;
844
845  return 0;
846}
847
848int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
849{
850  struct usb_ioctl command;
851  int ret;
852
853  command.ifno = interface;
854  command.ioctl_code = IOCTL_USB_DISCONNECT;
855  command.data = NULL;
856
857  ret = ioctl(dev->fd, IOCTL_USB_IOCTL, &command);
858  if (ret)
859    USB_ERROR_STR(-errno, "could not detach kernel driver from interface %d: %s",
860        interface, strerror(errno));
861
862  return 0;
863}
864
865