usb_request.c (230032) | usb_request.c (230091) |
---|---|
1/* $FreeBSD: head/sys/dev/usb/usb_request.c 230032 2012-01-12 21:21:20Z hselasky $ */ | 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; | 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; |
|
788 789#ifdef USB_DEBUG 790 uint16_t pr_poll_delay; 791 uint16_t pr_recovery_delay; 792 793#endif | 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 |
|
794 /* clear any leftover port reset changes first */ 795 usbd_req_clear_port_feature( 796 udev, mtx, port, UHF_C_PORT_RESET); 797 798 /* assert port reset on the given port */ 799 err = usbd_req_set_port_feature( 800 udev, mtx, port, UHF_PORT_RESET); 801 --- 10 unchanged lines hidden (view full) --- 812 } 813 pr_recovery_delay = usb_pr_recovery_delay; 814 if (pr_recovery_delay > 1000) { 815 pr_recovery_delay = 1000; 816 } 817#endif 818 n = 0; 819 while (1) { | 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) { |
820 uint16_t status; 821 uint16_t change; 822 | |
823#ifdef USB_DEBUG 824 /* wait for the device to recover from reset */ 825 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay)); 826 n += pr_poll_delay; 827#else 828 /* wait for the device to recover from reset */ 829 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY)); 830 n += USB_PORT_RESET_DELAY; 831#endif 832 err = usbd_req_get_port_status(udev, mtx, &ps, port); | 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); |
833 if (err) { | 835 if (err) |
834 goto done; | 836 goto done; |
835 } | 837 |
836 status = UGETW(ps.wPortStatus); 837 change = UGETW(ps.wPortChange); 838 839 /* if the device disappeared, just give up */ 840 if (!(status & UPS_CURRENT_CONNECT_STATUS)) 841 goto done; 842 843 /* check if reset is complete */ --- 13 unchanged lines hidden (view full) --- 857 n = 0; 858 break; 859 } 860 } 861 862 /* clear port reset first */ 863 err = usbd_req_clear_port_feature( 864 udev, mtx, port, UHF_C_PORT_RESET); | 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); |
865 if (err) { | 867 if (err) |
866 goto done; | 868 goto done; |
867 } | 869 |
868 /* check for timeout */ 869 if (n == 0) { 870 err = USB_ERR_TIMEOUT; 871 goto done; 872 } 873#ifdef USB_DEBUG 874 /* wait for the device to recover from reset */ 875 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay)); --- 17 unchanged lines hidden (view full) --- 893 * for SUPER-speed USB HUBs. 894 * 895 * Returns: 896 * 0: Success. The USB device should now be available again. 897 * Else: Failure. No USB device is present and the USB port should be 898 * disabled. 899 *------------------------------------------------------------------------*/ 900usb_error_t | 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 |
901usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) | 903usbd_req_warm_reset_port(struct usb_device *udev, struct mtx *mtx, 904 uint8_t port) |
902{ 903 struct usb_port_status ps; 904 usb_error_t err; 905 uint16_t n; | 905{ 906 struct usb_port_status ps; 907 usb_error_t err; 908 uint16_t n; |
909 uint16_t status; 910 uint16_t change; |
|
906 907#ifdef USB_DEBUG 908 uint16_t pr_poll_delay; 909 uint16_t pr_recovery_delay; 910 911#endif | 911 912#ifdef USB_DEBUG 913 uint16_t pr_poll_delay; 914 uint16_t pr_recovery_delay; 915 916#endif |
912 err = usbd_req_set_port_feature(udev, mtx, port, UHF_BH_PORT_RESET); 913 if (err) { | 917 918 DPRINTF("\n"); 919 920 err = usbd_req_get_port_status(udev, mtx, &ps, port); 921 if (err) |
914 goto done; | 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); |
|
915 } | 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 |
|
916#ifdef USB_DEBUG 917 /* range check input parameters */ 918 pr_poll_delay = usb_pr_poll_delay; 919 if (pr_poll_delay < 1) { 920 pr_poll_delay = 1; 921 } else if (pr_poll_delay > 1000) { 922 pr_poll_delay = 1000; 923 } --- 9 unchanged lines hidden (view full) --- 933 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay)); 934 n += pr_poll_delay; 935#else 936 /* wait for the device to recover from reset */ 937 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY)); 938 n += USB_PORT_RESET_DELAY; 939#endif 940 err = usbd_req_get_port_status(udev, mtx, &ps, port); | 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); |
941 if (err) { | 972 if (err) |
942 goto done; | 973 goto done; |
943 } | 974 975 status = UGETW(ps.wPortStatus); 976 change = UGETW(ps.wPortChange); 977 |
944 /* if the device disappeared, just give up */ | 978 /* if the device disappeared, just give up */ |
945 if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) { | 979 if (!(status & UPS_CURRENT_CONNECT_STATUS)) |
946 goto done; | 980 goto done; |
947 } | 981 |
948 /* check if reset is complete */ | 982 /* check if reset is complete */ |
949 if (UGETW(ps.wPortChange) & UPS_C_BH_PORT_RESET) { | 983 if (change & UPS_C_BH_PORT_RESET) |
950 break; | 984 break; |
951 } | 985 |
952 /* check for timeout */ 953 if (n > 1000) { 954 n = 0; 955 break; 956 } 957 } 958 959 /* clear port reset first */ 960 err = usbd_req_clear_port_feature( 961 udev, mtx, port, UHF_C_BH_PORT_RESET); | 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); |
962 if (err) { | 996 if (err) |
963 goto done; | 997 goto done; |
964 } | 998 |
965 /* check for timeout */ 966 if (n == 0) { 967 err = USB_ERR_TIMEOUT; 968 goto done; 969 } 970#ifdef USB_DEBUG 971 /* wait for the device to recover from reset */ 972 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay)); --- 1026 unchanged lines hidden (view full) --- 1999 udev->hs_port_no); 2000 if (err) { 2001 DPRINTF("Resetting parent High " 2002 "Speed TT failed (%s).\n", 2003 usbd_errstr(err)); 2004 } 2005 } 2006 | 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 |
|
2007 /* Try to reset the parent HUB port. */ 2008 err = usbd_req_reset_port(parent_hub, mtx, udev->port_no); 2009 if (err) { 2010 DPRINTFN(0, "addr=%d, port reset failed, %s\n", 2011 old_addr, usbd_errstr(err)); 2012 goto done; 2013 } 2014 --- 176 unchanged lines hidden --- | 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 --- |