Hi Jean,

can you test the attached modified patch please.
If it is OK we can forward it to
JE/Linus.

Thanks

Roman



Jean Tourrilhes wrote:
> 
> On Wed, Sep 19, 2001 at 03:42:18PM -0700, jt wrote:
> >
> >       I did a quick read in the source to see if I could implement
> > ZERO_PACKET. Well, let's just say that it's not as simple as I
> > tought. TD are done multiple of 4096, which doesn't fit with the code
> > I see in usb-uhci which have TD multiple of 64 (so you just need to
> > add an empty TD at the end). There must be some black magic there.
> 
>         Well, I'm totally stupid, the TD size doesn't matter. Just add
> a TD at the end and don't worry, be happy.
>         Patch attached. I don't know if the OHCI interface provide
> other way to do that more efficiently, but it works. Tested with my
> usual array of benchamrks and it's solid.
>         Enjoy...
> 
>         Jean
> 
> P.S. : Currently the irda-usb driver in the kernel can work only with
> usb-uhci, so if this patch could go in the kernel...
> 
>   ------------------------------------------------------------------------
> 
>    ir249_ohci_zero.diffName: ir249_ohci_zero.diff
>                        Type: Plain Text (text/plain)
--- usb.2.4.10pre12/usb-ohci.c  Thu Sep 20 09:41:52 2001
+++ usb/usb-ohci.c      Thu Sep 20 10:24:29 2001
@@ -12,6 +12,7 @@
  * 
  * History:
  * 
+ * 2001/09/19 USB_ZERO_PACKET support (Jean Tourrilhes)
  * 2001/07/17 power management and pmac cleanup (Benjamin Herrenschmidt)
  * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
        pci_map_single (db)
@@ -537,6 +538,7 @@
        ed_t * ed;
        urb_priv_t * urb_priv;
        unsigned int pipe = urb->pipe;
+       int maxps = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe));
        int i, size = 0;
        unsigned long flags;
        int bustime = 0;
@@ -579,6 +581,15 @@
        switch (usb_pipetype (pipe)) {
                case PIPE_BULK: /* one TD for every 4096 Byte */
                        size = (urb->transfer_buffer_length - 1) / 4096 + 1;
+
+                       /* If the transfer size is multiple of the pipe mtu,
+                        * we may need an extra TD to create a empty frame
+                        * Jean II */
+                       if ((urb->transfer_flags & USB_ZERO_PACKET) &&
+                           usb_pipeout (pipe) &&
+                           (urb->transfer_buffer_length != 0) && 
+                           ((urb->transfer_buffer_length % maxps) == 0))
+                               size++;
                        break;
                case PIPE_ISOCHRONOUS: /* number of packets from URB */
                        size = urb->number_of_packets;
@@ -1338,6 +1349,7 @@
        ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv;
        dma_addr_t data;
        int data_len = urb->transfer_buffer_length;
+       int maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe));
        int cnt = 0; 
        __u32 info = 0;
        unsigned int toggle = 0;
@@ -1374,6 +1386,19 @@
                                TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
                        td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 
data_len, urb, cnt);
                        cnt++;
+
+                       /* If the transfer size is multiple of the pipe mtu,
+                        * we may need an extra TD to create a empty frame
+                        * Note : another way to check this condition is
+                        * to test if(urb_priv->length > cnt) - Jean II */
+                       if ((urb->transfer_flags & USB_ZERO_PACKET) &&
+                           usb_pipeout (urb->pipe) &&
+                           (urb->transfer_buffer_length != 0) && 
+                           ((urb->transfer_buffer_length % maxps) == 0)) {
+                               td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), 0, 0, 
+urb, cnt);
+                               cnt++;
+                       }
+
                        if (!ohci->sleeping)
                                writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start 
bulk list */
                        break;

Reply via email to