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
227      if (timeout) {
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
280int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
281	int timeout)
282{
283  /* Ensure the endpoint address is correct */
284  return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
285		timeout);
286}
287
288int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
289	int timeout)
290{
291  /* Ensure the endpoint address is correct */
292  ep |= USB_ENDPOINT_IN;
293  return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
294		timeout);
295}
296
297/*
298 * FIXME: Packetize large buffers here. 2.4 HCDs (atleast, haven't checked
299 * 2.5 HCDs yet) don't handle multi-packet Interrupt transfers. So we need
300 * to lookup the endpoint packet size and packetize appropriately here.
301 */
302int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
303	int timeout)
304{
305  /* Ensure the endpoint address is correct */
306  return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
307		timeout);
308}
309
310int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
311	int timeout)
312{
313  /* Ensure the endpoint address is correct */
314  ep |= USB_ENDPOINT_IN;
315  return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
316		timeout);
317}
318
319int usb_os_find_busses(struct usb_bus **busses)
320{
321  struct usb_bus *fbus = NULL;
322  DIR *dir;
323  struct dirent *entry;
324
325  dir = opendir(usb_path);
326  if (!dir)
327    USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", usb_path,
328	strerror(errno));
329
330  while ((entry = readdir(dir)) != NULL) {
331    struct usb_bus *bus;
332
333    /* Skip anything starting with a . */
334    if (entry->d_name[0] == '.')
335      continue;
336
337    if (!strchr("0123456789", entry->d_name[strlen(entry->d_name) - 1])) {
338      if (usb_debug >= 2)
339        fprintf(stderr, "usb_os_find_busses: Skipping non bus directory %s\n",
340		entry->d_name);
341      continue;
342    }
343
344    bus = malloc(sizeof(*bus));
345    if (!bus)
346      USB_ERROR(-ENOMEM);
347
348    memset((void *)bus, 0, sizeof(*bus));
349
350    strncpy(bus->dirname, entry->d_name, sizeof(bus->dirname) - 1);
351    bus->dirname[sizeof(bus->dirname) - 1] = 0;
352
353    LIST_ADD(fbus, bus);
354
355    if (usb_debug >= 2)
356       fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
357  }
358
359  closedir(dir);
360
361  *busses = fbus;
362
363  return 0;
364}
365
366int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
367{
368  struct usb_device *fdev = NULL;
369  DIR *dir;
370  struct dirent *entry;
371  char dirpath[PATH_MAX + 1];
372
373  snprintf(dirpath, PATH_MAX, "%s/%s", usb_path, bus->dirname);
374
375  dir = opendir(dirpath);
376  if (!dir)
377    USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", dirpath,
378	strerror(errno));
379
380  while ((entry = readdir(dir)) != NULL) {
381    unsigned char device_desc[DEVICE_DESC_LENGTH];
382    char filename[PATH_MAX + 1];
383    struct usb_device *dev;
384    struct usb_connectinfo connectinfo;
385    int i, fd, ret;
386
387    /* Skip anything starting with a . */
388    if (entry->d_name[0] == '.')
389      continue;
390
391    dev = malloc(sizeof(*dev));
392    if (!dev)
393      USB_ERROR(-ENOMEM);
394
395    memset((void *)dev, 0, sizeof(*dev));
396
397    dev->bus = bus;
398
399    strncpy(dev->filename, entry->d_name, sizeof(dev->filename) - 1);
400    dev->filename[sizeof(dev->filename) - 1] = 0;
401
402    snprintf(filename, sizeof(filename) - 1, "%s/%s", dirpath, entry->d_name);
403    fd = open(filename, O_RDWR);
404    if (fd < 0) {
405      fd = open(filename, O_RDONLY);
406      if (fd < 0) {
407        if (usb_debug >= 2)
408          fprintf(stderr, "usb_os_find_devices: Couldn't open %s\n",
409                  filename);
410
411        free(dev);
412        continue;
413      }
414    }
415
416    /* Get the device number */
417    ret = ioctl(fd, IOCTL_USB_CONNECTINFO, &connectinfo);
418    if (ret < 0) {
419      if (usb_debug)
420        fprintf(stderr, "usb_os_find_devices: couldn't get connect info\n");
421    } else
422      dev->devnum = connectinfo.devnum;
423
424    ret = read(fd, (void *)device_desc, DEVICE_DESC_LENGTH);
425    if (ret < 0) {
426      if (usb_debug)
427        fprintf(stderr, "usb_os_find_devices: Couldn't read descriptor\n");
428
429      free(dev);
430
431      goto err;
432    }
433
434    /*
435     * Linux kernel converts the words in this descriptor to CPU endian, so
436     * we use the undocumented W character for usb_parse_descriptor() that
437     * doesn't convert endianess when parsing the descriptor
438     */
439    usb_parse_descriptor(device_desc, "bbWbbbbWWWbbbb", &dev->descriptor);
440
441    LIST_ADD(fdev, dev);
442
443    if (usb_debug >= 2)
444      fprintf(stderr, "usb_os_find_devices: Found %s on %s\n",
445		dev->filename, bus->dirname);
446
447    /* Now try to fetch the rest of the descriptors */
448    if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG)
449      /* Silent since we'll try again later */
450      goto err;
451
452    if (dev->descriptor.bNumConfigurations < 1)
453      /* Silent since we'll try again later */
454      goto err;
455
456    dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor));
457    if (!dev->config)
458      /* Silent since we'll try again later */
459      goto err;
460
461    memset(dev->config, 0, dev->descriptor.bNumConfigurations *
462          sizeof(struct usb_config_descriptor));
463
464    for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
465      unsigned char buffer[8], *bigbuffer;
466      struct usb_config_descriptor config;
467
468      /* Get the first 8 bytes so we can figure out what the total length is */
469      ret = read(fd, (void *)buffer, 8);
470      if (ret < 8) {
471        if (usb_debug >= 1) {
472          if (ret < 0)
473            fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
474          else
475            fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", 8, ret);
476        }
477
478        goto err;
479      }
480
481      usb_parse_descriptor(buffer, "bbw", &config);
482
483      bigbuffer = malloc(config.wTotalLength);
484      if (!bigbuffer) {
485        if (usb_debug >= 1)
486          fprintf(stderr, "Unable to allocate memory for descriptors\n");
487        goto err;
488      }
489
490      /* Read the rest of the config descriptor */
491      memcpy(bigbuffer, buffer, 8);
492
493      ret = read(fd, (void *)(bigbuffer + 8), config.wTotalLength - 8);
494      if (ret < config.wTotalLength - 8) {
495        if (usb_debug >= 1) {
496          if (ret < 0)
497            fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
498          else
499            fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, ret);
500        }
501
502        free(bigbuffer);
503        goto err;
504      }
505
506      ret = usb_parse_configuration(&dev->config[i], bigbuffer);
507      if (usb_debug >= 2) {
508        if (ret > 0)
509          fprintf(stderr, "Descriptor data still left\n");
510        else if (ret < 0)
511          fprintf(stderr, "Unable to parse descriptors\n");
512      }
513
514      free(bigbuffer);
515    }
516
517err:
518    close(fd);
519  }
520
521  closedir(dir);
522
523  *devices = fdev;
524
525  return 0;
526}
527
528int usb_os_determine_children(struct usb_bus *bus)
529{
530  struct usb_device *dev, *devices[256];
531  struct usb_ioctl command;
532  int ret, i, i1;
533
534  /* Create a list of devices first */
535  memset(devices, 0, sizeof(devices));
536  for (dev = bus->devices; dev; dev = dev->next)
537    if (dev->devnum)
538      devices[dev->devnum] = dev;
539
540  /* Now fetch the children for each device */
541  for (dev = bus->devices; dev; dev = dev->next) {
542    struct usb_hub_portinfo portinfo;
543    int fd;
544
545    fd = device_open(dev);
546    if (fd < 0)
547      continue;
548
549    /* Query the hub driver for the children of this device */
550    if (dev->config && dev->config->interface && dev->config->interface->altsetting)
551      command.ifno = dev->config->interface->altsetting->bInterfaceNumber;
552    else
553      command.ifno = 0;
554    command.ioctl_code = IOCTL_USB_HUB_PORTINFO;
555    command.data = &portinfo;
556    ret = ioctl(fd, IOCTL_USB_IOCTL, &command);
557    if (ret < 0) {
558      /* errno == ENOSYS means the device probably wasn't a hub */
559      if (errno != ENOSYS && usb_debug > 1)
560        fprintf(stderr, "error obtaining child information: %s\n",
561		strerror(errno));
562
563      close(fd);
564      continue;
565    }
566
567    dev->num_children = 0;
568    for (i = 0; i < portinfo.numports; i++)
569      if (portinfo.port[i])
570        dev->num_children++;
571
572    /* Free any old children first */
573    free(dev->children);
574
575    dev->children = malloc(sizeof(struct usb_device *) * dev->num_children);
576    if (!dev->children) {
577      if (usb_debug > 1)
578        fprintf(stderr, "error allocating %zu bytes memory for dev->children\n",
579                sizeof(struct usb_device *) * dev->num_children);
580
581      dev->num_children = 0;
582      close(fd);
583      continue;
584    }
585
586    for (i = 0, i1 = 0; i < portinfo.numports; i++) {
587      if (!portinfo.port[i])
588        continue;
589
590      dev->children[i1++] = devices[portinfo.port[i]];
591
592      devices[portinfo.port[i]] = NULL;
593    }
594
595    close(fd);
596  }
597
598  /*
599   * There should be one device left in the devices list and that should be
600   * the root device
601   */
602  for (i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
603    if (devices[i])
604      bus->root_dev = devices[i];
605  }
606
607  return 0;
608}
609
610static int check_usb_vfs(const char *dirname)
611{
612  DIR *dir;
613  struct dirent *entry;
614  int found = 0;
615
616  dir = opendir(dirname);
617  if (!dir)
618    return 0;
619
620  while ((entry = readdir(dir)) != NULL) {
621    /* Skip anything starting with a . */
622    if (entry->d_name[0] == '.')
623      continue;
624
625    /* We assume if we find any files that it must be the right place */
626    found = 1;
627    break;
628  }
629
630  closedir(dir);
631
632  return found;
633}
634
635void usb_os_init(void)
636{
637  /* Find the path to the virtual filesystem */
638  if (getenv("USB_DEVFS_PATH")) {
639    if (check_usb_vfs(getenv("USB_DEVFS_PATH"))) {
640      strncpy(usb_path, getenv("USB_DEVFS_PATH"), sizeof(usb_path) - 1);
641      usb_path[sizeof(usb_path) - 1] = 0;
642    } else if (usb_debug)
643      fprintf(stderr, "usb_os_init: couldn't find USB VFS in USB_DEVFS_PATH\n");
644  }
645
646  if (!usb_path[0]) {
647    if (check_usb_vfs("/dev/bus/usb")) {
648      strncpy(usb_path, "/dev/bus/usb", sizeof(usb_path) - 1);
649      usb_path[sizeof(usb_path) - 1] = 0;
650    } else if (check_usb_vfs("/proc/bus/usb")) {
651      strncpy(usb_path, "/proc/bus/usb", sizeof(usb_path) - 1);
652      usb_path[sizeof(usb_path) - 1] = 0;
653    } else
654      usb_path[0] = 0;	/* No path, no USB support */
655  }
656
657  if (usb_debug) {
658    if (usb_path[0])
659      fprintf(stderr, "usb_os_init: Found USB VFS at %s\n", usb_path);
660    else
661      fprintf(stderr, "usb_os_init: No USB VFS found, is it mounted?\n");
662  }
663}
664
665int usb_resetep(usb_dev_handle *dev, unsigned int ep)
666{
667  int ret;
668
669  ret = ioctl(dev->fd, IOCTL_USB_RESETEP, &ep);
670  if (ret)
671    USB_ERROR_STR(-errno, "could not reset ep %d: %s", ep,
672    	strerror(errno));
673
674  return 0;
675}
676
677int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
678{
679  int ret;
680
681  ret = ioctl(dev->fd, IOCTL_USB_CLEAR_HALT, &ep);
682  if (ret)
683    USB_ERROR_STR(-errno, "could not clear/halt ep %d: %s", ep,
684    	strerror(errno));
685
686  return 0;
687}
688
689int usb_reset(usb_dev_handle *dev)
690{
691  int ret;
692
693  ret = ioctl(dev->fd, IOCTL_USB_RESET, NULL);
694  if (ret)
695     USB_ERROR_STR(-errno, "could not reset: %s", strerror(errno));
696
697  return 0;
698}
699
700int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name,
701	unsigned int namelen)
702{
703  struct usb_getdriver getdrv;
704  int ret;
705
706  getdrv.interface = interface;
707  ret = ioctl(dev->fd, IOCTL_USB_GETDRIVER, &getdrv);
708  if (ret)
709    USB_ERROR_STR(-errno, "could not get bound driver: %s", strerror(errno));
710
711  strncpy(name, getdrv.driver, namelen - 1);
712  name[namelen - 1] = 0;
713
714  return 0;
715}
716
717int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
718{
719  struct usb_ioctl command;
720  int ret;
721
722  command.ifno = interface;
723  command.ioctl_code = IOCTL_USB_DISCONNECT;
724  command.data = NULL;
725
726  ret = ioctl(dev->fd, IOCTL_USB_IOCTL, &command);
727  if (ret)
728    USB_ERROR_STR(-errno, "could not detach kernel driver from interface %d: %s",
729        interface, strerror(errno));
730
731  return 0;
732}
733
734