David Brownell wrote:
> 
> > And I have also found a bug but it seems it's not the 'right' one
> > for this problem:
> >
> > urb_free_priv () just unmaps the last part (belonging to the last TD)
> > of the data buffer.
> 
> I'll have to patch that.  Clearly I was thinking I made OHCI do
> this the same way as EHCI ... not quite!  :)
> 
> This won't be an issue on x86 or other platforms that implement
> the mappings by virt_to_bus() calls, or for transfers that fit into
> exactly one TD.  Since 4 KBytes fits into one OHCI TD, that
> explains why this one may not have been seen "in the wild" yet.
> 
Hi Dave,

 here is the patch I have used so far.

-Roman

> - Dave
> 
> _______________________________________________
> [EMAIL PROTECTED]
> To unsubscribe, use the last form field at:
> http://lists.sourceforge.net/lists/listinfo/linux-usb-devel
--- drivers/usb.org/usb-ohci.c  Sun Jun  3 13:49:15 2001
+++ drivers/usb/usb-ohci.c      Thu Jun  7 17:19:21 2001
@@ -136,28 +136,39 @@
 {
        int             i;
        int             last = urb_priv->length - 1;
+       int             len;
+       int             dir;
        struct td       *td;
 
-       for (i = 0; i <= last; i++) {
-               td = urb_priv->td [i];
-               if (td) {
-                       int             len;
-                       int             dir;
+       if (last >= 0) {
 
-                       if ((td->hwINFO & cpu_to_le32 (TD_DP)) == TD_DP_SETUP) {
-                               len = 8;
-                               dir = PCI_DMA_TODEVICE;
-                       } else if (i == last) {
-                               len = td->urb->transfer_buffer_length,
-                               dir = usb_pipeout (td->urb->pipe)
+               /* ISOC, BULK, INTR data buffer starts at td 0 
+                * CTRL setup starts at td 0 */
+               td = urb_priv->td [0];
+
+               len = td->urb->transfer_buffer_length,
+               dir = usb_pipeout (td->urb->pipe)
                                        ? PCI_DMA_TODEVICE
                                        : PCI_DMA_FROMDEVICE;
-                       } else
-                               len = dir = 0;
-                       if (len && td->data_dma)
-                               pci_unmap_single (hc->ohci_dev,
-                                       td->data_dma, len, dir);
-                       td_free (hc, urb_priv->td [i]);
+
+               /* unmap CTRL URB setup */
+               if (usb_pipecontrol (td->urb->pipe)) {
+                       pci_unmap_single (hc->ohci_dev, 
+                                       td->data_dma, 8, PCI_DMA_TODEVICE);
+                       
+                       /* CTRL data buffer starts at td 1 if len > 0 */
+                       if (len && last > 0)
+                               td = urb_priv->td [1];          
+               } 
+
+               /* unmap data buffer */
+               if (len && td->data_dma)
+                       pci_unmap_single (hc->ohci_dev, td->data_dma, len, dir);
+               
+               for (i = 0; i <= last; i++) {
+                       td = urb_priv->td [i];
+                       if (td)
+                               td_free (hc, td);
                }
        }
 

Reply via email to