diff options
| author | Oliver Neukum <oliver@neukum.org> | 2009-08-04 23:52:09 +0200 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-08-07 16:05:14 -0700 | 
| commit | cf7fdd57f978d40ceb9a0f58a25f5cf9c84d6f33 (patch) | |
| tree | 17de519a492c4353dc65111bec683bd4f038a311 | |
| parent | c15e3ca1d822abba78c00b1ffc3e7b382a50396e (diff) | |
| download | olio-linux-3.10-cf7fdd57f978d40ceb9a0f58a25f5cf9c84d6f33.tar.xz olio-linux-3.10-cf7fdd57f978d40ceb9a0f58a25f5cf9c84d6f33.zip  | |
USB: fix oops on disconnect in cdc-acm
This patch fixes an oops caused when during an unplug a device's table
of endpoints is zeroed before the driver is notified. A pointer to
the endpoint must be cached.
this fixes a regression caused by commit
5186ffee2320942c3dc9745f7930e0eb15329ca6
Therefore it should go into 2.6.31
Signed-off-by: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 10 | ||||
| -rw-r--r-- | drivers/usb/class/cdc-acm.h | 2 | 
2 files changed, 7 insertions, 5 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index e1f89416ef8..2bfc41ece0e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -387,7 +387,6 @@ static void acm_rx_tasklet(unsigned long _acm)  	struct acm_ru *rcv;  	unsigned long flags;  	unsigned char throttled; -	struct usb_host_endpoint *ep;  	dbg("Entering acm_rx_tasklet"); @@ -463,14 +462,12 @@ urbs:  		rcv->buffer = buf; -		ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out) -				[usb_pipeendpoint(acm->rx_endpoint)]; -		if (usb_endpoint_xfer_int(&ep->desc)) +		if (acm->is_int_ep)  			usb_fill_int_urb(rcv->urb, acm->dev,  					 acm->rx_endpoint,  					 buf->base,  					 acm->readsize, -					 acm_read_bulk, rcv, ep->desc.bInterval); +					 acm_read_bulk, rcv, acm->bInterval);  		else  			usb_fill_bulk_urb(rcv->urb, acm->dev,  					  acm->rx_endpoint, @@ -1183,6 +1180,9 @@ made_compressed_probe:  	spin_lock_init(&acm->read_lock);  	mutex_init(&acm->mutex);  	acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); +	acm->is_int_ep = usb_endpoint_xfer_int(epread); +	if (acm->is_int_ep) +		acm->bInterval = epread->bInterval;  	tty_port_init(&acm->port);  	acm->port.ops = &acm_port_ops; diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 1602324808b..c4a0ee8ffcc 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -126,6 +126,8 @@ struct acm {  	unsigned int ctrl_caps;				/* control capabilities from the class specific header */  	unsigned int susp_count;			/* number of suspended interfaces */  	int combined_interfaces:1;			/* control and data collapsed */ +	int is_int_ep:1;				/* interrupt endpoints contrary to spec used */ +	u8 bInterval;  	struct acm_wb *delayed_wb;			/* write queued for a device about to be woken */  };  |