Re: USB Storage Device Not Working
Felipe Balbi <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, On Mon, 19 Nov 2007 00:54:53 +0530, balajirrao <[email protected]> wrote: > On Mon, Nov 12, 2007 at 03:29:57PM -0500, Alan Stern wrote: >> On Mon, 12 Nov 2007, balajirrao wrote: >> >> > > You will have to add a new method pointer to struct usb_hcd, maybe > call >> >> I made a mistake here. The new method pointer should be added to >> struct hc_driver, not struct usb_hcd. In other words, it should be >> stored along with all the other method pointers. >> >> > > it "relinquish". In ehci-hub.c make the method routine check that > its >> > > argument really is attached to a port on the root hub and hand that >> > > port over to the companion controller. Then in hub.c if >> > > hub_port_connect_change() fails, make it invoke this new method. > > I have made the necessary corrections and this patch works perfectly. > Please tell me if there's a mistake, i will correct and send it > immediatly. > > > Index: linux-2.6.24-rc3/drivers/usb/core/hcd.h > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/core/hcd.h > +++ linux-2.6.24-rc3/drivers/usb/core/hcd.h > @@ -210,6 +210,8 @@ struct hc_driver { > int (*start_port_reset)(struct usb_hcd *, unsigned port_num); > void (*hub_irq_enable)(struct usb_hcd *); > /* Needed only if port-change IRQs are level-triggered */ > + /* forcefully handover port to companion */ > + void (*relinquish_port)(struct usb_hcd *, int); > }; > > extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); > Index: linux-2.6.24-rc3/drivers/usb/host/ehci-hub.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/host/ehci-hub.c > +++ linux-2.6.24-rc3/drivers/usb/host/ehci-hub.c > @@ -864,3 +864,33 @@ error: > spin_unlock_irqrestore (&ehci->lock, flags); > return retval; > } > + > +static void ehci_relinquish_port (struct usb_hcd *hcd, int portnum) { > + struct ehci_hcd *ehci; > + int port_status; > + u32 __iomem *status_reg; > + int try; > + > + ehci = hcd_to_ehci(hcd); > + status_reg = &ehci->regs->port_status[--portnum]; > + port_status = ehci_readl(ehci, status_reg); > + > + if (ehci_is_TDI(ehci)) > + return; > + > + for (try = 4; try > 0; --try) { > + spin_lock_irq(&ehci->lock); > + port_status = ehci_readl(ehci, status_reg); > + if ((port_status & PORT_OWNER) == PORT_OWNER) Unnecessary == PORT_OWNER. Use only if (port_status & PORT_OWNER) > + try = 0; > + else { > + port_status ^= PORT_OWNER; do you really need this xor here ?? port_status |= PORT_OWNER looks better to me. > + port_status &= ~(PORT_PE | PORT_RWC_BITS); > + ehci_writel(ehci, port_status, status_reg); > + } > + spin_unlock_irq(&ehci->lock); > + if (try > 1) > + msleep(5); > + } > +} > + > Index: linux-2.6.24-rc3/drivers/usb/host/ehci-pci.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/host/ehci-pci.c > +++ linux-2.6.24-rc3/drivers/usb/host/ehci-pci.c > @@ -364,6 +364,7 @@ static const struct hc_driver ehci_pci_h > .hub_control = ehci_hub_control, > .bus_suspend = ehci_bus_suspend, > .bus_resume = ehci_bus_resume, > + .relinquish_port = ehci_relinquish_port, > }; > > > /*-------------------------------------------------------------------------*/ > Index: linux-2.6.24-rc3/drivers/usb/core/hub.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/core/hub.c > +++ linux-2.6.24-rc3/drivers/usb/core/hub.c > @@ -2482,6 +2482,7 @@ static void hub_port_connect_change(stru > { > struct usb_device *hdev = hub->hdev; > struct device *hub_dev = hub->intfdev; > + struct usb_hcd *hcd = bus_to_hcd(hdev->bus); > u16 wHubCharacteristics = > le16_to_cpu(hub->descriptor->wHubCharacteristics); > int status, i; > > @@ -2645,6 +2646,8 @@ loop: > > done: > hub_port_disable(hub, port1, 1); > + if (hcd->driver->relinquish_port && !hub->hdev->parent) > + hcd->driver->relinquish_port(hcd, port1); > } > > static void hub_events(void) > Index: linux-2.6.24-rc3/drivers/usb/host/ehci-au1xxx.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/host/ehci-au1xxx.c > +++ linux-2.6.24-rc3/drivers/usb/host/ehci-au1xxx.c > @@ -222,6 +222,7 @@ static const struct hc_driver ehci_au1xx > .hub_control = ehci_hub_control, > .bus_suspend = ehci_bus_suspend, > .bus_resume = ehci_bus_resume, > + .relinquish_port = ehci_relinquish_port > }; > > > /*-------------------------------------------------------------------------*/ > Index: linux-2.6.24-rc3/drivers/usb/host/ehci-fsl.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/host/ehci-fsl.c > +++ linux-2.6.24-rc3/drivers/usb/host/ehci-fsl.c > @@ -323,6 +323,7 @@ static const struct hc_driver ehci_fsl_h > .hub_control = ehci_hub_control, > .bus_suspend = ehci_bus_suspend, > .bus_resume = ehci_bus_resume, > + .relinquish_port = ehci_relinquish_port, > }; > > static int ehci_fsl_drv_probe(struct platform_device *pdev) > Index: linux-2.6.24-rc3/drivers/usb/host/ehci-ppc-soc.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/host/ehci-ppc-soc.c > +++ linux-2.6.24-rc3/drivers/usb/host/ehci-ppc-soc.c > @@ -162,6 +162,7 @@ static const struct hc_driver ehci_ppc_s > .hub_control = ehci_hub_control, > .bus_suspend = ehci_bus_suspend, > .bus_resume = ehci_bus_resume, > + .relinquish_port = ehci_relinquish_port, > }; > > static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) > Index: linux-2.6.24-rc3/drivers/usb/host/ehci-ps3.c > =================================================================== > --- linux-2.6.24-rc3.orig/drivers/usb/host/ehci-ps3.c > +++ linux-2.6.24-rc3/drivers/usb/host/ehci-ps3.c > @@ -72,6 +72,7 @@ static const struct hc_driver ps3_ehci_h > .bus_suspend = ehci_bus_suspend, > .bus_resume = ehci_bus_resume, > #endif > + .relinquish_port = ehci_relinquish_port, > }; > > static int ps3_ehci_probe(struct ps3_system_bus_device *dev) > > -- > > regards, > > balaji rao > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2005. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > [email protected] > To unsubscribe, use the last form field at: > https://lists.sourceforge.net/lists/listinfo/linux-usb-devel -- Best Regards, Felipe Balbi http://felipebalbi.com [email protected] ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel