| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: usbnet.c,v 1.45 2022/03/03 05:46:50 riastradh Exp $ */ | | 1 | /* $NetBSD: usbnet.c,v 1.46 2022/03/03 05:46:58 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.45 2022/03/03 05:46:50 riastradh Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.46 2022/03/03 05:46:58 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; |
| @@ -840,36 +840,36 @@ usbnet_init_rx_tx(struct usbnet * const | | | @@ -840,36 +840,36 @@ usbnet_init_rx_tx(struct usbnet * const |
840 | if (usbnet_rx_list_init(un)) { | | 840 | if (usbnet_rx_list_init(un)) { |
841 | aprint_error_dev(un->un_dev, "rx list init failed\n"); | | 841 | aprint_error_dev(un->un_dev, "rx list init failed\n"); |
842 | error = ENOBUFS; | | 842 | error = ENOBUFS; |
843 | goto out; | | 843 | goto out; |
844 | } | | 844 | } |
845 | | | 845 | |
846 | /* Init TX ring. */ | | 846 | /* Init TX ring. */ |
847 | if (usbnet_tx_list_init(un)) { | | 847 | if (usbnet_tx_list_init(un)) { |
848 | aprint_error_dev(un->un_dev, "tx list init failed\n"); | | 848 | aprint_error_dev(un->un_dev, "tx list init failed\n"); |
849 | error = ENOBUFS; | | 849 | error = ENOBUFS; |
850 | goto out; | | 850 | goto out; |
851 | } | | 851 | } |
852 | | | 852 | |
853 | /* Start up the receive pipe(s). */ | | | |
854 | usbnet_rx_start_pipes(un); | | | |
855 | | | | |
856 | /* Indicate we are up and running. */ | | 853 | /* Indicate we are up and running. */ |
857 | #if 0 | | 854 | #if 0 |
858 | /* XXX if_mcast_op() can call this without ifnet locked */ | | 855 | /* XXX if_mcast_op() can call this without ifnet locked */ |
859 | KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp)); | | 856 | KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp)); |
860 | #endif | | 857 | #endif |
861 | ifp->if_flags |= IFF_RUNNING; | | 858 | ifp->if_flags |= IFF_RUNNING; |
862 | | | 859 | |
| | | 860 | /* Start up the receive pipe(s). */ |
| | | 861 | usbnet_rx_start_pipes(un); |
| | | 862 | |
863 | callout_schedule(&unp->unp_stat_ch, hz); | | 863 | callout_schedule(&unp->unp_stat_ch, hz); |
864 | | | 864 | |
865 | out: | | 865 | out: |
866 | if (error) { | | 866 | if (error) { |
867 | usbnet_rx_list_fini(un); | | 867 | usbnet_rx_list_fini(un); |
868 | usbnet_tx_list_fini(un); | | 868 | usbnet_tx_list_fini(un); |
869 | usbnet_ep_close_pipes(un); | | 869 | usbnet_ep_close_pipes(un); |
870 | } | | 870 | } |
871 | usbnet_unbusy(un); | | 871 | usbnet_unbusy(un); |
872 | | | 872 | |
873 | usbnet_isowned_core(un); | | 873 | usbnet_isowned_core(un); |
874 | | | 874 | |
875 | return error; | | 875 | return error; |
| @@ -1116,50 +1116,51 @@ usbnet_stop(struct usbnet *un, struct if | | | @@ -1116,50 +1116,51 @@ usbnet_stop(struct usbnet *un, struct if |
1116 | | | 1116 | |
1117 | usbnet_isowned_core(un); | | 1117 | usbnet_isowned_core(un); |
1118 | | | 1118 | |
1119 | usbnet_busy(un); | | 1119 | usbnet_busy(un); |
1120 | | | 1120 | |
1121 | mutex_enter(&unp->unp_rxlock); | | 1121 | mutex_enter(&unp->unp_rxlock); |
1122 | mutex_enter(&unp->unp_txlock); | | 1122 | mutex_enter(&unp->unp_txlock); |
1123 | unp->unp_stopping = true; | | 1123 | unp->unp_stopping = true; |
1124 | mutex_exit(&unp->unp_txlock); | | 1124 | mutex_exit(&unp->unp_txlock); |
1125 | mutex_exit(&unp->unp_rxlock); | | 1125 | mutex_exit(&unp->unp_rxlock); |
1126 | | | 1126 | |
1127 | uno_stop(un, ifp, disable); | | 1127 | uno_stop(un, ifp, disable); |
1128 | | | 1128 | |
1129 | /* | | | |
1130 | * XXXSMP Would like to | | | |
1131 | * KASSERT(IFNET_LOCKED(ifp)) | | | |
1132 | * here but the locking order is: | | | |
1133 | * ifnet -> core_lock -> rxlock -> txlock | | | |
1134 | * and core_lock is already held. | | | |
1135 | */ | | | |
1136 | ifp->if_flags &= ~IFF_RUNNING; | | | |
1137 | unp->unp_timer = 0; | | 1129 | unp->unp_timer = 0; |
1138 | | | 1130 | |
1139 | callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock); | | 1131 | callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock); |
1140 | usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, | | 1132 | usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, |
1141 | &unp->unp_core_lock); | | 1133 | &unp->unp_core_lock); |
1142 | | | 1134 | |
1143 | /* Stop transfers. */ | | 1135 | /* Stop transfers. */ |
1144 | usbnet_ep_stop_pipes(un); | | 1136 | usbnet_ep_stop_pipes(un); |
1145 | | | 1137 | |
1146 | /* Free RX/TX resources. */ | | 1138 | /* Free RX/TX resources. */ |
1147 | usbnet_rx_list_fini(un); | | 1139 | usbnet_rx_list_fini(un); |
1148 | usbnet_tx_list_fini(un); | | 1140 | usbnet_tx_list_fini(un); |
1149 | | | 1141 | |
1150 | /* Close pipes. */ | | 1142 | /* Close pipes. */ |
1151 | usbnet_ep_close_pipes(un); | | 1143 | usbnet_ep_close_pipes(un); |
1152 | | | 1144 | |
| | | 1145 | /* |
| | | 1146 | * XXXSMP Would like to |
| | | 1147 | * KASSERT(IFNET_LOCKED(ifp)) |
| | | 1148 | * here but the locking order is: |
| | | 1149 | * ifnet -> core_lock -> rxlock -> txlock |
| | | 1150 | * and core_lock is already held. |
| | | 1151 | */ |
| | | 1152 | ifp->if_flags &= ~IFF_RUNNING; |
| | | 1153 | |
1153 | usbnet_unbusy(un); | | 1154 | usbnet_unbusy(un); |
1154 | } | | 1155 | } |
1155 | | | 1156 | |
1156 | static void | | 1157 | static void |
1157 | usbnet_if_stop(struct ifnet *ifp, int disable) | | 1158 | usbnet_if_stop(struct ifnet *ifp, int disable) |
1158 | { | | 1159 | { |
1159 | struct usbnet * const un = ifp->if_softc; | | 1160 | struct usbnet * const un = ifp->if_softc; |
1160 | struct usbnet_private * const unp = un->un_pri; | | 1161 | struct usbnet_private * const unp = un->un_pri; |
1161 | | | 1162 | |
1162 | mutex_enter(&unp->unp_core_lock); | | 1163 | mutex_enter(&unp->unp_core_lock); |
1163 | usbnet_stop(un, ifp, disable); | | 1164 | usbnet_stop(un, ifp, disable); |
1164 | mutex_exit(&unp->unp_core_lock); | | 1165 | mutex_exit(&unp->unp_core_lock); |
1165 | } | | 1166 | } |