Re: Oops in CDC ACM after an Openmoko phone (neo1973) changes its usb interface from ACM to Ethernet

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

 



Am Dienstag, 4. August 2009 11:04:33 schrieb Alex Riesen:
> On Tue, Aug 4, 2009 at 09:39, Oliver Neukum<oliver@xxxxxxxxxx> wrote:
> > +               if (!ep) { /* disconnected ? */
> > +                       spin_lock_irqsave(&acm->read_lock, flags);
> > +                       list_add(&buf->list, &acm->spare_read_bufs);
> > +                       list_add(&rcv->list, &acm->spare_read_urbs);
> > +                       acm->processing = 0;
> > +                       spin_unlock_irqrestore(&acm->read_lock, flags);
> > +                       return;
> > +               }
>
> Now it locks up with a warning (which scrolled away) from lockdep as soon
> as I close minicom. Softlock checker hits eventually (after a min).
>
> Hard to reproduce...

Alan's words are wise. Try this one.

	Regards
		Oliver

--

commit 2eef5561ca6d6f5b1312e4feedbc9640f023fa23
Author: Oliver Neukum <oliver@xxxxxxxxxx>
Date:   Tue Aug 4 21:59:12 2009 +0200

    usb: cdc-acm: catch usb_enable_endpoint nulling the array of endpoints

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index e1f8941..c07bcaf 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");
 
@@ -462,15 +461,13 @@ urbs:
 		list_del(&buf->list);
 
 		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 1602324..c4a0ee8 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 */
 };
 

--
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