aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hub.c374
1 files changed, 185 insertions, 189 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index e492bca74425..782ce2e31c7f 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4413,66 +4413,15 @@ hub_power_remaining (struct usb_hub *hub)
4413 return remaining; 4413 return remaining;
4414} 4414}
4415 4415
4416/* Handle physical or logical connection change events. 4416static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
4417 * This routine is called when: 4417 u16 portchange)
4418 * a port connection-change occurs;
4419 * a port enable-change occurs (often caused by EMI);
4420 * usb_reset_and_verify_device() encounters changed descriptors (as from
4421 * a firmware download)
4422 * caller already locked the hub
4423 */
4424static void hub_port_connect_change(struct usb_hub *hub, int port1,
4425 u16 portstatus, u16 portchange)
4426{ 4418{
4419 int status, i;
4420 unsigned unit_load;
4427 struct usb_device *hdev = hub->hdev; 4421 struct usb_device *hdev = hub->hdev;
4428 struct usb_hcd *hcd = bus_to_hcd(hdev->bus); 4422 struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
4429 struct usb_port *port_dev = hub->ports[port1 - 1]; 4423 struct usb_port *port_dev = hub->ports[port1 - 1];
4430 struct usb_device *udev; 4424 struct usb_device *udev = port_dev->child;
4431 int status, i;
4432 unsigned unit_load;
4433
4434 dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n",
4435 portstatus, portchange, portspeed(hub, portstatus));
4436
4437 if (hub->has_indicators) {
4438 set_port_led(hub, port1, HUB_LED_AUTO);
4439 hub->indicator[port1-1] = INDICATOR_AUTO;
4440 }
4441
4442#ifdef CONFIG_USB_OTG
4443 /* during HNP, don't repeat the debounce */
4444 if (hdev->bus->is_b_host)
4445 portchange &= ~(USB_PORT_STAT_C_CONNECTION |
4446 USB_PORT_STAT_C_ENABLE);
4447#endif
4448
4449 /* Try to resuscitate an existing device */
4450 udev = port_dev->child;
4451 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
4452 udev->state != USB_STATE_NOTATTACHED) {
4453 usb_lock_device(udev);
4454 if (portstatus & USB_PORT_STAT_ENABLE) {
4455 status = 0; /* Nothing to do */
4456
4457#ifdef CONFIG_PM_RUNTIME
4458 } else if (udev->state == USB_STATE_SUSPENDED &&
4459 udev->persist_enabled) {
4460 /* For a suspended device, treat this as a
4461 * remote wakeup event.
4462 */
4463 status = usb_remote_wakeup(udev);
4464#endif
4465
4466 } else {
4467 status = -ENODEV; /* Don't resuscitate */
4468 }
4469 usb_unlock_device(udev);
4470
4471 if (status == 0) {
4472 clear_bit(port1, hub->change_bits);
4473 return;
4474 }
4475 }
4476 4425
4477 /* Disconnect any existing devices under this port */ 4426 /* Disconnect any existing devices under this port */
4478 if (udev) { 4427 if (udev) {
@@ -4481,7 +4430,6 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
4481 usb_phy_notify_disconnect(hcd->phy, udev->speed); 4430 usb_phy_notify_disconnect(hcd->phy, udev->speed);
4482 usb_disconnect(&port_dev->child); 4431 usb_disconnect(&port_dev->child);
4483 } 4432 }
4484 clear_bit(port1, hub->change_bits);
4485 4433
4486 /* We can forget about a "removed" device when there's a physical 4434 /* We can forget about a "removed" device when there's a physical
4487 * disconnect or the connect status changes. 4435 * disconnect or the connect status changes.
@@ -4663,6 +4611,65 @@ done:
4663 hub_port_disable(hub, port1, 1); 4611 hub_port_disable(hub, port1, 1);
4664 if (hcd->driver->relinquish_port && !hub->hdev->parent) 4612 if (hcd->driver->relinquish_port && !hub->hdev->parent)
4665 hcd->driver->relinquish_port(hcd, port1); 4613 hcd->driver->relinquish_port(hcd, port1);
4614
4615}
4616
4617/* Handle physical or logical connection change events.
4618 * This routine is called when:
4619 * a port connection-change occurs;
4620 * a port enable-change occurs (often caused by EMI);
4621 * usb_reset_and_verify_device() encounters changed descriptors (as from
4622 * a firmware download)
4623 * caller already locked the hub
4624 */
4625static void hub_port_connect_change(struct usb_hub *hub, int port1,
4626 u16 portstatus, u16 portchange)
4627{
4628 struct usb_port *port_dev = hub->ports[port1 - 1];
4629 struct usb_device *udev = port_dev->child;
4630 int status = -ENODEV;
4631
4632 dev_dbg(&port_dev->dev, "status %04x, change %04x, %s\n", portstatus,
4633 portchange, portspeed(hub, portstatus));
4634
4635 if (hub->has_indicators) {
4636 set_port_led(hub, port1, HUB_LED_AUTO);
4637 hub->indicator[port1-1] = INDICATOR_AUTO;
4638 }
4639
4640#ifdef CONFIG_USB_OTG
4641 /* during HNP, don't repeat the debounce */
4642 if (hub->hdev->bus->is_b_host)
4643 portchange &= ~(USB_PORT_STAT_C_CONNECTION |
4644 USB_PORT_STAT_C_ENABLE);
4645#endif
4646
4647 /* Try to resuscitate an existing device */
4648 if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
4649 udev->state != USB_STATE_NOTATTACHED) {
4650 if (portstatus & USB_PORT_STAT_ENABLE) {
4651 status = 0; /* Nothing to do */
4652#ifdef CONFIG_PM_RUNTIME
4653 } else if (udev->state == USB_STATE_SUSPENDED &&
4654 udev->persist_enabled) {
4655 /* For a suspended device, treat this as a
4656 * remote wakeup event.
4657 */
4658 usb_lock_device(udev);
4659 status = usb_remote_wakeup(udev);
4660 usb_unlock_device(udev);
4661#endif
4662 } else {
4663 /* Don't resuscitate */;
4664 }
4665
4666 }
4667 clear_bit(port1, hub->change_bits);
4668
4669 if (status == 0)
4670 return;
4671
4672 hub_port_connect(hub, port1, portstatus, portchange);
4666} 4673}
4667 4674
4668/* Returns 1 if there was a remote wakeup and a connect status change. */ 4675/* Returns 1 if there was a remote wakeup and a connect status change. */
@@ -4705,6 +4712,121 @@ static int hub_handle_remote_wakeup(struct usb_hub *hub, unsigned int port,
4705 return connect_change; 4712 return connect_change;
4706} 4713}
4707 4714
4715static void port_event(struct usb_hub *hub, int port1)
4716{
4717 int connect_change, reset_device = 0;
4718 struct usb_port *port_dev = hub->ports[port1 - 1];
4719 struct usb_device *udev = port_dev->child;
4720 struct usb_device *hdev = hub->hdev;
4721 u16 portstatus, portchange;
4722
4723 connect_change = test_bit(port1, hub->change_bits);
4724 clear_bit(port1, hub->event_bits);
4725 clear_bit(port1, hub->wakeup_bits);
4726
4727 if (hub_port_status(hub, port1, &portstatus, &portchange) < 0)
4728 return;
4729
4730 if (portchange & USB_PORT_STAT_C_CONNECTION) {
4731 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_CONNECTION);
4732 connect_change = 1;
4733 }
4734
4735 if (portchange & USB_PORT_STAT_C_ENABLE) {
4736 if (!connect_change)
4737 dev_dbg(&port_dev->dev, "enable change, status %08x\n",
4738 portstatus);
4739 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_ENABLE);
4740
4741 /*
4742 * EM interference sometimes causes badly shielded USB devices
4743 * to be shutdown by the hub, this hack enables them again.
4744 * Works at least with mouse driver.
4745 */
4746 if (!(portstatus & USB_PORT_STAT_ENABLE)
4747 && !connect_change && udev) {
4748 dev_err(&port_dev->dev, "disabled by hub (EMI?), re-enabling...\n");
4749 connect_change = 1;
4750 }
4751 }
4752
4753 if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
4754 u16 status = 0, unused;
4755
4756 dev_dbg(&port_dev->dev, "over-current change\n");
4757 usb_clear_port_feature(hdev, port1,
4758 USB_PORT_FEAT_C_OVER_CURRENT);
4759 msleep(100); /* Cool down */
4760 hub_power_on(hub, true);
4761 hub_port_status(hub, port1, &status, &unused);
4762 if (status & USB_PORT_STAT_OVERCURRENT)
4763 dev_err(&port_dev->dev, "over-current condition\n");
4764 }
4765
4766 if (portchange & USB_PORT_STAT_C_RESET) {
4767 dev_dbg(&port_dev->dev, "reset change\n");
4768 usb_clear_port_feature(hdev, port1, USB_PORT_FEAT_C_RESET);
4769 }
4770 if ((portchange & USB_PORT_STAT_C_BH_RESET)
4771 && hub_is_superspeed(hdev)) {
4772 dev_dbg(&port_dev->dev, "warm reset change\n");
4773 usb_clear_port_feature(hdev, port1,
4774 USB_PORT_FEAT_C_BH_PORT_RESET);
4775 }
4776 if (portchange & USB_PORT_STAT_C_LINK_STATE) {
4777 dev_dbg(&port_dev->dev, "link state change\n");
4778 usb_clear_port_feature(hdev, port1,
4779 USB_PORT_FEAT_C_PORT_LINK_STATE);
4780 }
4781 if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) {
4782 dev_warn(&port_dev->dev, "config error\n");
4783 usb_clear_port_feature(hdev, port1,
4784 USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
4785 }
4786
4787 if (hub_handle_remote_wakeup(hub, port1, portstatus, portchange))
4788 connect_change = 1;
4789
4790 /*
4791 * Warm reset a USB3 protocol port if it's in
4792 * SS.Inactive state.
4793 */
4794 if (hub_port_warm_reset_required(hub, portstatus)) {
4795 dev_dbg(&port_dev->dev, "do warm reset\n");
4796 if (!udev || !(portstatus & USB_PORT_STAT_CONNECTION)
4797 || udev->state == USB_STATE_NOTATTACHED) {
4798 if (hub_port_reset(hub, port1, NULL,
4799 HUB_BH_RESET_TIME, true) < 0)
4800 hub_port_disable(hub, port1, 1);
4801 } else
4802 reset_device = 1;
4803 }
4804
4805 /*
4806 * On disconnect USB3 protocol ports transit from U0 to
4807 * SS.Inactive to Rx.Detect. If this happens a warm-
4808 * reset is not needed, but a (re)connect may happen
4809 * before khubd runs and sees the disconnect, and the
4810 * device may be an unknown state.
4811 *
4812 * If the port went through SS.Inactive without khubd
4813 * seeing it the C_LINK_STATE change flag will be set,
4814 * and we reset the dev to put it in a known state.
4815 */
4816 if (reset_device || (udev && hub_is_superspeed(hub->hdev)
4817 && (portchange & USB_PORT_STAT_C_LINK_STATE)
4818 && (portstatus & USB_PORT_STAT_CONNECTION))) {
4819 usb_lock_device(udev);
4820 usb_reset_device(udev);
4821 usb_unlock_device(udev);
4822 connect_change = 0;
4823 }
4824
4825 if (connect_change)
4826 hub_port_connect_change(hub, port1, portstatus, portchange);
4827}
4828
4829
4708static void hub_events(void) 4830static void hub_events(void)
4709{ 4831{
4710 struct list_head *tmp; 4832 struct list_head *tmp;
@@ -4714,10 +4836,7 @@ static void hub_events(void)
4714 struct device *hub_dev; 4836 struct device *hub_dev;
4715 u16 hubstatus; 4837 u16 hubstatus;
4716 u16 hubchange; 4838 u16 hubchange;
4717 u16 portstatus;
4718 u16 portchange;
4719 int i, ret; 4839 int i, ret;
4720 int connect_change, wakeup_change;
4721 4840
4722 /* 4841 /*
4723 * We restart the list every time to avoid a deadlock with 4842 * We restart the list every time to avoid a deadlock with
@@ -4791,135 +4910,12 @@ static void hub_events(void)
4791 4910
4792 /* deal with port status changes */ 4911 /* deal with port status changes */
4793 for (i = 1; i <= hdev->maxchild; i++) { 4912 for (i = 1; i <= hdev->maxchild; i++) {
4794 struct usb_port *port_dev = hub->ports[i - 1]; 4913 if (!test_bit(i, hub->busy_bits)
4795 struct usb_device *udev = port_dev->child; 4914 && (test_bit(i, hub->event_bits)
4796 4915 || test_bit(i, hub->change_bits)
4797 if (test_bit(i, hub->busy_bits)) 4916 || test_bit(i, hub->wakeup_bits)))
4798 continue; 4917 port_event(hub, i);
4799 connect_change = test_bit(i, hub->change_bits); 4918 }
4800 wakeup_change = test_and_clear_bit(i, hub->wakeup_bits);
4801 if (!test_and_clear_bit(i, hub->event_bits) &&
4802 !connect_change && !wakeup_change)
4803 continue;
4804
4805 ret = hub_port_status(hub, i,
4806 &portstatus, &portchange);
4807 if (ret < 0)
4808 continue;
4809
4810 if (portchange & USB_PORT_STAT_C_CONNECTION) {
4811 usb_clear_port_feature(hdev, i,
4812 USB_PORT_FEAT_C_CONNECTION);
4813 connect_change = 1;
4814 }
4815
4816 if (portchange & USB_PORT_STAT_C_ENABLE) {
4817 if (!connect_change)
4818 dev_dbg(&port_dev->dev,
4819 "enable change, status %08x\n",
4820 portstatus);
4821 usb_clear_port_feature(hdev, i,
4822 USB_PORT_FEAT_C_ENABLE);
4823
4824 /*
4825 * EM interference sometimes causes badly
4826 * shielded USB devices to be shutdown by
4827 * the hub, this hack enables them again.
4828 * Works at least with mouse driver.
4829 */
4830 if (!(portstatus & USB_PORT_STAT_ENABLE)
4831 && !connect_change && udev) {
4832 dev_err(&port_dev->dev,
4833 "disabled by hub (EMI?), re-enabling...\n");
4834 connect_change = 1;
4835 }
4836 }
4837
4838 if (hub_handle_remote_wakeup(hub, i,
4839 portstatus, portchange))
4840 connect_change = 1;
4841
4842 if (portchange & USB_PORT_STAT_C_OVERCURRENT) {
4843 u16 status = 0;
4844 u16 unused;
4845
4846 dev_dbg(&port_dev->dev, "over-current change\n");
4847 usb_clear_port_feature(hdev, i,
4848 USB_PORT_FEAT_C_OVER_CURRENT);
4849 msleep(100); /* Cool down */
4850 hub_power_on(hub, true);
4851 hub_port_status(hub, i, &status, &unused);
4852 if (status & USB_PORT_STAT_OVERCURRENT)
4853 dev_err(&port_dev->dev,
4854 "over-current condition\n");
4855 }
4856
4857 if (portchange & USB_PORT_STAT_C_RESET) {
4858 dev_dbg(&port_dev->dev, "reset change\n");
4859 usb_clear_port_feature(hdev, i,
4860 USB_PORT_FEAT_C_RESET);
4861 }
4862 if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
4863 hub_is_superspeed(hub->hdev)) {
4864 dev_dbg(&port_dev->dev, "warm reset change\n");
4865 usb_clear_port_feature(hdev, i,
4866 USB_PORT_FEAT_C_BH_PORT_RESET);
4867 }
4868 if (portchange & USB_PORT_STAT_C_LINK_STATE) {
4869 usb_clear_port_feature(hub->hdev, i,
4870 USB_PORT_FEAT_C_PORT_LINK_STATE);
4871 }
4872 if (portchange & USB_PORT_STAT_C_CONFIG_ERROR) {
4873 dev_warn(&port_dev->dev, "config error\n");
4874 usb_clear_port_feature(hub->hdev, i,
4875 USB_PORT_FEAT_C_PORT_CONFIG_ERROR);
4876 }
4877
4878 /* Warm reset a USB3 protocol port if it's in
4879 * SS.Inactive state.
4880 */
4881 if (hub_port_warm_reset_required(hub, portstatus)) {
4882 int status;
4883
4884 dev_dbg(&port_dev->dev, "warm reset\n");
4885 if (!udev ||
4886 !(portstatus & USB_PORT_STAT_CONNECTION) ||
4887 udev->state == USB_STATE_NOTATTACHED) {
4888 status = hub_port_reset(hub, i,
4889 NULL, HUB_BH_RESET_TIME,
4890 true);
4891 if (status < 0)
4892 hub_port_disable(hub, i, 1);
4893 } else {
4894 usb_lock_device(udev);
4895 status = usb_reset_device(udev);
4896 usb_unlock_device(udev);
4897 connect_change = 0;
4898 }
4899 /*
4900 * On disconnect USB3 protocol ports transit from U0 to
4901 * SS.Inactive to Rx.Detect. If this happens a warm-
4902 * reset is not needed, but a (re)connect may happen
4903 * before khubd runs and sees the disconnect, and the
4904 * device may be an unknown state.
4905 *
4906 * If the port went through SS.Inactive without khubd
4907 * seeing it the C_LINK_STATE change flag will be set,
4908 * and we reset the dev to put it in a known state.
4909 */
4910 } else if (udev && hub_is_superspeed(hub->hdev) &&
4911 (portchange & USB_PORT_STAT_C_LINK_STATE) &&
4912 (portstatus & USB_PORT_STAT_CONNECTION)) {
4913 usb_lock_device(udev);
4914 usb_reset_device(udev);
4915 usb_unlock_device(udev);
4916 connect_change = 0;
4917 }
4918
4919 if (connect_change)
4920 hub_port_connect_change(hub, i,
4921 portstatus, portchange);
4922 } /* end for i */
4923 4919
4924 /* deal with hub status changes */ 4920 /* deal with hub status changes */
4925 if (test_and_clear_bit(0, hub->event_bits) == 0) 4921 if (test_and_clear_bit(0, hub->event_bits) == 0)