I have captured a few dumps when this failure is happening. It ~always~ happens to the same type of transfer:
Enqueue: FA 2 ep2in bulk: len 13 short_ok pack_fifo @ c5d6/2e9c fmrem CC=f EP=2 DIR=2 CNT=0 LEN=13 MPS=64 TGL=1 ACT=1 FA=2 SPD=0 LST=1 B5=0 fc00 2840 080d 0002 unpack_fifo @ c5d7/73 fmrem CC=f EP=2 DIR=2 CNT=0 LEN=13 MPS=64 TGL=1 ACT=1 FA=2 SPD=0 LST=1 B5=0 fc00 2840 080d 0002 But it does not always happen at the same instance when this PTD is sent. Since I had this working prior to the latest changes, I incrementally imported your latest changes and narrowed it down to the short/underrun handling. I'm not saying this is bug, but this is causing what I am seeing. Below are the only changes between what I see as working what is not working (left is the working version). So for now, I will leave these changes out, but I'm sure you had some good reasons for these. I will send you some captures that show when this is happening, maybe you can see a pattern. >From what I can see the toggle bit is correct from the last transaction on endpoint 2. I have several failure logs, but I only have a log for the working system up until mounting the partition. After that my test that I am using for this would likely overflow my log buffer. For the endianness, the low level access functions are correct now. But because the URB transfer buffers are byte streams I needed to flip them in read/write_ptddata_from/to_fifo() before packing them into the 16-bit data field for isp116x_write_data except for the last byte. I need to have another look at it. What I have now seems to work, but it doesn't quite make sense to me. The only diffs: <working> <lockup> static void postproc_atl_queue(struct isp116x *isp116x) static void postproc_atl_queue(struct isp116x *isp116x) { { struct isp116x_ep *ep; struct isp116x_ep *ep; struct isp116x_req *req; struct isp116x_req *req; struct urb *urb; struct urb *urb; struct usb_device *udev; struct usb_device *udev; struct ptd *ptd; struct ptd *ptd; int partial_not_ok; | int short_not_ok; u8 cc; u8 cc; for (ep = isp116x->atl_active; ep; ep = ep->active) { for (ep = isp116x->atl_active; ep; ep = ep->active) { BUG_ON(list_empty(&ep->queue)); BUG_ON(list_empty(&ep->queue)); req = container_of(ep->queue.next, struct isp req = container_of(ep->queue.next, struct isp urb = req->urb; urb = req->urb; udev = urb->dev; udev = urb->dev; ptd = &ep->ptd; ptd = &ep->ptd; partial_not_ok = 1; < cc = PTD_GET_CC(ptd); cc = PTD_GET_CC(ptd); spin_lock(&urb->lock); spin_lock(&urb->lock); if (cc == TD_DATAUNDERRUN | short_not_ok = urb->transfer_flags & URB_SHORT_NOT_OK && !(urb->transfer_flags & URB_SHORT_NOT_ | //DBG("Allowed data underrun\n"); | /* 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 (! short_not_ok){ > DBG("Allowed data underrun\n"); cc = TD_CC_NOERROR; cc = TD_CC_NOERROR; partial_not_ok = 0; | }else{ } | ep->error_count = 1; if (PTD_GET_COUNT(ptd) || cc == TD_CC_NOERROR | if (usb_pipecontrol(urb->pipe)) ep->error_count = 0; | ep->nextpid = USB_PID_ACK; > else > usb_settoggle(udev, ep->epnum, ep->nextpid == U > urb->status = cc_to_error[TD_DATAUNDERRUN]; > 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 < 0x0E if (cc != TD_CC_NOERROR && cc < 0x0E && (++ep->error_count >= 3 || cc == TD_CC | && (++ep->error_count >= 3 || cc == TD_CC if (urb->status == -EINPROGRESS) if (urb->status == -EINPROGRESS) urb->status = cc_to_error[cc] urb->status = cc_to_error[cc] > // DBG("%d: nextpid %d, status %d, err > if (ep->nextpid == USB_PID_ACK) > ep->nextpid = 0; spin_unlock(&urb->lock); spin_unlock(&urb->lock); continue; continue; } -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] Behalf Of Olav Kongas Sent: Wednesday, January 19, 2005 6:43 AM To: Philipp Schmid Cc: linux-usb-devel@lists.sourceforge.net Subject: RE: [linux-usb-devel] isp116x-hcd update On Tue, 18 Jan 2005, Philipp Schmid wrote: > usb-storage: usb_stor_bulk_transfer_sglist: xfer 1024 bytes, 1 entries > usb-storage: Status code 0; transferred 832/1024 <= single PTD > usb-storage: -- short transfer > usb-storage: Bulk data transfer result 0x1 I haven't seen these messages. All my 3 storage devices work smoothly. Also, usbtests #1-8 (bulk transfer tests) seem to work reliably. > This case did not seem to happen before importing your latest changes > (likely because this case wasn't hit). The main changes being PTD length > handling in start_atl_transfers() and changes in postproc_atl_queue(). > Changing MAX_TRANSFER_SIZE_FULLSPEED doesn't seem to help. I also changed endianness handling. Though, if there was something wrong with that, it probably wouldn't work at all for you. Did you have to correct endianness? > PTDs: > > start_atl_transfers > pack_fifo @ f6d6/2e8c fmrem > CC=f EP=2 DIR=2 CNT=0 LEN=13 MPS=64 TGL=1 ACT=1 FA=2 SPD=0 LST=1 B5=0 > fc00 2840 080d 0002 > unpack_fifo @ f6d8/7b fmrem <= Note the late unpack Late unpacking *shouldn't* be a problem. > read_ptddata_from_fifo 2 13 > CC=f EP=2 DIR=2 CNT=0 LEN=13 MPS=64 TGL=1 ACT=1 FA=2 SPD=0 LST=1 B5=0 > fc00 2840 080d 0002 > ----- > start_atl_transfers > pack_fifo @ f6db/2e98 fmrem > CC=f EP=2 DIR=2 CNT=0 LEN=13 MPS=64 TGL=1 ACT=1 FA=2 SPD=0 LST=1 B5=0 > fc00 2840 080d 0002 > unpack_fifo @ f6dd/7b fmrem > read_ptddata_from_fifo 2 13 > CC=f EP=2 DIR=2 CNT=0 LEN=13 MPS=64 TGL=1 ACT=1 FA=2 SPD=0 LST=1 B5=0 > fc00 2840 080d 0002 > ..... continues This log shows that the device is NAK-ing the request. One reason may be that the device is not ready to send the last portion of the data. But fig.8-33 in usb 2.0 spec shows also another possible reason: host should do the same command also when it gets otherwise correct data, but just the toggle bit does not match. This would mean that the device already sent the latter portion of the data, which HC ignored, because it expected another toggle value, while the device just has nothing more to send. It may well be that I haven't got the toggle bit handling after errors right in the driver. The isp chip seems to have its own understanding of what to do with the toggle bit in case of errors and this does not fit with the spec; neither have I found it documented anywhere. Perhaps your system triggers some (recoverable) error conditions, which I don't see here and haven't therefore straightened out. I will take another look at the toggle bit handling. It would help if you could post PTD dumps from both older (working) and the latest driver versions so that the Toggle bit history for bulk transfers could be compared. Olav ------------------------------------------------------- The SF.Net email is sponsored by: Beat the post-holiday blues Get a FREE limited edition SourceForge.net t-shirt from ThinkGeek. It's fun and FREE -- well, almost....http://www.thinkgeek.com/sfshirt _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel ------------------------------------------------------- This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting Tool for open source databases. Create drag-&-drop reports. Save time by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. Download a FREE copy at http://www.intelliview.com/go/osdn_nl _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel