Пример #1
0
static void b1dma_handle_interrupt(avmcard *card)
{
	u32 status;
	u32 newcsr;

	spin_lock(&card->lock);

	status = b1dma_readl(card, AMCC_INTCSR);
	if ((status & ANY_S5933_INT) == 0) {
		spin_unlock(&card->lock);
		return;
	}

        newcsr = card->csr | (status & ALL_INT);
	if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
	if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
	b1dma_writel(card, newcsr, AMCC_INTCSR);

	if ((status & RX_TC_INT) != 0) {
		struct avmcard_dmainfo *dma = card->dma;
		u32 rxlen;
	   	if (card->dma->recvlen == 0) {
	        	rxlen = b1dma_readl(card, AMCC_RXLEN);
			if (rxlen == 0) {
				dma->recvlen = *((u32 *)dma->recvbuf.dmabuf);
				rxlen = (dma->recvlen + 3) & ~3;
				b1dma_writel(card, dma->recvbuf.dmaaddr+4, AMCC_RXPTR);
				b1dma_writel(card, rxlen, AMCC_RXLEN);
#ifdef AVM_B1DMA_DEBUG
			} else {
				printk(KERN_ERR "%s: rx not complete (%d).\n",
					card->name, rxlen);
#endif
			}
		} else {
			spin_unlock(&card->lock);
			b1dma_handle_rx(card);
	   		dma->recvlen = 0;
			spin_lock(&card->lock);
			b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR);
			b1dma_writel(card, 4, AMCC_RXLEN);
		}
	}

	if ((status & TX_TC_INT) != 0) {
		if (skb_queue_empty(&card->dma->send_queue))
			card->csr &= ~EN_TX_TC_INT;
		else
			b1dma_dispatch_tx(card);
	}
	b1dma_writel(card, card->csr, AMCC_INTCSR);

	spin_unlock(&card->lock);
}
Пример #2
0
void b1dma_reset(avmcard *card)
{
	card->csr = 0x0;
	b1dma_writel(card, card->csr, AMCC_INTCSR);
	b1dma_writel(card, 0, AMCC_MCSR);
	b1dma_writel(card, 0, AMCC_RXLEN);
	b1dma_writel(card, 0, AMCC_TXLEN);

	t1outp(card->port, 0x10, 0x00);
	t1outp(card->port, 0x07, 0x00);

	b1dma_writel(card, 0, AMCC_MCSR);
	mdelay(10);
	b1dma_writel(card, 0x0f000000, AMCC_MCSR); /*           */
	mdelay(10);
	b1dma_writel(card, 0, AMCC_MCSR);
	if (card->cardtype == avm_t1pci)
		mdelay(42);
	else
		mdelay(10);
}
Пример #3
0
static void b1dma_dispatch_tx(avmcard *card)
{
	avmcard_dmainfo *dma = card->dma;
	struct sk_buff *skb;
	u8 cmd, subcmd;
	u16 len;
	u32 txlen;
	void *p;
	
	skb = skb_dequeue(&dma->send_queue);

	len = CAPIMSG_LEN(skb->data);

	if (len) {
		cmd = CAPIMSG_COMMAND(skb->data);
		subcmd = CAPIMSG_SUBCOMMAND(skb->data);

		p = dma->sendbuf.dmabuf;

		if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
			u16 dlen = CAPIMSG_DATALEN(skb->data);
			_put_byte(&p, SEND_DATA_B3_REQ);
			_put_slice(&p, skb->data, len);
			_put_slice(&p, skb->data + len, dlen);
		} else {
			_put_byte(&p, SEND_MESSAGE);
			_put_slice(&p, skb->data, len);
		}
		txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
#ifdef AVM_B1DMA_DEBUG
#ifdef CONFIG_DEBUG_PRINTK
		printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
#else
		;
#endif
#endif
	} else {
		txlen = skb->len-2;
#ifdef AVM_B1DMA_POLLDEBUG
		if (skb->data[2] == SEND_POLLACK)
#ifdef CONFIG_DEBUG_PRINTK
			printk(KERN_INFO "%s: send ack\n", card->name);
#else
			;
#endif
#endif
#ifdef AVM_B1DMA_DEBUG
#ifdef CONFIG_DEBUG_PRINTK
		printk(KERN_DEBUG "tx: put 0x%x len=%d\n", 
		       skb->data[2], txlen);
#else
		;
#endif
#endif
		skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf,
						 skb->len - 2);
	}
	txlen = (txlen + 3) & ~3;

	b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR);
	b1dma_writel(card, txlen, AMCC_TXLEN);

	card->csr |= EN_TX_TC_INT;

	dev_kfree_skb_any(skb);
}