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;