[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <200912112042.02228.linux@rainbow-software.org>
Date: Fri, 11 Dec 2009 20:42:00 +0100
From: Ondrej Zary <linux@...nbow-software.org>
To: Alan Stern <stern@...land.harvard.edu>
Cc: linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: debugging oops after disconnecting Nexio USB touchscreen
On Thursday 10 December 2009, Alan Stern wrote:
> On Thu, 10 Dec 2009, Ondrej Zary wrote:
> > Narrowed down the code to this 170-line module which reproduces my
> > "rmmod usbtouchscreen" problem. Loading this module causes EHCI to fail.
> > Looks like it fails after calling usb_kill_urb(). Can a buggy device
> > cause this?
>
> I don't think so. But I am getting an idea of what the problem might
> be. Try applying the patch below and see if it makes any difference
> (make sure that CONFIG_USB_DEBUG is enabled).
Thank you very much for the patch. It seems to finally solve this long
thread!
I'm running 2.6.32 now (with usbtouchscreen copied from -next) so one hunk
had to be applied manually. With patch applied and CONFIG_USB_DEBUG enabled,
usbtouchscreen stopped working - the urb failed to submit. Return value of
usb_submit_urb() was not checked (and it wasn't my code this time :) Adding
a check revealed that the urb fails to submit with -EPIPE because of
endpoint vs. pipe mismatch.
Fixing that (see the patch below) solved the rmmod problem!
>
> If the module stops messing up EHCI, try changing the source code:
> > static int crashnexio_probe(struct usb_interface *intf,
> > const struct usb_device_id *id)
> > {
>
> ...
>
> > interface = intf->cur_altsetting;
> > /* find first input endpoint */
> > for (i = 0; i < interface->desc.bNumEndpoints; i++)
> > if (usb_endpoint_dir_in(&interface->endpoint[i].desc)) {
> > endpoint = &interface->endpoint[i].desc;
> > break;
> > }
>
> Does the interface have more than one input endpoint? (What does
> "lsusb -v" show for the Nexio?) If it does, how do you know the
> endpoint you want is the first one?
No, there is only one input endpoint:
Bus 001 Device 009: ID 1870:0001 Nexio Co., Ltd iNexio Touchscreen controller
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x1870 Nexio Co., Ltd
idProduct 0x0001 iNexio Touchscreen controller
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 67
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 0 None
iInterface 0
CDC Header:
bcdCDC 1.10
CDC ACM:
bmCapabilities 0x00
CDC Union:
bMasterInterface 0
bSlaveInterface 1
CDC Call Management:
bmCapabilities 0x00
bDataInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 255
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0 Unused
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 0
>
> ...
>
> > usb_fill_bulk_urb(crashnexio->irq, udev,
> > usb_rcvintpipe(udev, endpoint->bEndpointAddress),
>
> Either change this to usb_fill_int_urb() or else use usb_rcvbulkpipe().
>
> ...
>
> > static int __init crashnexio_init(void)
> > {
> > return usb_register(&crashnexio_driver);
> > }
>
> You should also have an __exit routine.
As I'm bad at writing cleanup functions and the purpose was to break EHCI,
the only exit was a reboot :)
--- linux-2.6.32/drivers/input/touchscreen/usbtouchscreen.5 2009-12-11 12:50:35.000000000 +0100
+++ linux-2.6.32/drivers/input/touchscreen/usbtouchscreen.c 2009-12-11 20:15:51.000000000 +0100
@@ -1375,10 +1375,16 @@
input_set_abs_params(input_dev, ABS_PRESSURE, type->min_press,
type->max_press, 0, 0);
- usb_fill_int_urb(usbtouch->irq, udev,
+ if (usb_endpoint_type(endpoint) == USB_ENDPOINT_XFER_INT)
+ usb_fill_int_urb(usbtouch->irq, udev,
usb_rcvintpipe(udev, endpoint->bEndpointAddress),
usbtouch->data, type->rept_size,
usbtouch_irq, usbtouch, endpoint->bInterval);
+ else
+ usb_fill_bulk_urb(usbtouch->irq, udev,
+ usb_rcvbulkpipe(udev, endpoint->bEndpointAddress),
+ usbtouch->data, type->rept_size,
+ usbtouch_irq, usbtouch);
usbtouch->irq->dev = udev;
usbtouch->irq->transfer_dma = usbtouch->data_dma;
--
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists