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>

authored by Oliver Neukum and committed by Greg Kroah-Hartman cf7fdd57 c15e3ca1

+7 -5
+5 -5
drivers/usb/class/cdc-acm.c
··· 387 struct acm_ru *rcv; 388 unsigned long flags; 389 unsigned char throttled; 390 - struct usb_host_endpoint *ep; 391 392 dbg("Entering acm_rx_tasklet"); 393 ··· 462 463 rcv->buffer = buf; 464 465 - ep = (usb_pipein(acm->rx_endpoint) ? acm->dev->ep_in : acm->dev->ep_out) 466 - [usb_pipeendpoint(acm->rx_endpoint)]; 467 - if (usb_endpoint_xfer_int(&ep->desc)) 468 usb_fill_int_urb(rcv->urb, acm->dev, 469 acm->rx_endpoint, 470 buf->base, 471 acm->readsize, 472 - acm_read_bulk, rcv, ep->desc.bInterval); 473 else 474 usb_fill_bulk_urb(rcv->urb, acm->dev, 475 acm->rx_endpoint, ··· 1180 spin_lock_init(&acm->read_lock); 1181 mutex_init(&acm->mutex); 1182 acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); 1183 tty_port_init(&acm->port); 1184 acm->port.ops = &acm_port_ops; 1185
··· 387 struct acm_ru *rcv; 388 unsigned long flags; 389 unsigned char throttled; 390 391 dbg("Entering acm_rx_tasklet"); 392 ··· 463 464 rcv->buffer = buf; 465 466 + if (acm->is_int_ep) 467 usb_fill_int_urb(rcv->urb, acm->dev, 468 acm->rx_endpoint, 469 buf->base, 470 acm->readsize, 471 + acm_read_bulk, rcv, acm->bInterval); 472 else 473 usb_fill_bulk_urb(rcv->urb, acm->dev, 474 acm->rx_endpoint, ··· 1183 spin_lock_init(&acm->read_lock); 1184 mutex_init(&acm->mutex); 1185 acm->rx_endpoint = usb_rcvbulkpipe(usb_dev, epread->bEndpointAddress); 1186 + acm->is_int_ep = usb_endpoint_xfer_int(epread); 1187 + if (acm->is_int_ep) 1188 + acm->bInterval = epread->bInterval; 1189 tty_port_init(&acm->port); 1190 acm->port.ops = &acm_port_ops; 1191
+2
drivers/usb/class/cdc-acm.h
··· 126 unsigned int ctrl_caps; /* control capabilities from the class specific header */ 127 unsigned int susp_count; /* number of suspended interfaces */ 128 int combined_interfaces:1; /* control and data collapsed */ 129 struct acm_wb *delayed_wb; /* write queued for a device about to be woken */ 130 }; 131
··· 126 unsigned int ctrl_caps; /* control capabilities from the class specific header */ 127 unsigned int susp_count; /* number of suspended interfaces */ 128 int combined_interfaces:1; /* control and data collapsed */ 129 + int is_int_ep:1; /* interrupt endpoints contrary to spec used */ 130 + u8 bInterval; 131 struct acm_wb *delayed_wb; /* write queued for a device about to be woken */ 132 }; 133