sys/bus/u4b/usb_request.c
usb_error_t
usbd_req_reset_port(struct usb_device *udev, struct lock *lock, uint8_t port)
{
	struct usb_port_status ps;
	usb_error_t err;
	uint16_t n;
	uint16_t status;
	uint16_t change;

#ifdef USB_DEBUG
	uint16_t pr_poll_delay;
	uint16_t pr_recovery_delay;

#endif

	DPRINTF("\n");

	/* clear any leftover port reset changes first */
	usbd_req_clear_port_feature(
	    udev, lock, port, UHF_C_PORT_RESET);

	/* assert port reset on the given port */
	err = usbd_req_set_port_feature(
	    udev, lock, port, UHF_PORT_RESET);

	/* check for errors */
	if (err)
		goto done;
#ifdef USB_DEBUG
	/* range check input parameters */
	pr_poll_delay = usb_pr_poll_delay;
	if (pr_poll_delay < 1) {
		pr_poll_delay = 1;
	} else if (pr_poll_delay > 1000) {
		pr_poll_delay = 1000;
	}
	pr_recovery_delay = usb_pr_recovery_delay;
	if (pr_recovery_delay > 1000) {
		pr_recovery_delay = 1000;
	}
#endif
	n = 0;
	while (1) {
#ifdef USB_DEBUG
		/* wait for the device to recover from reset */
		usb_pause_mtx(lock, USB_MS_TO_TICKS(pr_poll_delay));
		n += pr_poll_delay;
#else
		/* wait for the device to recover from reset */
		usb_pause_mtx(lock, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
		n += USB_PORT_RESET_DELAY;
#endif
		err = usbd_req_get_port_status(udev, lock, &ps, port);
		if (err)
			goto done;

		status = UGETW(ps.wPortStatus);
		change = UGETW(ps.wPortChange);

		/* if the device disappeared, just give up */
		if (!(status & UPS_CURRENT_CONNECT_STATUS))
			goto done;

		/* check if reset is complete */
		if (change & UPS_C_PORT_RESET)
			break;

		/*
		 * Some Virtual Machines like VirtualBox 4.x fail to
		 * generate a port reset change event. Check if reset
		 * is no longer asserted.
		 */
		if (!(status & UPS_RESET))
			break;

		/* check for timeout */
		if (n > 1000) {
			n = 0;
			break;
		}
	}

	/* clear port reset first */
	err = usbd_req_clear_port_feature(
	    udev, lock, port, UHF_C_PORT_RESET);
	if (err)
		goto done;

	/* check for timeout */
	if (n == 0) {
		err = USB_ERR_TIMEOUT;
		goto done;
	}
#ifdef USB_DEBUG
	/* wait for the device to recover from reset */
	usb_pause_mtx(lock, USB_MS_TO_TICKS(pr_recovery_delay));
#else
	/* wait for the device to recover from reset */
	usb_pause_mtx(lock, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY));
#endif

done:
	DPRINTFN(2, "port %d reset returning error=%s\n",
	    port, usbd_errstr(err));
	return (err);
}
/*------------------------------------------------------------------------*
 *	usbd_req_reset_port
 *
 * This function will instruct a USB HUB to perform a reset sequence
 * on the specified port number.
 *
 * Returns:
 *    0: Success. The USB device should now be at address zero.
 * Else: Failure. No USB device is present and the USB port should be
 *       disabled.
 *------------------------------------------------------------------------*/
usbd_req_reset_port
This function will instruct a USB HUB to perform a reset sequence
on the specified port number.

