From 10555ab2d5a801bd007800dd7e775dd0da22f97d Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 18:50:36 +0000
Subject: [PATCH 1/9] usbnet(9): Omit needless un->un_intr test in
 usbnet_pipe_intr.

un->un_intr can't change after attach, and we don't open the pipe if
it's null.  So no need to test it.
---
 sys/dev/usb/usbnet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index e85b1549943f..c7f776a7c401 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -447,7 +447,7 @@ usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
 	struct usbnet_private * const unp = un->un_pri;
 	struct usbnet_intr * const uni = un->un_intr;
 
-	if (uni == NULL || usbnet_isdying(un) || unp->unp_stopping ||
+	if (usbnet_isdying(un) || unp->unp_stopping ||
 	    status == USBD_INVAL || status == USBD_NOT_STARTED ||
 	    status == USBD_CANCELLED) {
 		USBNETHIST_CALLARGS("%jd: uni %#jx d/s %#jx status %#jx",

From 9ca71a9ed06bdf0836b19ea23f53f3c89b32ab60 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 18:52:29 +0000
Subject: [PATCH 2/9] usbnet(9): Don't touch unp_stopping in usbnet_pipe_intr.

This access was unprotected by a lock, but it's not necessary anyway
usbnet_stop aborts the pipes, and the xfer doesn't call usbd_transfer
to reschedule itself -- it's an intr pipe, so it's rescheduled
internally by usbdi(9) in a way that usbd_abort_pipe atomically
prevents.
---
 sys/dev/usb/usbnet.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index c7f776a7c401..a1f2cfce20ac 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -447,12 +447,12 @@ usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
 	struct usbnet_private * const unp = un->un_pri;
 	struct usbnet_intr * const uni = un->un_intr;
 
-	if (usbnet_isdying(un) || unp->unp_stopping ||
+	if (usbnet_isdying(un) ||
 	    status == USBD_INVAL || status == USBD_NOT_STARTED ||
 	    status == USBD_CANCELLED) {
-		USBNETHIST_CALLARGS("%jd: uni %#jx d/s %#jx status %#jx",
+		USBNETHIST_CALLARGS("%jd: uni %#jx dying %#jx status %#jx",
 		    unp->unp_number, (uintptr_t)uni,
-		    (usbnet_isdying(un) << 8) | unp->unp_stopping, status);
+		    usbnet_isdying(un), status);
 		return;
 	}
 

From 29c7fa1428cacf9efefe51e9134d97fc941e25c5 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 19:03:49 +0000
Subject: [PATCH 3/9] usbnet(9): Split unp_stopping into
 stopped/txstopped/rxstopped.

In practical terms this could be done with one variable and an atomic
store, but serializing all access with a lock makes reasoning easier,
and the locks have to be taken by the logic that queries the
variables anyway, and the variables are set only under heavy-weight
configuration changes anyway.

What this accomplishes is disentangling lock order between rxlock and
txlock: they are never taken at the same time, so no order is needed.

I renamed unp_stopping to unp_stopped for a compiler-assisted audit
to make sure I reviewed every case of it.
---
 sys/dev/usb/usbnet.c | 59 ++++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 18 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index a1f2cfce20ac..28a3eefeba08 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -58,7 +58,8 @@ struct usbnet_private {
 	 * - unp_txlock protects the tx path and its data
 	 *
 	 * the lock ordering is:
-	 *	ifnet lock -> unp_core_lock -> unp_rxlock -> unp_txlock
+	 *	ifnet lock -> unp_core_lock -> unp_rxlock
+	 *				    -> unp_txlock
 	 *				    -> unp_mcastlock
 	 * - ifnet lock is not needed for unp_core_lock, but if ifnet lock is
 	 *   involved, it must be taken first
@@ -79,7 +80,9 @@ struct usbnet_private {
 	struct usbd_pipe	*unp_ep[USBNET_ENDPT_MAX];
 
 	volatile bool		unp_dying;
-	bool			unp_stopping;
+	bool			unp_stopped;
+	bool			unp_rxstopped;
+	bool			unp_txstopped;
 	bool			unp_attached;
 	bool			unp_ifp_attached;
 	bool			unp_link;
@@ -347,7 +350,7 @@ usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
 
 	mutex_enter(&unp->unp_rxlock);
 
-	if (usbnet_isdying(un) || unp->unp_stopping ||
+	if (usbnet_isdying(un) || unp->unp_rxstopped ||
 	    status == USBD_INVAL || status == USBD_NOT_STARTED ||
 	    status == USBD_CANCELLED)
 		goto out;
@@ -374,7 +377,7 @@ usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
 	usbnet_isowned_rx(un);
 
 done:
-	if (usbnet_isdying(un) || unp->unp_stopping)
+	if (usbnet_isdying(un) || unp->unp_rxstopped)
 		goto out;
 
 	mutex_exit(&unp->unp_rxlock);
@@ -403,7 +406,7 @@ usbnet_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
 	    unp->unp_number, status, (uintptr_t)xfer, 0);
 
 	mutex_enter(&unp->unp_txlock);
-	if (unp->unp_stopping || usbnet_isdying(un)) {
+	if (unp->unp_txstopped || usbnet_isdying(un)) {
 		mutex_exit(&unp->unp_txlock);
 		return;
 	}
@@ -575,11 +578,11 @@ usbnet_if_start(struct ifnet *ifp)
 	struct usbnet_private * const unp = un->un_pri;
 
 	USBNETHIST_FUNC();
-	USBNETHIST_CALLARGS("%jd: stopping %jd",
-	    unp->unp_number, unp->unp_stopping, 0, 0);
+	USBNETHIST_CALLARGS("%jd: txstopped %jd",
+	    unp->unp_number, unp->unp_txstopped, 0, 0);
 
 	mutex_enter(&unp->unp_txlock);
-	if (!unp->unp_stopping)
+	if (!unp->unp_txstopped)
 		usbnet_start_locked(ifp);
 	mutex_exit(&unp->unp_txlock);
 }
@@ -665,8 +668,8 @@ usbnet_rx_start_pipes(struct usbnet * const un)
 	struct usbnet_private * const unp = un->un_pri;
 
 	mutex_enter(&unp->unp_rxlock);
-	mutex_enter(&unp->unp_txlock);
-	unp->unp_stopping = false;
+	KASSERT(unp->unp_rxstopped);
+	unp->unp_rxstopped = false;
 
 	for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
 		struct usbnet_chain *c = &cd->uncd_rx_chain[i];
@@ -676,7 +679,6 @@ usbnet_rx_start_pipes(struct usbnet * const un)
 		usbd_transfer(c->unc_xfer);
 	}
 
-	mutex_exit(&unp->unp_txlock);
 	mutex_exit(&unp->unp_rxlock);
 }
 
@@ -861,9 +863,17 @@ usbnet_init_rx_tx(struct usbnet * const un)
 		mutex_exit(&unp->unp_mcastlock);
 	}
 
+	/* Allow transmit.  */
+	mutex_enter(&unp->unp_txlock);
+	KASSERT(unp->unp_txstopped);
+	unp->unp_txstopped = false;
+	mutex_exit(&unp->unp_txlock);
+
 	/* Start up the receive pipe(s). */
 	usbnet_rx_start_pipes(un);
 
+	/* Kick off the watchdog/stats/mii tick.  */
+	unp->unp_stopped = false;
 	callout_schedule(&unp->unp_stat_ch, hz);
 
 out:
@@ -973,7 +983,7 @@ usbnet_media_upd(struct ifnet *ifp)
 			mii_phy_reset(miisc);
 	}
 
-	if (unp->unp_stopping)
+	if (unp->unp_stopped)
 		return 0;
 	return ether_mediachange(ifp);
 }
@@ -1083,17 +1093,21 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
 	 * Prevent new activity (rescheduling ticks, xfers, &c.) and
 	 * clear the watchdog timer.
 	 */
+	unp->unp_stopped = true;
+
 	mutex_enter(&unp->unp_rxlock);
+	unp->unp_rxstopped = true;
+	mutex_exit(&unp->unp_rxlock);
+
 	mutex_enter(&unp->unp_txlock);
-	unp->unp_stopping = true;
+	unp->unp_txstopped = true;
 	unp->unp_timer = 0;
 	mutex_exit(&unp->unp_txlock);
-	mutex_exit(&unp->unp_rxlock);
 
 	/*
 	 * Stop the timer first, then the task -- if the timer was
 	 * already firing, we stop the task or wait for it complete
-	 * only after if last fired.  Setting unp_stopping prevents the
+	 * only after if last fired.  Setting unp_stopped prevents the
 	 * timer task from being scheduled again.
 	 */
 	callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock);
