# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.564 -> 1.565 # drivers/usb/host/ohci-hub.c 1.6 -> 1.7 # drivers/usb/host/ohci-q.c 1.6 -> 1.7 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/04/30 david-b@pacbell.net 1.565 # [PATCH] Re: ohci-hcd and that NCR implementation ... # # The attached patch makes the one SiS controller behave # like the other... the key fix being wmb() to make sure that # no writes are still in CPU caches before telling the HC it's # OK to fetch the data. (And a minor tweak to access PCI # less often through the hub driver.) # # But the OPTi problem seems to be different. Could you # try this patch to see if it affects the problem your seeing # with that NCR implementation? And in any case, please # integrate it to Linus' latest. (Against 2.5.10, might be # some fuzz on the pci tweak due to that warning fix.) # # Those missing wmb() statements have likely been the root # cause of various usb-ohci flakes reported over time, too. # The drivers are still almost identical in those areas. (Though # something made ohci-hcd consistently lose that cache flush # race; maybe it's a bit faster.) # -------------------------------------------- # diff -Nru a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c --- a/drivers/usb/host/ohci-hub.c Thu May 2 16:48:29 2002 +++ b/drivers/usb/host/ohci-hub.c Thu May 2 16:48:29 2002 @@ -154,12 +154,10 @@ u16 wLength ) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); - int ports; + int ports = hcd->self.root_hub->maxchild; u32 temp; int retval = 0; - // if (port request) - ports = roothub_a (ohci) & RH_A_NDP; switch (typeReq) { case ClearHubFeature: switch (wValue) { diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c --- a/drivers/usb/host/ohci-q.c Thu May 2 16:48:29 2002 +++ b/drivers/usb/host/ohci-q.c Thu May 2 16:48:29 2002 @@ -569,6 +569,9 @@ td->hwNextTD = cpu_to_le32 (td_pt->td_dma); td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000); + /* HC might read the TD right after we link it ... */ + wmb (); + /* append to queue */ td->ed->hwTailP = td->hwNextTD; } @@ -641,8 +644,10 @@ cnt++; } /* start bulk list */ - if (!ohci->sleeping) + if (!ohci->sleeping) { + wmb (); writel (OHCI_BLF, &ohci->regs->cmdstatus); + } break; case PIPE_INTERRUPT: @@ -654,6 +659,7 @@ break; case PIPE_CONTROL: + /* control requests don't use toggle state */ info = TD_CC | TD_DP_SETUP | TD_T_DATA0; td_fill (ohci, info, #ifdef CONFIG_PCI @@ -678,8 +684,10 @@ : TD_CC | TD_DP_OUT | TD_T_DATA1; td_fill (ohci, info, data, 0, urb, cnt++); /* start control list */ - if (!ohci->sleeping) + if (!ohci->sleeping) { + wmb (); writel (OHCI_CLF, &ohci->regs->cmdstatus); + } break; case PIPE_ISOCHRONOUS: