| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: usbnet.c,v 1.75 2022/03/03 05:51:06 riastradh Exp $ */ | | 1 | /* $NetBSD: usbnet.c,v 1.76 2022/03/03 05:51:56 riastradh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2019 Matthew R. Green | | 4 | * Copyright (c) 2019 Matthew R. Green |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 21 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 23 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 24 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. | | 26 | * SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | /* | | 29 | /* |
30 | * Common code shared between USB network drivers. | | 30 | * Common code shared between USB network drivers. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.75 2022/03/03 05:51:06 riastradh Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.76 2022/03/03 05:51:56 riastradh Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/kmem.h> | | 38 | #include <sys/kmem.h> |
39 | #include <sys/module.h> | | 39 | #include <sys/module.h> |
40 | #include <sys/atomic.h> | | 40 | #include <sys/atomic.h> |
41 | | | 41 | |
42 | #include <dev/usb/usbnet.h> | | 42 | #include <dev/usb/usbnet.h> |
43 | #include <dev/usb/usbhist.h> | | 43 | #include <dev/usb/usbhist.h> |
44 | | | 44 | |
45 | struct usbnet_cdata { | | 45 | struct usbnet_cdata { |
46 | struct usbnet_chain *uncd_tx_chain; | | 46 | struct usbnet_chain *uncd_tx_chain; |
47 | struct usbnet_chain *uncd_rx_chain; | | 47 | struct usbnet_chain *uncd_rx_chain; |
| @@ -827,28 +827,26 @@ usbnet_init_rx_tx(struct usbnet * const | | | @@ -827,28 +827,26 @@ usbnet_init_rx_tx(struct usbnet * const |
827 | struct ifnet * const ifp = usbnet_ifp(un); | | 827 | struct ifnet * const ifp = usbnet_ifp(un); |
828 | usbd_status err; | | 828 | usbd_status err; |
829 | int error = 0; | | 829 | int error = 0; |
830 | | | 830 | |
831 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | | 831 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), |
832 | "%s", ifp->if_xname); | | 832 | "%s", ifp->if_xname); |
833 | | | 833 | |
834 | usbnet_isowned_core(un); | | 834 | usbnet_isowned_core(un); |
835 | | | 835 | |
836 | if (usbnet_isdying(un)) { | | 836 | if (usbnet_isdying(un)) { |
837 | return EIO; | | 837 | return EIO; |
838 | } | | 838 | } |
839 | | | 839 | |
840 | usbnet_busy(un); | | | |
841 | | | | |
842 | /* Open RX and TX pipes. */ | | 840 | /* Open RX and TX pipes. */ |
843 | err = usbnet_ep_open_pipes(un); | | 841 | err = usbnet_ep_open_pipes(un); |
844 | if (err) { | | 842 | if (err) { |
845 | aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n", | | 843 | aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n", |
846 | usbd_errstr(err)); | | 844 | usbd_errstr(err)); |
847 | error = EIO; | | 845 | error = EIO; |
848 | goto out; | | 846 | goto out; |
849 | } | | 847 | } |
850 | | | 848 | |
851 | /* Init RX ring. */ | | 849 | /* Init RX ring. */ |
852 | if (usbnet_rx_list_init(un)) { | | 850 | if (usbnet_rx_list_init(un)) { |
853 | aprint_error_dev(un->un_dev, "rx list init failed\n"); | | 851 | aprint_error_dev(un->un_dev, "rx list init failed\n"); |
854 | error = ENOBUFS; | | 852 | error = ENOBUFS; |
| @@ -869,27 +867,26 @@ usbnet_init_rx_tx(struct usbnet * const | | | @@ -869,27 +867,26 @@ usbnet_init_rx_tx(struct usbnet * const |
869 | ifp->if_flags |= IFF_RUNNING; | | 867 | ifp->if_flags |= IFF_RUNNING; |
870 | | | 868 | |
871 | /* Start up the receive pipe(s). */ | | 869 | /* Start up the receive pipe(s). */ |
872 | usbnet_rx_start_pipes(un); | | 870 | usbnet_rx_start_pipes(un); |
873 | | | 871 | |
874 | callout_schedule(&unp->unp_stat_ch, hz); | | 872 | callout_schedule(&unp->unp_stat_ch, hz); |
875 | | | 873 | |
876 | out: | | 874 | out: |
877 | if (error) { | | 875 | if (error) { |
878 | usbnet_rx_list_fini(un); | | 876 | usbnet_rx_list_fini(un); |
879 | usbnet_tx_list_fini(un); | | 877 | usbnet_tx_list_fini(un); |
880 | usbnet_ep_close_pipes(un); | | 878 | usbnet_ep_close_pipes(un); |
881 | } | | 879 | } |
882 | usbnet_unbusy(un); | | | |
883 | | | 880 | |
884 | usbnet_isowned_core(un); | | 881 | usbnet_isowned_core(un); |
885 | | | 882 | |
886 | return error; | | 883 | return error; |
887 | } | | 884 | } |
888 | | | 885 | |
889 | void | | 886 | void |
890 | usbnet_busy(struct usbnet *un) | | 887 | usbnet_busy(struct usbnet *un) |
891 | { | | 888 | { |
892 | struct usbnet_private * const unp = un->un_pri; | | 889 | struct usbnet_private * const unp = un->un_pri; |
893 | | | 890 | |
894 | usbnet_isowned_core(un); | | 891 | usbnet_isowned_core(un); |
895 | | | 892 | |
| @@ -1116,28 +1113,26 @@ usbnet_mcast_task(void *arg) | | | @@ -1116,28 +1113,26 @@ usbnet_mcast_task(void *arg) |
1116 | * usbnet_if_stop() is for the if_stop handler. | | 1113 | * usbnet_if_stop() is for the if_stop handler. |
1117 | */ | | 1114 | */ |
1118 | void | | 1115 | void |
1119 | usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) | | 1116 | usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) |
1120 | { | | 1117 | { |
1121 | struct usbnet_private * const unp = un->un_pri; | | 1118 | struct usbnet_private * const unp = un->un_pri; |
1122 | | | 1119 | |
1123 | USBNETHIST_FUNC(); USBNETHIST_CALLED(); | | 1120 | USBNETHIST_FUNC(); USBNETHIST_CALLED(); |
1124 | | | 1121 | |
1125 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | | 1122 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), |
1126 | "%s", ifp->if_xname); | | 1123 | "%s", ifp->if_xname); |
1127 | usbnet_isowned_core(un); | | 1124 | usbnet_isowned_core(un); |
1128 | | | 1125 | |
1129 | usbnet_busy(un); | | | |
1130 | | | | |
1131 | /* | | 1126 | /* |
1132 | * Prevent new activity (rescheduling ticks, xfers, &c.) and | | 1127 | * Prevent new activity (rescheduling ticks, xfers, &c.) and |
1133 | * clear the watchdog timer. | | 1128 | * clear the watchdog timer. |
1134 | */ | | 1129 | */ |
1135 | mutex_enter(&unp->unp_rxlock); | | 1130 | mutex_enter(&unp->unp_rxlock); |
1136 | mutex_enter(&unp->unp_txlock); | | 1131 | mutex_enter(&unp->unp_txlock); |
1137 | unp->unp_stopping = true; | | 1132 | unp->unp_stopping = true; |
1138 | unp->unp_timer = 0; | | 1133 | unp->unp_timer = 0; |
1139 | mutex_exit(&unp->unp_txlock); | | 1134 | mutex_exit(&unp->unp_txlock); |
1140 | mutex_exit(&unp->unp_rxlock); | | 1135 | mutex_exit(&unp->unp_rxlock); |
1141 | | | 1136 | |
1142 | /* | | 1137 | /* |
1143 | * Stop the timer first, then the task -- if the timer was | | 1138 | * Stop the timer first, then the task -- if the timer was |
| @@ -1166,28 +1161,26 @@ usbnet_stop(struct usbnet *un, struct if | | | @@ -1166,28 +1161,26 @@ usbnet_stop(struct usbnet *un, struct if |
1166 | usbnet_ep_stop_pipes(un); | | 1161 | usbnet_ep_stop_pipes(un); |
1167 | | | 1162 | |
1168 | /* Free RX/TX resources. */ | | 1163 | /* Free RX/TX resources. */ |
1169 | usbnet_rx_list_fini(un); | | 1164 | usbnet_rx_list_fini(un); |
1170 | usbnet_tx_list_fini(un); | | 1165 | usbnet_tx_list_fini(un); |
1171 | | | 1166 | |
1172 | /* Close pipes. */ | | 1167 | /* Close pipes. */ |
1173 | usbnet_ep_close_pipes(un); | | 1168 | usbnet_ep_close_pipes(un); |
1174 | | | 1169 | |
1175 | /* Everything is quesced now. */ | | 1170 | /* Everything is quesced now. */ |
1176 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), | | 1171 | KASSERTMSG(!unp->unp_ifp_attached || IFNET_LOCKED(ifp), |
1177 | "%s", ifp->if_xname); | | 1172 | "%s", ifp->if_xname); |
1178 | ifp->if_flags &= ~IFF_RUNNING; | | 1173 | ifp->if_flags &= ~IFF_RUNNING; |
1179 | | | | |
1180 | usbnet_unbusy(un); | | | |
1181 | } | | 1174 | } |
1182 | | | 1175 | |
1183 | static void | | 1176 | static void |
1184 | usbnet_if_stop(struct ifnet *ifp, int disable) | | 1177 | usbnet_if_stop(struct ifnet *ifp, int disable) |
1185 | { | | 1178 | { |
1186 | struct usbnet * const un = ifp->if_softc; | | 1179 | struct usbnet * const un = ifp->if_softc; |
1187 | struct usbnet_private * const unp = un->un_pri; | | 1180 | struct usbnet_private * const unp = un->un_pri; |
1188 | | | 1181 | |
1189 | KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); | | 1182 | KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname); |
1190 | | | 1183 | |
1191 | mutex_enter(&unp->unp_core_lock); | | 1184 | mutex_enter(&unp->unp_core_lock); |
1192 | usbnet_stop(un, ifp, disable); | | 1185 | usbnet_stop(un, ifp, disable); |
1193 | mutex_exit(&unp->unp_core_lock); | | 1186 | mutex_exit(&unp->unp_core_lock); |