@@ -1222,7 +1236,7 @@ usbnet_tick_task(void *arg)
 	uno_tick(un);
 
 	mutex_enter(&unp->unp_core_lock);
-	if (!unp->unp_stopping && !usbnet_isdying(un))
+	if (!unp->unp_stopped && !usbnet_isdying(un))
 		callout_schedule(&unp->unp_stat_ch, hz);
 	mutex_exit(&unp->unp_core_lock);
 }
@@ -1391,6 +1405,9 @@ usbnet_attach(struct usbnet *un)
 
 	unp->unp_number = atomic_inc_uint_nv(&usbnet_number);
 
+	unp->unp_stopped = true;
+	unp->unp_rxstopped = true;
+	unp->unp_txstopped = true;
 	unp->unp_attached = true;
 }
 
@@ -1580,11 +1597,17 @@ usbnet_activate(device_t self, devact_t act)
 
 		atomic_store_relaxed(&unp->unp_dying, true);
 
+		mutex_enter(&unp->unp_core_lock);
+		unp->unp_stopped = true;
+		mutex_exit(&unp->unp_core_lock);
+
 		mutex_enter(&unp->unp_rxlock);
+		unp->unp_rxstopped = true;
+		mutex_exit(&unp->unp_rxlock);
+
 		mutex_enter(&unp->unp_txlock);
