Tweak UHCI device settings. Ignore host root hubs.
[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 "vl.h"
25
26 #if defined(__linux__)
27 #include <dirent.h>
28 #include <sys/ioctl.h>
29 #include <linux/usbdevice_fs.h>
30 #include <linux/version.h>
31
32 /* We redefine it to avoid version problems */
33 struct usb_ctrltransfer {
34     uint8_t  bRequestType;
35     uint8_t  bRequest;
36     uint16_t wValue;
37     uint16_t wIndex;
38     uint16_t wLength;
39     uint32_t timeout;
40     void *data;
41 };
42
43 typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
44                         int vendor_id, int product_id, 
45                         const char *product_name, int speed);
46 static int usb_host_find_device(int *pbus_num, int *paddr, 
47                                 const char *devname);
48
49 //#define DEBUG
50
51 #define USBDEVFS_PATH "/proc/bus/usb"
52
53 typedef struct USBHostDevice {
54     USBDevice dev;
55     int fd;
56 } USBHostDevice;
57
58 static void usb_host_handle_reset(USBDevice *dev)
59 {
60 #if 0
61     USBHostDevice *s = (USBHostDevice *)dev;
62     /* USBDEVFS_RESET, but not the first time as it has already be
63        done by the host OS */
64     ioctl(s->fd, USBDEVFS_RESET);
65 #endif
66
67
68 static int usb_host_handle_control(USBDevice *dev,
69                                    int request,
70                                    int value,
71                                    int index,
72                                    int length,
73                                    uint8_t *data)
74 {
75     USBHostDevice *s = (USBHostDevice *)dev;
76     struct usb_ctrltransfer ct;
77     int ret;
78
79     if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
80         /* specific SET_ADDRESS support */
81         dev->addr = value;
82         return 0;
83     } else {
84         ct.bRequestType = request >> 8;
85         ct.bRequest = request;
86         ct.wValue = value;
87         ct.wIndex = index;
88         ct.wLength = length;
89         ct.timeout = 50;
90         ct.data = data;
91         ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
92         if (ret < 0) {
93             switch(errno) {
94             case ETIMEDOUT:
95                 return USB_RET_NAK;
96             default:
97                 return USB_RET_STALL;
98             }
99         } else {
100             return ret;
101         }
102    }
103 }
104
105 static int usb_host_handle_data(USBDevice *dev, int pid, 
106                                 uint8_t devep,
107                                 uint8_t *data, int len)
108 {
109     USBHostDevice *s = (USBHostDevice *)dev;
110     struct usbdevfs_bulktransfer bt;
111     int ret;
112
113     /* XXX: optimize and handle all data types by looking at the
114        config descriptor */
115     if (pid == USB_TOKEN_IN)
116         devep |= 0x80;
117     bt.ep = devep;
118     bt.len = len;
119     bt.timeout = 50;
120     bt.data = data;
121     ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
122     if (ret < 0) {
123         switch(errno) {
124         case ETIMEDOUT:
125             return USB_RET_NAK;
126         case EPIPE:
127         default:
128 #ifdef DEBUG
129             printf("handle_data: errno=%d\n", errno);
130 #endif
131             return USB_RET_STALL;
132         }
133     } else {
134         return ret;
135     }
136 }
137
138 /* XXX: exclude high speed devices or implement EHCI */
139 USBDevice *usb_host_device_open(const char *devname)
140 {
141     int fd, interface, ret, i;
142     USBHostDevice *dev;
143     struct usbdevfs_connectinfo ci;
144     uint8_t descr[1024];
145     char buf[1024];
146     int descr_len, dev_descr_len, config_descr_len, nb_interfaces;
147     int bus_num, addr;
148
149     if (usb_host_find_device(&bus_num, &addr, devname) < 0) 
150         return NULL;
151     
152     snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d", 
153              bus_num, addr);
154     fd = open(buf, O_RDWR);
155     if (fd < 0) {
156         perror(buf);
157         return NULL;
158     }
159
160     /* read the config description */
161     descr_len = read(fd, descr, sizeof(descr));
162     if (descr_len <= 0) {
163         perror("read descr");
164         goto fail;
165     }
166     
167     i = 0;
168     dev_descr_len = descr[0];
169     if (dev_descr_len > descr_len)
170         goto fail;
171     i += dev_descr_len;
172     config_descr_len = descr[i];
173     if (i + config_descr_len > descr_len)
174         goto fail;
175     nb_interfaces = descr[i + 4];
176     if (nb_interfaces != 1) {
177         /* NOTE: currently we grab only one interface */
178         fprintf(stderr, "usb_host: only one interface supported\n");
179         goto fail;
180     }
181
182 #ifdef USBDEVFS_DISCONNECT
183     /* earlier Linux 2.4 do not support that */
184     {
185         struct usbdevfs_ioctl ctrl;
186         ctrl.ioctl_code = USBDEVFS_DISCONNECT;
187         ctrl.ifno = 0;
188         ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl);
189         if (ret < 0 && errno != ENODATA) {
190             perror("USBDEVFS_DISCONNECT");
191             goto fail;
192         }
193     }
194 #endif
195
196     /* XXX: only grab if all interfaces are free */
197     interface = 0;
198     ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
199     if (ret < 0) {
200         if (errno == EBUSY) {
201             fprintf(stderr, "usb_host: device already grabbed\n");
202         } else {
203             perror("USBDEVFS_CLAIMINTERFACE");
204         }
205     fail:
206         close(fd);
207         return NULL;
208     }
209
210     ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
211     if (ret < 0) {
212         perror("USBDEVFS_CONNECTINFO");
213         goto fail;
214     }
215
216 #ifdef DEBUG
217     printf("host USB device %d.%d grabbed\n", bus_num, addr);
218 #endif    
219
220     dev = qemu_mallocz(sizeof(USBHostDevice));
221     if (!dev)
222         goto fail;
223     dev->fd = fd;
224     if (ci.slow)
225         dev->dev.speed = USB_SPEED_LOW;
226     else
227         dev->dev.speed = USB_SPEED_HIGH;
228     dev->dev.handle_packet = usb_generic_handle_packet;
229
230     dev->dev.handle_reset = usb_host_handle_reset;
231     dev->dev.handle_control = usb_host_handle_control;
232     dev->dev.handle_data = usb_host_handle_data;
233     return (USBDevice *)dev;
234 }
235
236 static int get_tag_value(char *buf, int buf_size,
237                          const char *str, const char *tag, 
238                          const char *stopchars)
239 {
240     const char *p;
241     char *q;
242     p = strstr(str, tag);
243     if (!p)
244         return -1;
245     p += strlen(tag);
246     while (isspace(*p))
247         p++;
248     q = buf;
249     while (*p != '\0' && !strchr(stopchars, *p)) {
250         if ((q - buf) < (buf_size - 1))
251             *q++ = *p;
252         p++;
253     }
254     *q = '\0';
255     return q - buf;
256 }
257
258 static int usb_host_scan(void *opaque, USBScanFunc *func)
259 {
260     FILE *f;
261     char line[1024];
262     char buf[1024];
263     int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
264     int ret;
265     char product_name[512];
266     
267     f = fopen(USBDEVFS_PATH "/devices", "r");
268     if (!f) {
269         term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
270         return 0;
271     }
272     device_count = 0;
273     bus_num = addr = speed = class_id = product_id = vendor_id = 0;
274     ret = 0;
275     for(;;) {
276         if (fgets(line, sizeof(line), f) == NULL)
277             break;
278         if (strlen(line) > 0)
279             line[strlen(line) - 1] = '\0';
280         if (line[0] == 'T' && line[1] == ':') {
281             if (device_count && (vendor_id || product_id)) {
282                 /* New device.  Add the previously discovered device.  */
283                 ret = func(opaque, bus_num, addr, class_id, vendor_id, 
284                            product_id, product_name, speed);
285                 if (ret)
286                     goto the_end;
287             }
288             if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
289                 goto fail;
290             bus_num = atoi(buf);
291             if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
292                 goto fail;
293             addr = atoi(buf);
294             if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
295                 goto fail;
296             if (!strcmp(buf, "480"))
297                 speed = USB_SPEED_HIGH;
298             else if (!strcmp(buf, "1.5"))
299                 speed = USB_SPEED_LOW;
300             else
301                 speed = USB_SPEED_FULL;
302             product_name[0] = '\0';
303             class_id = 0xff;
304             device_count++;
305             product_id = 0;
306             vendor_id = 0;
307         } else if (line[0] == 'P' && line[1] == ':') {
308             if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
309                 goto fail;
310             vendor_id = strtoul(buf, NULL, 16);
311             if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
312                 goto fail;
313             product_id = strtoul(buf, NULL, 16);
314         } else if (line[0] == 'S' && line[1] == ':') {
315             if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
316                 goto fail;
317             pstrcpy(product_name, sizeof(product_name), buf);
318         } else if (line[0] == 'D' && line[1] == ':') {
319             if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
320                 goto fail;
321             class_id = strtoul(buf, NULL, 16);
322         }
323     fail: ;
324     }
325     if (device_count && (vendor_id || product_id)) {
326         /* Add the last device.  */
327         ret = func(opaque, bus_num, addr, class_id, vendor_id, 
328                    product_id, product_name, speed);
329     }
330  the_end:
331     fclose(f);
332     return ret;
333 }
334
335 typedef struct FindDeviceState {
336     int vendor_id;
337     int product_id;
338     int bus_num;
339     int addr;
340 } FindDeviceState;
341
342 static int usb_host_find_device_scan(void *opaque, int bus_num, int addr, 
343                                      int class_id,
344                                      int vendor_id, int product_id, 
345                                      const char *product_name, int speed)
346 {
347     FindDeviceState *s = opaque;
348     if (vendor_id == s->vendor_id &&
349         product_id == s->product_id) {
350         s->bus_num = bus_num;
351         s->addr = addr;
352         return 1;
353     } else {
354         return 0;
355     }
356 }
357
358 /* the syntax is : 
359    'bus.addr' (decimal numbers) or 
360    'vendor_id:product_id' (hexa numbers) */
361 static int usb_host_find_device(int *pbus_num, int *paddr, 
362                                 const char *devname)
363 {
364     const char *p;
365     int ret;
366     FindDeviceState fs;
367
368     p = strchr(devname, '.');
369     if (p) {
370         *pbus_num = strtoul(devname, NULL, 0);
371         *paddr = strtoul(p + 1, NULL, 0);
372         return 0;
373     }
374     p = strchr(devname, ':');
375     if (p) {
376         fs.vendor_id = strtoul(devname, NULL, 16);
377         fs.product_id = strtoul(p + 1, NULL, 16);
378         ret = usb_host_scan(&fs, usb_host_find_device_scan);
379         if (ret) {
380             *pbus_num = fs.bus_num;
381             *paddr = fs.addr;
382             return 0;
383         }
384     }
385     return -1;
386 }
387
388 /**********************/
389 /* USB host device info */
390
391 struct usb_class_info {
392     int class;
393     const char *class_name;
394 };
395
396 static const struct usb_class_info usb_class_info[] = {
397     { USB_CLASS_AUDIO, "Audio"},
398     { USB_CLASS_COMM, "Communication"},
399     { USB_CLASS_HID, "HID"},
400     { USB_CLASS_HUB, "Hub" },
401     { USB_CLASS_PHYSICAL, "Physical" },
402     { USB_CLASS_PRINTER, "Printer" },
403     { USB_CLASS_MASS_STORAGE, "Storage" },
404     { USB_CLASS_CDC_DATA, "Data" },
405     { USB_CLASS_APP_SPEC, "Application Specific" },
406     { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
407     { USB_CLASS_STILL_IMAGE, "Still Image" },
408     { USB_CLASS_CSCID,  "Smart Card" },
409     { USB_CLASS_CONTENT_SEC, "Content Security" },
410     { -1, NULL }
411 };
412
413 static const char *usb_class_str(uint8_t class)
414 {
415     const struct usb_class_info *p;
416     for(p = usb_class_info; p->class != -1; p++) {
417         if (p->class == class)
418             break;
419     }
420     return p->class_name;
421 }
422
423 void usb_info_device(int bus_num, int addr, int class_id,
424                      int vendor_id, int product_id, 
425                      const char *product_name,
426                      int speed)
427 {
428     const char *class_str, *speed_str;
429
430     switch(speed) {
431     case USB_SPEED_LOW: 
432         speed_str = "1.5"; 
433         break;
434     case USB_SPEED_FULL: 
435         speed_str = "12"; 
436         break;
437     case USB_SPEED_HIGH: 
438         speed_str = "480"; 
439         break;
440     default:
441         speed_str = "?"; 
442         break;
443     }
444
445     term_printf("  Device %d.%d, speed %s Mb/s\n", 
446                 bus_num, addr, speed_str);
447     class_str = usb_class_str(class_id);
448     if (class_str) 
449         term_printf("    %s:", class_str);
450     else
451         term_printf("    Class %02x:", class_id);
452     term_printf(" USB device %04x:%04x", vendor_id, product_id);
453     if (product_name[0] != '\0')
454         term_printf(", %s", product_name);
455     term_printf("\n");
456 }
457
458 static int usb_host_info_device(void *opaque, int bus_num, int addr, 
459                                 int class_id,
460                                 int vendor_id, int product_id, 
461                                 const char *product_name,
462                                 int speed)
463 {
464     usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
465                     product_name, speed);
466     return 0;
467 }
468
469 void usb_host_info(void)
470 {
471     usb_host_scan(NULL, usb_host_info_device);
472 }
473
474 #else
475
476 void usb_host_info(void)
477 {
478     term_printf("USB host devices not supported\n");
479 }
480
481 /* XXX: modify configure to compile the right host driver */
482 USBDevice *usb_host_device_open(const char *devname)
483 {
484     return NULL;
485 }
486
487 #endif