Commit b9dc033c0dea8e1113110a903799c5b31bb2104d

Authored by balrog
1 parent 80f515e6

USB iso transfers support for the linux redirector and for UHCI, by Arnon Gilboa.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3328 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 621 additions and 89 deletions
hw/usb-uhci.c
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
25 25
26 //#define DEBUG 26 //#define DEBUG
27 //#define DEBUG_PACKET 27 //#define DEBUG_PACKET
  28 +//#define DEBUG_ISOCH
28 29
29 #define UHCI_CMD_FGR (1 << 4) 30 #define UHCI_CMD_FGR (1 << 4)
30 #define UHCI_CMD_EGSM (1 << 3) 31 #define UHCI_CMD_EGSM (1 << 3)
@@ -88,6 +89,7 @@ typedef struct UHCIState { @@ -88,6 +89,7 @@ typedef struct UHCIState {
88 other queues will not be processed until the next frame. The solution 89 other queues will not be processed until the next frame. The solution
89 is to allow multiple pending requests. */ 90 is to allow multiple pending requests. */
90 uint32_t async_qh; 91 uint32_t async_qh;
  92 + uint32_t async_frame_addr;
91 USBPacket usb_packet; 93 USBPacket usb_packet;
92 uint8_t usb_buf[2048]; 94 uint8_t usb_buf[2048];
93 } UHCIState; 95 } UHCIState;
@@ -146,6 +148,58 @@ static void uhci_reset(UHCIState *s) @@ -146,6 +148,58 @@ static void uhci_reset(UHCIState *s)
146 } 148 }
147 } 149 }
148 150
  151 +static void uhci_save(QEMUFile *f, void *opaque)
  152 +{
  153 + UHCIState *s = opaque;
  154 + uint8_t num_ports = NB_PORTS;
  155 + int i;
  156 +
  157 + pci_device_save(&s->dev, f);
  158 +
  159 + qemu_put_8s(f, &num_ports);
  160 + for (i = 0; i < num_ports; ++i)
  161 + qemu_put_be16s(f, &s->ports[i].ctrl);
  162 + qemu_put_be16s(f, &s->cmd);
  163 + qemu_put_be16s(f, &s->status);
  164 + qemu_put_be16s(f, &s->intr);
  165 + qemu_put_be16s(f, &s->frnum);
  166 + qemu_put_be32s(f, &s->fl_base_addr);
  167 + qemu_put_8s(f, &s->sof_timing);
  168 + qemu_put_8s(f, &s->status2);
  169 + qemu_put_timer(f, s->frame_timer);
  170 +}
  171 +
  172 +static int uhci_load(QEMUFile *f, void *opaque, int version_id)
  173 +{
  174 + UHCIState *s = opaque;
  175 + uint8_t num_ports;
  176 + int i, ret;
  177 +
  178 + if (version_id > 1)
  179 + return -EINVAL;
  180 +
  181 + ret = pci_device_load(&s->dev, f);
  182 + if (ret < 0)
  183 + return ret;
  184 +
  185 + qemu_get_8s(f, &num_ports);
  186 + if (num_ports != NB_PORTS)
  187 + return -EINVAL;
  188 +
  189 + for (i = 0; i < num_ports; ++i)
  190 + qemu_get_be16s(f, &s->ports[i].ctrl);
  191 + qemu_get_be16s(f, &s->cmd);
  192 + qemu_get_be16s(f, &s->status);
  193 + qemu_get_be16s(f, &s->intr);
  194 + qemu_get_be16s(f, &s->frnum);
  195 + qemu_get_be32s(f, &s->fl_base_addr);
  196 + qemu_get_8s(f, &s->sof_timing);
  197 + qemu_get_8s(f, &s->status2);
  198 + qemu_get_timer(f, s->frame_timer);
  199 +
  200 + return 0;
  201 +}
  202 +
149 static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) 203 static void uhci_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
150 { 204 {
151 UHCIState *s = opaque; 205 UHCIState *s = opaque;
@@ -449,10 +503,11 @@ static void uhci_async_complete_packet(USBPacket * packet, void *opaque); @@ -449,10 +503,11 @@ static void uhci_async_complete_packet(USBPacket * packet, void *opaque);
449 0 if TD successful 503 0 if TD successful
450 1 if TD unsuccessful or inactive 504 1 if TD unsuccessful or inactive
451 */ 505 */
452 -static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask) 506 +static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask,
  507 + int completion)