-		unp->unp_stopping = true;
+		unp->unp_txstopped = true;
 		mutex_exit(&unp->unp_txlock);
-		mutex_exit(&unp->unp_rxlock);
 
 		return 0;
 	default:

From 299ed67f4a0401f5313bd4bec30898b0ac86e246 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 19:13:20 +0000
Subject: [PATCH 4/9] usbnet(9): Assert core lock is held on usbnet_set_link.

This is only allowed to be called via the uno_statchg callback, which
in turn is called only with the core lock held.  (usbnet_set_link is
internally in usbnet(9) with the core lock held.)
---
 sys/dev/usb/usbnet.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index 28a3eefeba08..e7c0cb65154c 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -1285,6 +1285,7 @@ out:	mutex_exit(&un->un_pri->unp_core_lock);
 void
 usbnet_set_link(struct usbnet *un, bool link)
 {
+	usbnet_isowned_core(un);
 	un->un_pri->unp_link = link;
 }
 

From 75a2b819a7499cd39444e4ad9424733942a85b25 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 19:23:51 +0000
Subject: [PATCH 5/9] usbnet(9): Call uno_tick before mii stuff.

The one driver that uses it, cue(4), uses it just for statistics
gathering; hard to imagine that order could be important here.  But
this will allow for some simplification of the surrounding code.
---
 sys/dev/usb/usbnet.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index e7c0cb65154c..7caa89c2a09d 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -1223,6 +1223,9 @@ usbnet_tick_task(void *arg)
 	if (timeout)
 		usbnet_watchdog(ifp);
 
+	/* Call driver if requested. */
+	uno_tick(un);
+
 	DPRINTFN(8, "mii %#jx ifp %#jx", (uintptr_t)mii, (uintptr_t)ifp, 0, 0);
 	if (mii) {
 		mutex_enter(&unp->unp_core_lock);
@@ -1232,9 +1235,6 @@ usbnet_tick_task(void *arg)
 		mutex_exit(&unp->unp_core_lock);
 	}
 
-	/* Call driver if requested. */
-	uno_tick(un);
-
 	mutex_enter(&unp->unp_core_lock);
 	if (!unp->unp_stopped && !usbnet_isdying(un))
 		callout_schedule(&unp->unp_stat_ch, hz);

From 070481c2014ecd44e941e32853dfffe45886c7c2 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 19:26:21 +0000
Subject: [PATCH 6/9] usbnet(9): Simplify core lock use in usbnet_tick_task.

---
 sys/dev/usb/usbnet.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index 7caa89c2a09d..bc566cb879e0 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -1226,16 +1226,14 @@ usbnet_tick_task(void *arg)
 	/* Call driver if requested. */
 	uno_tick(un);
 
+	mutex_enter(&unp->unp_core_lock);
 	DPRINTFN(8, "mii %#jx ifp %#jx", (uintptr_t)mii, (uintptr_t)ifp, 0, 0);
 	if (mii) {
-		mutex_enter(&unp->unp_core_lock);
 		mii_tick(mii);
 		if (!unp->unp_link)
 			(*mii->mii_statchg)(ifp);
-		mutex_exit(&unp->unp_core_lock);
 	}
 
