Thu Mar 3 05:46:58 2022 UTC ()
usbnet: Set and clear IFF_RUNNING slightly earlier and later.

- Set IFF_RUNNING before any calls to usbnet_rxeof are possible.
- Don't clear IFF_RUNNING until all transfers have been aborted.


(riastradh)
diff -r1.45 -r1.46 src/sys/dev/usb/usbnet.c

cvs diff -r1.45 -r1.46 src/sys/dev/usb/usbnet.c (expand / switch to unified diff)

--- src/sys/dev/usb/usbnet.c 2022/03/03 05:46:50 1.45
+++ src/sys/dev/usb/usbnet.c 2022/03/03 05:46:58 1.46
@@ -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
45struct usbnet_cdata { 45struct 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
865out: 865out:
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
1156static void 1157static void
1157usbnet_if_stop(struct ifnet *ifp, int disable) 1158usbnet_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}