453 { 508 {
454 uint8_t pid; 509 uint8_t pid;
455 - int len, max_len, err, ret; 510 + int len = 0, max_len, err, ret = 0;
456 511
457 /* ??? This is wrong for async completion. */ 512 /* ??? This is wrong for async completion. */
458 if (td->ctrl & TD_CTRL_IOC) { 513 if (td->ctrl & TD_CTRL_IOC) {
@@ -465,7 +520,8 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask) @@ -465,7 +520,8 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
465 /* TD is active */ 520 /* TD is active */
466 max_len = ((td->token >> 21) + 1) & 0x7ff; 521 max_len = ((td->token >> 21) + 1) & 0x7ff;
467 pid = td->token & 0xff; 522 pid = td->token & 0xff;
468 - if (s->async_qh) { 523 +
  524 + if (completion && (s->async_qh || s->async_frame_addr)) {
469 ret = s->usb_packet.len; 525 ret = s->usb_packet.len;
470 if (ret >= 0) { 526 if (ret >= 0) {
471 len = ret; 527 len = ret;
@@ -481,7 +537,8 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask) @@ -481,7 +537,8 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
481 len = 0; 537 len = 0;
482 } 538 }
483 s->async_qh = 0; 539 s->async_qh = 0;
484 - } else { 540 + s->async_frame_addr = 0;
  541 + } else if (!completion) {
485 s->usb_packet.pid = pid; 542 s->usb_packet.pid = pid;
486 s->usb_packet.devaddr = (td->token >> 8) & 0x7f; 543 s->usb_packet.devaddr = (td->token >> 8) & 0x7f;
487 s->usb_packet.devep = (td->token >> 15) & 0xf; 544 s->usb_packet.devep = (td->token >> 15) & 0xf;
@@ -519,6 +576,7 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask) @@ -519,6 +576,7 @@ static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
519 return -1; 576 return -1;
520 } 577 }
521 } 578 }
  579 +
522 if (ret == USB_RET_ASYNC) { 580 if (ret == USB_RET_ASYNC) {
523 return 2; 581 return 2;
524 } 582 }
@@ -584,8 +642,42 @@ static void uhci_async_complete_packet(USBPacket * packet, void *opaque) @@ -584,8 +642,42 @@ static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
584 uint32_t link; 642 uint32_t link;
585 uint32_t old_td_ctrl; 643 uint32_t old_td_ctrl;
586 uint32_t val; 644 uint32_t val;
  645 + uint32_t frame_addr;
587 int ret; 646 int ret;
588 647
  648 + /* Handle async isochronous packet completion */
  649 + frame_addr = s->async_frame_addr;
  650 + if (frame_addr) {
  651 + cpu_physical_memory_read(frame_addr, (uint8_t *)&link, 4);
  652 + le32_to_cpus(&link);
  653 +
  654 + cpu_physical_memory_read(link & ~0xf, (uint8_t *)&td, sizeof(td));
  655 + le32_to_cpus(&td.link);
  656 + le32_to_cpus(&td.ctrl);
  657 + le32_to_cpus(&td.token);
  658 + le32_to_cpus(&td.buffer);
  659 + old_td_ctrl = td.ctrl;
  660 + ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
  661 +
  662 + /* update the status bits of the TD */
  663 + if (old_td_ctrl != td.ctrl) {
  664 + val = cpu_to_le32(td.ctrl);
  665 + cpu_physical_memory_write((link & ~0xf) + 4,
  666 + (const uint8_t *)&val,
  667 + sizeof(val));
  668 + }
  669 + if (ret == 2) {
  670 + s->async_frame_addr = frame_addr;
  671 + } else if (ret == 0) {
  672 + /* update qh element link */
  673 + val = cpu_to_le32(td.link);
  674 + cpu_physical_memory_write(frame_addr,
  675 + (const uint8_t *)&val,
  676 + sizeof(val));
  677 + }
  678 + return;
  679 + }
  680 +
589 link = s->async_qh; 681 link = s->async_qh;
590 if (!link) { 682 if (!link) {
591 /* This should never happen. It means a TD somehow got removed 683 /* This should never happen. It means a TD somehow got removed
@@ -604,7 +696,8 @@ static void uhci_async_complete_packet(USBPacket * packet, void *opaque) @@ -604,7 +696,8 @@ static void uhci_async_complete_packet(USBPacket * packet, void *opaque)
604 le32_to_cpus(&td.token); 696 le32_to_cpus(&td.token);
605 le32_to_cpus(&td.buffer); 697 le32_to_cpus(&td.buffer);
606 old_td_ctrl = td.ctrl; 698 old_td_ctrl = td.ctrl;
607 - ret = uhci_handle_td(s, &td, &s->pending_int_mask); 699 + ret = uhci_handle_td(s, &td, &s->pending_int_mask, 1);
  700 +
608 /* update the status bits of the TD */ 701 /* update the status bits of the TD */
609 if (old_td_ctrl != td.ctrl) { 702 if (old_td_ctrl != td.ctrl) {
610 val = cpu_to_le32(td.ctrl); 703 val = cpu_to_le32(td.ctrl);
@@ -697,7 +790,8 @@ static void uhci_frame_timer(void *opaque) @@ -697,7 +790,8 @@ static void uhci_frame_timer(void *opaque)
697 le32_to_cpus(&td.token); 790 le32_to_cpus(&td.token);
698 le32_to_cpus(&td.buffer); 791 le32_to_cpus(&td.buffer);
699 old_td_ctrl = td.ctrl; 792 old_td_ctrl = td.ctrl;
700 - ret = uhci_handle_td(s, &td, &int_mask); 793 + ret = uhci_handle_td(s, &td, &int_mask, 0);
  794 +
701 /* update the status bits of the TD */ 795 /* update the status bits of the TD */
702 if (old_td_ctrl != td.ctrl) { 796 if (old_td_ctrl != td.ctrl) {
703 val = cpu_to_le32(td.ctrl); 797 val = cpu_to_le32(td.ctrl);
@@ -731,27 +825,23 @@ static void uhci_frame_timer(void *opaque) @@ -731,27 +825,23 @@ static void uhci_frame_timer(void *opaque)
731 le32_to_cpus(&td.ctrl); 825 le32_to_cpus(&td.ctrl);
732 le32_to_cpus(&td.token); 826 le32_to_cpus(&td.token);
733 le32_to_cpus(&td.buffer); 827 le32_to_cpus(&td.buffer);
734 - /* Ignore isochonous transfers while there is an async packet  
735 - pending. This is wrong, but we don't implement isochronous  
736 - transfers anyway. */  
737 - if (s->async_qh == 0) {  
738 - old_td_ctrl = td.ctrl;  
739 - ret = uhci_handle_td(s, &td, &int_mask);  
740 - /* update the status bits of the TD */  
741 - if (old_td_ctrl != td.ctrl) {  
742 - val = cpu_to_le32(td.ctrl);  
743 - cpu_physical_memory_write((link & ~0xf) + 4,  
744 - (const uint8_t *)&val,  
745 - sizeof(val));  
746 - }  
747 - if (ret < 0)  
748 - break; /* interrupted frame */  
749 - if (ret == 2) {  
750 - /* We can't handle async isochronous transfers.  
751 - Cancel The packet. */  
752 - fprintf(stderr, "usb-uhci: Unimplemented async packet\n");  
753 - usb_cancel_packet(&s->usb_packet);  
754 - } 828 +
  829 + /* Handle isochonous transfer. */
  830 + /* FIXME: might be more than one isoc in frame */
  831 + old_td_ctrl = td.ctrl;
  832 + ret = uhci_handle_td(s, &td, &int_mask, 0);
  833 +
  834 + /* update the status bits of the TD */
  835 + if (old_td_ctrl != td.ctrl) {
  836 + val = cpu_to_le32(td.ctrl);
  837 + cpu_physical_memory_write((link & ~0xf) + 4,
  838 + (const uint8_t *)&val,
  839 + sizeof(val));
  840 + }
  841 + if (ret < 0)
  842 + break; /* interrupted frame */
  843 + if (ret == 2) {
  844 + s->async_frame_addr = frame_addr;
755 } 845 }
756 link = td.link; 846 link = td.link;
757 } 847 }
@@ -767,6 +857,7 @@ static void uhci_frame_timer(void *opaque) @@ -767,6 +857,7 @@ static void uhci_frame_timer(void *opaque)
767 usb_cancel_packet(&s->usb_packet); 857 usb_cancel_packet(&s->usb_packet);
768 s->async_qh = 0; 858 s->async_qh = 0;
769 } 859 }
  860 +
770 /* prepare the timer for the next frame */ 861 /* prepare the timer for the next frame */
771 expire_time = qemu_get_clock(vm_clock) + 862 expire_time = qemu_get_clock(vm_clock) +
772 (ticks_per_sec / FRAME_TIMER_FREQ); 863 (ticks_per_sec / FRAME_TIMER_FREQ);
@@ -855,4 +946,3 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn) @@ -855,4 +946,3 @@ void usb_uhci_piix4_init(PCIBus *bus, int devfn)
855 pci_register_io_region(&s->dev, 4, 0x20, 946 pci_register_io_region(&s->dev, 4, 0x20,
856 PCI_ADDRESS_SPACE_IO, uhci_map); 947 PCI_ADDRESS_SPACE_IO, uhci_map);
857 } 948 }
858 -  
usb-linux.c
@@ -28,6 +28,7 @@ @@ -28,6 +28,7 @@
28 #include <sys/ioctl.h> 28 #include <sys/ioctl.h>
29 #include <linux/usbdevice_fs.h> 29 #include <linux/usbdevice_fs.h>
30 #include <linux/version.h> 30 #include <linux/version.h>
  31 +#include <signal.h>
