Re: debugging oops after disconnecting Nexio USB touchscreen

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Monday 07 December 2009, Ondrej Zary wrote:
> On Friday 04 December 2009, Alan Stern wrote:
> > > With uhci_hcd, rmmod works fine. With ehci_hcd, rmmod hangs the bus -
> > > all urbs fail with -ENOENT:
> > > f67265e8 1428021080 S Bi:1:009:2 -115 128 <
> > > f67265e8 1431508327 C Bi:1:009:2 -108 0
> > > f6726718 1458252464 S Co:1:007:0 s 40 09 0001 0000 0000 0
> > > f6726718 1463261404 C Co:1:007:0 -2 0
> > > f6726978 1463261428 S Co:1:002:0 s 23 08 0070 0001 0000 0
> > > f6726718 1463261509 S Co:1:007:0 s 40 00 0000 0000 0000 0
> > > f6726978 1464273397 C Co:1:002:0 -2 0
> > > f6726718 1468273397 C Co:1:007:0 -2 0
> >
> > This may be a bug in ehci-hcd, a bug in your EHCI hardware, or a bug in
> > the hub.  Can you try using a different high-speed hub to see if it
> > makes any difference?
>
> Just tried another hub. Now there are two hubs connected to separate ports
> on the machine. Nexio is the only device connected to the "new" hub. No
> matter where I connect the device or the 2nd hub, it always appears on "Bus
> 001":
>
> Bus 002 Device 002: ID 041e:4068 Creative Technology, Ltd Webcam Live!
> Notebook Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
> Bus 003 Device 002: ID 413c:2003 Dell Computer Corp. Keyboard
> Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
> Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
> Bus 004 Device 002: ID 0bda:0158 Realtek Semiconductor Corp. USB 2.0
> multicard reader Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root
> hub
> Bus 001 Device 010: ID 1870:0001 Nexio Co., Ltd iNexio Touchscreen
> controller Bus 001 Device 009: ID 088c:2030 Swecoin AB Ticket Printer TTP
> 2030 Bus 001 Device 008: ID 0403:6001 Future Technology Devices
> International, Ltd FT232 USB-Serial (UART) IC Bus 001 Device 007: ID
> 065a:0001 Optoelectronics Co., Ltd Barcode scanner Bus 001 Device 002: ID
> 2001:f103 D-Link Corp. [hex] DUB-H7 7-port USB 2.0 hub Bus 001 Device 001:
> ID 1d6b:0002 Linux Foundation 2.0 root hub
> Bus 001 Device 005: ID 04cc:1521 Philips Semiconductors USB 2.0 Hub
>
> The problem is still the same. Removing the module causes devices on the
> other hub to fail.
>
> Disconnecting the touchscreen first and then removing the module does not
> cause any problems (with either of the hubs) - so it must be a software
> problem.

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?

#define DEBUG

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb.h>

struct crashnexio_usb {
	unsigned char *data;
	dma_addr_t data_dma;
	struct urb *irq;
	struct usb_interface *interface;
};

static struct usb_device_id crashnexio_devices[] = {
	{USB_DEVICE_AND_INTERFACE_INFO(0x1870, 0x0001, 0x0a, 0x00, 0x00)},
	{}
};

#define NEXIO_TIMEOUT	5000
#define NEXIO_BUFSIZE	1024
#define NEXIO_THRESHOLD	50
#define NEXIO_REPT_SIZE 128

static unsigned char nexio_init_pkt[4] = { 0x82, 0x04, 0x0a, 0x0f };

static int nexio_init(struct crashnexio_usb *crashnexio)
{
	struct usb_device *dev = interface_to_usbdev(crashnexio->interface);
	int ret = -ENOMEM;
	int actual_len;
	unsigned char *buf;
	int input_ep = 0x82, output_ep = 0x01;

	printk("%s\n", __func__);

	buf = kmalloc(NEXIO_BUFSIZE, GFP_KERNEL);
	if (!buf)
		goto out_buf;
	/* send init command */
	memcpy(buf, nexio_init_pkt, sizeof(nexio_init_pkt));
	ret = usb_bulk_msg(dev, usb_sndbulkpipe(dev, output_ep),
			   buf, sizeof(nexio_init_pkt), &actual_len,
			   NEXIO_TIMEOUT);
	if (ret < 0)
		goto out_buf;
	/* read reply */
	memset(buf, 0, NEXIO_BUFSIZE);
	ret = usb_bulk_msg(dev, usb_rcvbulkpipe(dev, input_ep),
			   buf, NEXIO_BUFSIZE, &actual_len,
			   NEXIO_TIMEOUT);
out_buf:
	kfree(buf);
	return ret;
}

