Lines Matching +full:suspend +full:- +full:to +full:- +full:disk

1 // SPDX-License-Identifier: GPL-2.0+
6 * (C) Copyright Johannes Erdfelt 1999-2001
15 * Adapted for U-Boot:
49 struct usb_device *dev; /* USB hub device to scan */
51 int port; /* USB port to scan */
64 return hdev->descriptor.bDeviceProtocol == 3; in usb_hub_is_superspeed()
70 if (device_get_uclass_id(hub->parent) != UCLASS_USB_HUB) in usb_hub_is_root_hub()
79 return -EINVAL; in usb_set_hub_depth()
134 * that U-Boot understands. Do this only when the hub is not root hub. in usb_get_port_status()
141 if (!usb_hub_is_root_hub(dev->dev) && usb_hub_is_superspeed(dev)) { in usb_get_port_status()
143 u16 tmp = (status->wPortStatus) & USB_SS_PORT_STAT_MASK; in usb_get_port_status()
145 if (status->wPortStatus & USB_SS_PORT_STAT_POWER) in usb_get_port_status()
147 if ((status->wPortStatus & USB_SS_PORT_STAT_SPEED) == in usb_get_port_status()
151 status->wPortStatus = tmp; in usb_get_port_status()
163 unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2; in usb_hub_power_on()
166 dev = hub->pusb_dev; in usb_hub_power_on()
169 for (i = 0; i < dev->maxchild; i++) { in usb_hub_power_on()
171 debug("port %d returns %lX\n", i + 1, dev->status); in usb_hub_power_on()
177 * in these values still being reset to 0. in usb_hub_power_on()
184 * Wait for power to become stable, in usb_hub_power_on()
185 * plus spec-defined max time for device to connect in usb_hub_power_on()
186 * but allow this time to be increased via env variable as some in usb_hub_power_on()
187 * devices break the spec and require longer warm-up times in usb_hub_power_on()
199 hub->query_delay = get_timer(0) + max(100, (int)pgood_delay); in usb_hub_power_on()
202 * Record the power-on timeout here. The max. delay (timeout) in usb_hub_power_on()
206 hub->connect_timeout = hub->query_delay + 1000; in usb_hub_power_on()
208 dev->devnum, max(100, (int)pgood_delay), in usb_hub_power_on()
220 /* Zero out global hub_dev in case its re-used again */ in usb_hub_reset()
259 * usb_hub_port_reset() - reset a port given its usb_device pointer
262 * sufficient time for it to show itself. The port status is returned.
264 * @dev: USB device to reset
265 * @port: Port number to reset (note ports are numbered from 0 here)
277 debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name, in usb_hub_port_reset()
291 dev->status); in usb_hub_port_reset()
292 return -1; in usb_hub_port_reset()
294 portstatus = le16_to_cpu(portsts->wPortStatus); in usb_hub_port_reset()
295 portchange = le16_to_cpu(portsts->wPortChange); in usb_hub_port_reset()
308 * - C_CONNECTION hasn't been set. in usb_hub_port_reset()
309 * - CONNECTION is still set. in usb_hub_port_reset()
312 * to the bus, and hasn't been unplugged or replaced while the in usb_hub_port_reset()
315 * However, if we do that, then (at least) a San Disk Ultra in usb_hub_port_reset()
316 * USB 3.0 16GB device fails to reset on (at least) an NVIDIA in usb_hub_port_reset()
318 * to briefly drop off the bus when this second bus reset is in usb_hub_port_reset()
326 /* Switch to long reset delay for the next round */ in usb_hub_port_reset()
334 return -1; in usb_hub_port_reset()
355 portstatus = le16_to_cpu(portsts->wPortStatus); in usb_hub_port_connect_change()
358 le16_to_cpu(portsts->wPortChange), in usb_hub_port_connect_change()
368 debug("usb_disconnect(&hub->children[port]);\n"); in usb_hub_port_connect_change()
371 return -ENOTCONN; in usb_hub_port_connect_change()
377 if (ret != -ENXIO) in usb_hub_port_connect_change()
400 ret = usb_scan_device(dev->dev, port + 1, speed, &child); in usb_hub_port_connect_change()
404 ret = usb_alloc_new_device(dev->controller, &usb); in usb_hub_port_connect_change()
410 dev->children[port] = usb; in usb_hub_port_connect_change()
411 usb->speed = speed; in usb_hub_port_connect_change()
412 usb->parent = dev; in usb_hub_port_connect_change()
413 usb->portnr = port + 1; in usb_hub_port_connect_change()
418 usb_free_device(dev->controller); in usb_hub_port_connect_change()
419 dev->children[port] = NULL; in usb_hub_port_connect_change()
440 dev = usb_scan->dev; in usb_scan_port()
441 hub = usb_scan->hub; in usb_scan_port()
442 i = usb_scan->port; in usb_scan_port()
445 * Don't talk to the device before the query delay is expired. in usb_scan_port()
446 * This is needed for voltages to stabalize. in usb_scan_port()
448 if (get_timer(0) < hub->query_delay) in usb_scan_port()
454 if (get_timer(0) >= hub->connect_timeout) { in usb_scan_port()
456 dev->devnum, i + 1); in usb_scan_port()
458 list_del(&usb_scan->list); in usb_scan_port()
465 portstatus = le16_to_cpu(portsts->wPortStatus); in usb_scan_port()
466 portchange = le16_to_cpu(portsts->wPortChange); in usb_scan_port()
473 * device is connected to the port (eg: CCS bit is set but CSC is not in usb_scan_port()
478 if (get_timer(0) >= hub->connect_timeout) { in usb_scan_port()
480 dev->devnum, i + 1); in usb_scan_port()
482 list_del(&usb_scan->list); in usb_scan_port()
501 debug("devnum=%d port=%d: USB dev found\n", dev->devnum, i + 1); in usb_scan_port()
510 * to Faraday EHCI in usb_scan_port()
515 * devices to be shutdown by the hub, this hack enables in usb_scan_port()
521 debug("already running port %i disabled by hub (EMI?), re-enabling...\n", in usb_scan_port()
529 debug("port %d suspend change\n", i + 1); in usb_scan_port()
534 debug("port %d over-current change\n", i + 1); in usb_scan_port()
537 /* Only power-on this one port */ in usb_scan_port()
539 hub->overcurrent_count[i]++; in usb_scan_port()
542 * If the max-scan-count is not reached, return without removing in usb_scan_port()
543 * the device from scan-list. This will re-issue a new scan. in usb_scan_port()
545 if (hub->overcurrent_count[i] <= in usb_scan_port()
550 printf("Port %d over-current occurred %d times\n", i + 1, in usb_scan_port()
551 hub->overcurrent_count[i]); in usb_scan_port()
558 list_del(&usb_scan->list); in usb_scan_port()
595 * USB devices. Set "running" back to 0, so that other USB controllers in usb_device_list_scan()
611 hub = dev_get_uclass_priv(dev->dev); in usb_get_hub_device()
630 return -ENOMEM; in usb_hub_configure()
631 hub->pusb_dev = dev; in usb_hub_configure()
636 debug("usb_hub_configure: failed to get hub " \ in usb_hub_configure()
637 "descriptor, giving up %lX\n", dev->status); in usb_hub_configure()
642 length = min_t(int, descriptor->bLength, in usb_hub_configure()
647 debug("usb_hub_configure: failed to get hub " \ in usb_hub_configure()
648 "descriptor 2nd giving up %lX\n", dev->status); in usb_hub_configure()
651 memcpy((unsigned char *)&hub->desc, buffer, length); in usb_hub_configure()
654 &descriptor->wHubCharacteristics)), in usb_hub_configure()
655 &hub->desc.wHubCharacteristics); in usb_hub_configure()
657 bitmap = (unsigned char *)&hub->desc.u.hs.DeviceRemovable[0]; in usb_hub_configure()
660 bitmap = (unsigned char *)&hub->desc.u.hs.PortPowerCtrlMask[0]; in usb_hub_configure()
663 for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++) in usb_hub_configure()
664 hub->desc.u.hs.DeviceRemovable[i] = in usb_hub_configure()
665 descriptor->u.hs.DeviceRemovable[i]; in usb_hub_configure()
667 for (i = 0; i < ((hub->desc.bNbrPorts + 1 + 7)/8); i++) in usb_hub_configure()
668 hub->desc.u.hs.PortPowerCtrlMask[i] = in usb_hub_configure()
669 descriptor->u.hs.PortPowerCtrlMask[i]; in usb_hub_configure()
671 dev->maxchild = descriptor->bNbrPorts; in usb_hub_configure()
672 debug("%d ports detected\n", dev->maxchild); in usb_hub_configure()
674 hubCharacteristics = get_unaligned(&hub->desc.wHubCharacteristics); in usb_hub_configure()
695 debug("global over-current protection\n"); in usb_hub_configure()
698 debug("individual port over-current protection\n"); in usb_hub_configure()
702 debug("no over-current protection\n"); in usb_hub_configure()
706 switch (dev->descriptor.bDeviceProtocol) { in usb_hub_configure()
716 hub->tt.multi = true; in usb_hub_configure()
726 dev->descriptor.bDeviceProtocol); in usb_hub_configure()
733 if (dev->descriptor.bDeviceProtocol != 0) { in usb_hub_configure()
734 hub->tt.think_time = 666; in usb_hub_configure()
736 8, hub->tt.think_time); in usb_hub_configure()
740 hub->tt.think_time = 666 * 2; in usb_hub_configure()
742 16, hub->tt.think_time); in usb_hub_configure()
745 hub->tt.think_time = 666 * 3; in usb_hub_configure()
747 24, hub->tt.think_time); in usb_hub_configure()
750 hub->tt.think_time = 666 * 4; in usb_hub_configure()
752 32, hub->tt.think_time); in usb_hub_configure()
756 debug("power on to power good time: %dms\n", in usb_hub_configure()
757 descriptor->bPwrOn2PwrGood * 2); in usb_hub_configure()
759 descriptor->bHubContrCurrent); in usb_hub_configure()
761 for (i = 0; i < dev->maxchild; i++) in usb_hub_configure()
763 hub->desc.u.hs.DeviceRemovable[(i + 1) / 8] & \ in usb_hub_configure()
767 debug("usb_hub_configure: failed to get Status - " \ in usb_hub_configure()
768 "too long: %d\n", descriptor->bLength); in usb_hub_configure()
769 return -EFBIG; in usb_hub_configure()
774 debug("usb_hub_configure: failed to get Status %lX\n", in usb_hub_configure()
775 dev->status); in usb_hub_configure()
782 le16_to_cpu(hubsts->wHubStatus), in usb_hub_configure()
783 le16_to_cpu(hubsts->wHubChange)); in usb_hub_configure()
785 (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \ in usb_hub_configure()
787 debug("%sover-current condition exists\n", in usb_hub_configure()
788 (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \ in usb_hub_configure()
797 if (ret < 0 && ret != -ENOSYS) { in usb_hub_configure()
798 debug("%s: failed to update hub device for HCD (%x)\n", in usb_hub_configure()
806 * USB device. USB 3.0 hubs use a 20-bit field called 'route string' in usb_hub_configure()
807 * to route packets to the designated downstream port. The hub uses a in usb_hub_configure()
809 * string' to locate the bits it uses to determine the downstream in usb_hub_configure()
812 if (usb_hub_is_root_hub(dev->dev)) { in usb_hub_configure()
813 hub->hub_depth = -1; in usb_hub_configure()
818 hdev = dev->dev->parent; in usb_hub_configure()
821 hdev = hdev->parent; in usb_hub_configure()
824 hub->hub_depth = depth; in usb_hub_configure()
827 debug("set hub (%p) depth to %d\n", dev, depth); in usb_hub_configure()
829 * This request sets the value that the hub uses to in usb_hub_configure()
835 debug("%s: failed to set hub depth (%lX)\n", in usb_hub_configure()
836 __func__, dev->status); in usb_hub_configure()
850 for (i = 0; i < dev->maxchild; i++) in usb_hub_configure()
855 * to a scanning list. This list will get scanned and devices that in usb_hub_configure()
860 for (i = 0; i < dev->maxchild; i++) { in usb_hub_configure()
866 return -ENOMEM; in usb_hub_configure()
868 usb_scan->dev = dev; in usb_hub_configure()
869 usb_scan->hub = hub; in usb_hub_configure()
870 usb_scan->port = i; in usb_hub_configure()
871 list_add_tail(&usb_scan->list, &usb_scan_list); in usb_hub_configure()
887 iface = &dev->config.if_desc[ifnum]; in usb_hub_check()
889 if (iface->desc.bInterfaceClass != USB_CLASS_HUB) in usb_hub_check()
891 /* Some hubs have a subclass of 1, which AFAICT according to the */ in usb_hub_check()
893 if ((iface->desc.bInterfaceSubClass != 0) && in usb_hub_check()
894 (iface->desc.bInterfaceSubClass != 1)) in usb_hub_check()
896 /* Multiple endpoints? What kind of mutant ninja-hub is this? */ in usb_hub_check()
897 if (iface->desc.bNumEndpoints != 1) in usb_hub_check()
899 ep = &iface->ep_desc[0]; in usb_hub_check()
901 if (!(ep->bEndpointAddress & USB_DIR_IN)) in usb_hub_check()
904 if ((ep->bmAttributes & 3) != 3) in usb_hub_check()
912 iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass, in usb_hub_check()
913 iface->desc.bNumEndpoints); in usb_hub_check()
916 ep->bEndpointAddress, ep->bmAttributes); in usb_hub_check()
919 return -ENOENT; in usb_hub_check()
948 { .compatible = "usb-hub" },