Message ID | 1341245761-30942-1-git-send-email-kraxel@redhat.com |
---|---|
State | New |
Headers | show |
On 2012-07-02 18:16, Gerd Hoffmann wrote: > Add support for (re-)initializing endpoints which belong to a specific > interface only. Use this in usb-host when changing altsetting for an > interface, so other interfaces are not disturbed. > qemu-system-x86_64: /data/qemu/hw/usb/host-linux.c:1220: usb_linux_update_endp_table: Assertion `usb_ep_get_type(&s->dev, pid, ep) == 255' failed. Do you need a trace again? Thanks, Jan PS: The device used here is this one: Bus 001 Device 060: ID 047f:c247 Plantronics, Inc. Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 8 idVendor 0x047f Plantronics, Inc. idProduct 0xc247 bcdDevice 0.27 iManufacturer 1 Plantronics iProduct 2 HW121N-USB iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 286 bNumInterfaces 4 bConfigurationValue 1 iConfiguration 3 v18M6 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 1 Control Device bInterfaceProtocol 0 iInterface 0 AudioControl Interface Descriptor: bLength 10 bDescriptorType 36 bDescriptorSubtype 1 (HEADER) bcdADC 1.00 wTotalLength 115 bInCollection 2 baInterfaceNr( 0) 1 baInterfaceNr( 1) 2 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 13 wTerminalType 0x0201 Microphone bAssocTerminal 0 bNrChannels 1 wChannelConfig 0x0000 iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 6 (FEATURE_UNIT) bUnitID 6 bSourceID 13 bControlSize 1 bmaControls( 0) 0x03 Mute Control Volume Control bmaControls( 1) 0x00 iFeature 0 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 12 wTerminalType 0x0101 USB Streaming bAssocTerminal 0 bNrChannels 2 wChannelConfig 0x0003 Left Front (L) Right Front (R) iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 13 bDescriptorType 36 bDescriptorSubtype 4 (MIXER_UNIT) bUnitID 9 bNrInPins 2 baSourceID( 0) 12 baSourceID( 1) 6 bNrChannels 2 wChannelConfig 0x0003 Left Front (L) Right Front (R) iChannelNames 0 bmControls 0x00 iMixer 0 AudioControl Interface Descriptor: bLength 13 bDescriptorType 36 bDescriptorSubtype 6 (FEATURE_UNIT) bUnitID 1 bSourceID 9 bControlSize 2 bmaControls( 0) 0x15 bmaControls( 0) 0x00 Mute Control Bass Control Treble Control bmaControls( 1) 0x02 bmaControls( 1) 0x00 Volume Control bmaControls( 2) 0x02 bmaControls( 2) 0x00 Volume Control iFeature 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 14 wTerminalType 0x0301 Speaker bAssocTerminal 11 bSourceID 1 iTerminal 0 AudioControl Interface Descriptor: bLength 12 bDescriptorType 36 bDescriptorSubtype 2 (INPUT_TERMINAL) bTerminalID 11 wTerminalType 0x0201 Microphone bAssocTerminal 14 bNrChannels 1 wChannelConfig 0x0000 iChannelNames 0 iTerminal 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 6 (FEATURE_UNIT) bUnitID 2 bSourceID 11 bControlSize 1 bmaControls( 0) 0x03 Mute Control Volume Control bmaControls( 1) 0x00 iFeature 0 AudioControl Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 5 (SELECTOR_UNIT) bUnitID 8 bNrInPins 1 baSource( 0) 2 iSelector 0 AudioControl Interface Descriptor: bLength 9 bDescriptorType 36 bDescriptorSubtype 3 (OUTPUT_TERMINAL) bTerminalID 10 wTerminalType 0x0101 USB Streaming bAssocTerminal 0 bSourceID 8 iTerminal 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 12 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 23 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 2 bSubframeSize 2 bBitResolution 16 bSamFreqType 5 Discrete tSamFreq[ 0] 8000 tSamFreq[ 1] 16000 tSamFreq[ 2] 32000 tSamFreq[ 3] 44100 tSamFreq[ 4] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x00c0 1x 192 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x01 Sampling Frequency bLockDelayUnits 2 Decoded PCM samples wLockDelay 1 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 0 bNumEndpoints 0 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 2 bAlternateSetting 1 bNumEndpoints 1 bInterfaceClass 1 Audio bInterfaceSubClass 2 Streaming bInterfaceProtocol 0 iInterface 0 AudioStreaming Interface Descriptor: bLength 7 bDescriptorType 36 bDescriptorSubtype 1 (AS_GENERAL) bTerminalLink 10 bDelay 0 frames wFormatTag 1 PCM AudioStreaming Interface Descriptor: bLength 23 bDescriptorType 36 bDescriptorSubtype 2 (FORMAT_TYPE) bFormatType 1 (FORMAT_TYPE_I) bNrChannels 1 bSubframeSize 2 bBitResolution 16 bSamFreqType 5 Discrete tSamFreq[ 0] 8000 tSamFreq[ 1] 16000 tSamFreq[ 2] 32000 tSamFreq[ 3] 44100 tSamFreq[ 4] 48000 Endpoint Descriptor: bLength 9 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 13 Transfer Type Isochronous Synch Type Synchronous Usage Type Data wMaxPacketSize 0x0060 1x 96 bytes bInterval 1 bRefresh 0 bSynchAddress 0 AudioControl Endpoint Descriptor: bLength 7 bDescriptorType 37 bDescriptorSubtype 1 (EP_GENERAL) bmAttributes 0x01 Sampling Frequency bLockDelayUnits 2 Decoded PCM samples wLockDelay 1 Decoded PCM samples Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 3 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 No Subclass bInterfaceProtocol 0 None iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.00 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 115 Report Descriptor: (length is 115) Item(Global): Logical Minimum, data= [ 0x00 ] 0 Item(Global): Logical Maximum, data= [ 0x01 ] 1 Item(Global): Report Size, data= [ 0x01 ] 1 Item(Global): Usage Page, data= [ 0x0c ] 12 Consumer Item(Local ): Usage, data= [ 0x01 ] 1 Consumer Control Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x01 ] 1 Item(Global): Report Count, data= [ 0x06 ] 6 Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0xea ] 234 Volume Decrement Item(Local ): Usage, data= [ 0xe9 ] 233 Volume Increment Item(Global): Report Count, data= [ 0x02 ] 2 Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x08 ] 8 Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Usage Page, data= [ 0xa0 0xff ] 65440 (null) Item(Global): Report ID, data= [ 0x10 ] 16 Item(Global): Report Count, data= [ 0x01 ] 1 Item(Local ): Usage, data= [ 0x98 ] 152 (null) Item(Global): Report Size, data= [ 0x01 ] 1 Item(Main ): Output, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x07 ] 7 Item(Main ): Output, data= [ 0x01 ] 1 Constant Array Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Item(Global): Usage Page, data= [ 0x0b ] 11 Telephony Item(Local ): Usage, data= [ 0x05 ] 5 Headset Item(Main ): Collection, data= [ 0x01 ] 1 Application Item(Global): Report ID, data= [ 0x02 ] 2 Item(Global): Report Size, data= [ 0x01 ] 1 Item(Global): Report Count, data= [ 0x03 ] 3 Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x2f ] 47 Phone Mute Item(Global): Report Count, data= [ 0x01 ] 1 Item(Main ): Input, data= [ 0x02 ] 2 Data Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x21 ] 33 Flash Item(Main ): Input, data= [ 0x06 ] 6 Data Variable Relative No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Local ): Usage, data= [ 0x20 ] 32 Hook Switch Item(Main ): Input, data= [ 0x22 ] 34 Data Variable Absolute No_Wrap Linear No_Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report Count, data= [ 0x0a ] 10 Item(Main ): Input, data= [ 0x03 ] 3 Constant Variable Absolute No_Wrap Linear Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Usage Page, data= [ 0x08 ] 8 LEDs Item(Global): Report ID, data= [ 0x18 ] 24 Item(Local ): Usage, data= [ 0x18 ] 24 Ring Item(Global): Report Count, data= [ 0x08 ] 8 Item(Main ): Output, data= [ 0x22 ] 34 Data Variable Absolute No_Wrap Linear No_Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report ID, data= [ 0x17 ] 23 Item(Local ): Usage, data= [ 0x17 ] 23 Off-Hook Item(Main ): Output, data= [ 0x22 ] 34 Data Variable Absolute No_Wrap Linear No_Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report ID, data= [ 0x1e ] 30 Item(Local ): Usage, data= [ 0x1e ] 30 Speaker Item(Main ): Output, data= [ 0x22 ] 34 Data Variable Absolute No_Wrap Linear No_Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report ID, data= [ 0x09 ] 9 Item(Local ): Usage, data= [ 0x09 ] 9 Mute Item(Main ): Output, data= [ 0x22 ] 34 Data Variable Absolute No_Wrap Linear No_Preferred_State No_Null_Position Non_Volatile Bitfield Item(Global): Report ID, data= [ 0x2a ] 42 Item(Local ): Usage, data= [ 0x2a ] 42 On-Line Item(Main ): Output, data= [ 0x22 ] 34 Data Variable Absolute No_Wrap Linear No_Preferred_State No_Null_Position Non_Volatile Bitfield Item(Main ): End Collection, data=none Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0003 1x 3 bytes bInterval 2 Device Status: 0x0000 (Bus Powered)
Gerd Hoffmann wrote: > Add support for (re-)initializing endpoints which belong to a specific > interface only. Use this in usb-host when changing altsetting for an > interface, so other interfaces are not disturbed. > Hi Gerd, I tested it on my AMD test system where the issue didn't appear with the same USB hardware (also before this patch!) - so the final test on my Intel test system is pending until next week where it happened. Best regards, Erik
Erik Rull wrote: > Gerd Hoffmann wrote: >> Add support for (re-)initializing endpoints which belong to a specific >> interface only. Use this in usb-host when changing altsetting for an >> interface, so other interfaces are not disturbed. >> > > Hi Gerd, > > I tested it on my AMD test system where the issue didn't appear with the > same USB hardware (also before this patch!) - so the final test on my Intel > test system is pending until next week where it happened. > > Best regards, > > Erik > > Hi Gerd, sorry for the delays, I tested the latest pulled patch queue and it's now fine on my Intel board, too. The dongle gets detected again without assertions. Thanks for your work. Still remaining are the multiple usb resets on host side before the dongle gets finally detected / usable on the guest. Best regards, Erik
diff --git a/hw/usb.h b/hw/usb.h index a5623d3..b6d7052 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -362,7 +362,7 @@ int usb_handle_packet(USBDevice *dev, USBPacket *p); void usb_packet_complete(USBDevice *dev, USBPacket *p); void usb_cancel_packet(USBPacket * p); -void usb_ep_init(USBDevice *dev); +void usb_ep_init(USBDevice *dev, int interface); void usb_ep_dump(USBDevice *dev); struct USBEndpoint *usb_ep_get(USBDevice *dev, int pid, int ep); uint8_t usb_ep_get_type(USBDevice *dev, int pid, int ep); diff --git a/hw/usb/bus.c b/hw/usb/bus.c index b649360..ad1daaf 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -190,7 +190,7 @@ static int usb_qdev_init(DeviceState *qdev) usb_device_get_product_desc(dev)); dev->auto_attach = 1; QLIST_INIT(&dev->strings); - usb_ep_init(dev); + usb_ep_init(dev, 0); rc = usb_claim_port(dev); if (rc != 0) { return rc; diff --git a/hw/usb/core.c b/hw/usb/core.c index 0e02da7..94c3c1a 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -550,31 +550,37 @@ void usb_packet_cleanup(USBPacket *p) qemu_iovec_destroy(&p->iov); } -void usb_ep_init(USBDevice *dev) +void usb_ep_init(USBDevice *dev, int interface) { int ep; - dev->ep_ctl.nr = 0; - dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL; - dev->ep_ctl.ifnum = 0; - dev->ep_ctl.dev = dev; - dev->ep_ctl.pipeline = false; - QTAILQ_INIT(&dev->ep_ctl.queue); + if (interface == 0) { + dev->ep_ctl.nr = 0; + dev->ep_ctl.type = USB_ENDPOINT_XFER_CONTROL; + dev->ep_ctl.ifnum = 0; + dev->ep_ctl.dev = dev; + dev->ep_ctl.pipeline = false; + QTAILQ_INIT(&dev->ep_ctl.queue); + } for (ep = 0; ep < USB_MAX_ENDPOINTS; ep++) { - dev->ep_in[ep].nr = ep + 1; - dev->ep_out[ep].nr = ep + 1; - dev->ep_in[ep].pid = USB_TOKEN_IN; - dev->ep_out[ep].pid = USB_TOKEN_OUT; - dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID; - dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID; - dev->ep_in[ep].ifnum = 0; - dev->ep_out[ep].ifnum = 0; - dev->ep_in[ep].dev = dev; - dev->ep_out[ep].dev = dev; - dev->ep_in[ep].pipeline = false; - dev->ep_out[ep].pipeline = false; - QTAILQ_INIT(&dev->ep_in[ep].queue); - QTAILQ_INIT(&dev->ep_out[ep].queue); + if (interface == 0 || interface == dev->ep_in[ep].ifnum) { + dev->ep_in[ep].nr = ep + 1; + dev->ep_in[ep].pid = USB_TOKEN_IN; + dev->ep_in[ep].type = USB_ENDPOINT_XFER_INVALID; + dev->ep_in[ep].ifnum = 0; + dev->ep_in[ep].dev = dev; + dev->ep_in[ep].pipeline = false; + QTAILQ_INIT(&dev->ep_in[ep].queue); + } + if (interface == 0 || interface == dev->ep_out[ep].ifnum) { + dev->ep_out[ep].nr = ep + 1; + dev->ep_out[ep].pid = USB_TOKEN_OUT; + dev->ep_out[ep].type = USB_ENDPOINT_XFER_INVALID; + dev->ep_out[ep].ifnum = 0; + dev->ep_out[ep].dev = dev; + dev->ep_out[ep].pipeline = false; + QTAILQ_INIT(&dev->ep_out[ep].queue); + } } } diff --git a/hw/usb/desc.c b/hw/usb/desc.c index 0a9d3c9..f010755 100644 --- a/hw/usb/desc.c +++ b/hw/usb/desc.c @@ -246,7 +246,7 @@ static void usb_desc_ep_init(USBDevice *dev) const USBDescIface *iface; int i, e, pid, ep; - usb_ep_init(dev); + usb_ep_init(dev, 0); for (i = 0; i < dev->ninterfaces; i++) { iface = dev->ifaces[i]; if (iface == NULL) { diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c index 5479fb5..8e5d1be 100644 --- a/hw/usb/host-linux.c +++ b/hw/usb/host-linux.c @@ -135,7 +135,7 @@ static int parse_filter(const char *spec, struct USBAutoFilter *f); static void usb_host_auto_check(void *unused); static int usb_host_read_file(char *line, size_t line_size, const char *device_file, const char *device_name); -static int usb_linux_update_endp_table(USBHostDevice *s); +static int usb_linux_update_endp_table(USBHostDevice *s, int ifnum); static int usb_host_usbfs_type(USBHostDevice *s, USBPacket *p) { @@ -648,7 +648,7 @@ static void usb_host_handle_reset(USBDevice *dev) usb_host_do_reset(s);; usb_host_claim_interfaces(s, 0); - usb_linux_update_endp_table(s); + usb_linux_update_endp_table(s, 0); } static void usb_host_handle_destroy(USBDevice *dev) @@ -988,7 +988,7 @@ again: return ctrl_error(); } usb_host_claim_interfaces(s, config); - usb_linux_update_endp_table(s); + usb_linux_update_endp_table(s, 0); return 0; } @@ -1024,7 +1024,7 @@ static int usb_host_set_interface(USBHostDevice *s, int iface, int alt) } s->dev.altsetting[iface] = alt; - usb_linux_update_endp_table(s); + usb_linux_update_endp_table(s, iface); return 0; } @@ -1120,7 +1120,7 @@ static int usb_host_handle_control(USBDevice *dev, USBPacket *p, } /* returns 1 on problem encountered or 0 for success */ -static int usb_linux_update_endp_table(USBHostDevice *s) +static int usb_linux_update_endp_table(USBHostDevice *s, int ifnum) { static const char *tname[] = { [USB_ENDPOINT_XFER_CONTROL] = "control", @@ -1136,7 +1136,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) USBDescriptor *d; bool active = false; - usb_ep_init(&s->dev); + usb_ep_init(&s->dev, ifnum); for (i = 0;; i += d->bLength) { if (i+2 >= s->descr_len) { @@ -1239,7 +1239,7 @@ static int usb_linux_update_endp_table(USBHostDevice *s) return 0; error: - usb_ep_init(&s->dev); + usb_ep_init(&s->dev, 0); return 1; } @@ -1326,7 +1326,7 @@ static int usb_host_open(USBHostDevice *dev, int bus_num, goto fail; } - ret = usb_linux_update_endp_table(dev); + ret = usb_linux_update_endp_table(dev, 0); if (ret) { goto fail; } diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index d949f04..4afa9c2 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -1136,7 +1136,7 @@ static void usbredir_device_disconnect(void *priv) for (i = 0; i < MAX_ENDPOINTS; i++) { QTAILQ_INIT(&dev->endpoint[i].bufpq); } - usb_ep_init(&dev->dev); + usb_ep_init(&dev->dev, 0); dev->interface_info.interface_count = NO_INTERFACE_INFO; dev->dev.addr = 0; dev->dev.speed = 0;
Add support for (re-)initializing endpoints which belong to a specific interface only. Use this in usb-host when changing altsetting for an interface, so other interfaces are not disturbed. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> --- hw/usb.h | 2 +- hw/usb/bus.c | 2 +- hw/usb/core.c | 48 +++++++++++++++++++++++++++--------------------- hw/usb/desc.c | 2 +- hw/usb/host-linux.c | 16 ++++++++-------- hw/usb/redirect.c | 2 +- 6 files changed, 39 insertions(+), 33 deletions(-)