if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool]) zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL; skb_unlink(skb); 
if (skb == zatm_dev->last_free[pos]) zatm_dev->last_free[pos] = NULL; skb_unlink(skb, zatm_dev->pool + pos); 
static void poll_rx(struct atm_dev *dev,int mbx){	struct zatm_dev *zatm_dev;	unsigned long pos;	u32 x;	int error;	EVENT("poll_rx\n",0,0);	zatm_dev = ZATM_DEV(dev);	pos = (zatm_dev->mbx_start[mbx] & ~0xffffUL) | zin(MTA(mbx));	while (x = zin(MWA(mbx)), (pos & 0xffff) != x) {		u32 *here;		struct sk_buff *skb;		struct atm_vcc *vcc;		int cells,size,chan;		EVENT("MBX: host 0x%lx, nic 0x%x\n",pos,x);		here = (u32 *) pos;		if (((pos += 16) & 0xffff) == zatm_dev->mbx_end[mbx])			pos = zatm_dev->mbx_start[mbx];		cells = here[0] & uPD98401_AAL5_SIZE;#if 0printk("RX IND: 0x%x, 0x%x, 0x%x, 0x%x\n",here[0],here[1],here[2],here[3]);{unsigned long *x;		printk("POOL: 0x%08x, 0x%08x\n",zpeekl(zatm_dev,		      zatm_dev->pool_base),		      zpeekl(zatm_dev,zatm_dev->pool_base+1));		x = (unsigned long *) here[2];		printk("[0..3] = 0x%08lx, 0x%08lx, 0x%08lx, 0x%08lx\n",		    x[0],x[1],x[2],x[3]);}#endif		error = 0;		if (here[3] & uPD98401_AAL5_ERR) {			error = (here[3] & uPD98401_AAL5_ES) >>			    uPD98401_AAL5_ES_SHIFT;			if (error == uPD98401_AAL5_ES_DEACT ||			    error == uPD98401_AAL5_ES_FREE) continue;		}EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>  uPD98401_AAL5_ES_SHIFT,error);		skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;		do_gettimeofday(&skb->stamp);#if 0printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],  ((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],  ((unsigned *) skb->data)[0]);#endif		EVENT("skb 0x%lx, here 0x%lx\n",(unsigned long) skb,		    (unsigned long) here);#if 0printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);#endif		size = error ? 0 : ntohs(((__be16 *) skb->data)[cells*		    ATM_CELL_PAYLOAD/sizeof(u16)-3]);		EVENT("got skb 0x%lx, size %d\n",(unsigned long) skb,size);		chan = (here[3] & uPD98401_AAL5_CHAN) >>		    uPD98401_AAL5_CHAN_SHIFT;		if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {			vcc = zatm_dev->rx_map[chan];			if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool])				zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL;			skb_unlink(skb);		}		else {			printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "			    "for non-existing channel\n",dev->number);			size = 0;			vcc = NULL;			event_dump();		}		if (error) {			static unsigned long silence = 0;			static int last_error = 0;			if (error != last_error ||			    time_after(jiffies, silence)  || silence == 0){				printk(KERN_WARNING DEV_LABEL "(itf %d): "				    "chan %d error %s\n",dev->number,chan,				    err_txt[error]);				last_error = error;				silence = (jiffies+2*HZ)|1;			}			size = 0;		}		if (size && (size > cells*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER ||		    size <= (cells-1)*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER)) {			printk(KERN_ERR DEV_LABEL "(itf %d): size %d with %d "			    "cells\n",dev->number,size,cells);			size = 0;			event_dump();		}		if (size > ATM_MAX_AAL5_PDU) {			printk(KERN_ERR DEV_LABEL "(itf %d): size too big "			    "(%d)\n",dev->number,size);			size = 0;			event_dump();		}		if (!size) {			dev_kfree_skb_irq(skb);			if (vcc) atomic_inc(&vcc->stats->rx_err);			continue;		}		if (!atm_charge(vcc,skb->truesize)) {			dev_kfree_skb_irq(skb);			continue;		}		skb->len = size;		ATM_SKB(skb)->vcc = vcc;		vcc->push(vcc,skb);		atomic_inc(&vcc->stats->rx);	}	zout(pos & 0xffff,MTA(mbx));#if 0 /* probably a stupid idea */	refill_pool(dev,zatm_vcc->pool);		/* maybe this saves us a few interrupts */#endif}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/8728b834b226ffcf2c94a58530090e292af2a7bf/zatm.c/buggy/drivers/atm/zatm.c