From nobody@FreeBSD.org  Sat Oct  8 11:33:21 2005
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C477316A41F
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  8 Oct 2005 11:33:21 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 5BD0B43D53
	for <freebsd-gnats-submit@FreeBSD.org>; Sat,  8 Oct 2005 11:33:21 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id j98BXLeK043450
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 8 Oct 2005 11:33:21 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id j98BXLHC043449;
	Sat, 8 Oct 2005 11:33:21 GMT
	(envelope-from nobody)
Message-Id: <200510081133.j98BXLHC043449@www.freebsd.org>
Date: Sat, 8 Oct 2005 11:33:21 GMT
From: Thierry DELHAISE <befree_fr@mac.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: xl0 : watchdog timeout on 6.0 BETA5
X-Send-Pr-Version: www-2.3

>Number:         87114
>Category:       kern
>Synopsis:       [xl] xl0 : watchdog timeout on 6.0 (regression)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    glebius
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Oct 08 11:40:15 GMT 2005
>Closed-Date:    Tue Jan 10 10:18:20 GMT 2006
>Last-Modified:  Tue Jan 10 10:18:20 GMT 2006
>Originator:     Thierry DELHAISE
>Release:        FreeBSD 6.0 Beta 5
>Organization:
GLC
>Environment:
FreeBSD sniffer.xxx.xxx 6.0-BETA5 FreeBSD 6.0-BETA5 #0: Sat Oct 8 12:11:33 CEST 2005 root@sniffer.xxx.xxx:/usr/obj/usr/src/sys/GENERIC i386
>Description:
On a Dell Inspirion 7500 (PIII- 500Mhz) with an xl0 card (3Com 3c575B
Fast Etherlink XL) cardbus : the network doesn't work :

xl0: watchdog timeout.

Intalling first BETA5 with an ISO CD, I had the problem. So, I reinstall
from scratch the machine with a FreeBSD 5.4 patch 7 : no problem, all is
working fine, network was up and running without any messages. So, update
source tree of 5.4 with cvsup with tag RELENG_6. Yesterday, afternoon.
it build "world, kernel" all the night. This morning "installkernel".
reboot. Figure the problem. "installworld" then reboot. Allways figure
the problem. 

The hardware is not responsible since in 5.4 p7 all is working fine on this
machine. I must add that I didn't change anything  (BIOS, hardware, etc). 
>How-To-Repeat:
Install FreeBSD 6 BETA5, with an xl0 cardbus card on Dell Inspirion 7500
(see below) : I can give help, to analyze ;-) but since I didn't develop
the xl0 driver, nor the new driver API, I think this is best if a Kernel
guru can contact me and drive me in analyzing what's wrong ;-)
>Fix:
None.
>Release-Note:
>Audit-Trail:

From: spil oss <spil.oss@googlemail.com>
To: bug-followup@FreeBSD.org, befree_fr@mac.com
Cc:  
Subject: Re: kern/87114: [xl] xl0 : watchdog timeout on 6.0 BETA5
Date: Mon, 7 Nov 2005 15:48:49 +0100

 Same here on FreeBSD 6.0-STABLE
 
 On freebsd-current I read a thread that deals with 3com 3c575 cardbus cards=
 :
 http://lists.freebsd.org/pipermail/freebsd-current/2005-October/056865.html
 
 Hopefully helpful details:
 * Worked fine on 5.4
 * Whilst downloading an iso, no watchdog timeouts occured and speed was 100%,
 but immediately after download finished they started popping up again
 (connecting seems to be slow though)
 * Inbound connections on xl1 are extremely laggy, switching screens via ssh
  take
 a long while to start but then suddenly the whole screen is redrawn. xl0 seems
 to be fine.
 
 snippet from dmesg:
 cardbus0: Resource not specified in CIS: id=3D14, size=3D80
 cardbus0: Resource not specified in CIS: id=3D18, size=3D80
 xl1: <3Com 3c575B Fast Etherlink XL> port 0x1000-0x107f mem
 0x88000000-0x8800007f,0x88000080-0x8800
 00ff irq 10 at device 0.0 on cardbus0
 miibus1: <MII bus> on xl1
 tdkphy0: <TDK 78Q2120 media interface> on miibus1
 tdkphy0: 10baseT, 100baseTX, auto
 xl1: Ethernet address: 00:00:86:57:76:22
 <cut>cut
 xl1: watchdog timeout
 xl1: watchdog timeout
 xl1: watchdog timeout

