PERFORCE change 144544 for review

Hans Petter Selasky hselasky at FreeBSD.org
Thu Jul 3 09:36:18 UTC 2008


http://perforce.freebsd.org/chv.cgi?CH=144544

Change 144544 by hselasky at hselasky_laptop001 on 2008/07/03 09:36:05

	
	USB ethernet related:
	
	- Add check for interface index to all probe functions.
	
	- Fix locking in miibus and ioctl callbacks to avoid
	recursive locking.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_aue2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_aue2_reg.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_axe2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_axe2_reg.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_cdce2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_cue2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_cue2_reg.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_kue2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_kue2_reg.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_rue2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_rue2_reg.h#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_udav2.c#3 edit
.. //depot/projects/usb/src/sys/dev/usb2/ethernet/if_udav2_reg.h#3 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_aue2.c#3 (text+ko) ====

@@ -471,8 +471,15 @@
 {
 	struct aue_softc *sc = device_get_softc(dev);
 	uint16_t i;
+	uint8_t do_unlock;
 
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	/*
 	 * The Am79C901 HomePNA PHY actually contains
@@ -519,8 +526,9 @@
 	i = aue_cfg_csr_read_2(sc, AUE_PHY_DATA);
 
 done:
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (i);
 }
 
@@ -529,11 +537,18 @@
 {
 	struct aue_softc *sc = device_get_softc(dev);
 	uint16_t i;
+	uint8_t do_unlock;
 
 	if (phy == 3) {
 		return (0);
 	}
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	aue_cfg_csr_write_2(sc, AUE_PHY_DATA, data);
 	aue_cfg_csr_write_1(sc, AUE_PHY_ADDR, phy);
@@ -554,8 +569,9 @@
 		}
 	}
 
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (0);
 }
 
@@ -564,8 +580,15 @@
 {
 	struct aue_softc *sc = device_get_softc(dev);
 	struct mii_data *mii = GET_MII(sc);
+	uint8_t do_unlock;
 
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	AUE_CFG_CLRBIT(sc, AUE_CTL0, AUE_CTL0_RX_ENB | AUE_CTL0_TX_ENB);
 
@@ -594,8 +617,9 @@
 		auxmode = aue_cfg_miibus_readreg(dev, 0, 0x1b);
 		aue_cfg_miibus_writereg(dev, 0, 0x1b, auxmode | 0x04);
 	}
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return;
 }
 
@@ -705,7 +729,10 @@
 	if (uaa->usb2_mode != USB_MODE_HOST) {
 		return (ENXIO);
 	}
-	if (uaa->info.bConfigIndex != 0) {
+	if (uaa->info.bConfigIndex != AUE_CONFIG_INDEX) {
+		return (ENXIO);
+	}
+	if (uaa->info.bIfaceIndex != AUE_IFACE_IDX) {
 		return (ENXIO);
 	}
 	return (usb2_lookup_id_by_uaa(aue_devs, sizeof(aue_devs), uaa));
@@ -1402,11 +1429,9 @@
 	struct mii_data *mii;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (command) {
 	case SIOCSIFFLAGS:
-
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				usb2_config_td_queue_command
@@ -1424,13 +1449,16 @@
 				    &aue_cfg_stop, 0, 0);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		mtx_lock(&(sc->sc_mtx));
 		usb2_config_td_queue_command
 		    (&(sc->sc_config_td), &aue_config_copy,
 		    &aue_cfg_setmulti, 0, 0);
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCGIFMEDIA:
@@ -1448,9 +1476,6 @@
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_aue2_reg.h#3 (text+ko) ====

@@ -49,7 +49,7 @@
 #define	AUE_UR_READREG		0xF0
 #define	AUE_UR_WRITEREG		0xF1
 
-#define	AUE_CONFIG_NO		1
+#define	AUE_CONFIG_INDEX	0	/* config number 1 */
 #define	AUE_IFACE_IDX		0
 
 /*

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_axe2.c#3 (text+ko) ====

@@ -325,8 +325,15 @@
 {
 	struct axe_softc *sc = device_get_softc(dev);
 	uint16_t val;
+	uint8_t do_unlock;
 
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 #if 0
 	/*
@@ -357,8 +364,9 @@
 		sc->sc_phyaddrs[0] = phy;
 	}
 done:
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (val);
 }
 
@@ -366,17 +374,25 @@
 axe_cfg_miibus_writereg(device_t dev, int phy, int reg, int val)
 {
 	struct axe_softc *sc = device_get_softc(dev);
+	uint8_t do_unlock;
 
 	val = htole16(val);
 
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_SW, 0, 0, NULL);
 	axe_cfg_cmd(sc, AXE_CMD_MII_WRITE_REG, reg, phy, &val);
 	axe_cfg_cmd(sc, AXE_CMD_MII_OPMODE_HW, 0, 0, NULL);
 
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (0);
 }
 
@@ -386,8 +402,15 @@
 	struct axe_softc *sc = device_get_softc(dev);
 	struct mii_data *mii = GET_MII(sc);
 	uint16_t val;
+	uint8_t do_unlock;
 
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
 		val = AXE_MEDIA_FULL_DUPLEX;
@@ -411,8 +434,9 @@
 		}
 	}
 	axe_cfg_cmd(sc, AXE_CMD_WRITE_MEDIA, 0, val, NULL);
-
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return;
 }
 
@@ -467,10 +491,8 @@
 	struct axe_softc *sc = ifp->if_softc;
 
 	mtx_lock(&(sc->sc_mtx));
-
 	ifmr->ifm_active = sc->sc_media_active;
 	ifmr->ifm_status = sc->sc_media_status;
-
 	mtx_unlock(&(sc->sc_mtx));
 
 	return;
@@ -550,7 +572,10 @@
 	if (uaa->usb2_mode != USB_MODE_HOST) {
 		return (ENXIO);
 	}
-	if (uaa->info.bConfigIndex != 0) {
+	if (uaa->info.bConfigIndex != AXE_CONFIG_IDX) {
+		return (ENXIO);
+	}
+	if (uaa->info.bIfaceIndex != AXE_IFACE_IDX) {
 		return (ENXIO);
 	}
 	return (usb2_lookup_id_by_uaa(axe_devs, sizeof(axe_devs), uaa));
@@ -1364,11 +1389,9 @@
 	struct mii_data *mii;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (command) {
 	case SIOCSIFFLAGS:
-
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				usb2_config_td_queue_command
@@ -1386,13 +1409,16 @@
 				    &axe_cfg_stop, 0, 0);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		mtx_lock(&(sc->sc_mtx));
 		usb2_config_td_queue_command
 		    (&(sc->sc_config_td), &axe_config_copy,
 		    &axe_cfg_setmulti, 0, 0);
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCGIFMEDIA:
@@ -1410,9 +1436,6 @@
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_axe2_reg.h#3 (text+ko) ====

@@ -143,7 +143,7 @@
 #define	AXE_CTL_READ		0x01
 #define	AXE_CTL_WRITE		0x02
 
-#define	AXE_CONFIG_NO		1
+#define	AXE_CONFIG_IDX		0	/* config number 1 */
 #define	AXE_IFACE_IDX		0
 
 /* The interrupt endpoint is currently unused by the ASIX part. */

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_cdce2.c#3 (text+ko) ====

@@ -514,11 +514,6 @@
 
 	/* start the interrupt transfer, if any */
 	mtx_lock(&(sc->sc_mtx));
-#ifdef CDCE_DO_BENCHMARK
-	usb2_transfer_start(sc->sc_xfer[0]);
-	usb2_transfer_start(sc->sc_xfer[1]);
-	device_printf(dev, "benchmarking enabled\n");
-#endif
 	usb2_transfer_start(sc->sc_xfer[4]);
 	mtx_unlock(&(sc->sc_mtx));
 
@@ -953,14 +948,14 @@
 cdce_suspend(device_t dev)
 {
 	device_printf(dev, "Suspending\n");
-	return 0;
+	return (0);
 }
 
 static int
 cdce_resume(device_t dev)
 {
 	device_printf(dev, "Resuming\n");
-	return 0;
+	return (0);
 }
 
 static int
@@ -969,10 +964,9 @@
 	struct cdce_softc *sc = ifp->if_softc;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (command) {
 	case SIOCSIFFLAGS:
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
 				cdce_init_cb(sc);
@@ -982,6 +976,7 @@
 				cdce_stop(sc);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCSIFMEDIA:
@@ -994,9 +989,6 @@
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_cue2.c#3 (text+ko) ====

@@ -385,7 +385,10 @@
 	if (uaa->usb2_mode != USB_MODE_HOST) {
 		return (ENXIO);
 	}
-	if (uaa->info.bConfigIndex != 0) {
+	if (uaa->info.bConfigIndex != CUE_CONFIG_IDX) {
+		return (ENXIO);
+	}
+	if (uaa->info.bIfaceIndex != CUE_IFACE_IDX) {
 		return (ENXIO);
 	}
 	return (usb2_lookup_id_by_uaa(cue_devs, sizeof(cue_devs), uaa));
@@ -842,10 +845,9 @@
 	struct cue_softc *sc = ifp->if_softc;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (command) {
 	case SIOCSIFFLAGS:
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				usb2_config_td_queue_command
@@ -863,22 +865,22 @@
 				    &cue_cfg_stop, 0, 0);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		mtx_lock(&(sc->sc_mtx));
 		usb2_config_td_queue_command
 		    (&(sc->sc_config_td), &cue_config_copy,
 		    &cue_cfg_promisc_upd, 0, 0);
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_cue2_reg.h#3 (text+ko) ====

@@ -109,7 +109,7 @@
 #define	CUE_CTL_READ		0x01
 #define	CUE_CTL_WRITE		0x02
 
-#define	CUE_CONFIG_NO		1
+#define	CUE_CONFIG_IDX		0	/* config number 1 */
 #define	CUE_IFACE_IDX		0
 
 /* The interrupt endpoint is currently unused by the KLSI part. */

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_kue2.c#3 (text+ko) ====

@@ -443,10 +443,13 @@
 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
 
 	if (uaa->usb2_mode != USB_MODE_HOST) {
-		return ((ENXIO));
+		return (ENXIO);
+	}
+	if (uaa->info.bConfigIndex != KUE_CONFIG_IDX) {
+		return (ENXIO);
 	}
-	if (uaa->info.bConfigIndex != 0) {
-		return ((ENXIO));
+	if (uaa->info.bIfaceIndex != KUE_IFACE_IDX) {
+		return (ENXIO);
 	}
 	return (usb2_lookup_id_by_uaa(kue_devs, sizeof(kue_devs), uaa));
 }
@@ -881,10 +884,9 @@
 	struct kue_softc *sc = ifp->if_softc;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (command) {
 	case SIOCSIFFLAGS:
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				usb2_config_td_queue_command
@@ -902,22 +904,22 @@
 				    &kue_cfg_stop, 0, 0);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		mtx_lock(&(sc->sc_mtx));
 		usb2_config_td_queue_command
 		    (&(sc->sc_config_td), &kue_config_copy,
 		    &kue_cfg_promisc_upd, 0, 0);
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	default:
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_kue2_reg.h#3 (text+ko) ====

@@ -111,7 +111,7 @@
 #define	KUE_CTL_READ		0x01
 #define	KUE_CTL_WRITE		0x02
 
-#define	KUE_CONFIG_NO		1
+#define	KUE_CONFIG_IDX		0	/* config number 1 */
 #define	KUE_IFACE_IDX		0
 
 /* The interrupt endpoint is currently unused by the KLSI part. */

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_rue2.c#3 (text+ko) ====

@@ -370,11 +370,18 @@
 	struct rue_softc *sc = device_get_softc(dev);
 	uint16_t rval;
 	uint16_t ruereg;
+	uint8_t do_unlock;
 
 	if (phy != 0) {			/* RTL8150 supports PHY == 0, only */
 		return (0);
 	}
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	switch (reg) {
 	case MII_BMCR:
@@ -408,8 +415,9 @@
 
 	rval = rue_cfg_csr_read_2(sc, ruereg);
 done:
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (rval);
 }
 
@@ -418,11 +426,18 @@
 {
 	struct rue_softc *sc = device_get_softc(dev);
 	uint16_t ruereg;
+	uint8_t do_unlock;
 
 	if (phy != 0) {			/* RTL8150 supports PHY == 0, only */
 		return (0);
 	}
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	switch (reg) {
 	case MII_BMCR:
@@ -454,8 +469,9 @@
 	}
 	rue_cfg_csr_write_2(sc, ruereg, data);
 done:
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (0);
 }
 
@@ -476,8 +492,15 @@
 	struct rue_softc *sc = device_get_softc(dev);
 	struct mii_data *mii = GET_MII(sc);
 	uint16_t bmcr;
+	uint8_t do_unlock;
 
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	RUE_CFG_CLRBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
 
@@ -497,7 +520,9 @@
 
 	RUE_CFG_SETBIT(sc, RUE_CR, (RUE_CR_RE | RUE_CR_TE));
 
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 #endif
 	return;
 }
@@ -599,10 +624,13 @@
 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
 
 	if (uaa->usb2_mode != USB_MODE_HOST) {
-		return ((ENXIO));
+		return (ENXIO);
+	}
+	if (uaa->info.bConfigIndex != RUE_CONFIG_IDX) {
+		return (ENXIO);
 	}
-	if (uaa->info.bConfigIndex != 0) {
-		return ((ENXIO));
+	if (uaa->info.bIfaceIndex != RUE_IFACE_IDX) {
+		return (ENXIO);
 	}
 	return (usb2_lookup_id_by_uaa(rue_devs, sizeof(rue_devs), uaa));
 }
@@ -1236,10 +1264,10 @@
 	struct mii_data *mii;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (command) {
 	case SIOCSIFFLAGS:
+
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				usb2_config_td_queue_command
@@ -1257,13 +1285,16 @@
 				    &rue_cfg_stop, 0, 0);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		mtx_lock(&(sc->sc_mtx));
 		usb2_config_td_queue_command
 		    (&(sc->sc_config_td), &rue_config_copy,
 		    &rue_cfg_promisc_upd, 0, 0);
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCGIFMEDIA:
@@ -1281,9 +1312,6 @@
 		error = ether_ioctl(ifp, command, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_rue2_reg.h#3 (text+ko) ====

@@ -26,7 +26,7 @@
  * $FreeBSD: src/sys/dev/usb/if_ruereg.h,v 1.8 2007/07/09 20:56:39 imp Exp $
  */
 
-#define	RUE_CONFIG_NO		1
+#define	RUE_CONFIG_IDX		0	/* config number 1 */
 #define	RUE_IFACE_IDX		0
 
 #define	RUE_ENDPT_MAX		6

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_udav2.c#3 (text+ko) ====

@@ -244,10 +244,13 @@
 	struct usb2_attach_arg *uaa = device_get_ivars(dev);
 
 	if (uaa->usb2_mode != USB_MODE_HOST) {
-		return ((ENXIO));
+		return (ENXIO);
+	}
+	if (uaa->info.bConfigIndex != UDAV_CONFIG_INDEX) {
+		return (ENXIO);
 	}
-	if (uaa->info.bConfigIndex != 0) {
-		return ((ENXIO));
+	if (uaa->info.bIfaceIndex != UDAV_IFACE_INDEX) {
+		return (ENXIO);
 	}
 	return (usb2_lookup_id_by_uaa(udav_devs, sizeof(udav_devs), uaa));
 }
@@ -1036,10 +1039,9 @@
 	struct mii_data *mii;
 	int error = 0;
 
-	mtx_lock(&(sc->sc_mtx));
-
 	switch (cmd) {
 	case SIOCSIFFLAGS:
+		mtx_lock(&(sc->sc_mtx));
 		if (ifp->if_flags & IFF_UP) {
 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 				usb2_config_td_queue_command
@@ -1057,13 +1059,16 @@
 				    &udav_cfg_stop, 0, 0);
 			}
 		}
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
+		mtx_lock(&(sc->sc_mtx));
 		usb2_config_td_queue_command
 		    (&(sc->sc_config_td), &udav_config_copy,
 		    &udav_cfg_promisc_upd, 0, 0);
+		mtx_unlock(&(sc->sc_mtx));
 		break;
 
 	case SIOCGIFMEDIA:
@@ -1081,9 +1086,6 @@
 		error = ether_ioctl(ifp, cmd, data);
 		break;
 	}
-
-	mtx_unlock(&(sc->sc_mtx));
-
 	return (error);
 }
 
