On Sun, 24 Mar 2002, Johannes Erdfelt wrote:

> There's a slight bug in your fixed code. len will always be 0 at the end
> of the previous loop, so your check will always incorrectly add the last
> zero packet.

Right. Just realized this when I saw the irda-usb still sending zero
packets at the wrong place. Seems my thinko was I've mixed up len-=pktsze
with maxsze (IIRC it was formerly) and thought len would become <0 except
for the case where we want to add the zero packet :(

> Does this patch work correctly?

Looks like you've changed the code so my thinko would become right now.
Haven't tested yet but will do tonight - and AFAICS it should be ok.
Meanwhile I'm appending what I've done just now to solve the problem. It
is already tested and made irda-usb now completely happy with uhci.
I think it's up to you to select which one you prefer.

Martin

----------------------------------

--- linux-2.5.7/drivers/usb/uhci.c      Sun Mar 10 03:45:21 2002
+++ v2.5.7-md/drivers/usb/uhci.c        Mon Mar 25 08:21:22 2002
@@ -1223,6 +1223,7 @@
        unsigned long destination, status;
        struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
        int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
+       int pktsze;
        int len = urb->transfer_buffer_length;
        struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
        dma_addr_t data = urbp->transfer_buffer_dma_handle;
@@ -1247,7 +1248,7 @@
         * Build the DATA TD's
         */
        do {    /* Allow zero length packets */
-               int pktsze = len;
+               pktsze = len;
 
                if (pktsze > maxsze)
                        pktsze = maxsze;
@@ -1270,14 +1271,20 @@
                        usb_pipeout(urb->pipe));
        } while (len > 0);
 
-       if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) &&
-          urb->transfer_buffer_length) {
+       /* USB_ZERO_PACKET means adding a 0-length packet, if
+        * direction is OUT and the transfer_length was an
+        * exact multiple of maxsze, hence pktsze==maxsze for
+        * last non-zero packet - which also excludes the case
+        * where transfer_buffer_length==0 (already handled above)
+        */
+       if ((urb->transfer_flags&USB_ZERO_PACKET) && usb_pipeout(urb->pipe)
+           && pktsze==maxsze) {
                td = uhci_alloc_td(uhci, urb->dev);
                if (!td)
                        return -ENOMEM;
 
                uhci_add_td_to_urb(urb, td);
-               uhci_fill_td(td, status, destination | UHCI_NULL_DATA_SIZE |
+               uhci_fill_td(td, status, destination | (UHCI_NULL_DATA_SIZE<<21) |
                        (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe),
                         usb_pipeout(urb->pipe)) << TD_TOKEN_TOGGLE),
                        data);


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to