On Tue, 16 Oct 2007, David Miller wrote:Okay, below is my patch with a warning message. It isn't just fine. See below for comments. Where did 100 come from? Why not rely on the reset_done criterion, which clearly is what you want? Why have two tests for end-of-loop? This also is a somewhat arbitrary limit. There's no obvious reason why PORT_RESET_HW_MSEC should be both the limit for this loop and the length of the msleep below. I realize that you are copying existing code here, but this makes the same kind of mistake you are trying to fix. If a broken controller fails to increment its framenumber register, this termination condition will never be satisfied. Better to compare against a jiffies value. What reason is there for having two warning messages? One ought to be enough. Alan Stern Index: usb-2.6/drivers/usb/host/ohci-hub.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ohci-hub.c +++ usb-2.6/drivers/usb/host/ohci-hub.c @@ -560,10 +560,10 @@ static void start_hnp(struct ohci_hcd *o /* called from some task, normally khubd */ static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) { - __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; - u32 temp; - u16 now = ohci_readl(ohci, &ohci->regs->fmnumber); - u16 reset_done = now + PORT_RESET_MSEC; + __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus[port]; + u32 temp; + unsigned long reset_done = jiffies + + msecs_to_jiffies(PORT_RESET_MSEC); /* build a "continuous enough" reset signal, with up to * 3msec gap between pulses. scheduler HZ==100 must work; @@ -578,6 +578,12 @@ static inline int root_port_reset (struc return -ESHUTDOWN; if (!(temp & RH_PS_PRS)) break; + if (time_after(jiffies, reset_done)) { + ohci_warn(ohci, "Port %d reset timeout, " + "status %x\n", + port + 1, temp); + break; + } udelay (500); } @@ -589,8 +595,7 @@ static inline int root_port_reset (struc /* start the next reset, sleep till it's probably done */ ohci_writel (ohci, RH_PS_PRS, portstat); msleep(PORT_RESET_HW_MSEC); - now = ohci_readl(ohci, &ohci->regs->fmnumber); - } while (tick_before(now, reset_done)); + } while (time_before_eq(jiffies, reset_done)); /* caller synchronizes using PRSC */ return 0; -
| David Miller | Re: Slow DOWN, please!!! |
| Tarkan Erimer | Re: Dual-Licensing Linux Kernel with GPL V2 and GPL V3 |
| Greg Kroah-Hartman | [PATCH 001/196] Chinese: Add the known_regression URI to the HOWTO |
| Greg KH | Re: [AppArmor 39/45] AppArmor: Profile loading and manipulation, pathname matching |
git: | |
| Jarek Poplawski | [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Josip Rodin | bnx2_poll panicking kernel |
| David Miller | [GIT]: Networking |
| Gerrit Renker | [PATCH 27/37] dccp: Integration of dynamic feature activation - part 2 (server side) |