31 32
32 /* We redefine it to avoid version problems */ 33 /* We redefine it to avoid version problems */
33 struct usb_ctrltransfer { 34 struct usb_ctrltransfer {
@@ -48,15 +49,172 @@ static int usb_host_find_device(int *pbus_num, int *paddr, @@ -48,15 +49,172 @@ static int usb_host_find_device(int *pbus_num, int *paddr,
48 const char *devname); 49 const char *devname);
49 50
50 //#define DEBUG 51 //#define DEBUG
  52 +//#define DEBUG_ISOCH
  53 +//#define USE_ASYNCIO
51 54
52 #define USBDEVFS_PATH "/proc/bus/usb" 55 #define USBDEVFS_PATH "/proc/bus/usb"
53 #define PRODUCT_NAME_SZ 32 56 #define PRODUCT_NAME_SZ 32
  57 +#define SIG_ISOCOMPLETE (SIGRTMIN+7)
  58 +#define MAX_ENDPOINTS 16
54 59
  60 +struct sigaction sigact;
  61 +
  62 +/* endpoint association data */
  63 +struct endp_data {
  64 + uint8_t type;
  65 +};
  66 +
  67 +/* FIXME: move USBPacket to PendingURB */
55 typedef struct USBHostDevice { 68 typedef struct USBHostDevice {
56 USBDevice dev; 69 USBDevice dev;
57 int fd; 70 int fd;
  71 + USBPacket *packet;
  72 + struct endp_data endp_table[MAX_ENDPOINTS];
  73 + int configuration;
  74 + uint8_t descr[1024];
  75 + int descr_len;
  76 + int urbs_ready;
58 } USBHostDevice; 77 } USBHostDevice;
59 78
  79 +typedef struct PendingURB {
  80 + struct usbdevfs_urb *urb;
  81 + USBHostDevice *dev;
  82 + QEMUBH *bh;
  83 + int status;
  84 + struct PendingURB *next;
  85 +} PendingURB;
  86 +
  87 +PendingURB *pending_urbs = NULL;
  88 +
  89 +int add_pending_urb(struct usbdevfs_urb *urb)
  90 +{
  91 + PendingURB *purb = qemu_mallocz(sizeof(PendingURB));
  92 + if (purb) {
  93 + purb->urb = urb;
  94 + purb->dev = NULL;
  95 + purb->bh = NULL;
  96 + purb->status = 0;
  97 + purb->next = pending_urbs;
  98 + pending_urbs = purb;
  99 + return 1;
  100 + }
  101 + return 0;
  102 +}
  103 +
  104 +int del_pending_urb(struct usbdevfs_urb *urb)
  105 +{
  106 + PendingURB *purb = pending_urbs;
  107 + PendingURB *prev = NULL;
  108 +
  109 + while (purb && purb->urb != urb) {
  110 + prev = purb;
  111 + purb = purb->next;
  112 + }
  113 +
  114 + if (purb && purb->urb == urb) {
  115 + if (prev) {
  116 + prev->next = purb->next;
  117 + } else {
  118 + pending_urbs = purb->next;
  119 + }
  120 + qemu_free(purb);
  121 + return 1;
  122 + }
  123 + return 0;
  124 +}
  125 +
  126 +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 +
  140 +static int usb_host_update_interfaces(USBHostDevice *dev, int configuration)
  141 +{
  142 + int dev_descr_len, config_descr_len;
  143 + int interface, nb_interfaces, nb_configurations;
  144 + int ret, i;
  145 +
  146 + if (configuration == 0) /* address state - ignore */
  147 + return 1;
  148 +
  149 + i = 0;
  150 + dev_descr_len = dev->descr[0];
  151 + if (dev_descr_len > dev->descr_len)
  152 + goto fail;
  153 + nb_configurations = dev->descr[17];
  154 +
  155 + i += dev_descr_len;
  156 + while (i < dev->descr_len) {
  157 +#ifdef DEBUG
  158 + printf("i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len,
  159 + dev->descr[i], dev->descr[i+1]);
  160 +#endif
  161 + if (dev->descr[i+1] != USB_DT_CONFIG) {
  162 + i += dev->descr[i];
  163 + continue;
  164 + }
  165 + config_descr_len = dev->descr[i];
  166 +
  167 + if (configuration == dev->descr[i + 5])
  168 + break;
  169 +
  170 + i += config_descr_len;
  171 + }
  172 +
  173 + if (i >= dev->descr_len) {
  174 + printf("usb_host: error - device has no matching configuration\n");
  175 + goto fail;
  176 + }
  177 + nb_interfaces = dev->descr[i + 4];
  178 +
  179 +#ifdef USBDEVFS_DISCONNECT
  180 + /* earlier Linux 2.4 do not support that */
  181 + {
  182 + struct usbdevfs_ioctl ctrl;
  183 + for (interface = 0; interface < nb_interfaces; interface++) {
  184 + ctrl.ioctl_code = USBDEVFS_DISCONNECT;
  185 + ctrl.ifno = interface;
  186 + ret = ioctl(dev->fd, USBDEVFS_IOCTL, &ctrl);
  187 + if (ret < 0 && errno != ENODATA) {
  188 + perror("USBDEVFS_DISCONNECT");
  189 + goto fail;
  190 + }
  191 + }
  192 + }
  193 +#endif
  194 +
  195 + /* XXX: only grab if all interfaces are free */
  196 + for (interface = 0; interface < nb_interfaces; interface++) {
  197 + ret = ioctl(dev->fd, USBDEVFS_CLAIMINTERFACE, &interface);
  198 + if (ret < 0) {
  199 + if (errno == EBUSY) {
  200 + fprintf(stderr,
  201 + "usb_host: warning - device already grabbed\n");
  202 + } else {
  203 + perror("USBDEVFS_CLAIMINTERFACE");
  204 + }
  205 + fail:
  206 + return 0;
  207 + }
  208 + }
  209 +
  210 +#ifdef DEBUG
  211 + printf("usb_host: %d interfaces claimed for configuration %d\n",
  212 + nb_interfaces, configuration);
  213 +#endif
  214 +
  215 + return 1;
  216 +}
  217 +
60 static void usb_host_handle_reset(USBDevice *dev) 218 static void usb_host_handle_reset(USBDevice *dev)
61 { 219 {
62 #if 0 220 #if 0
@@ -76,6 +234,8 @@ static void usb_host_handle_destroy(USBDevice *dev) @@ -76,6 +234,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
76 qemu_free(s); 234 qemu_free(s);
77 } 235 }
78 236
  237 +static int usb_linux_update_endp_table(USBHostDevice *s);
  238 +
79 static int usb_host_handle_control(USBDevice *dev, 239 static int usb_host_handle_control(USBDevice *dev,
80 int request, 240 int request,
81 int value, 241 int value,
@@ -85,13 +245,33 @@ static int usb_host_handle_control(USBDevice *dev, @@ -85,13 +245,33 @@ static int usb_host_handle_control(USBDevice *dev,
85 { 245 {
86 USBHostDevice *s = (USBHostDevice *)dev; 246 USBHostDevice *s = (USBHostDevice *)dev;
87 struct usb_ctrltransfer ct; 247 struct usb_ctrltransfer ct;
  248 + struct usbdevfs_setinterface si;
  249 + int intf_update_required = 0;
88 int ret; 250 int ret;
89 251
90 if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) { 252 if (request == (DeviceOutRequest | USB_REQ_SET_ADDRESS)) {
91 /* specific SET_ADDRESS support */ 253 /* specific SET_ADDRESS support */
92 dev->addr = value; 254 dev->addr = value;
93 return 0; 255 return 0;
  256 + } else if (request == ((USB_RECIP_INTERFACE << 8) |
  257 + USB_REQ_SET_INTERFACE)) {
  258 + /* set alternate setting for the interface */
  259 + si.interface = index;
  260 + si.altsetting = value;
  261 + ret = ioctl(s->fd, USBDEVFS_SETINTERFACE, &si);
  262 + usb_linux_update_endp_table(s);
  263 + } else if (request == (DeviceOutRequest | USB_REQ_SET_CONFIGURATION)) {
  264 +#ifdef DEBUG
  265 + printf("usb_host_handle_control: SET_CONFIGURATION request - "
  266 + "config %d\n", value & 0xff);
  267 +#endif
  268 + if (s->configuration != (value & 0xff)) {
  269 + s->configuration = (value & 0xff);
  270 + intf_update_required = 1;
  271 + }
  272 + goto do_request;
94 } else { 273 } else {
  274 + do_request:
95 ct.bRequestType = request >> 8; 275 ct.bRequestType = request >> 8;
96 ct.bRequest = request; 276 ct.bRequest = request;
97 ct.wValue = value; 277 ct.wValue = value;
@@ -100,19 +280,28 @@ static int usb_host_handle_control(USBDevice *dev, @@ -100,19 +280,28 @@ static int usb_host_handle_control(USBDevice *dev,
100 ct.timeout = 50; 280 ct.timeout = 50;
101 ct.data = data; 281 ct.data = data;
102 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct); 282 ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
103 - if (ret < 0) {  
104 - switch(errno) {  
105 - case ETIMEDOUT:  
106 - return USB_RET_NAK;  
107 - default:  
108 - return USB_RET_STALL;  
109 - }  
110 - } else {  
111 - return ret; 283 + }
  284 +
  285 + if (ret < 0) {
  286 + switch(errno) {
  287 + case ETIMEDOUT:
  288 + return USB_RET_NAK;
  289 + default:
  290 + return USB_RET_STALL;
  291 + }
  292 + } else {
  293 + if (intf_update_required) {
  294 +#ifdef DEBUG
  295 + printf("usb_host_handle_control: updating interfaces\n");
  296 +#endif
  297 + usb_host_update_interfaces(s, value & 0xff);
112 } 298 }
113 - } 299 + return ret;
  300 + }
114 } 301 }
115 302
  303 +static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p);
  304 +
116 static int usb_host_handle_data(USBDevice *dev, USBPacket *p) 305 static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
117 { 306 {
118 USBHostDevice *s = (USBHostDevice *)dev; 307 USBHostDevice *s = (USBHostDevice *)dev;
@@ -120,6 +309,10 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p) @@ -120,6 +309,10 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
120 int ret; 309 int ret;
121 uint8_t devep = p->devep; 310 uint8_t devep = p->devep;
122 311
  312 + if (s->endp_table[p->devep - 1].type == USBDEVFS_URB_TYPE_ISO) {
  313 + return usb_host_handle_isoch(dev, p);
  314 + }
  315 +
123 /* XXX: optimize and handle all data types by looking at the 316 /* XXX: optimize and handle all data types by looking at the
124 config descriptor */ 317 config descriptor */
125 if (p->pid == USB_TOKEN_IN) 318 if (p->pid == USB_TOKEN_IN)
@@ -145,18 +338,276 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p) @@ -145,18 +338,276 @@ static int usb_host_handle_data(USBDevice *dev, USBPacket *p)
145 } 338 }
146 } 339 }
147 340
  341 +static void usb_linux_bh_cb(void *opaque);
  342 +
  343 +void isoch_done(int signum, siginfo_t *info, void *context) {
  344 + struct usbdevfs_urb *urb = (struct usbdevfs_urb *)info->si_addr;
  345 + USBHostDevice *s = (USBHostDevice *)urb->usercontext;
  346 + PendingURB *purb;
  347 +
  348 + if (info->si_code != SI_ASYNCIO ||
  349 + info->si_signo != SIG_ISOCOMPLETE) {
  350 + return;
  351 + }
  352 +
  353 + purb = get_pending_urb(urb);
  354 + if (purb) {
  355 + purb->bh = qemu_bh_new(usb_linux_bh_cb, purb);
  356 + if (purb->bh) {
  357 + purb->dev = s;
  358 + purb->status = info->si_errno;
  359 + qemu_bh_schedule(purb->bh);
  360 + }
  361 + }
  362 +}
  363 +
  364 +static int usb_host_handle_isoch(USBDevice *dev, USBPacket *p)
  365 +{
  366 + USBHostDevice *s = (USBHostDevice *)dev;
  367 + struct usbdevfs_urb *urb, *purb = NULL;
  368 + int ret;
  369 + uint8_t devep = p->devep;
  370 +
  371 + if (p->pid == USB_TOKEN_IN)
  372 + devep |= 0x80;
  373 +
  374 + urb = qemu_mallocz(sizeof(struct usbdevfs_urb) +
  375 + sizeof(struct usbdevfs_iso_packet_desc));
  376 + if (!urb) {
  377 + printf("usb_host_handle_isoch: malloc failed\n");
  378 + return 0;
  379 + }
  380 +
  381 + urb->type = USBDEVFS_URB_TYPE_ISO;
  382 + urb->endpoint = devep;
  383 + urb->status = 0;
  384 + urb->flags = USBDEVFS_URB_ISO_ASAP;
  385 + urb->buffer = p->data;
  386 + urb->buffer_length = p->len;
  387 + urb->actual_length = 0;
  388 + urb->start_frame = 0;
  389 + urb->error_count = 0;
  390 +#ifdef USE_ASYNCIO
  391 + urb->signr = SIG_ISOCOMPLETE;
  392 +#else
  393 + urb->signr = 0;
  394 +#endif
  395 + urb->usercontext = s;
  396 + urb->number_of_packets = 1;
  397 + urb->iso_frame_desc[0].length = p->len;
  398 + urb->iso_frame_desc[0].actual_length = 0;
  399 + urb->iso_frame_desc[0].status = 0;
  400 + ret = ioctl(s->fd, USBDEVFS_SUBMITURB, urb);
  401 + if (ret == 0) {
  402 + if (!add_pending_urb(urb)) {
  403 + printf("usb_host_handle_isoch: add_pending_urb failed %p\n", urb);
  404 + }
  405 + } else {
  406 + printf("usb_host_handle_isoch: SUBMITURB ioctl=%d errno=%d\n",
  407 + ret, errno);
  408 + qemu_free(urb);
  409 + switch(errno) {
  410 + case ETIMEDOUT:
  411 + return USB_RET_NAK;
  412 + case EPIPE:
  413 + default:
  414 + return USB_RET_STALL;
  415 + }
  416 + }
  417 +#ifdef USE_ASYNCIO
  418 + /* FIXME: handle urbs_ready together with sync io
  419 + * workaround for injecting the signaled urbs into current frame */
  420 + if (s->urbs_ready > 0) {
  421 + ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
  422 + if (ret == 0) {
  423 + ret = purb->actual_length;
  424 + qemu_free(purb);
  425 + s->urbs_ready--;
  426 + }
  427 + return ret;
  428 + }
  429 + s->packet = p;
  430 + return USB_RET_ASYNC;
  431 +#else
  432 + ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
  433 + if (ret == 0) {
  434 + if (del_pending_urb(purb)) {
  435 + ret = purb->actual_length;
  436 + qemu_free(purb);
  437 + } else {
  438 + printf("usb_host_handle_isoch: del_pending_urb failed %p\n", purb);
  439 + }
  440 + } else {
  441 +#ifdef DEBUG_ISOCH
  442 + printf("usb_host_handle_isoch: REAPURBNDELAY ioctl=%d errno=%d\n",
  443 + ret, errno);
  444 +#endif
  445 + }
  446 + return ret;
  447 +#endif
  448 +}
  449 +
  450 +static void usb_linux_bh_cb(void *opaque)
  451 +{
  452 + PendingURB *pending_urb = (PendingURB *)opaque;
  453 + USBHostDevice *s = pending_urb->dev;
  454 + struct usbdevfs_urb *purb = NULL;
  455 + USBPacket *p = s->packet;
  456 + int ret;
  457 +
  458 + /* FIXME: handle purb->status */
  459 + qemu_free(pending_urb->bh);
  460 + del_pending_urb(pending_urb->urb);
  461 +
  462 + if (!p) {
  463 + s->urbs_ready++;
  464 + return;
  465 + }
  466 +
  467 + ret = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &purb);
  468 + if (ret < 0) {
  469 + printf("usb_linux_bh_cb: REAPURBNDELAY ioctl=%d errno=%d\n",
  470 + ret, errno);
  471 + return;
  472 + }
  473 +
  474 +#ifdef DEBUG_ISOCH
  475 + if (purb == pending_urb->urb) {
  476 + printf("usb_linux_bh_cb: urb mismatch reaped=%p pending=%p\n",
  477 + purb, urb);
  478 + }
  479 +#endif
  480 +
  481 + p->len = purb->actual_length;
  482 + usb_packet_complete(p);
  483 + qemu_free(purb);
  484 + s->packet = NULL;
  485 +}
  486 +
  487 +/* returns 1 on problem encountered or 0 for success */
  488 +static int usb_linux_update_endp_table(USBHostDevice *s)
  489 +{
  490 + uint8_t *descriptors;
  491 + uint8_t devep, type, configuration, alt_interface;
  492 + struct usb_ctrltransfer ct;
  493 + int interface, ret, length, i;
  494 +
  495 + ct.bRequestType = USB_DIR_IN;
  496 + ct.bRequest = USB_REQ_GET_CONFIGURATION;
  497 + ct.wValue = 0;
  498 + ct.wIndex = 0;
  499 + ct.wLength = 1;
  500 + ct.data = &configuration;
  501 + ct.timeout = 50;
  502 +
  503 + ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
  504 + if (ret < 0) {
  505 + perror("usb_linux_update_endp_table");
  506 + return 1;
  507 + }
  508 +
  509 + /* in address state */
  510 + if (configuration == 0)
  511 + return 1;
  512 +
  513 + /* get the desired configuration, interface, and endpoint descriptors
  514 + * from device description */
  515 + descriptors = &s->descr[18];
  516 + length = s->descr_len - 18;
  517 + i = 0;
  518 +
  519 + if (descriptors[i + 1] != USB_DT_CONFIG ||
  520 + descriptors[i + 5] != configuration) {
  521 + printf("invalid descriptor data - configuration\n");
  522 + return 1;
  523 + }
  524 + i += descriptors[i];
  525 +
  526 + while (i < length) {
  527 + if (descriptors[i + 1] != USB_DT_INTERFACE ||
  528 + (descriptors[i + 1] == USB_DT_INTERFACE &&
  529 + descriptors[i + 4] == 0)) {
  530 + i += descriptors[i];
  531 + continue;
  532 + }
  533 +
  534 + interface = descriptors[i + 2];
  535 +
  536 + ct.bRequestType = USB_DIR_IN | USB_RECIP_INTERFACE;
  537 + ct.bRequest = USB_REQ_GET_INTERFACE;
  538 + ct.wValue = 0;
  539 + ct.wIndex = interface;
  540 + ct.wLength = 1;
  541 + ct.data = &alt_interface;
  542 + ct.timeout = 50;
  543 +
  544 + ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
  545 + if (ret < 0) {
  546 + perror("usb_linux_update_endp_table");
  547 + return 1;
  548 + }
  549 +
  550 + /* the current interface descriptor is the active interface
  551 + * and has endpoints */
  552 + if (descriptors[i + 3] != alt_interface) {
  553 + i += descriptors[i];
  554 + continue;
  555 + }
  556 +
  557 + /* advance to the endpoints */
  558 + while (i < length && descriptors[i +1] != USB_DT_ENDPOINT)
  559 + i += descriptors[i];
  560 +
  561 + if (i >= length)
  562 + break;
  563 +
  564 + while (i < length) {
  565 + if (descriptors[i + 1] != USB_DT_ENDPOINT)
  566 + break;
  567 +
  568 + devep = descriptors[i + 2];
  569 + switch (descriptors[i + 3] & 0x3) {
  570 + case 0x00:
  571 + type = USBDEVFS_URB_TYPE_CONTROL;
  572 + break;
  573 + case 0x01:
  574 + type = USBDEVFS_URB_TYPE_ISO;
  575 + break;
  576 + case 0x02:
  577 + type = USBDEVFS_URB_TYPE_BULK;
  578 + break;
  579 + case 0x03:
  580 + type = USBDEVFS_URB_TYPE_INTERRUPT;
  581 + break;
  582 + default:
  583 + printf("usb_host: malformed endpoint type\n");
  584 + type = USBDEVFS_URB_TYPE_BULK;
  585 + }
  586 + s->endp_table[(devep & 0xf) - 1].type = type;
  587 +
  588 + i += descriptors[i];
  589 + }
  590 + }
  591 + return 0;
  592 +}
  593 +
148 /* XXX: exclude high speed devices or implement EHCI */ 594 /* XXX: exclude high speed devices or implement EHCI */
149 USBDevice *usb_host_device_open(const char *devname) 595 USBDevice *usb_host_device_open(const char *devname)
150 { 596 {
151 - int fd, interface, ret, i;  
152 - USBHostDevice *dev; 597 + int fd = -1, ret;
  598 + USBHostDevice *dev = NULL;
153 struct usbdevfs_connectinfo ci; 599 struct usbdevfs_connectinfo ci;
154 - uint8_t descr[1024];  
155 char buf[1024]; 600 char buf[1024];
156 - int descr_len, dev_descr_len, config_descr_len, nb_interfaces;  
157 int bus_num, addr; 601 int bus_num, addr;
158 char product_name[PRODUCT_NAME_SZ]; 602 char product_name[PRODUCT_NAME_SZ];
159 603
  604 + dev = qemu_mallocz(sizeof(USBHostDevice));
  605 + if (!dev)
  606 + goto fail;
  607 +
  608 +#ifdef DEBUG_ISOCH
  609 + printf("usb_host_device_open %s\n", devname);
  610 +#endif
160 if (usb_host_find_device(&bus_num, &addr, 611 if (usb_host_find_device(&bus_num, &addr,
161 product_name, sizeof(product_name), 612 product_name, sizeof(product_name),
162 devname) < 0) 613 devname) < 0)
@@ -164,61 +615,35 @@ USBDevice *usb_host_device_open(const char *devname) @@ -164,61 +615,35 @@ USBDevice *usb_host_device_open(const char *devname)
164 615
165 snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d", 616 snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
166 bus_num, addr); 617 bus_num, addr);
167 - fd = open(buf, O_RDWR); 618 + fd = open(buf, O_RDWR | O_NONBLOCK);
168 if (fd < 0) { 619 if (fd < 0) {
169 perror(buf); 620 perror(buf);
170 return NULL; 621 return NULL;
171 } 622 }
172 623
173 - /* read the config description */  
174 - descr_len = read(fd, descr, sizeof(descr));  
175 - if (descr_len <= 0) {  
176 - perror("read descr"); 624 + /* read the device description */
  625 + dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
  626 + if (dev->descr_len <= 0) {
  627 + perror("usb_host_update_interfaces: reading device data failed");
177 goto fail; 628 goto fail;
178 } 629 }
179 630
180 - i = 0;  
181 - dev_descr_len = descr[0];  
182 - if (dev_descr_len > descr_len)  
183 - goto fail;  
184 - i += dev_descr_len;  
185 - config_descr_len = descr[i];  
186 - if (i + config_descr_len > descr_len)  
187 - goto fail;  
188 - nb_interfaces = descr[i + 4];  
189 - if (nb_interfaces != 1) {  
190 - /* NOTE: currently we grab only one interface */  
191 - fprintf(stderr, "usb_host: only one interface supported\n");  
192 - goto fail;  
193 - }  
194 -  
195 -#ifdef USBDEVFS_DISCONNECT  
196 - /* earlier Linux 2.4 do not support that */ 631 +#ifdef DEBUG
197 { 632 {
198 - struct usbdevfs_ioctl ctrl;  
199 - ctrl.ioctl_code = USBDEVFS_DISCONNECT;  
200 - ctrl.ifno = 0;  
201 - ret = ioctl(fd, USBDEVFS_IOCTL, &ctrl);  
202 - if (ret < 0 && errno != ENODATA) {  
203 - perror("USBDEVFS_DISCONNECT");  
204 - goto fail;  
205 - } 633 + int x;
  634 + printf("=== begin dumping device descriptor data ===\n");
  635 + for (x = 0; x < dev->descr_len; x++)
  636 + printf("%02x ", dev->descr[x]);
  637 + printf("\n=== end dumping device descriptor data ===\n");
206 } 638 }
207 #endif 639 #endif
208 640
209 - /* XXX: only grab if all interfaces are free */  
210 - interface = 0;  
211 - ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);  
212 - if (ret < 0) {  
213 - if (errno == EBUSY) {  
214 - fprintf(stderr, "usb_host: device already grabbed\n");  
215 - } else {  
216 - perror("USBDEVFS_CLAIMINTERFACE");  
217 - }  
218 - fail:  
219 - close(fd);  
220 - return NULL;  
221 - } 641 + dev->fd = fd;
  642 + dev->configuration = 1;
  643 +
  644 + /* XXX - do something about initial configuration */
  645 + if (!usb_host_update_interfaces(dev, 1))
  646 + goto fail;
