int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) 
static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) 
int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb){	int nchar;	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];	volatile pcsca_bd_t __iomem *ptdescr;	int rcvd = 0;	volatile ucchar status;	ptdescr = (card->hw.rambase +				  RX_BD_ADDR(ch, chan->rx_first_bd));	while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {		nchar = cpc_readw(&ptdescr->len);		if ((status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT))		    || (nchar > BD_DEF_LEN)) {			if (nchar > BD_DEF_LEN)				status |= DST_RBIT;			rcvd = -status;			/* Discard remaining descriptors used by the bad frame */			while (chan->rx_first_bd != chan->rx_last_bd) {				cpc_writeb(&ptdescr->status, 0);				chan->rx_first_bd = (chan->rx_first_bd+1) & (N_DMA_RX_BUF-1);				if (status & DST_EOM)					break;				ptdescr = (card->hw.rambase +							  cpc_readl(&ptdescr->next));				status = cpc_readb(&ptdescr->status);			}			break;		}		if (nchar != 0) {			if (skb) {				memcpy_fromio(skb_put(skb, nchar),				 (card->hw.rambase+cpc_readl(&ptdescr->ptbuf)),nchar);			}			rcvd += nchar;		}		cpc_writeb(&ptdescr->status, 0);		cpc_writeb(&ptdescr->len, 0);		chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1);		if (status & DST_EOM)			break;		ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next));	}	if (rcvd != 0) {		/* Update pointer */		chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1);		/* Update EDA */		cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),			   RX_BD_ADDR(ch, chan->rx_last_bd));	}	return (rcvd);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/7665a08928f241247afe8c76865cdbe4ef5489bf/pc300_drv.c/buggy/drivers/net/wan/pc300_drv.c