Beispiel #1
0
static void
isac_rme_irq(struct isac_hw *isac)
{
	u8 val, count;

	val = ReadISAC(isac, ISAC_RSTA);
	if ((val & 0x70) != 0x20) {
		if (val & 0x40) {
			pr_debug("%s: ISAC RDO\n", isac->name);
#ifdef ERROR_STATISTIC
			isac->dch.err_rx++;
#endif
		}
		if (!(val & 0x20)) {
			pr_debug("%s: ISAC CRC error\n", isac->name);
#ifdef ERROR_STATISTIC
			isac->dch.err_crc++;
#endif
		}
		WriteISAC(isac, ISAC_CMDR, 0x80);
		if (isac->dch.rx_skb)
			dev_kfree_skb(isac->dch.rx_skb);
		isac->dch.rx_skb = NULL;
	} else {
		count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
		if (count == 0)
			count = 32;
		isac_empty_fifo(isac, count);
		recv_Dchannel(&isac->dch);
	}
}
Beispiel #2
0
static void
handle_rxD(struct w6692_hw *card) {
	u8	stat;
	int	count;

	stat = ReadW6692(card, W_D_RSTA);
	if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
		if (stat & W_D_RSTA_RDOV) {
			pr_debug("%s: D-channel RDOV\n", card->name);
#ifdef ERROR_STATISTIC
			card->dch.err_rx++;
#endif
		}
		if (stat & W_D_RSTA_CRCE) {
			pr_debug("%s: D-channel CRC error\n", card->name);
#ifdef ERROR_STATISTIC
			card->dch.err_crc++;
#endif
		}
		if (stat & W_D_RSTA_RMB) {
			pr_debug("%s: D-channel ABORT\n", card->name);
#ifdef ERROR_STATISTIC
			card->dch.err_rx++;
#endif
		}
		if (card->dch.rx_skb)
			dev_kfree_skb(card->dch.rx_skb);
		card->dch.rx_skb = NULL;
		WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
	} else {
		count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
		if (count == 0)
			count = W_D_FIFO_THRESH;
		W6692_empty_Dfifo(card, count);
		recv_Dchannel(&card->dch);
	}
}
static void
hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
		 int finish)
{
	struct hfcsusb	*hw = fifo->hw;
	struct sk_buff	*rx_skb = NULL;
	int		maxlen = 0;
	int		fifon = fifo->fifonum;
	int		i;
	int		hdlc = 0;

	if (debug & DBG_HFC_CALL_TRACE)
		printk(KERN_DEBUG "%s: %s: fifo(%i) len(%i) "
		       "dch(%p) bch(%p) ech(%p)\n",
		       hw->name, __func__, fifon, len,
		       fifo->dch, fifo->bch, fifo->ech);

	if (!len)
		return;

	if ((!!fifo->dch + !!fifo->bch + !!fifo->ech) != 1) {
		printk(KERN_DEBUG "%s: %s: undefined channel\n",
		       hw->name, __func__);
		return;
	}

	spin_lock(&hw->lock);
	if (fifo->dch) {
		rx_skb = fifo->dch->rx_skb;
		maxlen = fifo->dch->maxlen;
		hdlc = 1;
	}
	if (fifo->bch) {
		rx_skb = fifo->bch->rx_skb;
		maxlen = fifo->bch->maxlen;
		hdlc = test_bit(FLG_HDLC, &fifo->bch->Flags);
	}
	if (fifo->ech) {
		rx_skb = fifo->ech->rx_skb;
		maxlen = fifo->ech->maxlen;
		hdlc = 1;
	}

	if (!rx_skb) {
		rx_skb = mI_alloc_skb(maxlen, GFP_ATOMIC);
		if (rx_skb) {
			if (fifo->dch)
				fifo->dch->rx_skb = rx_skb;
			if (fifo->bch)
				fifo->bch->rx_skb = rx_skb;
			if (fifo->ech)
				fifo->ech->rx_skb = rx_skb;
			skb_trim(rx_skb, 0);
		} else {
			printk(KERN_DEBUG "%s: %s: No mem for rx_skb\n",
			       hw->name, __func__);
			spin_unlock(&hw->lock);
			return;
		}
	}

	if (fifo->dch || fifo->ech) {
		
		if ((rx_skb->len + len) >= MAX_DFRAME_LEN_L1) {
			printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
			       "for fifo(%d) HFCUSB_D_RX\n",
			       hw->name, __func__, fifon);
			skb_trim(rx_skb, 0);
			spin_unlock(&hw->lock);
			return;
		}
	} else if (fifo->bch) {
		
		if ((rx_skb->len + len) >= (MAX_BCH_SIZE + 3)) {
			printk(KERN_DEBUG "%s: %s: sbk mem exceeded "
			       "for fifo(%d) HFCUSB_B_RX\n",
			       hw->name, __func__, fifon);
			skb_trim(rx_skb, 0);
			spin_unlock(&hw->lock);
			return;
		}
	}

	memcpy(skb_put(rx_skb, len), data, len);

	if (hdlc) {
		
		if (finish) {
			if ((rx_skb->len > 3) &&
			    (!(rx_skb->data[rx_skb->len - 1]))) {
				if (debug & DBG_HFC_FIFO_VERBOSE) {
					printk(KERN_DEBUG "%s: %s: fifon(%i)"
					       " new RX len(%i): ",
					       hw->name, __func__, fifon,
					       rx_skb->len);
					i = 0;
					while (i < rx_skb->len)
						printk("%02x ",
						       rx_skb->data[i++]);
					printk("\n");
				}

				
				skb_trim(rx_skb, rx_skb->len - 3);

				if (fifo->dch)
					recv_Dchannel(fifo->dch);
				if (fifo->bch)
					recv_Bchannel(fifo->bch, MISDN_ID_ANY);
				if (fifo->ech)
					recv_Echannel(fifo->ech,
						      &hw->dch);
			} else {
				if (debug & DBG_HFC_FIFO_VERBOSE) {
					printk(KERN_DEBUG
					       "%s: CRC or minlen ERROR fifon(%i) "
					       "RX len(%i): ",
					       hw->name, fifon, rx_skb->len);
					i = 0;
					while (i < rx_skb->len)
						printk("%02x ",
						       rx_skb->data[i++]);
					printk("\n");
				}
				skb_trim(rx_skb, 0);
			}
		}
	} else {
		
		if (rx_skb->len >= poll)
			recv_Bchannel(fifo->bch, MISDN_ID_ANY);
	}
	spin_unlock(&hw->lock);
}