/* 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; }
int hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat) { int tries, status; unsigned delay = HUB_SHORT_RESET_TIME; int oldspeed = dev->speed; /* root hub ports have a slightly longer reset period * (from USB 2.0 spec, section 7.1.7.5) */ if (!dev->parent) { delay = HUB_ROOT_RESET_TIME; } /* Some low speed devices have problems with the quick delay, so */ /* be a bit pessimistic with those devices. RHbug #23670 */ if (oldspeed == USB_SPEED_LOW) delay = HUB_LONG_RESET_TIME; USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port); for (tries = 0; tries < MAX_TRIES; tries++) { status = usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET); if (status) USB_HUB_PRINTF("cannot reset port %d (err = %d)\n", port, status); else { status = hub_port_wait_reset(dev, port, delay, portstat); if (status && status != -ENOTCONN) USB_HUB_PRINTF("port_wait_reset: err = %d\n", status); } /* return on disconnect or reset */ switch (status) { case 0: /* TRSTRCY = 10 ms; plus some extra */ mdelay(10 + 40); /* FALL THROUGH */ case -1: case -ENOTCONN: /* we have finished trying to reset, so return */ usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_RESET); return 0; } USB_HUB_PRINTF ( "port %d not enabled, trying reset again...\n", port); delay = HUB_LONG_RESET_TIME; } if (tries == MAX_TRIES) { USB_HUB_PRINTF("Cannot enable port %i after %i retries, " \ "disabling port.\n", port + 1, MAX_TRIES); USB_HUB_PRINTF("Maybe the USB cable is bad?\n"); return -1; } return 0; }