From: =?windows-1251?Q?=C2=E0=F1=E8=EB=E8=E9_=CB=E5=EE=ED=E8=E4=EE=E2=E8?=
	 =?windows-1251?Q?=F7_=CE=EB=E5=F5=EE=E2?= <olekhov@yandex.ru>
To: bug-followup@FreeBSD.org, befree_fr@mac.com
Cc:  
Subject: Re: kern/87114: [xl] xl0 : watchdog timeout on 6.0 (regression)
Date: Sun, 27 Nov 2005 17:32:51 +0300

 This is a multi-part message in MIME format.
 --------------060607060705050806060607
 Content-Type: text/plain; charset=windows-1251; format=flowed
 Content-Transfer-Encoding: 7bit
 
 "me too"
 Used hardware: HP Omnibook 900b, 440BX chipset (Intel 82443BX), 
 PIII-450, PCMCIA Card: 3Com 3CXFE575CT
 
 on 6.0-RELEASE networking doesn't work.
 portions from dmesg:
 > cardbus0: Resource not specified in CIS: id=14, size=80
 > cardbus0: Resource not specified in CIS: id=18, size=80
 > xl0: <3Com 3c575C Fast Etherlink XL> port 0x1000-0x107f mem 0x88000000-0x8800007f,0x88000080-0x880000ff irq 10 at device 0.0 on cardbus0
 > miibus0: <MII bus> on xl0
 > tdkphy0: <TDK 78Q2120 media interface> on miibus0
 > tdkphy0:  10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
 > xl0: Ethernet address: 00:00:86:3d:b2:d9
 > xl0: link state changed to DOWN
 > xl0: link state changed to UP
 > xl0: watchdog timeout
 symptoms:
 When the interface xl0 brings up, the led on hub lights up, but nor data 
 can be transmitted, nor pings, etc.
 When I try to assign a used IP address to the interface, system reports 
 that it is already used by a device with specified MAC address.
 Sometimes, very rare, 'pings' get through, but with immense replies, 
 about 5000msec (5 seconds)
 xl0: watchdog timeout occurs about once a minute.
 
 This probably indicates, that low-level protocols are still somehow 
 functionating.
 
 xl works fine when I boot the notebook with kernel 5.4-RELEASE, 
 previously compiled on another machine.
 
 backporting of if_xl driver from 5.4-REL to 6.0-REL does not help. 
 (backport patch attached).
 
 Attaching the device after system boots up does not help. various 
 combinations:
 xl built in kernel:
 * boot with device detached, attach after root login
 * boot with device attached
 xl as module:
 * boot with device detached, kldload xl, attach device
 * boot with device detached, attach after root login, kldload xl
 * boot with device attached, kldload xl after root login
 
 + same with acpi disabled (some lists indicate that this could help)
 
 It seems, that problem is probably in cardbus driver.
 
 --------------060607060705050806060607
 Content-Type: text/plain;
  name="if_xl.5.4-REL.ported.to.6.0-REL.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="if_xl.5.4-REL.ported.to.6.0-REL.patch"
 
 Index: if_xl.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/pci/if_xl.c,v
 retrieving revision 1.190.2.6
 diff -u -r1.190.2.6 if_xl.c
 --- if_xl.c	9 Oct 2005 04:11:20 -0000	1.190.2.6
 +++ if_xl.c	23 Nov 2005 18:59:02 -0000
 @@ -31,7 +31,7 @@
   */
  
  #include <sys/cdefs.h>
 -__FBSDID("$FreeBSD$");
 +__FBSDID("$FreeBSD: src/sys/pci/if_xl.c,v 1.179.2.6 2005/03/01 08:11:52 imp Exp $");
  
  /*
   * 3Com 3c90x Etherlink XL PCI NIC driver
 @@ -101,10 +101,6 @@
   * PCI-based NICs.
   */
  
 -#ifdef HAVE_KERNEL_OPTION_HEADERS
 -#include "opt_device_polling.h"
 -#endif
 -
  #include <sys/param.h>
  #include <sys/systm.h>
  #include <sys/sockio.h>
 @@ -113,7 +109,6 @@
  #include <sys/kernel.h>
  #include <sys/module.h>
  #include <sys/socket.h>
 -#include <sys/taskqueue.h>
  
  #include <net/if.h>
  #include <net/if_arp.h>
 @@ -232,7 +227,6 @@
  static void xl_stats_update_locked(struct xl_softc *);
  static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf *);
  static void xl_rxeof(struct xl_softc *);
 -static void xl_rxeof_task(void *, int);
  static int xl_rx_resync(struct xl_softc *);
  static void xl_txeof(struct xl_softc *);
  static void xl_txeof_90xB(struct xl_softc *);
 @@ -250,11 +244,6 @@
  static int xl_suspend(device_t);
  static int xl_resume(device_t);
  
 -#ifdef DEVICE_POLLING
 -static void xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
 -static void xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
 -#endif
 -
  static int xl_ifmedia_upd(struct ifnet *);
  static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  
 @@ -462,6 +451,8 @@
  {
  	int			i, ack;
  
 +	/*XL_LOCK_ASSERT(sc);*/
 +
  	/* Set up frame for RX. */
  	frame->mii_stdelim = XL_MII_STARTDELIM;
  	frame->mii_opcode = XL_MII_READOP;
 @@ -530,6 +521,8 @@
  xl_mii_writereg(struct xl_softc *sc, struct xl_mii_frame *frame)
  {
  
 +	/*XL_LOCK_ASSERT(sc);*/
 +
  	/* Set up frame for TX. */
  	frame->mii_stdelim = XL_MII_STARTDELIM;
  	frame->mii_opcode = XL_MII_WRITEOP;
 @@ -617,6 +610,8 @@
  	sc = device_get_softc(dev);
  	mii = device_get_softc(sc->xl_miibus);
  
 +	/*XL_LOCK_ASSERT(sc);*/
 +
  	xl_setcfg(sc);
  
  	/* Set ASIC's duplex mode to match the PHY. */
 @@ -649,6 +644,8 @@
  	mii = device_get_softc(sc->xl_miibus);
  	ifm = &mii->mii_media;
  
 +	/*XL_LOCK_ASSERT(sc);*/
 +
  	if (sc->xl_media & (XL_MEDIAOPT_AUI | XL_MEDIAOPT_10FL)) {
  		/*
  		 * Check for a 10baseFL board in disguise.
 @@ -712,6 +709,8 @@
  	int			err = 0, i;
  	u_int16_t		word = 0, *ptr;
  
 +	XL_LOCK_ASSERT(sc);
 +
  #define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F))
  #define EEPROM_8BIT_OFFSET(A) ((A) & 0x003F)
  	/*
 @@ -771,10 +770,8 @@
  		return;
  	}
  
 -	IF_ADDR_LOCK(ifp);
  	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
  		mcnt++;
 -	IF_ADDR_UNLOCK(ifp);
  
  	if (mcnt)
  		rxfilt |= XL_RXFILTER_ALLMULTI;
 @@ -813,7 +810,6 @@
  		CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH|i);
  
  	/* now program new ones */
 -	IF_ADDR_LOCK(ifp);
  	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
  		if (ifma->ifma_addr->sa_family != AF_LINK)
  			continue;
 @@ -835,7 +831,6 @@
  		    h | XL_CMD_RX_SET_HASH | XL_HASH_SET);
  		mcnt++;
  	}
 -	IF_ADDR_UNLOCK(ifp);
  
  	if (mcnt)
  		rxfilt |= XL_RXFILTER_MULTIHASH;
 @@ -898,7 +893,7 @@
  	u_int16_t		mediastat;
  	char			*pmsg = "", *dmsg = "";
  
 -	XL_LOCK_ASSERT(sc);
 +	/*XL_LOCK_ASSERT(sc);*/
  
  	XL_SEL_WIN(4);
  	mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
 @@ -1085,6 +1080,8 @@
  xl_mediacheck(struct xl_softc *sc)
  {
  
 +	XL_LOCK_ASSERT(sc);
 +
  	/*
  	 * If some of the media options bits are set, assume they are
  	 * correct. If not, try to figure it out down below.
 @@ -1351,10 +1348,10 @@
  	ifp->if_softc = sc;
  	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  
 -	/* Reset the adapter. */
  	XL_LOCK(sc);
 +
 +	/* Reset the adapter. */
  	xl_reset(sc);
 -	XL_UNLOCK(sc);
  
  	/*
  	 * Get station address from the EEPROM.
 @@ -1362,12 +1359,14 @@
  	if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1)) {
  		device_printf(dev, "failed to read station address\n");
  		error = ENXIO;
 +		XL_UNLOCK(sc);
  		goto fail;
  	}
  
 +	XL_UNLOCK(sc);
 +
  	sc->xl_unit = unit;
 -	callout_init_mtx(&sc->xl_stat_callout, &sc->xl_mtx, 0);
 -	TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc);
 +	callout_handle_init(&sc->xl_stat_ch);
  
  	/*
  	 * Now allocate a tag for the DMA descriptor lists and a chunk
 @@ -1457,6 +1456,8 @@
  	if (error)
  		goto fail;
  
 +	XL_LOCK(sc);
 +
  	/*
  	 * Figure out the card type. 3c905B adapters have the
  	 * 'supportsNoTxLength' bit set in the capabilities
 @@ -1486,10 +1487,6 @@
  		ifp->if_capabilities |= IFCAP_HWCSUM;
  #endif
  	}
 -	ifp->if_capenable = ifp->if_capabilities;
 -#ifdef DEVICE_POLLING
 -	ifp->if_capabilities |= IFCAP_POLLING;
 -#endif
  	ifp->if_start = xl_start;
  	ifp->if_watchdog = xl_watchdog;
  	ifp->if_init = xl_init;
 @@ -1497,6 +1494,7 @@
  	IFQ_SET_MAXLEN(&ifp->if_snd, XL_TX_LIST_CNT - 1);
  	ifp->if_snd.ifq_drv_maxlen = XL_TX_LIST_CNT - 1;
  	IFQ_SET_READY(&ifp->if_snd);
 +	ifp->if_capenable = ifp->if_capabilities;
  
  	/*
  	 * Now we have to see what sort of media we have.
 @@ -1515,6 +1513,9 @@
  
  	xl_mediacheck(sc);
  
 +	/* XXX Downcalls to ifmedia, miibus about to happen. */
 +	XL_UNLOCK(sc);
 +
  	if (sc->xl_media & XL_MEDIAOPT_MII ||
  	    sc->xl_media & XL_MEDIAOPT_BTX ||
  	    sc->xl_media & XL_MEDIAOPT_BT4) {
 @@ -1535,8 +1536,12 @@
  	 * a 10/100 card of some kind, we need to force the transceiver
  	 * type to something sane.
  	 */
 -	if (sc->xl_xcvr == XL_XCVR_AUTO)
 +	if (sc->xl_xcvr == XL_XCVR_AUTO) {
 +		/* XXX Direct hardware access needs lock coverage. */
 +		XL_LOCK(sc);
  		xl_choose_xcvr(sc, bootverbose);
 +		XL_UNLOCK(sc);
 +	}
  
  	/*
  	 * Do ifmedia setup.
 @@ -1585,6 +1590,7 @@
  		ifmedia_add(&sc->ifmedia, IFM_ETHER|IFM_100_FX, 0, NULL);
  	}
  
 +	/* XXX: Unlocked, leaf will take lock. */
  	media = IFM_ETHER|IFM_100_TX|IFM_FDX;
  	xl_choose_media(sc, &media);
  
 @@ -1592,6 +1598,7 @@
  		ifmedia_set(&sc->ifmedia, media);
  
  done:
 +	/* XXX: Unlocked hardware access, narrow race. */
  	if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
  		XL_SEL_WIN(0);
  		CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
 @@ -1607,6 +1614,7 @@
  	if (error) {
  		device_printf(dev, "couldn't set up irq\n");
  		ether_ifdetach(ifp);
 +		if_free(ifp);
  		goto fail;
  	}
  
 @@ -1620,8 +1628,7 @@
  /*
   * Choose a default media.
   * XXX This is a leaf function only called by xl_attach() and
 - *     acquires/releases the non-recursible driver mutex to
 - *     satisfy lock assertions.
 + *     acquires/releases the non-recursible driver mutex.
   */
  static void
  xl_choose_media(struct xl_softc *sc, int *media)
 @@ -1688,11 +1695,7 @@
  	ifp = sc->xl_ifp;
  
  	KASSERT(mtx_initialized(&sc->xl_mtx), ("xl mutex not initialized"));
 -
 -#ifdef DEVICE_POLLING
 -	if (ifp->if_capenable & IFCAP_POLLING)
 -		ether_poll_deregister(ifp);
 -#endif
 +	XL_LOCK(sc);
  
  	if (sc->xl_flags & XL_FLAG_USE_MMIO) {
  		rid = XL_PCI_LOMEM;
 @@ -1704,16 +1707,11 @@
  
  	/* These should only be active if attach succeeded */
  	if (device_is_attached(dev)) {
 -		XL_LOCK(sc);
  		xl_reset(sc);
  		xl_stop(sc);
 -		XL_UNLOCK(sc);
 -		taskqueue_drain(taskqueue_swi, &sc->xl_task);
 -		callout_drain(&sc->xl_stat_callout);
  		ether_ifdetach(ifp);
 -	}
 -	if (ifp)
  		if_free(ifp);
 +	}
  	if (sc->xl_miibus)
  		device_delete_child(dev, sc->xl_miibus);
  	bus_generic_detach(dev);
 @@ -1748,6 +1746,7 @@
  		bus_dma_tag_destroy(sc->xl_ldata.xl_tx_tag);
  	}
  
 +	XL_UNLOCK(sc);
  	mtx_destroy(&sc->xl_mtx);
  
  	return (0);
 @@ -1963,13 +1962,6 @@
  	bus_dmamap_sync(sc->xl_ldata.xl_rx_tag, sc->xl_ldata.xl_rx_dmamap,
  	    BUS_DMASYNC_POSTREAD);
  	while ((rxstat = le32toh(sc->xl_cdata.xl_rx_head->xl_ptr->xl_status))) {
 -#ifdef DEVICE_POLLING
 -		if (ifp->if_capenable & IFCAP_POLLING) {
 -			if (sc->rxcycles <= 0)
 -				break;
 -			sc->rxcycles--;
 -		}
 -#endif
  		cur_rx = sc->xl_cdata.xl_rx_head;
  		sc->xl_cdata.xl_rx_head = cur_rx->xl_next;
  		total_len = rxstat & XL_RXSTAT_LENMASK;
 @@ -2057,14 +2049,6 @@
  		XL_UNLOCK(sc);
  		(*ifp->if_input)(ifp, m);
  		XL_LOCK(sc);
 -
 -		/*
 -		 * If we are running from the taskqueue, the interface
 -		 * might have been stopped while we were passing the last
 -		 * packet up the network stack.
 -		 */
 -		if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
 -			return;
  	}
  
  	/*
 @@ -2091,22 +2075,6 @@
  }
  
  /*
 - * Taskqueue wrapper for xl_rxeof().
 - */
 -static void
 -xl_rxeof_task(void *arg, int pending)
 -{
 -	struct xl_softc *sc = (struct xl_softc *)arg;
 -
 -	NET_LOCK_GIANT();
 -	XL_LOCK(sc);
 -	if (sc->xl_ifp->if_drv_flags & IFF_DRV_RUNNING)
 -		xl_rxeof(sc);
 -	XL_UNLOCK(sc);
 -	NET_UNLOCK_GIANT();
 -}
 -
 -/*
   * A frame was downloaded to the chip. It's safe for us to clean up
   * the list buffers.
   */
 @@ -2278,13 +2246,6 @@
  
  	XL_LOCK(sc);
  
 -#ifdef DEVICE_POLLING
 -	if (ifp->if_capenable & IFCAP_POLLING) {
 -		XL_UNLOCK(sc);
 -		return;
 -	}
 -#endif
 -
  	while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
  	    status != 0xFFFF) {
  		CSR_WRITE_2(sc, XL_COMMAND,
 @@ -2335,67 +2296,6 @@
  	XL_UNLOCK(sc);
  }
  
 -#ifdef DEVICE_POLLING
 -static void
 -xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
 -{
 -	struct xl_softc *sc = ifp->if_softc;
 -
 -	XL_LOCK(sc);
 -	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 -		xl_poll_locked(ifp, cmd, count);
 -	XL_UNLOCK(sc);
 -}
 -
 -static void
 -xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
 -{
 -	struct xl_softc *sc = ifp->if_softc;
 -
 -	XL_LOCK_ASSERT(sc);
 -
 -	sc->rxcycles = count;
 -	xl_rxeof(sc);
 -	if (sc->xl_type == XL_TYPE_905B)
 -		xl_txeof_90xB(sc);
 -	else
 -		xl_txeof(sc);
 -
 -	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
 -		if (sc->xl_type == XL_TYPE_905B)
 -			xl_start_90xB_locked(ifp);
 -		else
 -			xl_start_locked(ifp);
 -	}
 -
 -	if (cmd == POLL_AND_CHECK_STATUS) {
 -		u_int16_t status;
 -
 -		status = CSR_READ_2(sc, XL_STATUS);
 -		if (status & XL_INTRS && status != 0xFFFF) {
 -			CSR_WRITE_2(sc, XL_COMMAND,
 -			    XL_CMD_INTR_ACK|(status & XL_INTRS));
 -
 -			if (status & XL_STAT_TX_COMPLETE) {
 -				ifp->if_oerrors++;
 -				xl_txeoc(sc);
 -			}
 -
 -			if (status & XL_STAT_ADFAIL) {
 -				xl_reset(sc);
 -				xl_init_locked(sc);
 -			}
 -
 -			if (status & XL_STAT_STATSOFLOW) {
 -				sc->xl_stats_no_timeout = 1;
 -				xl_stats_update_locked(sc);
 -				sc->xl_stats_no_timeout = 0;
 -			}
 -		}
 -	}
 -}
 -#endif /* DEVICE_POLLING */
 -
  /*
   * XXX: This is an entry point for callout which needs to take the lock.
   */
 @@ -2404,8 +2304,9 @@
  {
  	struct xl_softc *sc = xsc;
  
 -	XL_LOCK_ASSERT(sc);
 +	XL_LOCK(sc);
  	xl_stats_update_locked(sc);
 +	XL_UNLOCK(sc);
  }
  
  static void
 @@ -2452,7 +2353,7 @@
  	XL_SEL_WIN(7);
  
  	if (!sc->xl_stats_no_timeout)
 -		callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc);
 +		sc->xl_stat_ch = timeout(xl_stats_update, sc, hz);
  }
  
  /*
 @@ -2677,7 +2578,7 @@
  	 * nature of their chips in all their marketing literature;
  	 * we may as well take advantage of it. :)
  	 */
 -	taskqueue_enqueue(taskqueue_swi, &sc->xl_task);
 +	xl_rxeof(sc);
  }
  
  static void
 @@ -2964,12 +2865,6 @@
  	 */
  	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
  	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
 -#ifdef DEVICE_POLLING
 -	/* Disable interrupts if we are polling. */
 -	if (ifp->if_capenable & IFCAP_POLLING)
 -		CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
 -	else
 -#endif
  	CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
  	if (sc->xl_flags & XL_FLAG_FUNCREG)
  	    bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
 @@ -2994,7 +2889,7 @@
  	ifp->if_drv_flags |= IFF_DRV_RUNNING;
  	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  
 -	callout_reset(&sc->xl_stat_callout, hz, xl_stats_update, sc);
 +	sc->xl_stat_ch = timeout(xl_stats_update, sc, hz);
  }
  
  /*
 @@ -3007,7 +2902,7 @@
  	struct ifmedia		*ifm = NULL;
  	struct mii_data		*mii = NULL;
  
 -	XL_LOCK(sc);
 +	/*XL_LOCK_ASSERT(sc);*/
  
  	if (sc->xl_miibus != NULL)
  		mii = device_get_softc(sc->xl_miibus);
 @@ -3031,13 +2926,11 @@
  	if (sc->xl_media & XL_MEDIAOPT_MII ||
  	    sc->xl_media & XL_MEDIAOPT_BTX ||
  	    sc->xl_media & XL_MEDIAOPT_BT4) {
 -		xl_init_locked(sc);
 +		xl_init(sc); /* XXX */
  	} else {
  		xl_setmode(sc, ifm->ifm_media);
  	}
  
 -	XL_UNLOCK(sc);
 -
  	return (0);
  }
  
 @@ -3052,7 +2945,7 @@
  	u_int16_t		status = 0;
  	struct mii_data		*mii = NULL;
  
 -	XL_LOCK(sc);
 +	/*XL_LOCK_ASSERT(sc);*/
  
  	if (sc->xl_miibus != NULL)
  		mii = device_get_softc(sc->xl_miibus);
 @@ -3112,8 +3005,6 @@
  		if_printf(ifp, "unknown XCVR type: %d\n", icfg);
  		break;
  	}
 -
 -	XL_UNLOCK(sc);
  }
  
  static int
 @@ -3171,6 +3062,8 @@
  		break;
  	case SIOCGIFMEDIA:
  	case SIOCSIFMEDIA:
 +		/* XXX Downcall from ifmedia possibly with locks held. */
 +		/*XL_LOCK(sc);*/
  		if (sc->xl_miibus != NULL)
  			mii = device_get_softc(sc->xl_miibus);
  		if (mii == NULL)
 @@ -3179,37 +3072,9 @@
  		else
  			error = ifmedia_ioctl(ifp, ifr,
  			    &mii->mii_media, command);
 +		/*XL_UNLOCK(sc);*/
  		break;
  	case SIOCSIFCAP:
 -#ifdef DEVICE_POLLING
 -		if (ifr->ifr_reqcap & IFCAP_POLLING &&
 -		    !(ifp->if_capenable & IFCAP_POLLING)) {
 -			error = ether_poll_register(xl_poll, ifp);
 -			if (error)
 -				return(error);
 -			XL_LOCK(sc);
 -			/* Disable interrupts */
 -			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
 -			ifp->if_capenable |= IFCAP_POLLING;
 -			XL_UNLOCK(sc);
 -			return (error);
 -			
 -		}
 -		if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
 -		    ifp->if_capenable & IFCAP_POLLING) {
 -			error = ether_poll_deregister(ifp);
 -			/* Enable interrupts. */
 -			XL_LOCK(sc);
 -			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
 -			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
 -			if (sc->xl_flags & XL_FLAG_FUNCREG)
 -				bus_space_write_4(sc->xl_ftag, sc->xl_fhandle,
 -				    4, 0x8000);
 -			ifp->if_capenable &= ~IFCAP_POLLING;
 -			XL_UNLOCK(sc);
 -			return (error);
 -		}
 -#endif /* DEVICE_POLLING */
  		XL_LOCK(sc);
  		ifp->if_capenable = ifr->ifr_reqcap;
  		if (ifp->if_capenable & IFCAP_TXCSUM)
 @@ -3298,7 +3163,7 @@
  		bus_space_write_4(sc->xl_ftag, sc->xl_fhandle, 4, 0x8000);
  
  	/* Stop the stats updater. */
 -	callout_stop(&sc->xl_stat_callout);
 +	untimeout(xl_stats_update, sc, sc->xl_stat_ch);
  
  	/*
  	 * Free data in the RX lists.
 Index: if_xlreg.h
 ===================================================================
 RCS file: /home/ncvs/src/sys/pci/if_xlreg.h,v
 retrieving revision 1.55.2.1
 diff -u -r1.55.2.1 if_xlreg.h
 --- if_xlreg.h	26 Aug 2005 14:46:22 -0000	1.55.2.1
 +++ if_xlreg.h	23 Nov 2005 18:58:46 -0000
 @@ -29,7 +29,7 @@
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   * THE POSSIBILITY OF SUCH DAMAGE.
   *
 - * $FreeBSD$
 + * $FreeBSD: src/sys/pci/if_xlreg.h,v 1.50.2.2 2005/01/31 23:26:51 imp Exp $
   */
  
  #define XL_EE_READ	0x0080	/* read, 5 bit address */
 @@ -601,16 +601,12 @@
  	int			xl_if_flags;
  	struct xl_list_data	xl_ldata;
  	struct xl_chain_data	xl_cdata;
 -	struct callout		xl_stat_callout;
 +	struct callout_handle	xl_stat_ch;
  	int			xl_flags;
  	struct resource		*xl_fres;
  	bus_space_handle_t	xl_fhandle;
  	bus_space_tag_t		xl_ftag;
  	struct mtx		xl_mtx;
 -	struct task		xl_task;
 -#ifdef DEVICE_POLLING
 -	int			rxcycles;
 -#endif
  };
  
  #define XL_LOCK(_sc)		mtx_lock(&(_sc)->xl_mtx)
 
 --------------060607060705050806060607--

