Re: Possible bug in isp116x-hcd

ok <[email protected]>
Newsgroups gmane.linux.usb.devel
Message-ID <[email protected]>
On Mon, Jun 18, 2007 at 11:00:10AM -0400, Alan Stern wrote:
> Olav,
> 
> What would be involved in refactoring isp116x-hcd so that the driver
> called usb_hcd_giveback_urb() as soon as the URB was completed?  If I
> understand the current code correctly, postproc_atl_queue() goes
> through all the active endpoints and stores the status for the
> completed URBs, and then later finish_atl_transfers() gives them back.
> 
> It looks like this shouldn't present any difficulty except for one 
> thing: When you get a short Control-IN transfer with URB_SHORT_NOT_OK 
> set, the error status gets stored while the URB's status stage 
> executes.  That would have to be changed so that the status stage was 
> skipped entirely.  Doing this shouldn't cause any problems in practice; 
> the other HCDs skip the status stage when this sort of error occurs.
> 
> The point of making this change is that it would allow the driver to 
> avoid saving values in urb->status, leading eventually to the 
> possibility of removing the status field from struct urb.

Hi Alan,

Do you mean something like that below? I haven't tested it.

Olav


--- linux-2.6.22-rc5-or/drivers/usb/host/isp116x-hcd.c	2007-06-17 05:09:12.000000000 +0300
+++ linux-2.6.22-rc5-isp/drivers/usb/host/isp116x-hcd.c	2007-06-20 22:49:27.000000000 +0300
@@ -210,6 +210,9 @@
 
 /*---------------------------------------------------------------*/
 
+static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep,
+			   struct urb *urb);
+
 /*
   Set up PTD's.
 */
@@ -296,11 +299,6 @@
 		short_not_ok = 1;
 		spin_lock(&urb->lock);
 
-		/* Data underrun is special. For allowed underrun
-		   we clear the error and continue as normal. For
-		   forbidden underrun we finish the DATA stage
-		   immediately while for control transfer,
-		   we do a STATUS stage. */
 		if (cc == TD_DATAUNDERRUN) {
 			if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) {
 				DBG("Allowed data underrun\n");
@@ -308,22 +306,16 @@
 				short_not_ok = 0;
 			} else {
 				ep->error_count = 1;
-				if (usb_pipecontrol(urb->pipe))
-					ep->nextpid = USB_PID_ACK;
-				else
-					usb_settoggle(udev, ep->epnum,
-						      ep->nextpid ==
-						      USB_PID_OUT,
-						      PTD_GET_TOGGLE(ptd));
+				usb_settoggle(udev, ep->epnum,
+					      ep->nextpid == USB_PID_OUT,
+					      PTD_GET_TOGGLE(ptd));
 				urb->actual_length += PTD_GET_COUNT(ptd);
 				urb->status = cc_to_error[TD_DATAUNDERRUN];
+				finish_request(isp116x, ep, urb);
 				spin_unlock(&urb->lock);
 				continue;
 			}
 		}
-		/* Keep underrun error through the STATUS stage */
-		if (urb->status == cc_to_error[TD_DATAUNDERRUN])
-			cc = TD_DATAUNDERRUN;
 
 		if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED
 		    && (++ep->error_count >= 3 || cc == TD_CC_STALL
@@ -332,6 +324,7 @@
 				urb->status = cc_to_error[cc];
 			if (ep->nextpid == USB_PID_ACK)
 				ep->nextpid = 0;
+			finish_request(isp116x, ep, urb);
 			spin_unlock(&urb->lock);
 			continue;
 		}
@@ -341,6 +334,7 @@
 		if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) {
 			if (urb->status == -EINPROGRESS)
 				urb->status = 0;
+			finish_request(isp116x, ep, urb);
 			spin_unlock(&urb->lock);
 			continue;
 		}
@@ -409,6 +403,8 @@
 		default:
 			BUG();
 		}
+		if (urb->status != -EINPROGRESS)
+			finish_request(isp116x, ep, urb);
 		spin_unlock(&urb->lock);
 	}
 }
@@ -570,9 +566,6 @@
 */
 static void finish_atl_transfers(struct isp116x *isp116x)
 {
-	struct isp116x_ep *ep;
-	struct urb *urb;
-
 	if (!isp116x->atl_active)
 		return;
 	/* Fifo not ready? */
@@ -582,16 +575,6 @@
 	atomic_inc(&isp116x->atl_finishing);
 	unpack_fifo(isp116x);
 	postproc_atl_queue(isp116x);
-	for (ep = isp116x->atl_active; ep; ep = ep->active) {
-		urb =
-		    container_of(ep->hep->urb_list.next, struct urb, urb_list);
-		/* USB_PID_ACK check here avoids finishing of
-		   control transfers, for which TD_DATAUNDERRUN
-		   occured, while URB_SHORT_NOT_OK was set */
-		if (urb && urb->status != -EINPROGRESS
-		    && ep->nextpid != USB_PID_ACK)
-			finish_request(isp116x, ep, urb);
-	}
 	atomic_dec(&isp116x->atl_finishing);
 }
 

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.