-	mutex_enter(&unp->unp_core_lock);
 	if (!unp->unp_stopped && !usbnet_isdying(un))
 		callout_schedule(&unp->unp_stat_ch, hz);
 	mutex_exit(&unp->unp_core_lock);

From e594ac9cf9256d8828eb964fda3314d3504ca935 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 19:56:00 +0000
Subject: [PATCH 7/9] usbnet(9): Omit needless usbnet_core_mutex function.

While here, use inline, not __inline__, since this is not a header
file where inline might be redefined by the user.
---
 sys/dev/usb/usbnet.c | 14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index bc566cb879e0..cccb794c2b0b 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -105,16 +105,10 @@ volatile unsigned usbnet_number;
 static void usbnet_isowned_rx(struct usbnet *);
 static void usbnet_isowned_tx(struct usbnet *);
 
-static kmutex_t *
-usbnet_mutex_core(struct usbnet *un)
-{
-	return &un->un_pri->unp_core_lock;
-}
-
-static __inline__ void
+static inline void
 usbnet_isowned_core(struct usbnet *un)
 {
-	KASSERT(mutex_owned(usbnet_mutex_core(un)));
+	KASSERT(mutex_owned(&un->un_pri->unp_core_lock));
 }
 
 static int usbnet_modcmd(modcmd_t, void *);
@@ -1430,9 +1424,9 @@ usbnet_attach_mii(struct usbnet *un, const struct usbnet_mii *unm)
 
 	usbnet_ec(un)->ec_mii = mii;
 	ifmedia_init_with_lock(&mii->mii_media, 0,
-	    usbnet_media_upd, ether_mediastatus, usbnet_mutex_core(un));
+	    usbnet_media_upd, ether_mediastatus, &unp->unp_core_lock);
 	mii_attach(un->un_dev, mii, unm->un_mii_capmask, unm->un_mii_phyloc,
-		   unm->un_mii_offset, unm->un_mii_flags);
+	    unm->un_mii_offset, unm->un_mii_flags);
 
 	if (LIST_FIRST(&mii->mii_phys) == NULL) {
 		ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);

From 165f96af1686b962edaafaf29601850ba63628b2 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 19:52:57 +0000
Subject: [PATCH 8/9] usbnet(9): Limit scope of core lock to mii and tick
 scheduling.

Bringing the interface up or down is serialized by IFNET_LOCK, so
there's no need for another lock to cover it.

Note: This means that the usbnet(9) mii callbacks may be invoked
concurrently with uno_init or uno_stop.  I'm not sure if this is a
problem.
---
 sys/dev/usb/usbnet.c | 46 +++++++++++++++++++-------------------------
 1 file changed, 20 insertions(+), 26 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index cccb794c2b0b..89289a6e6baf 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -52,17 +52,15 @@ struct usbnet_cdata {
 
 struct usbnet_private {
 	/*
-	 * - unp_core_lock protects most of this structure, the public one,
-	 *   and the MII / media data.
+	 * - unp_core_lock protects the MII / media data and tick scheduling.
 	 * - unp_rxlock protects the rx path and its data
 	 * - unp_txlock protects the tx path and its data
 	 *
 	 * the lock ordering is:
-	 *	ifnet lock -> unp_core_lock -> unp_rxlock
-	 *				    -> unp_txlock
-	 *				    -> unp_mcastlock
-	 * - ifnet lock is not needed for unp_core_lock, but if ifnet lock is
-	 *   involved, it must be taken first
+	 *	ifnet lock -> unp_core_lock
+	 *		   -> unp_rxlock
+	 *		   -> unp_txlock
+	 *		   -> unp_mcastlock
 	 */
 	kmutex_t		unp_core_lock;
 	kmutex_t		unp_rxlock;
@@ -813,8 +811,6 @@ usbnet_init_rx_tx(struct usbnet * const un)
 
 	KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
 
-	usbnet_isowned_core(un);
-
 	if (usbnet_isdying(un)) {
 		return EIO;
 	}
@@ -867,8 +863,10 @@ usbnet_init_rx_tx(struct usbnet * const un)
 	usbnet_rx_start_pipes(un);
 
 	/* Kick off the watchdog/stats/mii tick.  */
+	mutex_enter(&unp->unp_core_lock);
 	unp->unp_stopped = false;
 	callout_schedule(&unp->unp_stat_ch, hz);
+	mutex_exit(&unp->unp_core_lock);
 
 out:
 	if (error) {
@@ -881,10 +879,11 @@ out:
 	 * For devices without any media autodetection, treat success
 	 * here as an active link.
 	 */
-	if (un->un_ops->uno_statchg == NULL)
+	if (un->un_ops->uno_statchg == NULL) {
+		mutex_enter(&unp->unp_core_lock);
 		usbnet_set_link(un, error == 0);
-
-	usbnet_isowned_core(un);
+		mutex_exit(&unp->unp_core_lock);
+	}
 
 	return error;
 }
@@ -1069,13 +1068,11 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
 	USBNETHIST_FUNC(); USBNETHIST_CALLED();
 
 	KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
-	usbnet_isowned_core(un);
 
 	/*
 	 * For drivers with hardware multicast filter update callbacks:
 	 * Prevent concurrent access to the hardware registers by
-	 * multicast filter updates, which happens without IFNET_LOCK
-	 * or the usbnet core lock.
+	 * multicast filter updates, which happens without IFNET_LOCK.
 	 */
 	if (un->un_ops->uno_mcast) {
 		mutex_enter(&unp->unp_mcastlock);
@@ -1087,7 +1084,9 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
 	 * Prevent new activity (rescheduling ticks, xfers, &c.) and
 	 * clear the watchdog timer.
 	 */
+	mutex_enter(&unp->unp_core_lock);
 	unp->unp_stopped = true;
+	mutex_exit(&unp->unp_core_lock);
 
 	mutex_enter(&unp->unp_rxlock);
 	unp->unp_rxstopped = true;
@@ -1101,12 +1100,12 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
 	/*
 	 * Stop the timer first, then the task -- if the timer was
 	 * already firing, we stop the task or wait for it complete
-	 * only after if last fired.  Setting unp_stopped prevents the
+	 * only after it last fired.  Setting unp_stopped prevents the
 	 * timer task from being scheduled again.
 	 */
-	callout_halt(&unp->unp_stat_ch, &unp->unp_core_lock);
+	callout_halt(&unp->unp_stat_ch, NULL);
 	usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER,
-	    &unp->unp_core_lock);
+	    NULL);
 
 	/* Stop transfers. */
 	usbnet_ep_stop_pipes(un);
@@ -1140,7 +1139,6 @@ static void
 usbnet_if_stop(struct ifnet *ifp, int disable)
 {
 	struct usbnet * const un = ifp->if_softc;
-	struct usbnet_private * const unp = un->un_pri;
 
 	KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
 
@@ -1154,9 +1152,7 @@ usbnet_if_stop(struct ifnet *ifp, int disable)
 	if ((ifp->if_flags & IFF_RUNNING) == 0)
 		return;
 
-	mutex_enter(&unp->unp_core_lock);
 	usbnet_stop(un, ifp, disable);
-	mutex_exit(&unp->unp_core_lock);
 }
 
 /*
@@ -1259,16 +1255,14 @@ usbnet_if_init(struct ifnet *ifp)
 	if (ifp->if_flags & IFF_RUNNING)
 		return 0;
 
-	mutex_enter(&un->un_pri->unp_core_lock);
 	error = uno_init(un, ifp);
 	if (error)
-		goto out;
+		return error;
 	error = usbnet_init_rx_tx(un);
 	if (error)
-		goto out;
-out:	mutex_exit(&un->un_pri->unp_core_lock);
+		return error;
 
-	return error;
+	return 0;
 }
 
 

From b32e6090c7af1640d388ddc5a95918400a9405d3 Mon Sep 17 00:00:00 2001
From: Taylor R Campbell <riastradh@NetBSD.org>
Date: Sun, 14 Aug 2022 20:12:52 +0000
Subject: [PATCH 9/9] usbnet(9): Rename core lock -> mii lock.

No functional change intended.
---
 sys/dev/usb/usbnet.c | 62 ++++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 31 deletions(-)

diff --git a/sys/dev/usb/usbnet.c b/sys/dev/usb/usbnet.c
index 89289a6e6baf..f0ca4c321af1 100644
--- a/sys/dev/usb/usbnet.c
+++ b/sys/dev/usb/usbnet.c
@@ -52,17 +52,17 @@ struct usbnet_cdata {
 
 struct usbnet_private {
 	/*
-	 * - unp_core_lock protects the MII / media data and tick scheduling.
+	 * - unp_miilock protects the MII / media data and tick scheduling.
 	 * - unp_rxlock protects the rx path and its data
 	 * - unp_txlock protects the tx path and its data
 	 *
 	 * the lock ordering is:
-	 *	ifnet lock -> unp_core_lock
+	 *	ifnet lock -> unp_miilock
 	 *		   -> unp_rxlock
 	 *		   -> unp_txlock
 	 *		   -> unp_mcastlock
 	 */
-	kmutex_t		unp_core_lock;
+	kmutex_t		unp_miilock;
 	kmutex_t		unp_rxlock;
 	kmutex_t		unp_txlock;
 
@@ -104,9 +104,9 @@ static void usbnet_isowned_rx(struct usbnet *);
 static void usbnet_isowned_tx(struct usbnet *);
 
 static inline void
-usbnet_isowned_core(struct usbnet *un)
+usbnet_isowned_mii(struct usbnet *un)
 {
-	KASSERT(mutex_owned(&un->un_pri->unp_core_lock));
+	KASSERT(mutex_owned(&un->un_pri->unp_miilock));
 }
 
 static int usbnet_modcmd(modcmd_t, void *);
@@ -162,7 +162,7 @@ static void
 uno_stop(struct usbnet *un, struct ifnet *ifp, int disable)
 {
 	KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
-	usbnet_isowned_core(un);
+	usbnet_isowned_mii(un);
 	if (un->un_ops->uno_stop)
 		(*un->un_ops->uno_stop)(ifp, disable);
 }
@@ -205,21 +205,21 @@ uno_init(struct usbnet *un, struct ifnet *ifp)
 static int
 uno_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
 {
-	usbnet_isowned_core(un);
+	usbnet_isowned_mii(un);
 	return (*un->un_ops->uno_read_reg)(un, phy, reg, val);
 }
 
 static int
 uno_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
 {
-	usbnet_isowned_core(un);
+	usbnet_isowned_mii(un);
 	return (*un->un_ops->uno_write_reg)(un, phy, reg, val);
 }
 
 static void
 uno_mii_statchg(struct usbnet *un, struct ifnet *ifp)
 {
-	usbnet_isowned_core(un);
+	usbnet_isowned_mii(un);
 	(*un->un_ops->uno_statchg)(ifp);
 }
 
@@ -863,10 +863,10 @@ usbnet_init_rx_tx(struct usbnet * const un)
 	usbnet_rx_start_pipes(un);
 
 	/* Kick off the watchdog/stats/mii tick.  */
-	mutex_enter(&unp->unp_core_lock);
+	mutex_enter(&unp->unp_miilock);
 	unp->unp_stopped = false;
 	callout_schedule(&unp->unp_stat_ch, hz);
-	mutex_exit(&unp->unp_core_lock);
+	mutex_exit(&unp->unp_miilock);
 
 out:
 	if (error) {
@@ -880,9 +880,9 @@ out:
 	 * here as an active link.
 	 */
 	if (un->un_ops->uno_statchg == NULL) {
-		mutex_enter(&unp->unp_core_lock);
+		mutex_enter(&unp->unp_miilock);
 		usbnet_set_link(un, error == 0);
-		mutex_exit(&unp->unp_core_lock);
+		mutex_exit(&unp->unp_miilock);
 	}
 
 	return error;
@@ -897,8 +897,8 @@ usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val)
 	struct usbnet * const un = device_private(dev);
 	int err;
 
-	/* MII layer ensures core_lock is held. */
-	usbnet_isowned_core(un);
+	/* MII layer ensures miilock is held. */
+	usbnet_isowned_mii(un);
 
 	if (usbnet_isdying(un)) {
 		return EIO;
@@ -921,8 +921,8 @@ usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val)
 	struct usbnet * const un = device_private(dev);
 	int err;
 
-	/* MII layer ensures core_lock is held. */
-	usbnet_isowned_core(un);
+	/* MII layer ensures miilock is held. */
+	usbnet_isowned_mii(un);
 
 	if (usbnet_isdying(un)) {
 		return EIO;
@@ -944,8 +944,8 @@ usbnet_mii_statchg(struct ifnet *ifp)
 	USBNETHIST_FUNC(); USBNETHIST_CALLED();
 	struct usbnet * const un = ifp->if_softc;
 
-	/* MII layer ensures core_lock is held. */
-	usbnet_isowned_core(un);
+	/* MII layer ensures miilock is held. */
+	usbnet_isowned_mii(un);
 
 	uno_mii_statchg(un, ifp);
 }
@@ -958,8 +958,8 @@ usbnet_media_upd(struct ifnet *ifp)
 	struct usbnet_private * const unp = un->un_pri;
 	struct mii_data * const mii = usbnet_mii(un);
 
-	/* ifmedia layer ensures core_lock is held. */
-	usbnet_isowned_core(un);
+	/* ifmedia layer ensures miilock is held. */
+	usbnet_isowned_mii(un);
 
 	/* ifmedia changes only with IFNET_LOCK held.  */
 	KASSERTMSG(IFNET_LOCKED(ifp), "%s", ifp->if_xname);
@@ -1084,9 +1084,9 @@ usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
 	 * Prevent new activity (rescheduling ticks, xfers, &c.) and
 	 * clear the watchdog timer.
 	 */
-	mutex_enter(&unp->unp_core_lock);
+	mutex_enter(&unp->unp_miilock);
 	unp->unp_stopped = true;
-	mutex_exit(&unp->unp_core_lock);
+	mutex_exit(&unp->unp_miilock);
 
 	mutex_enter(&unp->unp_rxlock);
 	unp->unp_rxstopped = true;
@@ -1216,7 +1216,7 @@ usbnet_tick_task(void *arg)
 	/* Call driver if requested. */
 	uno_tick(un);
 
-	mutex_enter(&unp->unp_core_lock);
+	mutex_enter(&unp->unp_miilock);
 	DPRINTFN(8, "mii %#jx ifp %#jx", (uintptr_t)mii, (uintptr_t)ifp, 0, 0);
 	if (mii) {
 		mii_tick(mii);
@@ -1226,7 +1226,7 @@ usbnet_tick_task(void *arg)
 
 	if (!unp->unp_stopped && !usbnet_isdying(un))
 		callout_schedule(&unp->unp_stat_ch, hz);
-	mutex_exit(&unp->unp_core_lock);
+	mutex_exit(&unp->unp_miilock);
 }
 
 static int
@@ -1271,7 +1271,7 @@ usbnet_if_init(struct ifnet *ifp)
 void
 usbnet_set_link(struct usbnet *un, bool link)
 {
-	usbnet_isowned_core(un);
+	usbnet_isowned_mii(un);
 	un->un_pri->unp_link = link;
 }
 
@@ -1381,7 +1381,7 @@ usbnet_attach(struct usbnet *un)
 
 	mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
 	mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
-	mutex_init(&unp->unp_core_lock, MUTEX_DEFAULT, IPL_NONE);
+	mutex_init(&unp->unp_miilock, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&unp->unp_mcastlock, MUTEX_DEFAULT, IPL_SOFTCLOCK);
 
 	rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev),
@@ -1418,7 +1418,7 @@ usbnet_attach_mii(struct usbnet *un, const struct usbnet_mii *unm)
 
 	usbnet_ec(un)->ec_mii = mii;
 	ifmedia_init_with_lock(&mii->mii_media, 0,
-	    usbnet_media_upd, ether_mediastatus, &unp->unp_core_lock);
+	    usbnet_media_upd, ether_mediastatus, &unp->unp_miilock);
 	mii_attach(un->un_dev, mii, unm->un_mii_capmask, unm->un_mii_phyloc,
 	    unm->un_mii_offset, unm->un_mii_flags);
 
@@ -1547,7 +1547,7 @@ usbnet_detach(device_t self, int flags)
 	rnd_detach_source(&unp->unp_rndsrc);
 
 	mutex_destroy(&unp->unp_mcastlock);
-	mutex_destroy(&unp->unp_core_lock);
+	mutex_destroy(&unp->unp_miilock);
 	mutex_destroy(&unp->unp_rxlock);
 	mutex_destroy(&unp->unp_txlock);
 
@@ -1584,9 +1584,9 @@ usbnet_activate(device_t self, devact_t act)
 
 		atomic_store_relaxed(&unp->unp_dying, true);
 
-		mutex_enter(&unp->unp_core_lock);
+		mutex_enter(&unp->unp_miilock);
 		unp->unp_stopped = true;
-		mutex_exit(&unp->unp_core_lock);
+		mutex_exit(&unp->unp_miilock);
 
 		mutex_enter(&unp->unp_rxlock);
 		unp->unp_rxstopped = true;