Thu Mar 3 05:51:56 2022 UTC ()
usbnet: No need for usbnet_busy in usbnet_init_rx_tx or usbnet_stop.

These run with IFNET_LOCK held, and the interface cannot be detached
until the IFNET_LOCK is released, so there is no need to hang onto a
reference count here.


(riastradh)
diff -r1.75 -r1.76 src/sys/dev/usb/usbnet.c

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

--- src/sys/dev/usb/usbnet.c 2022/03/03 05:51:06 1.75
+++ src/sys/dev/usb/usbnet.c 2022/03/03 05:51:56 1.76
@@ -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
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;
@@ -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
876out: 874out:
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
889void 886void
890usbnet_busy(struct usbnet *un) 887usbnet_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 */
1118void 1115void
1119usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) 1116usbnet_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
1183static void 1176static void
1184usbnet_if_stop(struct ifnet *ifp, int disable) 1177usbnet_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);