// Check if device attached to port static int usb_hub_detect(struct usbhub_s *hub, u32 port) { // Turn on power to port. int ret = set_port_feature(hub, port, USB_PORT_FEAT_POWER); if (ret) goto fail; // Wait for port power to stabilize. msleep(hub->powerwait); // Check periodically for a device connect. struct usb_port_status sts; u64 end = calc_future_tsc(USB_TIME_SIGATT); for (;;) { ret = get_port_status(hub, port, &sts); if (ret) goto fail; if (sts.wPortStatus & USB_PORT_STAT_CONNECTION) // Device connected. break; if (check_tsc(end)) // No device found. return -1; msleep(5); } // XXX - wait USB_TIME_ATTDB time? return 0; fail: dprintf(1, "Failure on hub port %d detect\n", port); return -1; }
/* return: -1 on error, 0 on success, 1 on disconnect. */ static int hub_port_reset(struct usb_device *hub, int port, struct usb_device *dev, unsigned int delay) { int i, status; /* Reset the port */ for (i = 0; i < HUB_RESET_TRIES; i++) { set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET); /* return on disconnect or reset */ status = hub_port_wait_reset(hub, port, dev, delay); if (status != -1) { clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET); dev->state = status ? USB_STATE_NOTATTACHED : USB_STATE_DEFAULT; return status; } dev_dbg (hubdev (hub), "port %d not enabled, trying reset again...\n", port + 1); delay = HUB_LONG_RESET_TIME; } dev_err (hubdev (hub), "Cannot enable port %i. Maybe the USB cable is bad?\n", port + 1); return -1; }
static void ush_hsic_port_enable(struct pci_dev *pdev) { printk(KERN_ERR "%s---->\n", __func__); if (hsic.rh_dev) { dev_dbg(&pci_dev->dev, "%s----> enable port\n", __func__); printk(KERN_ERR "%s----> Enable PP\n", __func__); set_port_feature(hsic.rh_dev, HSIC_USH_PORT, USB_PORT_FEAT_POWER); } hsic.hsic_stopped = 0; hsic_enable = 1; }
static void hub_power_on(struct usb_hub *hub) { struct usb_device *dev; int i; /* Enable power to the ports */ dev_dbg(hubdev(interface_to_usbdev(hub->intf)), "enabling power on all ports\n"); dev = interface_to_usbdev(hub->intf); for (i = 0; i < hub->descriptor->bNbrPorts; i++) set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); /* Wait for power to be enabled */ wait_ms(hub->descriptor->bPwrOn2PwrGood * 2); }
static void ush_hsic_port_enable(void) { hsic_enable = 1; if ((hsic.modem_dev) && (hsic.autosuspend_enable != 0)) { dev_dbg(&pci_dev->dev, "Disable auto suspend in port enable\n"); usb_disable_autosuspend(hsic.modem_dev); usb_disable_autosuspend(hsic.rh_dev); hsic.autosuspend_enable = 0; } if (hsic.rh_dev) { if (hsic.autosuspend_enable != 0) { dev_dbg(&pci_dev->dev, "Disable auto suspend in port enable\n"); usb_disable_autosuspend(hsic.rh_dev); hsic.autosuspend_enable = 0; } set_port_feature(hsic.rh_dev, HSIC_USH_PORT, USB_PORT_FEAT_POWER); } s3_wake_lock(); }
// Reset device on port static int usb_hub_reset(struct usbhub_s *hub, u32 port) { int ret = set_port_feature(hub, port, USB_PORT_FEAT_RESET); if (ret) goto fail; // Wait for reset to complete. struct usb_port_status sts; u64 end = calc_future_tsc(USB_TIME_DRST * 2); for (;;) { ret = get_port_status(hub, port, &sts); if (ret) goto fail; if (!(sts.wPortStatus & USB_PORT_STAT_RESET)) break; if (check_tsc(end)) { warn_timeout(); goto fail; } msleep(5); } // Reset complete. if (!(sts.wPortStatus & USB_PORT_STAT_CONNECTION)) // Device no longer present return -1; return ((sts.wPortStatus & USB_PORT_STAT_SPEED_MASK) >> USB_PORT_STAT_SPEED_SHIFT); fail: dprintf(1, "Failure on hub port %d reset\n", port); usb_hub_disconnect(hub, port); return -1; }