static void crashnexio_irq(struct urb *urb)
{
	int retval;

	printk("%s\n", __func__);

	switch (urb->status) {
	case 0:
		/* success */
		break;
	case -ETIME:
		/* this urb is timing out */
		dbg("%s - urb timed out - was the device unplugged?",
		    __func__);
		return;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
	case -EPIPE:
		/* this urb is terminated, clean up */
		dbg("%s - urb shutting down with status: %d",
		    __func__, urb->status);
		return;
	default:
		dbg("%s - nonzero urb status received: %d",
		    __func__, urb->status);
		goto exit;
	}

exit:
	retval = usb_submit_urb(urb, GFP_ATOMIC);
	if (retval)
		err("%s - usb_submit_urb failed with result: %d",
		    __func__, retval);
}

static int crashnexio_probe(struct usb_interface *intf,
			  const struct usb_device_id *id)
{
	struct crashnexio_usb *crashnexio;
	struct usb_host_interface *interface;
	struct usb_endpoint_descriptor *endpoint = NULL;
	struct usb_device *udev = interface_to_usbdev(intf);
	int err = -ENOMEM;
	int i;

	printk("%s\n", __func__);

	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;
		}
	if (!endpoint)
		return -ENXIO;

	crashnexio = kzalloc(sizeof(struct crashnexio_usb), GFP_KERNEL);
	if (!crashnexio)
		goto out_free;

	crashnexio->data = usb_buffer_alloc(udev, NEXIO_REPT_SIZE,
	                                  GFP_KERNEL, &crashnexio->data_dma);
	if (!crashnexio->data)
		goto out_free;

	crashnexio->irq = usb_alloc_urb(0, GFP_KERNEL);
	if (!crashnexio->irq) {
		dbg("%s - usb_alloc_urb failed: crashnexio->irq", __func__);
		goto out_free_buffers;
	}

	crashnexio->interface = intf;

	usb_fill_bulk_urb(crashnexio->irq, udev,
			 usb_rcvintpipe(udev, endpoint->bEndpointAddress),
			 crashnexio->data, NEXIO_REPT_SIZE,
			 crashnexio_irq, crashnexio);

	usb_set_intfdata(intf, crashnexio);

	nexio_init(crashnexio);

	usb_submit_urb(crashnexio->irq, GFP_KERNEL);
	/* This will crash all EHCI communication */
	usb_kill_urb(crashnexio->irq);

	return 0;

out_free_buffers:
	usb_buffer_free(udev, NEXIO_REPT_SIZE, crashnexio->data, crashnexio->data_dma);
out_free:
	kfree(crashnexio);
	return err;
}

MODULE_DEVICE_TABLE(usb, crashnexio_devices);

static struct usb_driver crashnexio_driver = {
	.name		= "crashnexio",
	.probe		= crashnexio_probe,
	.id_table	= crashnexio_devices,
};

static int __init crashnexio_init(void)
{
	return usb_register(&crashnexio_driver);
}

module_init(crashnexio_init);

MODULE_LICENSE("GPL");



dmesg when loaded:
[   29.504260] usb 1-1.7: New USB device found, idVendor=1870, idProduct=0001
[   29.504277] usb 1-1.7: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[   29.504290] usb 1-1.7: Product: iNexio USB
[   29.504299] usb 1-1.7: Manufacturer: iNexio
[   29.504529] usb 1-1.7: configuration #1 chosen from 1 choice
[   29.783276] crashnexio_probe
[   29.783289] nexio_init
[   29.783941] crashnexio_irq
[   29.783954] drivers/input/touchscreen/crashnexio.c: crashnexio_irq - urb shutting down with status: -2
[   29.784123] usbcore: registered new interface driver crashnexio
[   46.328105] ftdi_sio ttyUSB0: Unable to write latency timer: -110
...more USB errors