@@ -1246,14 +1248,21 @@
 udav_cfg_miibus_readreg(device_t dev, int phy, int reg)
 {
 	struct udav_softc *sc = device_get_softc(dev);
+	uint16_t data16;
 	uint8_t val[2];
-	uint16_t data16;
+	uint8_t do_unlock;
 
 	/* XXX: one PHY only for the internal PHY */
 	if (phy != 0) {
 		return (0);
 	}
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	/* select internal PHY and set PHY register address */
 	udav_cfg_csr_write1(sc, UDAV_EPAR,
@@ -1270,8 +1279,9 @@
 	/* retrieve the result from data registers */
 	udav_cfg_csr_read(sc, UDAV_EPDRL, val, 2);
 
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	data16 = (val[0] | (val[1] << 8));
 
 	DPRINTF(10, "phy=%d reg=0x%04x => 0x%04x\n",
@@ -1285,12 +1295,19 @@
 {
 	struct udav_softc *sc = device_get_softc(dev);
 	uint8_t val[2];
+	uint8_t do_unlock;
 
 	/* XXX: one PHY only for the internal PHY */
 	if (phy != 0) {
 		return (0);
 	}
-	mtx_lock(&(sc->sc_mtx));	/* XXX */
+	/* avoid recursive locking */
+	if (mtx_owned(&(sc->sc_mtx))) {
+		do_unlock = 0;
+	} else {
+		mtx_lock(&(sc->sc_mtx));
+		do_unlock = 1;
+	}
 
 	/* select internal PHY and set PHY register address */
 	udav_cfg_csr_write1(sc, UDAV_EPAR,
@@ -1309,8 +1326,9 @@
 	/* end write command */
 	UDAV_CFG_CLRBIT(sc, UDAV_EPCR, UDAV_EPCR_ERPRW);
 
-	mtx_unlock(&(sc->sc_mtx));	/* XXX */
-
+	if (do_unlock) {
+		mtx_unlock(&(sc->sc_mtx));
+	}
 	return (0);
 }
 

==== //depot/projects/usb/src/sys/dev/usb2/ethernet/if_udav2_reg.h#3 (text+ko) ====

@@ -32,7 +32,7 @@
  */
 
 #define	UDAV_IFACE_INDEX	0
-#define	UDAV_CONFIG_NO		1
+#define	UDAV_CONFIG_INDEX	0	/* config number 1 */
 
 #define	UDAV_ENDPT_MAX		6	/* units */
 


More information about the p4-projects mailing list