From: spil oss <spil.oss@googlemail.com>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: kern/87114: [xl] xl0 : watchdog timeout on 6.0 (regression)
Date: Mon, 19 Dec 2005 14:50:59 +0100

 Workaround: Use polling on the device
 Polling generates quite a bit of load on my machine though :'(
 powerd doesn't switch to 49MHz anymore (min 99MHz),
 top shows > 50% Interrupt continuously.
 On a Dell LS laptop 400MHz P3-M 256MB mem
State-Changed-From-To: open->analyzed 
State-Changed-By: glebius 
State-Changed-When: Tue Dec 27 09:03:08 UTC 2005 
State-Changed-Why:  
Me and Warner are working on this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=87114 
State-Changed-From-To: analyzed->patched 
State-Changed-By: glebius 
State-Changed-When: Wed Dec 28 10:15:12 UTC 2005 
State-Changed-Why:  
A fix committed to HEAD. 


Responsible-Changed-From-To: freebsd-bugs->glebius 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Wed Dec 28 10:15:12 UTC 2005 
Responsible-Changed-Why:  
I'm handling this PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=87114 
State-Changed-From-To: patched->closed 
State-Changed-By: glebius 
State-Changed-When: Tue Jan 10 10:18:06 UTC 2006 
State-Changed-Why:  
Merged to RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=87114 
>Unformatted:
