Deleted Added
sdiff udiff text old ( 230032 ) new ( 230091 )
full compact
1/* $FreeBSD: head/sys/dev/usb/usb_request.c 230091 2012-01-13 22:26:13Z hselasky $ */
2/*-
3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved.
4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved.
5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:

--- 770 unchanged lines hidden (view full) ---

780 * disabled.
781 *------------------------------------------------------------------------*/
782usb_error_t
783usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port)
784{
785 struct usb_port_status ps;
786 usb_error_t err;
787 uint16_t n;
788 uint16_t status;
789 uint16_t change;
790
791#ifdef USB_DEBUG
792 uint16_t pr_poll_delay;
793 uint16_t pr_recovery_delay;
794
795#endif
796
797 DPRINTF("\n");
798
799 /* clear any leftover port reset changes first */
800 usbd_req_clear_port_feature(
801 udev, mtx, port, UHF_C_PORT_RESET);
802
803 /* assert port reset on the given port */
804 err = usbd_req_set_port_feature(
805 udev, mtx, port, UHF_PORT_RESET);
806

--- 10 unchanged lines hidden (view full) ---

817 }
818 pr_recovery_delay = usb_pr_recovery_delay;
819 if (pr_recovery_delay > 1000) {
820 pr_recovery_delay = 1000;
821 }
822#endif
823 n = 0;
824 while (1) {
825#ifdef USB_DEBUG
826 /* wait for the device to recover from reset */
827 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
828 n += pr_poll_delay;
829#else
830 /* wait for the device to recover from reset */
831 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
832 n += USB_PORT_RESET_DELAY;
833#endif
834 err = usbd_req_get_port_status(udev, mtx, &ps, port);
835 if (err)
836 goto done;
837
838 status = UGETW(ps.wPortStatus);
839 change = UGETW(ps.wPortChange);
840
841 /* if the device disappeared, just give up */
842 if (!(status & UPS_CURRENT_CONNECT_STATUS))
843 goto done;
844
845 /* check if reset is complete */

--- 13 unchanged lines hidden (view full) ---

859 n = 0;
860 break;
861 }
862 }
863
864 /* clear port reset first */
865 err = usbd_req_clear_port_feature(
866 udev, mtx, port, UHF_C_PORT_RESET);
867 if (err)
868 goto done;
869
870 /* check for timeout */
871 if (n == 0) {
872 err = USB_ERR_TIMEOUT;
873 goto done;
874 }
875#ifdef USB_DEBUG
876 /* wait for the device to recover from reset */
877 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));

--- 17 unchanged lines hidden (view full) ---

895 * for SUPER-speed USB HUBs.
896 *
897 * Returns:
898 * 0: Success. The USB device should now be available again.
899 * Else: Failure. No USB device is present and the USB port should be
900 * disabled.
901 *------------------------------------------------------------------------*/
902usb_error_t
903usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx,
904 uint8_t port)
905{
906 struct usb_port_status ps;
907 usb_error_t err;
908 uint16_t n;
909 uint16_t status;
910 uint16_t change;
911
912#ifdef USB_DEBUG
913 uint16_t pr_poll_delay;
914 uint16_t pr_recovery_delay;
915
916#endif
917
918 DPRINTF("\n");
919
920 err = usbd_req_get_port_status(udev, mtx, &ps, port);
921 if (err)
922 goto done;
923
924 status = UGETW(ps.wPortStatus);
925
926 switch (UPS_PORT_LINK_STATE_GET(status)) {
927 case UPS_PORT_LS_U3:
928 case UPS_PORT_LS_COMP_MODE:
929 case UPS_PORT_LS_LOOPBACK:
930 case UPS_PORT_LS_SS_INA:
931 break;
932 default:
933 DPRINTF("Wrong state for warm reset\n");
934 return (0);
935 }
936
937 /* clear any leftover warm port reset changes first */
938 usbd_req_clear_port_feature(udev, mtx,
939 port, UHF_C_BH_PORT_RESET);
940
941 /* set warm port reset */
942 err = usbd_req_set_port_feature(udev, mtx,
943 port, UHF_BH_PORT_RESET);
944 if (err)
945 goto done;
946
947#ifdef USB_DEBUG
948 /* range check input parameters */
949 pr_poll_delay = usb_pr_poll_delay;
950 if (pr_poll_delay < 1) {
951 pr_poll_delay = 1;
952 } else if (pr_poll_delay > 1000) {
953 pr_poll_delay = 1000;
954 }

--- 9 unchanged lines hidden (view full) ---

964 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
965 n += pr_poll_delay;
966#else
967 /* wait for the device to recover from reset */
968 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
969 n += USB_PORT_RESET_DELAY;
970#endif
971 err = usbd_req_get_port_status(udev, mtx, &ps, port);
972 if (err)
973 goto done;
974
975 status = UGETW(ps.wPortStatus);
976 change = UGETW(ps.wPortChange);
977
978 /* if the device disappeared, just give up */
979 if (!(status & UPS_CURRENT_CONNECT_STATUS))
980 goto done;
981
982 /* check if reset is complete */
983 if (change & UPS_C_BH_PORT_RESET)
984 break;
985
986 /* check for timeout */
987 if (n > 1000) {
988 n = 0;
989 break;
990 }
991 }
992
993 /* clear port reset first */
994 err = usbd_req_clear_port_feature(
995 udev, mtx, port, UHF_C_BH_PORT_RESET);
996 if (err)
997 goto done;
998
999 /* check for timeout */
1000 if (n == 0) {
1001 err = USB_ERR_TIMEOUT;
1002 goto done;
1003 }
1004#ifdef USB_DEBUG
1005 /* wait for the device to recover from reset */
1006 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));

--- 1026 unchanged lines hidden (view full) ---

2033 udev->hs_port_no);
2034 if (err) {
2035 DPRINTF("Resetting parent High "
2036 "Speed TT failed (%s).\n",
2037 usbd_errstr(err));
2038 }
2039 }
2040
2041 /* Try to warm reset first */
2042 if (parent_hub->speed == USB_SPEED_SUPER)
2043 usbd_req_warm_reset_port(parent_hub, mtx, udev->port_no);
2044
2045 /* Try to reset the parent HUB port. */
2046 err = usbd_req_reset_port(parent_hub, mtx, udev->port_no);
2047 if (err) {
2048 DPRINTFN(0, "addr=%d, port reset failed, %s\n",
2049 old_addr, usbd_errstr(err));
2050 goto done;
2051 }
2052

--- 176 unchanged lines hidden ---