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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.