axe(4) doesn't work (patch to replace obsolete if_watchdog interface)

Norikatsu Shigemura nork at FreeBSD.org
Sun Jun 1 18:46:32 UTC 2008


Hi, wpaul.

	I got USB2.0 GbE Ether Adaptor a.k.a. PLANEX GU-1000T, but I
	can't use it by axe(4).  So I tried to improve axe(4) driver,
	but I couldn't improve it:-(.  Would you please fix this driver?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ehci0: <Intel 82801FB (ICH6) USB 2.0 controller> mem 0xb0040000-0xb00403ff irq 23 at device 29.7 on pci0
ehci0: [GIANT-LOCKED]
ehci0: [ITHREAD]
usb1: EHCI version 1.0
usb1: companion controller, 2 ports each: usb0
usb1: <Intel 82801FB (ICH6) USB 2.0 controller> on ehci0
usb1: USB revision 2.0
uhub1: <Intel EHCI root hub, class 9/0, rev 2.00/1.00, addr 1> on usb1
uhub1: 2 ports with 2 removable, self powered
axe0: <vendor 0x0b95 product 0x1780, class 255/255, rev 2.00/0.01, addr 2> on uhub1
axe0: AX88178, bufsz 4096, boundary 512
miibus0: <MII bus> on axe0
ukphy0: <Generic IEEE 802.3u media interface> PHY 0 on miibus0
ukphy0:  10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, 1000baseSX, 1000baseT, 1000baseT-FDX, auto
axe0: WARNING: using obsoleted if_watchdog interface
axe0: WARNING: using obsoleted IFF_NEEDSGIANT flag
axe0: Ethernet address: 00:90:cc:ef:b9:f6
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

	ISSUE:
	1. after ether cable connected, axe(4) doesn't link up.
	2. axe0 doesn't link up by 'ifconfig axe0 up', too.
	3. so I couldn't communicate other machines.
	4. I didn't know that axe(4) requires GIANT lock:-(.

	HAPPY:
	1. MAC Address is correct.
	2. I could replace obsolete if_watchdog interface.
	   SEE ALSO: attached patches
-------------- next part --------------
--- sys/dev/usb/if_axe.c.orig	2008-05-13 23:00:09.000000000 +0900
+++ sys/dev/usb/if_axe.c	2008-06-02 03:19:07.685569729 +0900
@@ -171,7 +171,7 @@
 static int axe_ioctl(struct ifnet *, u_long, caddr_t);
 static void axe_init(void *);
 static void axe_stop(struct axe_softc *);
-static void axe_watchdog(struct ifnet *);
+static void axe_watchdog(struct axe_softc *);
 static int axe_cmd(struct axe_softc *, int, int, int, void *);
 static int axe_ifmedia_upd(struct ifnet *);
 static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *);
@@ -604,7 +604,7 @@
 
 	mtx_init(&sc->axe_mtx, device_get_nameunit(self), MTX_NETWORK_LOCK,
 	    MTX_DEF | MTX_RECURSE);
-	sx_init(&sc->axe_sleeplock, device_get_nameunit(self));
+	sx_init(&sc->axe_sx, device_get_nameunit(self));
 	AXE_SLEEPLOCK(sc);
 	AXE_LOCK(sc);
 
@@ -640,7 +640,7 @@
 		device_printf(sc->axe_dev, "can not if_alloc()\n");
 		AXE_UNLOCK(sc);
 		AXE_SLEEPUNLOCK(sc);
-		sx_destroy(&sc->axe_sleeplock);
+		sx_destroy(&sc->axe_sx);
 		mtx_destroy(&sc->axe_mtx);
 		return ENXIO;
 	}
@@ -651,7 +651,6 @@
 	    IFF_NEEDSGIANT;
 	ifp->if_ioctl = axe_ioctl;
 	ifp->if_start = axe_start;
-	ifp->if_watchdog = axe_watchdog;
 	ifp->if_init = axe_init;
 	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
 	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
@@ -663,7 +662,7 @@
 		if_free(ifp);
 		AXE_UNLOCK(sc);
 		AXE_SLEEPUNLOCK(sc);
-		sx_destroy(&sc->axe_sleeplock);
+		sx_destroy(&sc->axe_sx);
 		mtx_destroy(&sc->axe_mtx);
 		return ENXIO;
 	}
@@ -709,7 +708,7 @@
 		usbd_abort_pipe(sc->axe_ep[AXE_ENDPT_INTR]);
 
 	AXE_UNLOCK(sc);
-	sx_destroy(&sc->axe_sleeplock);
+	sx_destroy(&sc->axe_sx);
 	mtx_destroy(&sc->axe_mtx);
 
 	return(0);
@@ -939,7 +938,7 @@
 		return;
 	}
 
-	ifp->if_timer = 0;
+	sc->axe_timer = 0;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	usbd_get_xfer_status(c->axe_xfer, NULL, NULL, NULL, &err);
 
@@ -971,6 +970,8 @@
 	if (sc->axe_dying)
 		return;
 
+	axe_watchdog(sc);
+
 	/* Perform periodic stuff in process context */
 	usb_add_task(sc->axe_udev, &sc->axe_tick_task, USB_TASKQ_DRIVER);
 }
@@ -1111,7 +1112,7 @@
 	/*
 	 * Set a timeout in case the chip goes out to lunch.
 	 */
-	ifp->if_timer = 5;
+	sc->axe_timer = 5;
 	AXE_UNLOCK(sc);
 
 	return;
@@ -1310,15 +1311,18 @@
 }
 
 static void
-axe_watchdog(struct ifnet *ifp)
+axe_watchdog(struct axe_softc *sc)
 {
-	struct axe_softc	*sc;
+	struct ifnet		*ifp;
 	struct axe_chain	*c;
 	usbd_status		stat;
 
-	sc = ifp->if_softc;
+	ifp = sc->axe_ifp;
 	AXE_LOCK(sc);
 
+	if (sc->axe_timer == 0 || --sc->axe_timer)
+		return;
+
 	ifp->if_oerrors++;
 	device_printf(sc->axe_dev, "watchdog timeout\n");
 
@@ -1348,7 +1352,7 @@
 	AXE_LOCK(sc);
 
 	ifp = sc->axe_ifp;
-	ifp->if_timer = 0;
+	sc->axe_timer = 0;
 
 	untimeout(axe_tick, sc, sc->axe_stat_ch);
 
-------------- next part --------------
--- sys/dev/usb/if_axereg.h.orig	2007-11-11 01:23:38.000000000 +0900
+++ sys/dev/usb/if_axereg.h	2008-06-02 03:04:49.185709160 +0900
@@ -231,9 +231,10 @@
 	struct axe_cdata	axe_cdata;
 	struct callout_handle	axe_stat_ch;
 	struct mtx		axe_mtx;
-	struct sx		axe_sleeplock;
+	struct sx		axe_sx;
 	char			axe_dying;
 	int			axe_link;
+	int			axe_timer;
 	unsigned char		axe_ipgs[3];
 	unsigned char 		axe_phyaddrs[2];
 	struct timeval		axe_rx_notice;
@@ -249,6 +250,6 @@
 #define	AXE_LOCK(_sc)
 #define	AXE_UNLOCK(_sc)
 #endif
-#define	AXE_SLEEPLOCK(_sc)	sx_xlock(&(_sc)->axe_sleeplock)
-#define	AXE_SLEEPUNLOCK(_sc)	sx_xunlock(&(_sc)->axe_sleeplock)
-#define	AXE_SLEEPLOCKASSERT(_sc) sx_assert(&(_sc)->axe_sleeplock, SX_XLOCKED)
+#define	AXE_SLEEPLOCK(_sc)	sx_xlock(&(_sc)->axe_sx)
+#define	AXE_SLEEPUNLOCK(_sc)	sx_xunlock(&(_sc)->axe_sx)
+#define	AXE_SLEEPLOCKASSERT(_sc) sx_assert(&(_sc)->axe_sx, SX_XLOCKED)


More information about the freebsd-current mailing list