usbmon output:
f60f1d40 1250266541 S Ci:1:009:0 s 80 06 0100 0000 0012 18 <
f60f1d40 1250266801 C Ci:1:009:0 0 18 = 12011001 02000008 70180100 00010102 0301
f60f1d40 1250266844 S Ci:1:009:0 s 80 06 0200 0000 0009 9 <
f60f1d40 1250267057 C Ci:1:009:0 0 9 = 09024300 020100c0 fa
f60f1d40 1250267107 S Ci:1:009:0 s 80 06 0200 0000 0043 67 <
f60f1d40 1250267423 C Ci:1:009:0 0 67 = 09024300 020100c0 fa090400 00010202 00000524 00100104 24020005 24060001
f60f1d40 1250267478 S Ci:1:009:0 s 80 06 0300 0000 00ff 255 <
f60f1d40 1250267673 C Ci:1:009:0 0 6 = 06030904 1204
f60f1d40 1250267734 S Ci:1:009:0 s 80 06 0302 0409 00ff 255 <
f60f1d40 1250267923 C Ci:1:009:0 0 22 = 16036900 4e006500 78006900 6f002000 55005300 4200
f60f1d40 1250267984 S Ci:1:009:0 s 80 06 0301 0409 00ff 255 <
f60f1d40 1250268171 C Ci:1:009:0 0 14 = 0e036900 4e006500 78006900 6f00
f60f1d40 1250268217 S Ci:1:009:0 s 80 06 0303 0409 00ff 255 <
f60f1d40 1255266704 C Ci:1:009:0 -2 0
f60f1d40 1255266822 S Ci:1:009:0 s 80 06 0303 0409 0002 2 <
f60f1c40 1255266840 S Co:1:002:0 s 23 08 8090 0001 0000 0
f60f1c40 1255266930 C Co:1:002:0 0 0
f6527c40 1259050204 S Bo:1:004:1 -115 31 = 55534243 24000000 00000000 00000600 00000000 00000000 00000000 000000
f6527c40 1259050331 C Bo:1:004:1 0 31 >
f6527c40 1259050351 S Bi:1:004:2 -115 13 <
f6527c40 1259050936 C Bi:1:004:2 0 13 = 55534253 24000000 00000000 01
f6527c40 1259050962 S Bo:1:004:1 -115 31 = 55534243 25000000 12000000 80000603 00000012 00000000 00000000 000000
f6527c40 1259051073 C Bo:1:004:1 0 31 >
f64b1f40 1259051111 S Bi:1:004:2 -115 18 <
f64b1f40 1259051960 C Bi:1:004:2 0 18 = 70000200 0000000a 00000000 3a000000 0000
f6527c40 1259052025 S Bi:1:004:2 -115 13 <
f6527c40 1259052320 C Bi:1:004:2 0 13 = 55534253 25000000 00000000 00
f6527c40 1259052471 S Bo:1:004:1 -115 31 = 55534243 26000000 00000000 00000600 00000000 00000000 00000000 000000
f6527c40 1259052573 C Bo:1:004:1 0 31 >
f6527c40 1259052605 S Bi:1:004:2 -115 13 <
f6527c40 1259053074 C Bi:1:004:2 0 13 = 55534253 26000000 00000000 01
f6527c40 1259053116 S Bo:1:004:1 -115 31 = 55534243 27000000 12000000 80000603 00000012 00000000 00000000 000000
f6527c40 1259053186 C Bo:1:004:1 0 31 >
f64b1f40 1259053227 S Bi:1:004:2 -115 18 <
f64b1f40 1259054208 C Bi:1:004:2 0 18 = 70000200 0000000a 00000000 3a000000 0000
f6527c40 1259054264 S Bi:1:004:2 -115 13 <
f6527c40 1259054561 C Bi:1:004:2 0 13 = 55534253 27000000 00000000 00
f60f1d40 1260266607 C Ci:1:009:0 -2 0
f60f1d40 1260266987 S Co:1:009:0 s 00 09 0001 0000 0000 0
f60f1c40 1260267046 S Co:1:002:0 s 23 08 8090 0001 0000 0
f60f1c40 1260267201 C Co:1:002:0 0 0
f60f1d40 1260267449 C Co:1:009:0 0 0
f60f1d40 1260267925 S Ci:1:002:0 s a3 00 0000 0007 0004 4 <


-- 
Ondrej Zary
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux