Fix elf loader range checking
[qemu] / usb-bsd.c
1 /*
2  * BSD host USB redirector
3  *
4  * Copyright (c) 2006 Lonnie Mendez
5  * Portions of code and concepts borrowed from
6  * usb-linux.c and libusb's bsd.c and are copyright their respective owners.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26
27 #include "qemu-common.h"
28 #include "monitor.h"
29 #include "hw/usb.h"
30
31 /* usb.h declares these */
32 #undef USB_SPEED_HIGH
33 #undef USB_SPEED_FULL
34 #undef USB_SPEED_LOW
35
36 #include <sys/ioctl.h>
37 #ifndef __DragonFly__
38 #include <dev/usb/usb.h>
39 #else
40 #include <bus/usb/usb.h>
41 #endif
42 #include <signal.h>
43
44 /* This value has maximum potential at 16.
45  * You should also set hw.usb.debug to gain
46  * more detailed view.
47  */
48 //#define DEBUG
49 #define UGEN_DEBUG_LEVEL 0
50
51
52 typedef int USBScanFunc(void *opaque, int bus_num, int addr, int class_id,
53                         int vendor_id, int product_id,
54                         const char *product_name, int speed);
55 static int usb_host_find_device(int *pbus_num, int *paddr,
56                                 const char *devname);
57
58 typedef struct USBHostDevice {
59     USBDevice dev;
60     int ep_fd[USB_MAX_ENDPOINTS];
61     int devfd;
62     char devpath[32];
63 } USBHostDevice;
64
65
66 static int ensure_ep_open(USBHostDevice *dev, int ep, int mode)
67 {
68     char buf[32];
69     int fd;
70
71     /* Get the address for this endpoint */
72     ep = UE_GET_ADDR(ep);
73
74     if (dev->ep_fd[ep] < 0) {
75 #if defined(__FreeBSD__) || defined(__DragonFly__)
76         snprintf(buf, sizeof(buf) - 1, "%s.%d", dev->devpath, ep);
77 #else
78         snprintf(buf, sizeof(buf) - 1, "%s.%02d", dev->devpath, ep);
79 #endif
80         /* Try to open it O_RDWR first for those devices which have in and out
81          * endpoints with the same address (eg 0x02 and 0x82)
82          */
83         fd = open(buf, O_RDWR);
84         if (fd < 0 && errno == ENXIO)
85             fd = open(buf, mode);
86         if (fd < 0) {
87 #ifdef DEBUG
88             printf("ensure_ep_open: failed to open device endpoint %s: %s\n",
89                    buf, strerror(errno));
90 #endif
91         }
92         dev->ep_fd[ep] = fd;
93     }
94
95     return dev->ep_fd[ep];
96 }
97
98 static void ensure_eps_closed(USBHostDevice *dev)
99 {
100     int epnum = 1;
101
102     if (!dev)
103         return;
104
105     while (epnum < USB_MAX_ENDPOINTS) {
106         if (dev->ep_fd[epnum] >= 0) {
107             close(dev->ep_fd[epnum]);
108             dev->ep_fd[epnum] = -1;
109         }
110         epnum++;
111     }
112 }
113
114 static void usb_host_handle_reset(USBDevice *dev)
115 {
116 #if 0
117     USBHostDevice *s = (USBHostDevice *)dev;
118 #endif
119 }
120
121 /* XXX:
122  * -check device states against transfer requests
123  *  and return appropriate response
124  */
125 static int usb_host_handle_control(USBDevice *dev,
126                                    int request,
127                                    int value,
128                                    int index,
129                                    int length,
130                                    uint8_t *data)
131 {
132     USBHostDevice *s = (USBHostDevice *)dev;
133     struct usb_ctl_request req;
134     struct usb_alt_interface aiface;
135     int ret, timeout = 50;
136
137     if ((request >> 8) == UT_WRITE_DEVICE &&
138         (request & 0xff) == UR_SET_ADDRESS) {
139
140         /* specific SET_ADDRESS support */
141         dev->addr = value;
142         return 0;
143     } else if ((request >> 8) == UT_WRITE_DEVICE &&
144                (request & 0xff) == UR_SET_CONFIG) {
145
146         ensure_eps_closed(s); /* can't do this without all eps closed */
147
148         ret = ioctl(s->devfd, USB_SET_CONFIG, &value);
149         if (ret < 0) {
150 #ifdef DEBUG
151             printf("handle_control: failed to set configuration - %s\n",
152                    strerror(errno));
153 #endif
154             return USB_RET_STALL;
155         }
156
157         return 0;
158     } else if ((request >> 8) == UT_WRITE_INTERFACE &&
159                (request & 0xff) == UR_SET_INTERFACE) {
160
161         aiface.uai_interface_index = index;
162         aiface.uai_alt_no = value;
163
164         ensure_eps_closed(s); /* can't do this without all eps closed */
165         ret = ioctl(s->devfd, USB_SET_ALTINTERFACE, &aiface);
166         if (ret < 0) {
167 #ifdef DEBUG
168             printf("handle_control: failed to set alternate interface - %s\n",
169                    strerror(errno));
170 #endif
171             return USB_RET_STALL;
172         }
173
174         return 0;
175     } else {
176         req.ucr_request.bmRequestType = request >> 8;
177         req.ucr_request.bRequest = request & 0xff;
178         USETW(req.ucr_request.wValue, value);
179         USETW(req.ucr_request.wIndex, index);
180         USETW(req.ucr_request.wLength, length);
181         req.ucr_data = data;
182         req.ucr_flags = USBD_SHORT_XFER_OK;
183
184         ret = ioctl(s->devfd, USB_SET_TIMEOUT, &timeout);
185 #if defined(__NetBSD__) || defined(__OpenBSD__)
186         if (ret < 0 && errno != EINVAL) {
187 #else
188         if (ret < 0) {
189 #endif
190 #ifdef DEBUG
191             printf("handle_control: setting timeout failed - %s\n",
192                    strerror(errno));
193 #endif
194         }
195
196         ret = ioctl(s->devfd, USB_DO_REQUEST, &req);
197         /* ugen returns EIO for usbd_do_request_ no matter what
198          * happens with the transfer */
199         if (ret < 0) {
200 #ifdef DEBUG
201             printf("handle_control: error after request - %s\n",
202                    strerror(errno));
203 #endif
204             return USB_RET_NAK; // STALL
205         } else {
206             return req.ucr_actlen;
207         }
208     }
209 }
210
211 static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
212 {
213     USBHostDevice *s = (USBHostDevice *)dev;
214     int ret, fd, mode;
215     int one = 1, shortpacket = 0, timeout = 50;
216     sigset_t new_mask, old_mask;
217     uint8_t devep = p->devep;
218
219     /* protect data transfers from SIGALRM signal */
220     sigemptyset(&new_mask);
221     sigaddset(&new_mask, SIGALRM);
222     sigprocmask(SIG_BLOCK, &new_mask, &old_mask);
223
224     if (p->pid == USB_TOKEN_IN) {
225         devep |= 0x80;
226         mode = O_RDONLY;
227         shortpacket = 1;
228     } else {
229         mode = O_WRONLY;
230     }
231
232     fd = ensure_ep_open(s, devep, mode);
233     if (fd < 0) {
234         sigprocmask(SIG_SETMASK, &old_mask, NULL);
235         return USB_RET_NODEV;
236     }
237
238     if (ioctl(fd, USB_SET_TIMEOUT, &timeout) < 0) {
239 #ifdef DEBUG
240         printf("handle_data: failed to set timeout - %s\n",
241                strerror(errno));
242 #endif
243     }
244
245     if (shortpacket) {
246         if (ioctl(fd, USB_SET_SHORT_XFER, &one) < 0) {
247 #ifdef DEBUG
248             printf("handle_data: failed to set short xfer mode - %s\n",
249                    strerror(errno));
250 #endif
251             sigprocmask(SIG_SETMASK, &old_mask, NULL);
252         }
253     }
254
255     if (p->pid == USB_TOKEN_IN)
256         ret = read(fd, p->data, p->len);
257     else
258         ret = write(fd, p->data, p->len);
259
260     sigprocmask(SIG_SETMASK, &old_mask, NULL);
261
262     if (ret < 0) {
263 #ifdef DEBUG
264         printf("handle_data: error after %s data - %s\n",
265                pid == USB_TOKEN_IN ? "reading" : "writing", strerror(errno));
266 #endif
267         switch(errno) {
268         case ETIMEDOUT:
269         case EINTR:
270             return USB_RET_NAK;
271         default:
272             return USB_RET_STALL;
273         }
274     } else {
275         return ret;
276     }
277 }
278
279 static void usb_host_handle_destroy(USBDevice *opaque)
280 {
281     USBHostDevice *s = (USBHostDevice *)opaque;
282     int i;
283
284     for (i = 0; i < USB_MAX_ENDPOINTS; i++)
285         if (s->ep_fd[i] >= 0)
286             close(s->ep_fd[i]);
287
288     if (s->devfd < 0)
289         return;
290
291     close(s->devfd);
292
293     qemu_free(s);
294 }
295
296 USBDevice *usb_host_device_open(const char *devname)
297 {
298     struct usb_device_info bus_info, dev_info;
299     USBHostDevice *dev;
300     char ctlpath[PATH_MAX + 1];
301     char buspath[PATH_MAX + 1];
302     int bfd, dfd, bus, address, i;
303     int ugendebug = UGEN_DEBUG_LEVEL;
304
305     if (usb_host_find_device(&bus, &address, devname) < 0)
306         return NULL;
307
308     snprintf(buspath, PATH_MAX, "/dev/usb%d", bus);
309
310     bfd = open(buspath, O_RDWR);
311     if (bfd < 0) {
312 #ifdef DEBUG
313         printf("usb_host_device_open: failed to open usb bus - %s\n",
314                strerror(errno));
315 #endif
316         return NULL;
317     }
318
319     bus_info.udi_addr = address;
320     if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0) {
321 #ifdef DEBUG
322         printf("usb_host_device_open: failed to grab bus information - %s\n",
323                strerror(errno));
324 #endif
325         return NULL;
326     }
327
328 #if defined(__FreeBSD__) || defined(__DragonFly__)
329     snprintf(ctlpath, PATH_MAX, "/dev/%s", bus_info.udi_devnames[0]);
330 #else
331     snprintf(ctlpath, PATH_MAX, "/dev/%s.00", bus_info.udi_devnames[0]);
332 #endif
333
334     dfd  = open(ctlpath, O_RDWR);
335     if (dfd < 0) {
336         dfd = open(ctlpath, O_RDONLY);
337         if (dfd < 0) {
338 #ifdef DEBUG
339             printf("usb_host_device_open: failed to open usb device %s - %s\n",
340                    ctlpath, strerror(errno));
341 #endif
342         }
343     }
344
345     if (dfd >= 0) {
346         dev = qemu_mallocz(sizeof(USBHostDevice));
347         dev->devfd = dfd;
348
349         if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0) {
350 #ifdef DEBUG
351             printf("usb_host_device_open: failed to grab device info - %s\n",
352                    strerror(errno));
353 #endif
354             goto fail;
355         }
356
357         if (dev_info.udi_speed == 1)
358             dev->dev.speed = USB_SPEED_LOW - 1;
359         else
360             dev->dev.speed = USB_SPEED_FULL - 1;
361
362         dev->dev.handle_packet = usb_generic_handle_packet;
363
364         dev->dev.handle_reset = usb_host_handle_reset;
365         dev->dev.handle_control = usb_host_handle_control;
366         dev->dev.handle_data = usb_host_handle_data;
367         dev->dev.handle_destroy = usb_host_handle_destroy;
368
369         if (strncmp(dev_info.udi_product, "product", 7) != 0)
370             pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
371                     dev_info.udi_product);
372         else
373             snprintf(dev->dev.devname, sizeof(dev->dev.devname),
374                      "host:%s", devname);
375
376         pstrcpy(dev->devpath, sizeof(dev->devpath), "/dev/");
377         pstrcat(dev->devpath, sizeof(dev->devpath), dev_info.udi_devnames[0]);
378
379         /* Mark the endpoints as not yet open */
380         for (i = 0; i < USB_MAX_ENDPOINTS; i++)
381            dev->ep_fd[i] = -1;
382
383         ioctl(dfd, USB_SETDEBUG, &ugendebug);
384
385         return (USBDevice *)dev;
386     }
387
388 fail:
389     return NULL;
390 }
391
392 static int usb_host_scan(void *opaque, USBScanFunc *func)
393 {
394     struct usb_device_info bus_info;
395     struct usb_device_info dev_info;
396     uint16_t vendor_id, product_id, class_id, speed;
397     int bfd, dfd, bus, address;
398     char busbuf[20], devbuf[20], product_name[256];
399     int ret = 0;
400
401     for (bus = 0; bus < 10; bus++) {
402
403         snprintf(busbuf, sizeof(busbuf) - 1, "/dev/usb%d", bus);
404         bfd = open(busbuf, O_RDWR);
405         if (bfd < 0)
406             continue;
407
408         for (address = 1; address < 127; address++) {
409
410             bus_info.udi_addr = address;
411             if (ioctl(bfd, USB_DEVICEINFO, &bus_info) < 0)
412                 continue;
413
414             /* only list devices that can be used by generic layer */
415             if (strncmp(bus_info.udi_devnames[0], "ugen", 4) != 0)
416                 continue;
417
418 #if defined(__FreeBSD__) || defined(__DragonFly__)
419             snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s", bus_info.udi_devnames[0]);
420 #else
421             snprintf(devbuf, sizeof(devbuf) - 1, "/dev/%s.00", bus_info.udi_devnames[0]);
422 #endif
423
424             dfd = open(devbuf, O_RDONLY);
425             if (dfd < 0) {
426 #ifdef DEBUG
427                 printf("usb_host_scan: couldn't open device %s - %s\n", devbuf,
428                        strerror(errno));
429 #endif
430                 continue;
431             }
432
433             if (ioctl(dfd, USB_GET_DEVICEINFO, &dev_info) < 0)
434                 printf("usb_host_scan: couldn't get device information for %s - %s\n",
435                        devbuf, strerror(errno));
436
437             // XXX: might need to fixup endianess of word values before copying over
438
439             vendor_id = dev_info.udi_vendorNo;
440             product_id = dev_info.udi_productNo;
441             class_id = dev_info.udi_class;
442             speed = dev_info.udi_speed;
443
444             if (strncmp(dev_info.udi_product, "product", 7) != 0)
445                 pstrcpy(product_name, sizeof(product_name),
446                         dev_info.udi_product);
447             else
448                 product_name[0] = '\0';
449
450             ret = func(opaque, bus, address, class_id, vendor_id,
451                        product_id, product_name, speed);
452
453             close(dfd);
454
455             if (ret)
456                 goto the_end;
457         }
458
459         close(bfd);
460     }
461
462 the_end:
463     return ret;
464 }
465
466 typedef struct FindDeviceState {
467     int vendor_id;
468     int product_id;
469     int bus_num;
470     int addr;
471 } FindDeviceState;
472
473 static int usb_host_find_device_scan(void *opaque, int bus_num, int addr,
474                                      int class_id,
475                                      int vendor_id, int product_id,
476                                      const char *product_name, int speed)
477 {
478     FindDeviceState *s = opaque;
479     if (vendor_id == s->vendor_id &&
480         product_id == s->product_id) {
481         s->bus_num = bus_num;
482         s->addr = addr;
483         return 1;
484      } else {
485         return 0;
486      }
487 }
488
489
490 /* the syntax is :
491    'bus.addr' (decimal numbers) or
492    'vendor_id:product_id' (hexa numbers) */
493 static int usb_host_find_device(int *pbus_num, int *paddr,
494                                 const char *devname)
495 {
496     const char *p;
497     int ret;
498     FindDeviceState fs;
499
500     p = strchr(devname, '.');
501     if (p) {
502         *pbus_num = strtoul(devname, NULL, 0);
503         *paddr = strtoul(p + 1, NULL, 0);
504         return 0;
505     }
506     p = strchr(devname, ':');
507     if (p) {
508         fs.vendor_id = strtoul(devname, NULL, 16);
509         fs.product_id = strtoul(p + 1, NULL, 16);
510         ret = usb_host_scan(&fs, usb_host_find_device_scan);
511         if (ret) {
512             *pbus_num = fs.bus_num;
513             *paddr = fs.addr;
514             return 0;
515         }
516      }
517      return -1;
518 }
519
520 /**********************/
521 /* USB host device info */
522
523 struct usb_class_info {
524     int class;
525     const char *class_name;
526 };
527
528 static const struct usb_class_info usb_class_info[] = {
529     { USB_CLASS_AUDIO, "Audio"},
530     { USB_CLASS_COMM, "Communication"},
531     { USB_CLASS_HID, "HID"},
532     { USB_CLASS_HUB, "Hub" },
533     { USB_CLASS_PHYSICAL, "Physical" },
534     { USB_CLASS_PRINTER, "Printer" },
535     { USB_CLASS_MASS_STORAGE, "Storage" },
536     { USB_CLASS_CDC_DATA, "Data" },
537     { USB_CLASS_APP_SPEC, "Application Specific" },
538     { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
539     { USB_CLASS_STILL_IMAGE, "Still Image" },
540     { USB_CLASS_CSCID, "Smart Card" },
541     { USB_CLASS_CONTENT_SEC, "Content Security" },
542     { -1, NULL }
543 };
544
545 static const char *usb_class_str(uint8_t class)
546 {
547     const struct usb_class_info *p;
548     for (p = usb_class_info; p->class != -1; p++) {
549         if (p->class == class)
550             break;
551     }
552     return p->class_name;
553 }
554
555 static void usb_info_device(int bus_num, int addr, int class_id,
556                             int vendor_id, int product_id,
557                             const char *product_name,
558                             int speed)
559 {
560     const char *class_str, *speed_str;
561     Monitor *mon = cur_mon;
562
563     switch(speed) {
564     case USB_SPEED_LOW:
565         speed_str = "1.5";
566         break;
567     case USB_SPEED_FULL:
568         speed_str = "12";
569         break;
570     case USB_SPEED_HIGH:
571         speed_str = "480";
572         break;
573     default:
574         speed_str = "?";
575         break;
576     }
577
578     monitor_printf(mon, "  Device %d.%d, speed %s Mb/s\n",
579                    bus_num, addr, speed_str);
580     class_str = usb_class_str(class_id);
581     if (class_str)
582         monitor_printf(mon, "    %s:", class_str);
583     else
584         monitor_printf(mon, "    Class %02x:", class_id);
585     monitor_printf(mon, " USB device %04x:%04x", vendor_id, product_id);
586     if (product_name[0] != '\0')
587         monitor_printf(mon, ", %s", product_name);
588     monitor_printf(mon, "\n");
589 }
590
591 static int usb_host_info_device(void *opaque,
592                                 int bus_num, int addr,
593                                 int class_id,
594                                 int vendor_id, int product_id,
595                                 const char *product_name,
596                                 int speed)
597 {
598     usb_info_device(bus_num, addr, class_id, vendor_id, product_id,
599                     product_name, speed);
600     return 0;
601 }
602
603 void usb_host_info(Monitor *mon)
604 {
605     usb_host_scan(NULL, usb_host_info_device);
606 }
607
608 /* XXX add this */
609 int usb_host_device_close(const char *devname)
610 {
611     return 0;
612 }