222 647
223 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci); 648 ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
224 if (ret < 0) { 649 if (ret < 0) {
@@ -230,10 +655,10 @@ USBDevice *usb_host_device_open(const char *devname) @@ -230,10 +655,10 @@ USBDevice *usb_host_device_open(const char *devname)
230 printf("host USB device %d.%d grabbed\n", bus_num, addr); 655 printf("host USB device %d.%d grabbed\n", bus_num, addr);
231 #endif 656 #endif
232 657
233 - dev = qemu_mallocz(sizeof(USBHostDevice));  
234 - if (!dev) 658 + ret = usb_linux_update_endp_table(dev);
  659 + if (ret)
235 goto fail; 660 goto fail;
236 - dev->fd = fd; 661 +
237 if (ci.slow) 662 if (ci.slow)
238 dev->dev.speed = USB_SPEED_LOW; 663 dev->dev.speed = USB_SPEED_LOW;
239 else 664 else
@@ -252,7 +677,24 @@ USBDevice *usb_host_device_open(const char *devname) @@ -252,7 +677,24 @@ USBDevice *usb_host_device_open(const char *devname)
252 pstrcpy(dev->dev.devname, sizeof(dev->dev.devname), 677 pstrcpy(dev->dev.devname, sizeof(dev->dev.devname),
253 product_name); 678 product_name);
254 679
  680 +#ifdef USE_ASYNCIO
  681 + /* set up the signal handlers */
  682 + sigemptyset(&sigact.sa_mask);
  683 + sigact.sa_sigaction = isoch_done;
  684 + sigact.sa_flags = SA_SIGINFO;
  685 + sigact.sa_restorer = 0;
  686 + ret = sigaction(SIG_ISOCOMPLETE, &sigact, NULL);
  687 + if (ret < 0) {
  688 + printf("sigaction SIG_ISOCOMPLETE=%d errno=%d\n", ret, errno);
  689 + }
  690 +#endif
  691 + dev->urbs_ready = 0;
255 return (USBDevice *)dev; 692 return (USBDevice *)dev;
  693 +fail:
  694 + if (dev)
  695 + qemu_free(dev);
  696 + close(fd);
  697 + return NULL;
256 } 698 }
257 699
258 static int get_tag_value(char *buf, int buf_size, 700 static int get_tag_value(char *buf, int buf_size,
@@ -438,7 +880,7 @@ static const struct usb_class_info usb_class_info[] = { @@ -438,7 +880,7 @@ static const struct usb_class_info usb_class_info[] = {
438 { USB_CLASS_APP_SPEC, "Application Specific" }, 880 { USB_CLASS_APP_SPEC, "Application Specific" },
439 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" }, 881 { USB_CLASS_VENDOR_SPEC, "Vendor Specific" },
440 { USB_CLASS_STILL_IMAGE, "Still Image" }, 882 { USB_CLASS_STILL_IMAGE, "Still Image" },
441 - { USB_CLASS_CSCID, "Smart Card" }, 883 + { USB_CLASS_CSCID, "Smart Card" },
442 { USB_CLASS_CONTENT_SEC, "Content Security" }, 884 { USB_CLASS_CONTENT_SEC, "Content Security" },
443 { -1, NULL } 885 { -1, NULL }
444 }; 886 };