Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
0
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;
}