Commit d99f6b41 authored by Dan Williams's avatar Dan Williams Committed by Greg Kroah-Hartman

usb: rename usb_port device objects

The current port name "portX" is ambiguous.  Before adding more port
messages rename ports to "<hub-device-name>-portX"

This is an ABI change, but the suspicion is that it will go unnoticed as
the port power control implementation has been broken since its
introduction.  If however, someone was relying on the old name we can
add sysfs links from the old name to the new name.

Additionally, it unifies/simplifies port dev_printk messages and modifies
instances of:
	dev_XXX(hub->intfdev, ..."port %d"...
	dev_XXX(&hdev->dev, ..."port%d"...
into:
	dev_XXX(&port_dev->dev, ...

Now that the names are unique usb_port devices it would be nice if they
could be included in /sys/bus/usb.  However, it turns out that this
breaks 'lsusb -t'.  For now, create a dummy port driver so that print
messages are prefixed "usb 1-1-port3" rather than the
subsystem-ambiguous " 1-1-port3".

Finally, it corrects an odd usage of sscanf("port%d") in usb-acpi.c.
Suggested-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9262c19d
......@@ -412,30 +412,35 @@ static int set_port_feature(struct usb_device *hdev, int port1, int feature)
NULL, 0, 1000);
}
static char *to_led_name(int selector)
{
switch (selector) {
case HUB_LED_AMBER:
return "amber";
case HUB_LED_GREEN:
return "green";
case HUB_LED_OFF:
return "off";
case HUB_LED_AUTO:
return "auto";
default:
return "??";
}
}
/*
* USB 2.0 spec Section 11.24.2.7.1.10 and table 11-7
* for info about using port indicators
*/
static void set_port_led(
struct usb_hub *hub,
int port1,
int selector
)
static void set_port_led(struct usb_hub *hub, int port1, int selector)
{
int status = set_port_feature(hub->hdev, (selector << 8) | port1,
struct usb_port *port_dev = hub->ports[port1 - 1];
int status;
status = set_port_feature(hub->hdev, (selector << 8) | port1,
USB_PORT_FEAT_INDICATOR);
if (status < 0)
dev_dbg (hub->intfdev,
"port %d indicator %s status %d\n",
port1,
({ char *s; switch (selector) {
case HUB_LED_AMBER: s = "amber"; break;
case HUB_LED_GREEN: s = "green"; break;
case HUB_LED_OFF: s = "off"; break;
case HUB_LED_AUTO: s = "auto"; break;
default: s = "??"; break;
} s; }),
status);
dev_dbg(&port_dev->dev, "indicator %s status %d\n",
to_led_name(selector), status);
}
#define LED_CYCLE_PERIOD ((2*HZ)/3)
......@@ -909,20 +914,20 @@ static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
msleep(HUB_DEBOUNCE_STEP);
}
if (total_time >= HUB_DEBOUNCE_TIMEOUT)
dev_warn(hub->intfdev, "Could not disable port %d after %d ms\n",
port1, total_time);
dev_warn(&hub->ports[port1 - 1]->dev,
"Could not disable after %d ms\n", total_time);
return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT);
}
static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
{
struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *hdev = hub->hdev;
int ret = 0;
if (hub->ports[port1 - 1]->child && set_state)
usb_set_device_state(hub->ports[port1 - 1]->child,
USB_STATE_NOTATTACHED);
if (port_dev->child && set_state)
usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
if (!hub->error) {
if (hub_is_superspeed(hub->hdev))
ret = hub_usb3_port_disable(hub, port1);
......@@ -931,8 +936,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
USB_PORT_FEAT_ENABLE);
}
if (ret && ret != -ENODEV)
dev_err(hub->intfdev, "cannot disable port %d (err = %d)\n",
port1, ret);
dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
return ret;
}
......@@ -943,7 +947,7 @@ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
*/
static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
{
dev_dbg(hub->intfdev, "logical disconnect on port %d\n", port1);
dev_dbg(&hub->ports[port1 - 1]->dev, "logical disconnect\n");
hub_port_disable(hub, port1, 1);
/* FIXME let caller ask to power down the port:
......@@ -1081,21 +1085,23 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
}
init2:
/* Check each port and set hub->change_bits to let khubd know
/*
* Check each port and set hub->change_bits to let khubd know
* which ports need attention.
*/
for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
struct usb_device *udev = hub->ports[port1 - 1]->child;
struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *udev = port_dev->child;
u16 portstatus, portchange;
portstatus = portchange = 0;
status = hub_port_status(hub, port1, &portstatus, &portchange);
if (udev || (portstatus & USB_PORT_STAT_CONNECTION))
dev_dbg(hub->intfdev,
"port %d: status %04x change %04x\n",
port1, portstatus, portchange);
dev_dbg(&port_dev->dev, "status %04x change %04x\n",
portstatus, portchange);
/* After anything other than HUB_RESUME (i.e., initialization
/*
* After anything other than HUB_RESUME (i.e., initialization
* or any sort of reset), every port should be disabled.
* Unconnected ports should likewise be disabled (paranoia),
* and so should ports for which we have no usb_device.
......@@ -2571,9 +2577,9 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
if (delay_time >= 2 * HUB_SHORT_RESET_TIME)
delay = HUB_LONG_RESET_TIME;
dev_dbg (hub->intfdev,
"port %d not %sreset yet, waiting %dms\n",
port1, warm ? "warm " : "", delay);
dev_dbg(&hub->ports[port1 - 1]->dev,
"not %sreset yet, waiting %dms\n",
warm ? "warm " : "", delay);
}
if ((portstatus & USB_PORT_STAT_RESET))
......@@ -2657,6 +2663,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
{
int i, status;
u16 portchange, portstatus;
struct usb_port *port_dev = hub->ports[port1 - 1];
if (!hub_is_superspeed(hub->hdev)) {
if (warm) {
......@@ -2690,9 +2697,9 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
if (status == -ENODEV) {
; /* The hub is gone */
} else if (status) {
dev_err(hub->intfdev,
"cannot %sreset port %d (err = %d)\n",
warm ? "warm " : "", port1, status);
dev_err(&port_dev->dev,
"cannot %sreset (err = %d)\n",
warm ? "warm " : "", status);
} else {
status = hub_port_wait_reset(hub, port1, udev, delay,
warm);
......@@ -2725,21 +2732,19 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
* hot or warm reset failed. Try another warm reset.
*/
if (!warm) {
dev_dbg(hub->intfdev, "hot reset failed, warm reset port %d\n",
port1);
dev_dbg(&port_dev->dev,
"hot reset failed, warm reset\n");
warm = true;
}
}
dev_dbg (hub->intfdev,
"port %d not enabled, trying %sreset again...\n",
port1, warm ? "warm " : "");
dev_dbg(&port_dev->dev,
"not enabled, trying %sreset again...\n",
warm ? "warm " : "");
delay = HUB_LONG_RESET_TIME;
}
dev_err (hub->intfdev,
"Cannot enable port %i. Maybe the USB cable is bad?\n",
port1);
dev_err(&port_dev->dev, "Cannot enable. Maybe the USB cable is bad?\n");
done:
if (!hub_is_superspeed(hub->hdev))
......@@ -2790,6 +2795,8 @@ static int check_port_resume_type(struct usb_device *udev,
struct usb_hub *hub, int port1,
int status, unsigned portchange, unsigned portstatus)
{
struct usb_port *port_dev = hub->ports[port1 - 1];
/* Is the device still present? */
if (status || port_is_suspended(hub, portstatus) ||
!port_is_power_on(hub, portstatus) ||
......@@ -2809,9 +2816,8 @@ static int check_port_resume_type(struct usb_device *udev,
}
if (status) {
dev_dbg(hub->intfdev,
"port %d status %04x.%04x after resume, %d\n",
port1, portchange, portstatus, status);
dev_dbg(&port_dev->dev, "status %04x.%04x after resume, %d\n",
portchange, portstatus, status);
} else if (udev->reset_resume) {
/* Late port handoff can set status-change bits */
......@@ -3042,8 +3048,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
status = 0;
}
if (status) {
dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
port1, status);
dev_dbg(&port_dev->dev, "can't suspend, status %d\n", status);
/* Try to enable USB3 LPM and LTM again */
usb_unlocked_enable_lpm(udev);
......@@ -3234,8 +3239,6 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
if (status == 0 && !port_is_suspended(hub, portstatus))
goto SuspendCleared;
/* dev_dbg(hub->intfdev, "resume port %d\n", port1); */
set_bit(port1, hub->busy_bits);
/* see 7.1.7.7; affects power usage, but not budgeting */
......@@ -3245,8 +3248,7 @@ int usb_port_resume(struct usb_device *udev, pm_message_t msg)
status = usb_clear_port_feature(hub->hdev,
port1, USB_PORT_FEAT_SUSPEND);
if (status) {
dev_dbg(hub->intfdev, "can't resume port %d, status %d\n",
port1, status);
dev_dbg(&port_dev->dev, "can't resume, status %d\n", status);
} else {
/* drive resume for at least 20 msec */
dev_dbg(&udev->dev, "usb %sresume\n",
......@@ -3347,12 +3349,11 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
*/
hub->wakeup_enabled_descendants = 0;
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *udev = port_dev->child;
udev = hub->ports[port1 - 1]->child;
if (udev && udev->can_submit) {
dev_warn(&intf->dev, "port %d not suspended yet\n",
port1);
dev_warn(&port_dev->dev, "not suspended yet\n");
if (PMSG_IS_AUTO(msg))
return -EBUSY;
}
......@@ -3892,9 +3893,10 @@ EXPORT_SYMBOL_GPL(usb_enable_ltm);
int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)
{
int ret;
int total_time, stable_time = 0;
u16 portchange, portstatus;
unsigned connection = 0xffff;
int total_time, stable_time = 0;
struct usb_port *port_dev = hub->ports[port1 - 1];
for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
ret = hub_port_status(hub, port1, &portstatus, &portchange);
......@@ -3923,9 +3925,8 @@ int hub_port_debounce(struct usb_hub *hub, int port1, bool must_be_connected)
msleep(HUB_DEBOUNCE_STEP);
}
dev_dbg (hub->intfdev,
"debounce: port %d: total %dms stable %dms status 0x%x\n",
port1, total_time, stable_time, portstatus);
dev_dbg(&port_dev->dev, "debounce total %dms stable %dms status 0x%x\n",
total_time, stable_time, portstatus);
if (stable_time < HUB_DEBOUNCE_STABLE)
return -ETIMEDOUT;
......@@ -3984,13 +3985,14 @@ static int hub_set_address(struct usb_device *udev, int devnum)
*/
static void hub_set_initial_usb2_lpm_policy(struct usb_device *udev)
{
int connect_type;
struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
int connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
if (!udev->usb2_hw_lpm_capable)
return;
connect_type = usb_get_hub_port_connect_type(udev->parent,
udev->portnum);
if (hub)
connect_type = hub->ports[udev->portnum - 1]->connect_type;
if ((udev->bos->ext_cap->bmAttributes & cpu_to_le32(USB_BESL_SUPPORT)) ||
connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
......@@ -4366,9 +4368,10 @@ hub_power_remaining (struct usb_hub *hub)
remaining = hdev->bus_mA - hub->descriptor->bHubContrCurrent;
for (port1 = 1; port1 <= hdev->maxchild; ++port1) {
struct usb_device *udev = hub->ports[port1 - 1]->child;
int delta;
unsigned unit_load;
struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *udev = port_dev->child;
unsigned unit_load;
int delta;
if (!udev)
continue;
......@@ -4388,9 +4391,8 @@ hub_power_remaining (struct usb_hub *hub)
else
delta = 8;
if (delta > hub->mA_per_port)
dev_warn(&udev->dev,
"%dmA is over %umA budget for port %d!\n",
delta, hub->mA_per_port, port1);
dev_warn(&port_dev->dev, "%dmA is over %umA budget!\n",
delta, hub->mA_per_port);
remaining -= delta;
}
if (remaining < 0) {
......@@ -4413,15 +4415,14 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
u16 portstatus, u16 portchange)
{
struct usb_device *hdev = hub->hdev;
struct device *hub_dev = hub->intfdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
struct usb_port *port_dev = hub->ports[port1 - 1];
struct usb_device *udev;
int status, i;
unsigned unit_load;
dev_dbg (hub_dev,
"port %d, status %04x, change %04x, %s\n",
port1, portstatus, portchange, portspeed(hub, portstatus));
dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n",
portstatus, portchange, portspeed(hub, portstatus));
if (hub->has_indicators) {
set_port_led(hub, port1, HUB_LED_AUTO);
......@@ -4436,7 +4437,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
#endif
/* Try to resuscitate an existing device */
udev = hub->ports[port1 - 1]->child;
udev = port_dev->child;
if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
udev->state != USB_STATE_NOTATTACHED) {
usb_lock_device(udev);
......@@ -4468,7 +4469,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if (hcd->phy && !hdev->parent &&
!(portstatus & USB_PORT_STAT_CONNECTION))
usb_phy_notify_disconnect(hcd->phy, udev->speed);
usb_disconnect(&hub->ports[port1 - 1]->child);
usb_disconnect(&port_dev->child);
}
clear_bit(port1, hub->change_bits);
......@@ -4484,8 +4485,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
status = hub_port_debounce_be_stable(hub, port1);
if (status < 0) {
if (status != -ENODEV && printk_ratelimit())
dev_err(hub_dev, "connect-debounce failed, "
"port %d disabled\n", port1);
dev_err(&port_dev->dev,
"connect-debounce failed\n");
portstatus &= ~USB_PORT_STAT_CONNECTION;
} else {
portstatus = status;
......@@ -4520,9 +4521,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
*/
udev = usb_alloc_dev(hdev, hdev->bus, port1);
if (!udev) {
dev_err (hub_dev,
"couldn't allocate port %d usb_device\n",
port1);
dev_err(&port_dev->dev,
"couldn't allocate usb_device\n");
goto done;
}
......@@ -4604,7 +4604,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if (hdev->state == USB_STATE_NOTATTACHED)
status = -ENOTCONN;
else
hub->ports[port1 - 1]->child = udev;
port_dev->child = udev;
spin_unlock_irq(&device_state_lock);
/* Run it through the hoops (find a driver, etc) */
......@@ -4612,7 +4612,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
status = usb_new_device(udev);
if (status) {
spin_lock_irq(&device_state_lock);
hub->ports[port1 - 1]->child = NULL;
port_dev->child = NULL;
spin_unlock_irq(&device_state_lock);
}
}
......@@ -4622,7 +4622,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
status = hub_power_remaining(hub);
if (status)
dev_dbg(hub_dev, "%dmA power budget left\n", status);
dev_dbg(hub->intfdev, "%dmA power budget left\n", status);
return;
......@@ -4640,8 +4640,8 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
!hcd->driver->port_handed_over ||
!(hcd->driver->port_handed_over)(hcd, port1)) {
if (status != -ENOTCONN && status != -ENODEV)
dev_err(hub_dev, "unable to enumerate USB device on port %d\n",
port1);
dev_err(&port_dev->dev,
"unable to enumerate USB device\n");
}
done:
......@@ -4654,13 +4654,14 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
u16 portstatus, u16 portchange)
{
struct usb_port *port_dev = hub->ports[port - 1];
struct usb_device *hdev;
struct usb_device *udev;
int connect_change = 0;
int ret;
hdev = hub->hdev;
udev = hub->ports[port - 1]->child;
udev = port_dev->child;
if (!hub_is_superspeed(hdev)) {
if (!(portchange & USB_PORT_STAT_C_SUSPEND))
return 0;
......@@ -4685,8 +4686,7 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
ret = -ENODEV;
hub_port_disable(hub, port, 1);
}
dev_dbg(hub->intfdev, "resume on port %d, status %d\n",
port, ret);
dev_dbg(&port_dev->dev, "resume, status %d\n", ret);
return connect_change;
}
......@@ -4776,7 +4776,8 @@ static void hub_events(void)
/* deal with port status changes */
for (i = 1; i <= hdev->maxchild; i++) {
struct usb_device *udev = hub->ports[i - 1]->child;
struct usb_port *port_dev = hub->ports[i - 1];
struct usb_device *udev = port_dev->child;
if (test_bit(i, hub->busy_bits))
continue;
......@@ -4799,10 +4800,9 @@ static void hub_events(void)
if (portchange & USB_PORT_STAT_C_ENABLE) {
if (!connect_change)
dev_dbg (hub_dev,
"port %d enable change, "
"status %08x\n",
i, portstatus);
dev_dbg(&port_dev->dev,
"enable change, status %08x\n",
portstatus);
usb_clear_port_feature(hdev, i,
USB_PORT_FEAT_C_ENABLE);
......@@ -4813,13 +4813,9 @@ static void hub_events(void)
* Works at least with mouse driver.
*/
if (!(portstatus & USB_PORT_STAT_ENABLE)
&& !connect_change
&& hub->ports[i - 1]->child) {
dev_err (hub_dev,
"port %i "
"disabled by hub (EMI?), "
"re-enabling...\n",
i);
&& !connect_change && udev) {
dev_err(&port_dev->dev,
"disabled by hub (EMI?), re-enabling...\n");
connect_change = 1;
}
}
......@@ -4832,30 +4828,25 @@ static void hub_events(void)
u16 status = 0;
u16 unused;
dev_dbg(hub_dev, "over-current change on port "
"%d\n", i);
dev_dbg(&port_dev->dev, "over-current change\n");
usb_clear_port_feature(hdev, i,
USB_PORT_FEAT_C_OVER_CURRENT);
msleep(100); /* Cool down */
hub_power_on(hub, true);
hub_port_status(hub, i, &status, &unused);
if (status & USB_PORT_STAT_OVERCURRENT)
dev_err(hub_dev, "over-current "
"condition on port %d\n", i);
dev_err(&port_dev->dev,
"over-current condition\n");
}
if (portchange & USB_PORT_STAT_C_RESET) {
dev_dbg (hub_dev,
"reset change on port %d\n",
i);
dev_dbg(&port_dev->dev, "reset change\n");
usb_clear_port_feature(hdev, i,
USB_PORT_FEAT_C_RESET);
}
if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
hub_is_superspeed(hub->hdev)) {
dev_dbg(hub_dev,
"warm reset change on port %d\n",
i);
dev_dbg(&port_dev->dev, "warm reset change\n");
usb_clear_port_feature(hdev, i,
USB_PORT_FEAT_C_BH_PORT_RESET);
}
......@@ -4864,9 +4855,7 @@ static void hub_events(void)
USB_PORT_FEAT_C_PORT_LINK_STATE);
}
if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) {
dev_warn(hub_dev,
"config error on port %d\n",
i);
dev_warn(&port_dev->dev, "config error\n");
usb_clear_port_feature(hub->hdev, i,
USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
}
......@@ -4877,7 +4866,7 @@ static void hub_events(void)
if (hub_port_warm_reset_required(hub, portstatus)) {
int status;
dev_dbg(hub_dev, "warm reset port %d\n", i);
dev_dbg(&port_dev->dev, "warm reset\n");
if (!udev ||
!(portstatus & USB_PORT_STAT_CONNECTION) ||
udev->state == USB_STATE_NOTATTACHED) {
......@@ -5478,56 +5467,26 @@ struct usb_device *usb_hub_find_child(struct usb_device *hdev,
}
EXPORT_SYMBOL_GPL(usb_hub_find_child);
/**
* usb_set_hub_port_connect_type - set hub port connect type.
* @hdev: USB device belonging to the usb hub
* @port1: port num of the port
* @type: connect type of the port
*/
void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
enum usb_port_connect_type type)
{
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
if (hub)
hub->ports[port1 - 1]->connect_type = type;
}
/**
* usb_get_hub_port_connect_type - Get the port's connect type
* @hdev: USB device belonging to the usb hub
* @port1: port num of the port
*
* Return: The connect type of the port if successful. Or
* USB_PORT_CONNECT_TYPE_UNKNOWN if input params are invalid.
*/
enum usb_port_connect_type
usb_get_hub_port_connect_type(struct usb_device *hdev, int port1)
{
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
if (!hub)
return USB_PORT_CONNECT_TYPE_UNKNOWN;
return hub->ports[port1 - 1]->connect_type;
}
void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc)
{
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
enum usb_port_connect_type connect_type;
int i;
if (!hub)
return;
if (!hub_is_superspeed(hdev)) {
for (i = 1; i <= hdev->maxchild; i++) {
connect_type = usb_get_hub_port_connect_type(hdev, i);
struct usb_port *port_dev = hub->ports[i - 1];
connect_type = port_dev->connect_type;
if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
u8 mask = 1 << (i%8);
if (!(desc->u.hs.DeviceRemovable[i/8] & mask)) {
dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n",
i);
dev_dbg(&port_dev->dev, "DeviceRemovable is changed to 1 according to platform information.\n");
desc->u.hs.DeviceRemovable[i/8] |= mask;
}
}
......@@ -5536,14 +5495,14 @@ void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
u16 port_removable = le16_to_cpu(desc->u.ss.DeviceRemovable);
for (i = 1; i <= hdev->maxchild; i++) {
connect_type = usb_get_hub_port_connect_type(hdev, i);
struct usb_port *port_dev = hub->ports[i - 1];
connect_type = port_dev->connect_type;
if (connect_type == USB_PORT_CONNECT_TYPE_HARD_WIRED) {
u16 mask = 1 << i;
if (!(port_removable & mask)) {
dev_dbg(&hdev->dev, "usb port%d's DeviceRemovable is changed to 1 according to platform information.\n",
i);
dev_dbg(&port_dev->dev, "DeviceRemovable is changed to 1 according to platform information.\n");
port_removable |= mask;
}
}
......
......@@ -152,6 +152,11 @@ struct device_type usb_port_device_type = {
.pm = &usb_port_pm_ops,
};
static struct device_driver usb_port_driver = {
.name = "usb",
.owner = THIS_MODULE,
};
int usb_hub_create_port_device(struct usb_hub *hub, int port1)
{
struct usb_port *port_dev = NULL;
......@@ -169,8 +174,9 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1)
port_dev->dev.parent = hub->intfdev;
port_dev->dev.groups = port_dev_group;
port_dev->dev.type = &usb_port_device_type;
dev_set_name(&port_dev->dev, "port%d", port1);
port_dev->dev.driver = &usb_port_driver;
dev_set_name(&port_dev->dev, "%s-port%d", dev_name(&hub->hdev->dev),
port1);
retval = device_register(&port_dev->dev);
if (retval)
goto error_register;
......
......@@ -17,7 +17,7 @@
#include <linux/pci.h>
#include <linux/usb/hcd.h>
#include "usb.h"
#include "hub.h"
/**
* usb_acpi_power_manageable - check whether usb port has
......@@ -55,13 +55,18 @@ EXPORT_SYMBOL_GPL(usb_acpi_power_manageable);
*/
int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
{
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
struct usb_port *port_dev;
acpi_handle port_handle;
unsigned char state;
int port1 = index + 1;
int error = -EINVAL;
port_handle = (acpi_handle)usb_get_hub_port_acpi_handle(hdev,
port1);
if (!hub)
return -ENODEV;
port_dev = hub->ports[port1 - 1];
port_handle = (acpi_handle) usb_get_hub_port_acpi_handle(hdev, port1);
if (!port_handle)
return error;
......@@ -72,10 +77,9 @@ int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable)
error = acpi_bus_set_power(port_handle, state);
if (!error)
dev_dbg(&hdev->dev, "The power of hub port %d was set to %d\n",
port1, enable);
dev_dbg(&port_dev->dev, "acpi: power was set to %d\n", enable);
else
dev_dbg(&hdev->dev, "The power of hub port failed to be set\n");
dev_dbg(&port_dev->dev, "acpi: power failed to be set\n");
return error;
}
......@@ -84,12 +88,17 @@ EXPORT_SYMBOL_GPL(usb_acpi_set_power_state);
static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
acpi_handle handle, int port1)
{
acpi_status status;
enum usb_port_connect_type connect_type = USB_PORT_CONNECT_TYPE_UNKNOWN;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *upc;
struct usb_hub *hub = usb_hub_to_struct_hub(hdev);
struct acpi_pld_info *pld;
union acpi_object *upc;
acpi_status status;
int ret = 0;
if (!hub)
return 0;
/*
* According to ACPI Spec 9.13. PLD indicates whether usb port is
* user visible and _UPC indicates whether it is connectable. If
......@@ -112,13 +121,12 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
if (upc->package.elements[0].integer.value)
if (pld->user_visible)
usb_set_hub_port_connect_type(hdev, port1,
USB_PORT_CONNECT_TYPE_HOT_PLUG);
connect_type = USB_PORT_CONNECT_TYPE_HOT_PLUG;
else
usb_set_hub_port_connect_type(hdev, port1,
USB_PORT_CONNECT_TYPE_HARD_WIRED);
connect_type = USB_PORT_CONNECT_TYPE_HARD_WIRED;
else if (!pld->user_visible)
usb_set_hub_port_connect_type(hdev, port1, USB_PORT_NOT_USED);
connect_type = USB_PORT_NOT_USED;
hub->ports[port1 - 1]->connect_type = connect_type;
out:
ACPI_FREE(pld);
......@@ -128,9 +136,9 @@ static int usb_acpi_check_port_connect_type(struct usb_device *hdev,
static struct acpi_device *usb_acpi_find_companion(struct device *dev)
{
int port1;
struct usb_device *udev;
acpi_handle *parent_handle;
int port_num;
/*
* In the ACPI DSDT table, only usb root hub and usb ports are
......@@ -147,16 +155,16 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
*/
if (is_usb_device(dev)) {
udev = to_usb_device(dev);
port1 = udev->portnum;
if (udev->parent) {
enum usb_port_connect_type type;
struct usb_hub *hub;
hub = usb_hub_to_struct_hub(udev->parent);
/*
* According usb port's connect type to set usb device's
* removability.
*/
type = usb_get_hub_port_connect_type(udev->parent,
udev->portnum);
switch (type) {
switch (hub->ports[port1 - 1]->connect_type) {
case USB_PORT_CONNECT_TYPE_HOT_PLUG:
udev->removable = USB_DEVICE_REMOVABLE;
break;
......@@ -173,13 +181,14 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
/* root hub's parent is the usb hcd. */
return acpi_find_child_device(ACPI_COMPANION(dev->parent),
udev->portnum, false);
port1, false);
} else if (is_usb_port(dev)) {
struct usb_port *port_dev = to_usb_port(dev);
struct acpi_device *adev = NULL;
sscanf(dev_name(dev), "port%d", &port_num);
/* Get the struct usb_device point of port's hub */
udev = to_usb_device(dev->parent->parent);
port1 = port_dev->portnum;
/*
* The root hub ports' parent is the root hub. The non-root-hub
......@@ -188,12 +197,11 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
*/
if (!udev->parent) {
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
int raw_port_num;
int raw;
raw_port_num = usb_hcd_find_raw_port_number(hcd,
port_num);
raw = usb_hcd_find_raw_port_number(hcd, port1);
adev = acpi_find_child_device(ACPI_COMPANION(&udev->dev),
raw_port_num, false);
raw, false);
if (!adev)
return NULL;
} else {
......@@ -204,11 +212,11 @@ static struct acpi_device *usb_acpi_find_companion(struct device *dev)
return NULL;
acpi_bus_get_device(parent_handle, &adev);
adev = acpi_find_child_device(adev, port_num, false);
adev = acpi_find_child_device(adev, port1, false);
if (!adev)
return NULL;
}
usb_acpi_check_port_connect_type(udev, adev->handle, port_num);
usb_acpi_check_port_connect_type(udev, adev->handle, port1);
return adev;
}
......
......@@ -175,10 +175,6 @@ extern void usb_notify_add_device(struct usb_device *udev);
extern void usb_notify_remove_device(struct usb_device *udev);
extern void usb_notify_add_bus(struct usb_bus *ubus);
extern void usb_notify_remove_bus(struct usb_bus *ubus);
extern enum usb_port_connect_type
usb_get_hub_port_connect_type(struct usb_device *hdev, int port1);
extern void usb_set_hub_port_connect_type(struct usb_device *hdev, int port1,
enum usb_port_connect_type type);
extern void usb_hub_adjust_deviceremovable(struct usb_device *hdev,
struct usb_hub_descriptor *desc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment