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); }
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); }
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); }