Success. The USB device should now be at address zero.
Else: Failure. No USB device is present and the USB port should be
disabled.
usbd_req_reset_port This function will instruct a USB HUB to perform a reset sequence on the specified port number . Success . The USB device should now be at address zero . Else : Failure . No USB device is present and the USB port should be disabled .
usb_error_t
usbd_req_reset_port(struct usb_device *udev, struct lock *lock, uint8_t port)
{
	struct usb_port_status ps;
	usb_error_t err;
	uint16_t n;
	uint16_t status;
	uint16_t change;
#ifdef USB_DEBUG
	uint16_t pr_poll_delay;
	uint16_t pr_recovery_delay;
#endif
	DPRINTF("\n");
	usbd_req_clear_port_feature(
	    udev, lock, port, UHF_C_PORT_RESET);
	err = usbd_req_set_port_feature(
	    udev, lock, port, UHF_PORT_RESET);
	if (err)
		goto done;
#ifdef USB_DEBUG
	pr_poll_delay = usb_pr_poll_delay;
	if (pr_poll_delay < 1) {
		pr_poll_delay = 1;
	} else if (pr_poll_delay > 1000) {
		pr_poll_delay = 1000;
	}
	pr_recovery_delay = usb_pr_recovery_delay;
	if (pr_recovery_delay > 1000) {
		pr_recovery_delay = 1000;
	}
#endif
	n = 0;
	while (1) {
#ifdef USB_DEBUG
		usb_pause_mtx(lock, USB_MS_TO_TICKS(pr_poll_delay));
		n += pr_poll_delay;
#else
		usb_pause_mtx(lock, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
		n += USB_PORT_RESET_DELAY;
#endif
		err = usbd_req_get_port_status(udev, lock, &ps, port);
		if (err)
			goto done;
		status = UGETW(ps.wPortStatus);
		change = UGETW(ps.wPortChange);
		if (!(status & UPS_CURRENT_CONNECT_STATUS))
			goto done;
		if (change & UPS_C_PORT_RESET)
			break;
		if (!(status & UPS_RESET))
			break;
		if (n > 1000) {
			n = 0;
			break;
		}
	}
	err = usbd_req_clear_port_feature(
	    udev, lock, port, UHF_C_PORT_RESET);
	if (err)
		goto done;
	if (n == 0) {
		err = USB_ERR_TIMEOUT;
		goto done;
	}
#ifdef USB_DEBUG
	usb_pause_mtx(lock, USB_MS_TO_TICKS(pr_recovery_delay));
#else
	usb_pause_mtx(lock, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY));
#endif
done:
	DPRINTFN(2, "port %d reset returning error=%s\n",
	    port, usbd_errstr(err));
	return (err);
}
usb_error_t usbd_req_reset_port ( struct usb_device * udev , struct lock * lock , uint8_t port ) { struct usb_port_status ps ; usb_error_t err ; uint16_t n ; uint16_t status ; uint16_t change ; #ifdef USB_DEBUG uint16_t pr_poll_delay ; uint16_t pr_recovery_delay ; #endif DPRINTF ( " \n " ) ; usbd_req_clear_port_feature ( udev , lock , port , UHF_C_PORT_RESET ) ; err = usbd_req_set_port_feature ( udev , lock , port , UHF_PORT_RESET ) ; if ( err ) goto done ; #ifdef USB_DEBUG pr_poll_delay = usb_pr_poll_delay ; if ( pr_poll_delay < 1 ) { pr_poll_delay = 1 ; } else if ( pr_poll_delay > 1000 ) { pr_poll_delay = 1000 ; } pr_recovery_delay = usb_pr_recovery_delay ; if ( pr_recovery_delay > 1000 ) { pr_recovery_delay = 1000 ; } #endif n = 0 ; while ( 1 ) { #ifdef USB_DEBUG usb_pause_mtx ( lock , USB_MS_TO_TICKS ( pr_poll_delay ) ) ; n += pr_poll_delay ; #else usb_pause_mtx ( lock , USB_MS_TO_TICKS ( USB_PORT_RESET_DELAY ) ) ; n += USB_PORT_RESET_DELAY ; #endif err = usbd_req_get_port_status ( udev , lock , & ps , port ) ; if ( err ) goto done ; status = UGETW ( ps . wPortStatus ) ; change = UGETW ( ps . wPortChange ) ; if ( ! ( status & UPS_CURRENT_CONNECT_STATUS ) ) goto done ; if ( change & UPS_C_PORT_RESET ) break ; if ( ! ( status & UPS_RESET ) ) break ; if ( n > 1000 ) { n = 0 ; break ; } } err = usbd_req_clear_port_feature ( udev , lock , port , UHF_C_PORT_RESET ) ; if ( err ) goto done ; if ( n == 0 ) { err = USB_ERR_TIMEOUT ; goto done ; } #ifdef USB_DEBUG usb_pause_mtx ( lock , USB_MS_TO_TICKS ( pr_recovery_delay ) ) ; #else usb_pause_mtx ( lock , USB_MS_TO_TICKS ( USB_PORT_RESET_RECOVERY ) ) ; #endif done : DPRINTFN ( 2 , " \n " , port , usbd_errstr ( err ) ) ; return ( err ) ; }
usbd_req_reset_port
 This function will instruct a USB HUB to perform a reset sequence
 on the specified port number.
usbd_req_reset_port This function will instruct a USB HUB to perform a reset sequence on the specified port number .
/* clear any leftover port reset changes first */ /* assert port reset on the given port */ /* check for errors */ /* range check input parameters */ /* wait for the device to recover from reset */ /* wait for the device to recover from reset */ /* if the device disappeared, just give up */ /* check if reset is complete */ /*
		 * Some Virtual Machines like VirtualBox 4.x fail to
		 * generate a port reset change event. Check if reset
		 * is no longer asserted.
		 */ /* check for timeout */ /* clear port reset first */ /* check for timeout */ /* wait for the device to recover from reset */ /* wait for the device to recover from reset */