From: Ondrej Zary <linux@rainbow-software.org>
To: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: debugging oops after disconnecting Nexio USB touchscreen
Date: Thu, 10 Dec 2009 16:40:02 +0100 [thread overview]
Message-ID: <200912101640.02897.linux@rainbow-software.org> (raw)
In-Reply-To: <200912071607.38351.linux@rainbow-software.org>
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
next prev parent reply other threads:[~2009-12-10 15:40 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-27 13:38 debugging oops after disconnecting Nexio USB touchscreen Ondrej Zary
2009-11-27 18:19 ` Alan Stern
2009-11-30 15:30 ` Ondrej Zary
2009-11-30 20:19 ` Alan Stern
2009-12-01 10:06 ` Ondrej Zary
2009-12-01 15:11 ` Alan Stern
2009-12-02 8:52 ` Ondrej Zary
2009-12-02 9:42 ` Oliver Neukum
2009-12-03 9:30 ` Ondrej Zary
2009-12-02 15:58 ` Alan Stern
2009-12-03 12:31 ` Ondrej Zary
2009-12-03 19:39 ` Alan Stern
2009-12-03 20:55 ` Ondrej Zary
2009-12-03 22:22 ` Alan Stern
2009-12-04 12:22 ` Ondrej Zary
2009-12-04 15:47 ` Alan Stern
2009-12-04 19:17 ` Ondrej Zary
2009-12-04 19:34 ` Alan Stern
2009-12-04 19:55 ` Ondrej Zary
2009-12-04 21:24 ` Alan Stern
2009-12-07 9:02 ` Ondrej Zary
2009-12-07 15:22 ` Alan Stern
2009-12-08 9:03 ` Ondrej Zary
2009-12-08 15:03 ` Alan Stern
2009-12-08 15:21 ` Ondrej Zary
2009-12-07 15:07 ` Ondrej Zary
2009-12-07 16:02 ` Alan Stern
2009-12-10 15:40 ` Ondrej Zary [this message]
2009-12-10 20:38 ` Alan Stern
2009-12-11 19:42 ` Ondrej Zary
2009-12-11 20:49 ` Alan Stern
2009-12-05 7:36 ` Andreas Mohr
2009-12-05 17:16 ` Alan Stern
2009-12-06 11:38 ` Andreas Mohr
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200912101640.02897.linux@rainbow-software.org \
--to=linux@rainbow-software.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=stern@rowland.harvard.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.