delta < TX_RING_SIZE - 2) { 
delta < lp->tx_ring_size - 2) { 
pcnet32_interrupt(int irq, void *dev_id, struct pt_regs * regs){    struct net_device *dev = dev_id;    struct pcnet32_private *lp;    unsigned long ioaddr;    u16 csr0,rap;    int boguscnt =  max_interrupt_work;    int must_restart;    if (!dev) {	if (pcnet32_debug & NETIF_MSG_INTR)	    printk (KERN_DEBUG "%s(): irq %d for unknown device\n",		__FUNCTION__, irq);	return IRQ_NONE;    }    ioaddr = dev->base_addr;    lp = dev->priv;    spin_lock(&lp->lock);    rap = lp->a.read_rap(ioaddr);    while ((csr0 = lp->a.read_csr (ioaddr, 0)) & 0x8f00 && --boguscnt >= 0) {	if (csr0 == 0xffff) {	    break;			/* PCMCIA remove happened */	}	/* Acknowledge all of the current interrupt sources ASAP. */	lp->a.write_csr (ioaddr, 0, csr0 & ~0x004f);	must_restart = 0;	if (netif_msg_intr(lp))	    printk(KERN_DEBUG "%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",		   dev->name, csr0, lp->a.read_csr (ioaddr, 0));	if (csr0 & 0x0400)		/* Rx interrupt */	    pcnet32_rx(dev);	if (csr0 & 0x0200) {		/* Tx-done interrupt */	    unsigned int dirty_tx = lp->dirty_tx;	    int delta;	    while (dirty_tx != lp->cur_tx) {		int entry = dirty_tx & TX_RING_MOD_MASK;		int status = (short)le16_to_cpu(lp->tx_ring[entry].status);		if (status < 0)		    break;		/* It still hasn't been Txed */		lp->tx_ring[entry].base = 0;		if (status & 0x4000) {		    /* There was an major error, log it. */		    int err_status = le32_to_cpu(lp->tx_ring[entry].misc);		    lp->stats.tx_errors++;		    if (netif_msg_tx_err(lp))			printk(KERN_ERR "%s: Tx error status=%04x err_status=%08x\n",				dev->name, status, err_status);		    if (err_status & 0x04000000) lp->stats.tx_aborted_errors++;		    if (err_status & 0x08000000) lp->stats.tx_carrier_errors++;		    if (err_status & 0x10000000) lp->stats.tx_window_errors++;#ifndef DO_DXSUFLO		    if (err_status & 0x40000000) {			lp->stats.tx_fifo_errors++;			/* Ackk!  On FIFO errors the Tx unit is turned off! */			/* Remove this verbosity later! */			if (netif_msg_tx_err(lp))			    printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n",				    dev->name, csr0);			must_restart = 1;		    }#else		    if (err_status & 0x40000000) {			lp->stats.tx_fifo_errors++;			if (! lp->dxsuflo) {  /* If controller doesn't recover ... */			    /* Ackk!  On FIFO errors the Tx unit is turned off! */			    /* Remove this verbosity later! */			    if (netif_msg_tx_err(lp))				printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n",					dev->name, csr0);			    must_restart = 1;			}		    }#endif		} else {		    if (status & 0x1800)			lp->stats.collisions++;		    lp->stats.tx_packets++;		}		/* We must free the original skb */		if (lp->tx_skbuff[entry]) {		    pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[entry],			lp->tx_skbuff[entry]->len, PCI_DMA_TODEVICE);		    dev_kfree_skb_irq(lp->tx_skbuff[entry]);		    lp->tx_skbuff[entry] = NULL;		    lp->tx_dma_addr[entry] = 0;		}		dirty_tx++;	    }	    delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);	    if (delta > TX_RING_SIZE) {		if (netif_msg_drv(lp))		    printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",			    dev->name, dirty_tx, lp->cur_tx, lp->tx_full);		dirty_tx += TX_RING_SIZE;		delta -= TX_RING_SIZE;	    }	    if (lp->tx_full &&		netif_queue_stopped(dev) &&		delta < TX_RING_SIZE - 2) {		/* The ring is no longer full, clear tbusy. */		lp->tx_full = 0;		netif_wake_queue (dev);	    }	    lp->dirty_tx = dirty_tx;	}	/* Log misc errors. */	if (csr0 & 0x4000) lp->stats.tx_errors++; /* Tx babble. */	if (csr0 & 0x1000) {	    /*	     * this happens when our receive ring is full. This shouldn't	     * be a problem as we will see normal rx interrupts for the frames	     * in the receive ring. But there are some PCI chipsets (I can	     * reproduce this on SP3G with Intel saturn chipset) which have	     * sometimes problems and will fill up the receive ring with	     * error descriptors. In this situation we don't get a rx	     * interrupt, but a missed frame interrupt sooner or later.	     * So we try to clean up our receive ring here.	     */	    pcnet32_rx(dev);	    lp->stats.rx_errors++; /* Missed a Rx frame. */	}	if (csr0 & 0x0800) {	    if (netif_msg_drv(lp))		printk(KERN_ERR "%s: Bus master arbitration failure, status %4.4x.\n",			dev->name, csr0);	    /* unlike for the lance, there is no restart needed */	}	if (must_restart) {	    /* reset the chip to clear the error condition, then restart */	    lp->a.reset(ioaddr);	    lp->a.write_csr(ioaddr, 4, 0x0915);	    pcnet32_restart(dev, 0x0002);	    netif_wake_queue(dev);	}    }    /* Set interrupt enable. */    lp->a.write_csr (ioaddr, 0, 0x0040);    lp->a.write_rap (ioaddr,rap);    if (netif_msg_intr(lp))	printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",		dev->name, lp->a.read_csr (ioaddr, 0));    spin_unlock(&lp->lock);    return IRQ_HANDLED;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/eabf04151682bc7b57c84fea58cf9e4e5a3cf2a9/pcnet32.c/buggy/drivers/net/pcnet32.c