/*
 * Function pcbit_receive at linux-2.6.34-rc1/drivers/isdn/pcbit/layer2.c:325-457
 * Allocation call kzalloc at 38
 * Release call    kfree at 87
 * DEG: 8 LOC: 49
*/

pcbit_receive(struct pcbit_dev *dev)
{
	unsigned short tt;
	u_char cpu,
	 proc;
	struct frame_buf *frame = NULL;
	unsigned long flags;
	u_char type1;

	if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
		return;

	tt = pcbit_readw(dev);

	if ((tt & 0x7fffU) > 511) {
		printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n",
		       tt);
		pcbit_l2_error(dev);
		return;
	}
	if (!(tt & 0x8000U)) {  /* Type 0 */
		type1 = 0;

		if (dev->read_frame) {
			printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
			/* discard previous queued frame */
			kfree_skb(dev->read_frame->skb);
			kfree(dev->read_frame);
			dev->read_frame = NULL;
		}
		frame = kzalloc(sizeof(struct frame_buf), GFP_ATOMIC);                              //ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC ALLOC

		if (frame == NULL) {
			printk(KERN_WARNING "kmalloc failed\n");
			return;
		}

		cpu = pcbit_readb(dev);
		proc = pcbit_readb(dev);


		if (cpu != 0x06 && cpu != 0x02) {
			printk(KERN_DEBUG "pcbit: invalid cpu value\n");
			kfree(frame);
			pcbit_l2_error(dev);
			return;
		}
		/*
		 * we discard cpu & proc on receiving
		 * but we read it to update the pointer
		 */

		frame->hdr_len = pcbit_readw(dev);
		frame->dt_len = pcbit_readw(dev);

		/*
		   * 0 sized packet
		   * I don't know if they are an error or not...
		   * But they are very frequent
		   * Not documented
		 */

		if (frame->hdr_len == 0) {
			kfree(frame);
#ifdef DEBUG
			printk(KERN_DEBUG "0 sized frame\n");
#endif
			pcbit_firmware_bug(dev);
			return;
		}
		/* sanity check the length values */
		if (frame->hdr_len > 1024 || frame->dt_len > 2048) {
#ifdef DEBUG
			printk(KERN_DEBUG "length problem: ");
			printk(KERN_DEBUG "TH=%04x TD=%04x\n",
			       frame->hdr_len,
			       frame->dt_len);
#endif
			pcbit_l2_error(dev);
			kfree(frame);                                                        //FREE FREE FREE FREE FREE FREE FREE FREE FREE FREE 
			return;
		}
		/* minimum frame read */

		frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len +
					   ((frame->hdr_len + 15) & ~15));

		if (!frame->skb) {
			printk(KERN_DEBUG "pcbit_receive: out of memory\n");
			kfree(frame);
			return;
		}
		/* 16 byte alignment for IP */
		if (frame->dt_len)
			skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15);

	} else {
		/* Type 1 */
		type1 = 1;
		tt &= 0x7fffU;

		if (!(frame = dev->read_frame)) {
			printk("Type 1 frame and no frame queued\n");
			/* usually after an error: toss frame */
			dev->readptr += tt;
			if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
				dev->readptr -= BANKLEN;
			return;

		}
	}

	memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);

	frame->copied += tt;
	spin_lock_irqsave(&dev->lock, flags);
	if (frame->copied == frame->hdr_len + frame->dt_len) {

		if (type1) {
			dev->read_frame = NULL;
		}
		if (dev->read_queue) {
			struct frame_buf *ptr;
			for (ptr = dev->read_queue; ptr->next; ptr = ptr->next);
			ptr->next = frame;
		} else
			dev->read_queue = frame;

	} else {
		dev->read_frame = frame;
	}
	spin_unlock_irqrestore(&dev->lock, flags);
}
