Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 82215
b: refs/heads/master
c: 90da096
h: refs/heads/master
i:
  82213: 558dc50
  82211: e99c1e6
  82207: 2494593
v: v3
  • Loading branch information
Balaji Rao authored and Greg Kroah-Hartman committed Feb 1, 2008
1 parent 9bc06b8 commit 089360f
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 25 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: eb0be47dbbdca133b1b94adc564297f25176b3ab
refs/heads/master: 90da096ee46b682011b7d549e52b81cf9742e60b
3 changes: 3 additions & 0 deletions trunk/drivers/usb/core/hcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ 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 */

/* force handover of high-speed port to full-speed companion */
void (*relinquish_port)(struct usb_hcd *, int);
};

extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
{
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;

Expand Down Expand Up @@ -2645,6 +2646,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,

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)
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci-au1xxx.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
.hub_control = ehci_hub_control,
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
};

/*-------------------------------------------------------------------------*/
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci-fsl.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
.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)
Expand Down
68 changes: 44 additions & 24 deletions trunk/drivers/usb/host/ehci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,41 +314,21 @@ static ssize_t show_companion(struct device *dev,
}

/*
* Dedicate or undedicate a port to the companion controller.
* Syntax is "[-]portnum", where a leading '-' sign means
* return control of the port to the EHCI controller.
* Sets the owner of a port
*/
static ssize_t store_companion(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
static void set_owner(struct ehci_hcd *ehci, int portnum, int new_owner)
{
struct ehci_hcd *ehci;
int portnum, new_owner, try;
u32 __iomem *status_reg;
u32 port_status;
int try;

ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev)));
new_owner = PORT_OWNER; /* Owned by companion */
if (sscanf(buf, "%d", &portnum) != 1)
return -EINVAL;
if (portnum < 0) {
portnum = - portnum;
new_owner = 0; /* Owned by EHCI */
}
if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params))
return -ENOENT;
status_reg = &ehci->regs->port_status[--portnum];
if (new_owner)
set_bit(portnum, &ehci->companion_ports);
else
clear_bit(portnum, &ehci->companion_ports);
status_reg = &ehci->regs->port_status[portnum];

/*
* The controller won't set the OWNER bit if the port is
* enabled, so this loop will sometimes require at least two
* iterations: one to disable the port and one to set OWNER.
*/

for (try = 4; try > 0; --try) {
spin_lock_irq(&ehci->lock);
port_status = ehci_readl(ehci, status_reg);
Expand All @@ -365,6 +345,36 @@ static ssize_t store_companion(struct device *dev,
if (try > 1)
msleep(5);
}
}

/*
* Dedicate or undedicate a port to the companion controller.
* Syntax is "[-]portnum", where a leading '-' sign means
* return control of the port to the EHCI controller.
*/
static ssize_t store_companion(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct ehci_hcd *ehci;
int portnum, new_owner;

ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev)));
new_owner = PORT_OWNER; /* Owned by companion */
if (sscanf(buf, "%d", &portnum) != 1)
return -EINVAL;
if (portnum < 0) {
portnum = - portnum;
new_owner = 0; /* Owned by EHCI */
}
if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params))
return -ENOENT;
portnum--;
if (new_owner)
set_bit(portnum, &ehci->companion_ports);
else
clear_bit(portnum, &ehci->companion_ports);
set_owner(ehci, portnum, new_owner);
return count;
}
static DEVICE_ATTR(companion, 0644, show_companion, store_companion);
Expand Down Expand Up @@ -867,3 +877,13 @@ static int ehci_hub_control (
spin_unlock_irqrestore (&ehci->lock, flags);
return retval;
}

static void ehci_relinquish_port(struct usb_hcd *hcd, int portnum)
{
struct ehci_hcd *ehci = hcd_to_ehci(hcd);

if (ehci_is_TDI(ehci))
return;
set_owner(ehci, --portnum, PORT_OWNER);
}

1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ static const struct hc_driver ehci_pci_hc_driver = {
.hub_control = ehci_hub_control,
.bus_suspend = ehci_bus_suspend,
.bus_resume = ehci_bus_resume,
.relinquish_port = ehci_relinquish_port,
};

/*-------------------------------------------------------------------------*/
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci-ppc-soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = {
.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)
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/host/ehci-ps3.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ static const struct hc_driver ps3_ehci_hc_driver = {
.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)
Expand Down

0 comments on commit 089360f

Please sign in to comment.