Break up vl.h.
[qemu] / usb-linux.c
1 /*
2  * Linux host USB redirector
3  *
4  * Copyright (c) 2005 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu-common.h"
25 #include "hw/usb.h"
26 #include "console.h"
27
28 #if defined(__linux__)
29 #include <dirent.h>
30 #include <sys/ioctl.h>
31 #include <linux/usbdevice_fs.h>
32 #include <linux/version.h>
33 #include <signal.h>
34
35 /* We redefine it to avoid version problems */
36 struct usb_ctrltransfer {
37     uint8_t  bRequestType;
38     uint8_t  bRequest;
39     uint16_t wValue;
40     uint16_t wIndex;
41     uint16_t wLength;
42     uint32_t timeout;
43     void *data;
44 };
45
46 typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
47                         int vendor_id, int product_id,
48                         const char *product_name, int speed);
49 static int usb_host_find_device(int *pbus_num, int *paddr,
50                                 char *product_name, int product_name_size,
51                                 const char *devname);
52
53 //#define DEBUG
54 //#define DEBUG_ISOCH
55 //#define USE_ASYNCIO
56
57 #define USBDEVFS_PATH "/proc/bus/usb"
58 #define PRODUCT_NAME_SZ 32
59 #define SIG_ISOCOMPLETE (SIGRTMIN+7)
60 #define MAX_ENDPOINTS 16
61
62 struct sigaction sigact;
63
64 /* endpoint association data */
65 struct endp_data {
66     uint8_t type;
67 };
68
69 /* FIXME: move USBPacket to PendingURB */
70 typedef struct USBHostDevice {
71     USBDevice dev;
72     int fd;
73     int pipe_fds[2];
74     USBPacket *packet;
75     struct endp_data endp_table[MAX_ENDPOINTS];
76     int configuration;
77     uint8_t descr[1024];
78     int descr_len;
79     int urbs_ready;
80 } USBHostDevice;
81
82 typedef struct PendingURB {
83     struct usbdevfs_urb *urb;
84     int status;
85     struct PendingURB *next;
86 } PendingURB;
87
88 static PendingURB *pending_urbs = NULL;
89
90 static int add_pending_urb(struct usbdevfs_urb *urb)
91 {
92     PendingURB *purb = qemu_mallocz(sizeof(PendingURB));
93     if (purb) {
94         purb->urb = urb;
95         purb->status = 0;
96         purb->next = pending_urbs;
97         pending_urbs = purb;
98         return 1;
99     }
100     return 0;
101 }
102
103 static int del_pending_urb(struct usbdevfs_urb *urb)
104 {
105     PendingURB *purb = pending_urbs;
106     PendingURB *prev = NULL;
107
108     while (purb && purb->urb != urb) {
109         prev = purb;
110         purb = purb->next;
111     }
112
113     if (purb && purb->urb == urb) {
114         if (prev) {
115             prev->next = purb->next;
116         } else {
117             pending_urbs = purb->next;
118         }
119         qemu_free(purb);
120         return 1;
121     }
122     return 0;
123 }
124
125 #ifdef USE_ASYNCIO
126 static PendingURB *get_pending_urb(struct usbdevfs_urb *urb)
127 {
128     PendingURB *purb = pending_urbs;
129
130     while (purb && purb->urb != urb) {
131         purb = purb->next;
132     }
133
134     if (purb && purb->urb == urb) {
135         return purb;
136     }
137     return NULL;
138 }
139 #endif
140
141 static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
142 {
143     int dev_descr_len, config_descr_len;
144     int interface, nb_interfaces, nb_configurations;
145     int ret, i;
146
147     if (configuration == 0) /* address state - ignore */
148         return 1;
149
150     i = 0;
151     dev_descr_len = dev->descr[0];
152     if (dev_descr_len > dev->descr_len)
153         goto fail;
154     nb_configurations = dev->descr[17];
155
156     i += dev_descr_len;
157     while (i < dev->descr_len) {
158 #ifdef DEBUG
159         printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
160                dev->descr[i], dev->descr[i+1]);
161 #endif
162         if (dev->descr[i+1] != USB_DT_CONFIG) {
163             i += dev->descr[i];
164             continue;
165         }
166         config_descr_len = dev->descr[i];
167
168         if (configuration == dev->descr[i + 5])
169             break;
170
171         i += config_descr_len;
172     }
173
174     if (i >= dev->descr_len) {
175         printf("usb_host: error - device has no matching configuration\n");
176         goto fail;
177     }
178     nb_interfaces = dev->descr[i + 4];
179
180 #ifdef USBDEVFS_DISCONNECT
181     /* earlier Linux 2.4 do not support that */
182     {
183         struct usbdevfs_ioctl ctrl;
184         for (interface = 0; interface < nb_interfaces; interface++) {
185             ctrl.ioctl_code = USBDEVFS_DISCONNECT;
186             ctrl.ifno = interface;
187             ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
188             if (ret < 0 && errno != ENODATA) {
189                 perror("USBDEVFS_DISCONNECT");
190                 goto fail;
191             }
192         }
193     }
194 #endif
195
196     /* XXX: only grab if all interfaces are free */
197     for (interface = 0; interface < nb_interfaces; interface++) {
198         ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
199         if (ret < 0) {
200             if (errno == EBUSY) {
201                 fprintf(stderr,
202                         "usb_host: warning - device already grabbed\n");
203             } else {
204                 perror("USBDEVFS_CLAIMINTERFACE");
205             }
206         fail:
207             return 0;
208         }
209     }
210
211 #ifdef DEBUG
212     printf("usb_host: %d interfaces claimed for configuration %d\n",
213            nb_interfaces, configuration);
214 #endif
215
216     return 1;
217 }
218
219 static void usb_host_handle_reset(USBDevice *dev)
220 {
221 #if 0
222     USBHostDevice *s = (USBHostDevice *)dev;
223     /* USBDEVFS_RESET, but not the first time as it has already be
224        done by the host OS */
225     ioctl(s->fd, USBDEVFS_RESET);
226 #endif
227 }
228
229 static void usb_host_handle_destroy(USBDevice *dev)
230 {
231     USBHostDevice *s = (USBHostDevice *)dev;
232
233     if (s->fd >= 0)
234         close(s->fd);
235     qemu_free(s);
236 }
237
238 static int usb_linux_update_endp_table(USBHostDevice *s);
239
240 static int usb_host_handle_control(USBDevice *dev,
241                                    int request,
242                                    int value,
243                                    int index,
244                                    int length,
245                                    uint8_t *data)
246 {
247     USBHostDevice *s = (USBHostDevice *)dev;
248     struct usb_ctrltransfer ct;
249     struct usbdevfs_setinterface si;
250     int intf_update_required = 0;
251     int ret;
252
253     if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
254         /* specific SET_ADDRESS support */
255         dev->addr = value;
256         return 0;
257     } else if (request == ((USB_RECIP_INTERFACE << 8) |
258                            USB_REQ_SET_INTERFACE)) {
259         /* set alternate setting for the interface */
260         si.interface = index;
261         si.altsetting = value;
262         ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
263         usb_linux_update_endp_table(s);
264     } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
265 #ifdef DEBUG
266         printf("usb_host_handle_control: SET_CONFIGURATION request - "
267                "config %d\n", value & 0xff);
268 #endif
269         if (s->configuration != (value & 0xff)) {
270             s->configuration = (value & 0xff);
271             intf_update_required = 1;
272         }
273         goto do_request;
274     } else {
275     do_request:
276         ct.bRequestType = request >> 8;
277         ct.bRequest = request;
278         ct.wValue = value;
279         ct.wIndex = index;
280         ct.wLength = length;
281         ct.timeout = 50;
282         ct.data = data;
283         ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
284     }
285
286     if (ret < 0) {
287         switch(errno) {
288         case ETIMEDOUT:
289             return USB_RET_NAK;
290         default:
291             return USB_RET_STALL;
292         }
293     } else {
294         if (intf_update_required) {
295 #ifdef DEBUG
296             printf("usb_host_handle_control: updating interfaces\n");
297 #endif
298             usb_host_update_interfaces(s, value & 0xff);
299         }
300         return ret;
301     }
302 }
303
304 static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);
305
306 static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
307 {
308     USBHostDevice *s = (USBHostDevice *)dev;
309     struct usbdevfs_bulktransfer bt;
310     int ret;
311     uint8_t devep = p->devep;
312
313     if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {
314         return usb_host_handle_isoch(dev, p);
315     }
316
317     /* XXX: optimize and handle all data types by looking at the
318        config descriptor */
319     if (p->pid == USB_TOKEN_IN)
320         devep |= 0x80;
321     bt.ep = devep;
322     bt.len = p->len;
323     bt.timeout = 50;
324     bt.data = p->data;
325     ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
326     if (ret < 0) {
327         switch(errno) {
328         case ETIMEDOUT:
329             return USB_RET_NAK;
330         case EPIPE:
331         default:
332 #ifdef DEBUG
333             printf("handle_data: errno=%d\n", errno);
334 #endif
335             return USB_RET_STALL;
336         }
337     } else {
338         return ret;
339     }
340 }
341
342 #ifdef USE_ASYNCIO
343 static void urb_completion_pipe_read(void *opaque)
344 {
345     USBHostDevice *s = opaque;
346     USBPacket *p = s->packet;
347     PendingURB *pending_urb = NULL;
348     struct usbdevfs_urb *purb = NULL;
349     int len, ret;
350
351     len = read(s->pipe_fds[0], &pending_urb, sizeof(pending_urb));
352     if (len != sizeof(pending_urb)) {
353         printf("urb_completion: error reading pending_urb, len=%d\n", len);
354         return;
355     }
356
357     /* FIXME: handle pending_urb->status */
358     del_pending_urb(pending_urb->urb);
359
360     if (!p) {
361         s->urbs_ready++;
362         return;
363     }
364
365     ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
366     if (ret < 0) {
367         printf("urb_completion: REAPURBNDELAY ioctl=%d errno=%d\n",
368                ret, errno);
369         return;
370     }
371
372 #ifdef DEBUG_ISOCH
373     if (purb == pending_urb->urb) {
374         printf("urb_completion: urb mismatch reaped=%p pending=%p\n",
375                purb, urb);
376     }
377 #endif
378
379     p->len = purb->actual_length;
380     usb_packet_complete(p);
381     qemu_free(purb);
382     s->packet = NULL;
383 }
384
385 static void isoch_done(int signum, siginfo_t *info, void *context)
386 {
387     struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;
388     USBHostDevice *s = (USBHostDevice *)urb->usercontext;
389     PendingURB *purb;
390
391     if (info->si_code != SI_ASYNCIO ||
392         info->si_signo != SIG_ISOCOMPLETE) {
393         return;
394     }
395
396     purb = get_pending_urb(urb);
397     if (purb) {
398         purb->status = info->si_errno;
399         write(s->pipe_fds[1], &purb, sizeof(purb));
400     }
401 }
402 #endif
403
404 static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)
405 {
406     USBHostDevice *s = (USBHostDevice *)dev;
407     struct usbdevfs_urb *urb, *purb = NULL;
408     int ret;
409     uint8_t devep = p->devep;
410
411     if (p->pid == USB_TOKEN_IN)
412         devep |= 0x80;
413
414     urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +
415                        sizeof(struct usbdevfs_iso_packet_desc));
416     if (!urb) {
417         printf("usb_host_handle_isoch: malloc failed\n");
418         return 0;
419     }
420
421     urb->type = USBDEVFS_URB_TYPE_ISO;
422     urb->endpoint = devep;
423     urb->status = 0;
424     urb->flags = USBDEVFS_URB_ISO_ASAP;
425     urb->buffer = p->data;
426     urb->buffer_length = p->len;
427     urb->actual_length = 0;
428     urb->start_frame = 0;
429     urb->error_count = 0;
430 #ifdef USE_ASYNCIO
431     urb->signr = SIG_ISOCOMPLETE;
432 #else
433     urb->signr = 0;
434 #endif
435     urb->usercontext = s;
436     urb->number_of_packets = 1;
437     urb->iso_frame_desc[0].length = p->len;
438     urb->iso_frame_desc[0].actual_length = 0;
439     urb->iso_frame_desc[0].status = 0;
440     ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
441     if (ret == 0) {
442         if (!add_pending_urb(urb)) {
443             printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);
444         }
445     } else {
446         printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n",
447                ret, errno);
448         qemu_free(urb);
449         switch(errno) {
450         case ETIMEDOUT:
451             return USB_RET_NAK;
452         case EPIPE:
453         default:
454             return USB_RET_STALL;
455         }
456     }
457 #ifdef USE_ASYNCIO
458     /* FIXME: handle urbs_ready together with sync io
459      * workaround for injecting the signaled urbs into current frame */
460     if (s->urbs_ready > 0) {
461         ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
462         if (ret == 0) {
463             ret = purb->actual_length;
464             qemu_free(purb);
465             s->urbs_ready--;
466         }
467         return ret;
468     }
469     s->packet = p;
470     return USB_RET_ASYNC;
471 #else
472     ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
473     if (ret == 0) {
474         if (del_pending_urb(purb)) {
475             ret = purb->actual_length;
476             qemu_free(purb);
477         } else {
478             printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);
479         }
480     } else {
481 #ifdef DEBUG_ISOCH
482         printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n",
483                ret, errno);
484 #endif
485     }
486     return ret;
487 #endif
488 }
489
490 /* returns 1 on problem encountered or 0 for success */
491 static int usb_linux_update_endp_table(USBHostDevice *s)
492 {
493     uint8_t *descriptors;
494     uint8_t devep, type, configuration, alt_interface;
495     struct usb_ctrltransfer ct;
496     int interface, ret, length, i;
497
498     ct.bRequestType = USB_DIR_IN;
499     ct.bRequest = USB_REQ_GET_CONFIGURATION;
500     ct.wValue = 0;
501     ct.wIndex = 0;
502     ct.wLength = 1;
503     ct.data = &configuration;
504     ct.timeout = 50;
505
506     ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
507     if (ret < 0) {
508         perror("usb_linux_update_endp_table");
509         return 1;
510     }
511
512     /* in address state */
513     if (configuration == 0)
514         return 1;
515
516     /* get the desired configuration, interface, and endpoint descriptors
517      * from device description */
518     descriptors = &s->descr[18];
519     length = s->descr_len - 18;
520     i = 0;
521
522     if (descriptors[i + 1] != USB_DT_CONFIG ||
523         descriptors[i + 5] != configuration) {
524         printf("invalid descriptor data - configuration\n");
525         return 1;
526     }
527     i += descriptors[i];
528
529     while (i < length) {
530         if (descriptors[i + 1] != USB_DT_INTERFACE ||
531             (descriptors[i + 1] == USB_DT_INTERFACE &&
532              descriptors[i + 4] == 0)) {
533             i += descriptors[i];
534             continue;
535         }
536
537         interface = descriptors[i + 2];
538
539         ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
540         ct.bRequest = USB_REQ_GET_INTERFACE;
541         ct.wValue = 0;
542         ct.wIndex = interface;
543         ct.wLength = 1;
544         ct.data = &alt_interface;
545         ct.timeout = 50;
546
547         ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
548         if (ret < 0) {
549             perror("usb_linux_update_endp_table");
550             return 1;
551         }
552
553         /* the current interface descriptor is the active interface
554          * and has endpoints */
555         if (descriptors[i + 3] != alt_interface) {
556             i += descriptors[i];
557             continue;
558         }
559
560         /* advance to the endpoints */
561         while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
562             i += descriptors[i];
563
564         if (i >= length)
565             break;
566
567         while (i < length) {
568             if (descriptors[i + 1] != USB_DT_ENDPOINT)
569                 break;
570
571             devep = descriptors[i + 2];
572             switch (descriptors[i + 3] & 0x3) {
573             case 0x00:
574                 type = USBDEVFS_URB_TYPE_CONTROL;
575                 break;
576             case 0x01:
577                 type = USBDEVFS_URB_TYPE_ISO;
578                 break;
579             case 0x02:
580                 type = USBDEVFS_URB_TYPE_BULK;
581                 break;
582             case 0x03:
583                 type = USBDEVFS_URB_TYPE_INTERRUPT;
584                 break;
585             default:
586                 printf("usb_host: malformed endpoint type\n");
587                 type = USBDEVFS_URB_TYPE_BULK;
588             }
589             s->endp_table[(devep & 0xf) - 1].type = type;
590
591             i += descriptors[i];
592         }
593     }
594     return 0;
595 }
596
597 /* XXX: exclude high speed devices or implement EHCI */
598 USBDevice *usb_host_device_open(const char *devname)
599 {
600     int fd = -1, ret;
601     USBHostDevice *dev = NULL;
602     struct usbdevfs_connectinfo ci;
603     char buf[1024];
604     int bus_num, addr;
605     char product_name[PRODUCT_NAME_SZ];
606
607     dev = qemu_mallocz(sizeof(USBHostDevice));
608     if (!dev)
609         goto fail;
610
611 #ifdef DEBUG_ISOCH
612     printf("usb_host_device_open %s\n", devname);
613 #endif
614     if (usb_host_find_device(&bus_num, &addr,
615                              product_name, sizeof(product_name),
616                              devname) < 0)
617         return NULL;
618
619     snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
620              bus_num, addr);
621     fd = open(buf, O_RDWR | O_NONBLOCK);
622     if (fd < 0) {
623         perror(buf);
624         return NULL;
625     }
626
627     /* read the device description */
628     dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
629     if (dev->descr_len <= 0) {
630         perror("usb_host_device_open: reading device data failed");
631         goto fail;
632     }
633
634 #ifdef DEBUG
635     {
636         int x;
637         printf("=== begin dumping device descriptor data ===\n");
638         for (x = 0; x < dev->descr_len; x++)
639             printf("%02x ", dev->descr[x]);
640         printf("\n=== end dumping device descriptor data ===\n");
641     }
642 #endif
643
644     dev->fd = fd;
645     dev->configuration = 1;
646
647     /* XXX - do something about initial configuration */
648     if (!usb_host_update_interfaces(dev, 1))
649         goto fail;
650
651     ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
652     if (ret < 0) {
653         perror("usb_host_device_open: USBDEVFS_CONNECTINFO");
654         goto fail;
655     }
656
657 #ifdef DEBUG
658     printf("host USB device %d.%d grabbed\n", bus_num, addr);
659 #endif
660
661     ret = usb_linux_update_endp_table(dev);
662     if (ret)
663         goto fail;
664
665     if (ci.slow)
666         dev->dev.speed = USB_SPEED_LOW;
667     else
668         dev->dev.speed = USB_SPEED_HIGH;
669     dev->dev.handle_packet = usb_generic_handle_packet;
670
671     dev->dev.handle_reset = usb_host_handle_reset;
672     dev->dev.handle_control = usb_host_handle_control;
673     dev->dev.handle_data = usb_host_handle_data;
674     dev->dev.handle_destroy = usb_host_handle_destroy;
675
676     if (product_name[0] == '\0')
677         snprintf(dev->dev.devname, sizeof(dev->dev.devname),
678                  "host:%s", devname);
679     else
680         pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
681                 product_name);
682
683 #ifdef USE_ASYNCIO
684     /* set up the signal handlers */
685     sigemptyset(&sigact.sa_mask);
686     sigact.sa_sigaction = isoch_done;
687     sigact.sa_flags = SA_SIGINFO;
688     sigact.sa_restorer = 0;
689     ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);
690     if (ret < 0) {
691         perror("usb_host_device_open: sigaction failed");
692         goto fail;
693     }
694
695     if (pipe(dev->pipe_fds) < 0) {
696         perror("usb_host_device_open: pipe creation failed");
697         goto fail;
698     }
699     fcntl(dev->pipe_fds[0], F_SETFL, O_NONBLOCK | O_ASYNC);
700     fcntl(dev->pipe_fds[1], F_SETFL, O_NONBLOCK);
701     qemu_set_fd_handler(dev->pipe_fds[0], urb_completion_pipe_read, NULL, dev);
702 #endif
703     dev->urbs_ready = 0;
704     return (USBDevice *)dev;
705 fail:
706     if (dev)
707         qemu_free(dev);
708     close(fd);
709     return NULL;
710 }
711
712 static int get_tag_value(char *buf, int buf_size,
713                          const char *str, const char *tag,
714                          const char *stopchars)
715 {
716     const char *p;
717     char *q;
718     p = strstr(str, tag);
719     if (!p)
720         return -1;
721     p += strlen(tag);
722     while (isspace(*p))
723         p++;
724     q = buf;
725     while (*p != '\0' && !strchr(stopchars, *p)) {
726         if ((q - buf) < (buf_size - 1))
727             *q++ = *p;
728         p++;
729     }
730     *q = '\0';
731     return q - buf;
732 }
733
734 static int usb_host_scan(void *opaque, USBScanFunc *func)
735 {
736     FILE *f;
737     char line[1024];
738     char buf[1024];
739     int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
740     int ret;
741     char product_name[512];
742
743     f = fopen(USBDEVFS_PATH "/devices", "r");
744     if (!f) {
745         term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
746         return 0;
747     }
748     device_count = 0;
749     bus_num = addr = speed = class_id = product_id = vendor_id = 0;
750     ret = 0;
751     for(;;) {
752         if (fgets(line, sizeof(line), f) == NULL)
753             break;
754         if (strlen(line) > 0)
755             line[strlen(line) - 1] = '\0';
756         if (line[0] == 'T' && line[1] == ':') {
757             if (device_count && (vendor_id || product_id)) {
758                 /* New device.  Add the previously discovered device.  */
759                 ret = func(opaque, bus_num, addr, class_id, vendor_id,
760                            product_id, product_name, speed);
761                 if (ret)
762                     goto the_end;
763             }
764             if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
765                 goto fail;
766             bus_num = atoi(buf);
767             if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
768                 goto fail;
769             addr = atoi(buf);
770             if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
771                 goto fail;
772             if (!strcmp(buf, "480"))
773                 speed = USB_SPEED_HIGH;
774             else if (!strcmp(buf, "1.5"))
775                 speed = USB_SPEED_LOW;
776             else
777                 speed = USB_SPEED_FULL;
778             product_name[0] = '\0';
779             class_id = 0xff;
780             device_count++;
781             product_id = 0;
782             vendor_id = 0;
783         } else if (line[0] == 'P' && line[1] == ':') {
784             if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
785                 goto fail;
786             vendor_id = strtoul(buf, NULL, 16);
787             if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
788                 goto fail;
789             product_id = strtoul(buf, NULL, 16);
790         } else if (line[0] == 'S' && line[1] == ':') {
791             if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
792                 goto fail;
793             pstrcpy(product_name, sizeof(product_name), buf);
794         } else if (line[0] == 'D' && line[1] == ':') {
795             if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
796                 goto fail;
797             class_id = strtoul(buf, NULL, 16);
798         }
799     fail: ;
800     }
801     if (device_count && (vendor_id || product_id)) {
802         /* Add the last device.  */
803         ret = func(opaque, bus_num, addr, class_id, vendor_id,
804                    product_id, product_name, speed);
805     }
806  the_end:
807     fclose(f);
808     return ret;
809 }
810
811 typedef struct FindDeviceState {
812     int vendor_id;
813     int product_id;
814     int bus_num;
815     int addr;
816     char product_name[PRODUCT_NAME_SZ];
817 } FindDeviceState;
818
819 static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
820                                      int class_id,
821                                      int vendor_id, int product_id,
822                                      const char *product_name, int speed)
823 {
824     FindDeviceState *s = opaque;
825     if ((vendor_id == s->vendor_id &&
826         product_id == s->product_id) ||
827         (bus_num == s->bus_num &&
828         addr == s->addr)) {
829         pstrcpy(s->product_name, PRODUCT_NAME_SZ, product_name);
830         s->bus_num = bus_num;
831         s->addr = addr;
832         return 1;
833     } else {
834         return 0;
835     }
836 }
837
838 /* the syntax is :
839    'bus.addr' (decimal numbers) or
840    'vendor_id:product_id' (hexa numbers) */
841 static int usb_host_find_device(int *pbus_num, int *paddr,
842                                 char *product_name, int product_name_size,
843                                 const char *devname)
844 {
845     const char *p;
846     int ret;
847     FindDeviceState fs;
848
849     p = strchr(devname, '.');
850     if (p) {
851         *pbus_num = strtoul(devname, NULL, 0);
852         *paddr = strtoul(p + 1, NULL, 0);
853         fs.bus_num = *pbus_num;
854         fs.addr = *paddr;
855         ret = usb_host_scan(&fs, usb_host_find_device_scan);
856         if (ret)
857             pstrcpy(product_name, product_name_size, fs.product_name);
858         return 0;
859     }
860     p = strchr(devname, ':');
861     if (p) {
862         fs.vendor_id = strtoul(devname, NULL, 16);
863         fs.product_id = strtoul(p + 1, NULL, 16);
864         ret = usb_host_scan(&fs, usb_host_find_device_scan);
865         if (ret) {
866             *pbus_num = fs.bus_num;
867             *paddr = fs.addr;
868             pstrcpy(product_name, product_name_size, fs.product_name);
869             return 0;
870         }
871     }
872     return -1;
873 }
874
875 /**********************/
876 /* USB host device info */
877
878 struct usb_class_info {
879     int class;
880     const char *class_name;
881 };
882
883 static const struct usb_class_info usb_class_info[] = {
884     { USB_CLASS_AUDIO, "Audio"},
885     { USB_CLASS_COMM, "Communication"},
886     { USB_CLASS_HID, "HID"},
887     { USB_CLASS_HUB, "Hub" },
888     { USB_CLASS_PHYSICAL, "Physical" },
889     { USB_CLASS_PRINTER, "Printer" },
890     { USB_CLASS_MASS_STORAGE, "Storage" },
891     { USB_CLASS_CDC_DATA, "Data" },
892     { USB_CLASS_APP_SPEC, "Application Specific" },
893     { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
894     { USB_CLASS_STILL_IMAGE, "Still Image" },
895     { USB_CLASS_CSCID, "Smart Card" },
896     { USB_CLASS_CONTENT_SEC, "Content Security" },
897     { -1, NULL }
898 };
899
900 static const char *usb_class_str(uint8_t class)
901 {
902     const struct usb_class_info *p;
903     for(p = usb_class_info; p->class != -1; p++) {
904         if (p->class == class)
905             break;
906     }
907     return p->class_name;
908 }
909
910 void usb_info_device(int bus_num, int addr, int class_id,
911                      int vendor_id, int product_id,
912                      const char *product_name,
913                      int speed)
914 {
915     const char *class_str, *speed_str;
916
917     switch(speed) {
918     case USB_SPEED_LOW:
919         speed_str = "1.5";
920         break;
921     case USB_SPEED_FULL:
922         speed_str = "12";
923         break;
924     case USB_SPEED_HIGH:
925         speed_str = "480";
926         break;
927     default:
928         speed_str = "?";
929         break;
930     }
931
932     term_printf("  Device %d.%d, speed %s Mb/s\n",
933                 bus_num, addr, speed_str);
934     class_str = usb_class_str(class_id);
935     if (class_str)
936         term_printf("    %s:", class_str);
937     else
938         term_printf("    Class %02x:", class_id);
939     term_printf(" USB device %04x:%04x", vendor_id, product_id);
940     if (product_name[0] != '\0')
941         term_printf(", %s", product_name);
942     term_printf("\n");
943 }
944
945 static int usb_host_info_device(void *opaque, int bus_num, int addr,
946                                 int class_id,
947                                 int vendor_id, int product_id,
948                                 const char *product_name,
949                                 int speed)
950 {
951     usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
952                     product_name, speed);
953     return 0;
954 }
955
956 void usb_host_info(void)
957 {
958     usb_host_scan(NULL, usb_host_info_device);
959 }
960
961 #else
962
963 void usb_host_info(void)
964 {
965     term_printf("USB host devices not supported\n");
966 }
967
968 /* XXX: modify configure to compile the right host driver */
969 USBDevice *usb_host_device_open(const char *devname)
970 {
971     return NULL;
972 }
973
974 #endif