Commit 2c5a8715 authored by Kai Germaschewski's avatar Kai Germaschewski

Merge tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linus-2.5.vm

into tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linux-2.5.isdn
parents afae6f7c 97affa39
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#ifndef _AVMCARD_H_ #ifndef _AVMCARD_H_
#define _AVMCARD_H_ #define _AVMCARD_H_
#include <linux/spinlock.h>
#define AVMB1_PORTLEN 0x1f #define AVMB1_PORTLEN 0x1f
#define AVM_MAXVERSION 8 #define AVM_MAXVERSION 8
#define AVM_NCCI_PER_CHANNEL 4 #define AVM_NCCI_PER_CHANNEL 4
...@@ -57,6 +59,8 @@ typedef struct avmcard_dmainfo { ...@@ -57,6 +59,8 @@ typedef struct avmcard_dmainfo {
typedef struct avmcard { typedef struct avmcard {
char name[32]; char name[32];
spinlock_t lock;
unsigned int port; unsigned int port;
unsigned irq; unsigned irq;
unsigned long membase; unsigned long membase;
......
...@@ -64,7 +64,7 @@ static void b1dma_dispatch_tx(avmcard *card); ...@@ -64,7 +64,7 @@ static void b1dma_dispatch_tx(avmcard *card);
# define AVM_FLAG 0x30000000L # define AVM_FLAG 0x30000000L
# define ANY_S5933_INT 0x00800000L # define ANY_S5933_INT 0x00800000L
# define READ_TC_INT 0x00080000L # define READ_TC_INT 0x00080000L
# define WRITE_TC_INT 0x00040000L # define WRITE_TC_INT 0x00040000L
# define TX_TC_INT READ_TC_INT # define TX_TC_INT READ_TC_INT
# define RX_TC_INT WRITE_TC_INT # define RX_TC_INT WRITE_TC_INT
...@@ -83,12 +83,15 @@ static void b1dma_dispatch_tx(avmcard *card); ...@@ -83,12 +83,15 @@ static void b1dma_dispatch_tx(avmcard *card);
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#define b1dmaoutmeml(addr, value) writel(value, addr) static inline void b1dma_writel(avmcard *card, u32 value, int off)
#define b1dmainmeml(addr) readl(addr) {
#define b1dmaoutmemw(addr, value) writew(value, addr) writel(value, card->mbase + off);
#define b1dmainmemw(addr) readw(addr) }
#define b1dmaoutmemb(addr, value) writeb(value, addr)
#define b1dmainmemb(addr) readb(addr) static inline u32 b1dma_readl(avmcard *card, int off)
{
return readl(card->mbase + off);
}
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -214,26 +217,20 @@ static inline u32 _get_slice(void **pp, unsigned char *dp) ...@@ -214,26 +217,20 @@ static inline u32 _get_slice(void **pp, unsigned char *dp)
void b1dma_reset(avmcard *card) void b1dma_reset(avmcard *card)
{ {
unsigned long flags;
save_flags(flags);
cli();
card->csr = 0x0; card->csr = 0x0;
b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr); b1dma_writel(card, card->csr, AMCC_INTCSR);
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); b1dma_writel(card, 0, AMCC_MCSR);
b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0); b1dma_writel(card, 0, AMCC_RXLEN);
b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0); b1dma_writel(card, 0, AMCC_TXLEN);
t1outp(card->port, 0x10, 0x00); t1outp(card->port, 0x10, 0x00);
t1outp(card->port, 0x07, 0x00); t1outp(card->port, 0x07, 0x00);
restore_flags(flags); b1dma_writel(card, 0, AMCC_MCSR);
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0);
mdelay(10); mdelay(10);
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */ b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */
mdelay(10); mdelay(10);
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); b1dma_writel(card, 0, AMCC_MCSR);
if (card->cardtype == avm_t1pci) if (card->cardtype == avm_t1pci)
mdelay(42); mdelay(42);
else else
...@@ -244,31 +241,31 @@ void b1dma_reset(avmcard *card) ...@@ -244,31 +241,31 @@ void b1dma_reset(avmcard *card)
int b1dma_detect(avmcard *card) int b1dma_detect(avmcard *card)
{ {
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); b1dma_writel(card, 0, AMCC_MCSR);
mdelay(10); mdelay(10);
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0x0f000000); /* reset all */ b1dma_writel(card, 0x0f000000, AMCC_MCSR); /* reset all */
mdelay(10); mdelay(10);
b1dmaoutmeml(card->mbase+AMCC_MCSR, 0); b1dma_writel(card, 0, AMCC_MCSR);
mdelay(42); mdelay(42);
b1dmaoutmeml(card->mbase+AMCC_RXLEN, 0); b1dma_writel(card, 0, AMCC_RXLEN);
b1dmaoutmeml(card->mbase+AMCC_TXLEN, 0); b1dma_writel(card, 0, AMCC_TXLEN);
card->csr = 0x0; card->csr = 0x0;
b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr); b1dma_writel(card, card->csr, AMCC_INTCSR);
if (b1dmainmeml(card->mbase+AMCC_MCSR) != 0x000000E6) if (b1dma_readl(card, AMCC_MCSR) != 0x000000E6)
return 1; return 1;
b1dmaoutmeml(card->mbase+AMCC_RXPTR, 0xffffffff); b1dma_writel(card, 0xffffffff, AMCC_RXPTR);
b1dmaoutmeml(card->mbase+AMCC_TXPTR, 0xffffffff); b1dma_writel(card, 0xffffffff, AMCC_TXPTR);
if ( b1dmainmeml(card->mbase+AMCC_RXPTR) != 0xfffffffc if ( b1dma_readl(card, AMCC_RXPTR) != 0xfffffffc
|| b1dmainmeml(card->mbase+AMCC_TXPTR) != 0xfffffffc) || b1dma_readl(card, AMCC_TXPTR) != 0xfffffffc)
return 2; return 2;
b1dmaoutmeml(card->mbase+AMCC_RXPTR, 0x0); b1dma_writel(card, 0x0, AMCC_RXPTR);
b1dmaoutmeml(card->mbase+AMCC_TXPTR, 0x0); b1dma_writel(card, 0x0, AMCC_TXPTR);
if ( b1dmainmeml(card->mbase+AMCC_RXPTR) != 0x0 if ( b1dma_readl(card, AMCC_RXPTR) != 0x0
|| b1dmainmeml(card->mbase+AMCC_TXPTR) != 0x0) || b1dma_readl(card, AMCC_TXPTR) != 0x0)
return 3; return 3;
t1outp(card->port, 0x10, 0x00); t1outp(card->port, 0x10, 0x00);
...@@ -350,12 +347,27 @@ int b1pciv4_detect(avmcard *card) ...@@ -350,12 +347,27 @@ int b1pciv4_detect(avmcard *card)
return 0; return 0;
} }
static void b1dma_queue_tx(avmcard *card, struct sk_buff *skb)
{
unsigned long flags;
spin_lock_irqsave(&card->lock, flags);
skb_queue_tail(&card->dma->send_queue, skb);
if (!(card->csr & EN_TX_TC_INT)) {
b1dma_dispatch_tx(card);
b1dma_writel(card, card->csr, AMCC_INTCSR);
}
spin_unlock_irqrestore(&card->lock, flags);
}
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static void b1dma_dispatch_tx(avmcard *card) static void b1dma_dispatch_tx(avmcard *card)
{ {
avmcard_dmainfo *dma = card->dma; avmcard_dmainfo *dma = card->dma;
unsigned long flags;
struct sk_buff *skb; struct sk_buff *skb;
u8 cmd, subcmd; u8 cmd, subcmd;
u16 len; u16 len;
...@@ -363,24 +375,9 @@ static void b1dma_dispatch_tx(avmcard *card) ...@@ -363,24 +375,9 @@ static void b1dma_dispatch_tx(avmcard *card)
int inint; int inint;
void *p; void *p;
save_flags(flags);
cli();
inint = card->interrupt; inint = card->interrupt;
if (card->csr & EN_TX_TC_INT) { /* tx busy */
restore_flags(flags);
return;
}
skb = skb_dequeue(&dma->send_queue); skb = skb_dequeue(&dma->send_queue);
if (!skb) {
#ifdef CONFIG_B1DMA_DEBUG
printk(KERN_DEBUG "tx(%d): underrun\n", inint);
#endif
restore_flags(flags);
return;
}
len = CAPIMSG_LEN(skb->data); len = CAPIMSG_LEN(skb->data);
...@@ -418,15 +415,11 @@ static void b1dma_dispatch_tx(avmcard *card) ...@@ -418,15 +415,11 @@ static void b1dma_dispatch_tx(avmcard *card)
} }
txlen = (txlen + 3) & ~3; txlen = (txlen + 3) & ~3;
b1dmaoutmeml(card->mbase+AMCC_TXPTR, dma->sendbuf.dmaaddr); b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR);
b1dmaoutmeml(card->mbase+AMCC_TXLEN, txlen); b1dma_writel(card, txlen, AMCC_TXLEN);
card->csr |= EN_TX_TC_INT; card->csr |= EN_TX_TC_INT;
if (!inint)
b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr);
restore_flags(flags);
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
...@@ -449,8 +442,7 @@ static void queue_pollack(avmcard *card) ...@@ -449,8 +442,7 @@ static void queue_pollack(avmcard *card)
_put_byte(&p, SEND_POLLACK); _put_byte(&p, SEND_POLLACK);
skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb); b1dma_queue_tx(card, skb);
b1dma_dispatch_tx(card);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -585,7 +577,7 @@ static void b1dma_handle_rx(avmcard *card) ...@@ -585,7 +577,7 @@ static void b1dma_handle_rx(avmcard *card)
static void b1dma_handle_interrupt(avmcard *card) static void b1dma_handle_interrupt(avmcard *card)
{ {
u32 status = b1dmainmeml(card->mbase+AMCC_INTCSR); u32 status = b1dma_readl(card, AMCC_INTCSR);
u32 newcsr; u32 newcsr;
if ((status & ANY_S5933_INT) == 0) if ((status & ANY_S5933_INT) == 0)
...@@ -594,7 +586,7 @@ static void b1dma_handle_interrupt(avmcard *card) ...@@ -594,7 +586,7 @@ static void b1dma_handle_interrupt(avmcard *card)
newcsr = card->csr | (status & ALL_INT); newcsr = card->csr | (status & ALL_INT);
if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT; if (status & TX_TC_INT) newcsr &= ~EN_TX_TC_INT;
if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT; if (status & RX_TC_INT) newcsr &= ~EN_RX_TC_INT;
b1dmaoutmeml(card->mbase+AMCC_INTCSR, newcsr); b1dma_writel(card, newcsr, AMCC_INTCSR);
if ((status & RX_TC_INT) != 0) { if ((status & RX_TC_INT) != 0) {
struct avmcard_dmainfo *dma = card->dma; struct avmcard_dmainfo *dma = card->dma;
...@@ -602,23 +594,27 @@ static void b1dma_handle_interrupt(avmcard *card) ...@@ -602,23 +594,27 @@ static void b1dma_handle_interrupt(avmcard *card)
if (card->dma->recvlen == 0) { if (card->dma->recvlen == 0) {
dma->recvlen = *((u32 *)dma->recvbuf.dmabuf); dma->recvlen = *((u32 *)dma->recvbuf.dmabuf);
rxlen = (dma->recvlen + 3) & ~3; rxlen = (dma->recvlen + 3) & ~3;
b1dmaoutmeml(card->mbase+AMCC_RXPTR, b1dma_writel(card, dma->recvbuf.dmaaddr+4, AMCC_RXPTR);
dma->recvbuf.dmaaddr+4); b1dma_writel(card, rxlen, AMCC_RXLEN);
b1dmaoutmeml(card->mbase+AMCC_RXLEN, rxlen);
} else { } else {
b1dma_handle_rx(card); b1dma_handle_rx(card);
dma->recvlen = 0; dma->recvlen = 0;
b1dmaoutmeml(card->mbase+AMCC_RXPTR, b1dma_writel(card, dma->recvbuf.dmaaddr, AMCC_RXPTR);
dma->recvbuf.dmaaddr); b1dma_writel(card, 4, AMCC_RXLEN);
b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4);
} }
} }
spin_lock(&card->lock);
if ((status & TX_TC_INT) != 0) { if ((status & TX_TC_INT) != 0) {
card->csr &= ~EN_TX_TC_INT; if (skb_queue_empty(&card->dma->send_queue))
b1dma_dispatch_tx(card); card->csr &= ~EN_TX_TC_INT;
else
b1dma_dispatch_tx(card);
} }
b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr); b1dma_writel(card, card->csr, AMCC_INTCSR);
spin_unlock(&card->lock);
} }
void b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs) void b1dma_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
...@@ -697,15 +693,13 @@ static void b1dma_send_init(avmcard *card) ...@@ -697,15 +693,13 @@ static void b1dma_send_init(avmcard *card)
_put_word(&p, card->cardnr - 1); _put_word(&p, card->cardnr - 1);
skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb); b1dma_queue_tx(card, skb);
b1dma_dispatch_tx(card);
} }
int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card; avmcard *card = cinfo->card;
unsigned long flags;
int retval; int retval;
b1dma_reset(card); b1dma_reset(card);
...@@ -732,24 +726,19 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) ...@@ -732,24 +726,19 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
return -EIO; return -EIO;
} }
save_flags(flags);
cli();
card->csr = AVM_FLAG; card->csr = AVM_FLAG;
b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr); b1dma_writel(card, card->csr, AMCC_INTCSR);
b1dmaoutmeml(card->mbase+AMCC_MCSR, b1dma_writel(card, EN_A2P_TRANSFERS|EN_P2A_TRANSFERS|A2P_HI_PRIORITY|
EN_A2P_TRANSFERS|EN_P2A_TRANSFERS P2A_HI_PRIORITY|RESET_A2P_FLAGS|RESET_P2A_FLAGS,
|A2P_HI_PRIORITY|P2A_HI_PRIORITY AMCC_MCSR);
|RESET_A2P_FLAGS|RESET_P2A_FLAGS);
t1outp(card->port, 0x07, 0x30); t1outp(card->port, 0x07, 0x30);
t1outp(card->port, 0x10, 0xF0); t1outp(card->port, 0x10, 0xF0);
card->dma->recvlen = 0; card->dma->recvlen = 0;
b1dmaoutmeml(card->mbase+AMCC_RXPTR, card->dma->recvbuf.dmaaddr); b1dma_writel(card, card->dma->recvbuf.dmaaddr, AMCC_RXPTR);
b1dmaoutmeml(card->mbase+AMCC_RXLEN, 4); b1dma_writel(card, 4, AMCC_RXLEN);
card->csr |= EN_RX_TC_INT; card->csr |= EN_RX_TC_INT;
b1dmaoutmeml(card->mbase+AMCC_INTCSR, card->csr); b1dma_writel(card, card->csr, AMCC_INTCSR);
restore_flags(flags);
b1dma_send_init(card); b1dma_send_init(card);
...@@ -803,8 +792,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl, ...@@ -803,8 +792,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl,
_put_word(&p, rp->datablklen); _put_word(&p, rp->datablklen);
skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb); b1dma_queue_tx(card, skb);
b1dma_dispatch_tx(card);
ctrl->appl_registered(ctrl, appl); ctrl->appl_registered(ctrl, appl);
} }
...@@ -831,8 +819,8 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl) ...@@ -831,8 +819,8 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl)
_put_word(&p, appl); _put_word(&p, appl);
skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_put(skb, (u8 *)p - (u8 *)skb->data);
skb_queue_tail(&card->dma->send_queue, skb);
b1dma_dispatch_tx(card); b1dma_queue_tx(card, skb);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -841,8 +829,8 @@ void b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) ...@@ -841,8 +829,8 @@ void b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card; avmcard *card = cinfo->card;
skb_queue_tail(&card->dma->send_queue, skb);
b1dma_dispatch_tx(card); b1dma_queue_tx(card, skb);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -852,7 +840,6 @@ int b1dmactl_read_proc(char *page, char **start, off_t off, ...@@ -852,7 +840,6 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card; avmcard *card = cinfo->card;
unsigned long flags;
u8 flag; u8 flag;
int len = 0; int len = 0;
char *s; char *s;
...@@ -909,18 +896,13 @@ int b1dmactl_read_proc(char *page, char **start, off_t off, ...@@ -909,18 +896,13 @@ int b1dmactl_read_proc(char *page, char **start, off_t off,
} }
len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname);
save_flags(flags); txoff = (dma_addr_t)b1dma_readl(card, AMCC_TXPTR)-card->dma->sendbuf.dmaaddr;
cli(); txlen = b1dma_readl(card, AMCC_TXLEN);
txoff = (dma_addr_t)b1dmainmeml(card->mbase+0x2c)-card->dma->sendbuf.dmaaddr;
txlen = b1dmainmeml(card->mbase+0x30);
rxoff = (dma_addr_t)b1dmainmeml(card->mbase+0x24)-card->dma->recvbuf.dmaaddr;
rxlen = b1dmainmeml(card->mbase+0x28);
csr = b1dmainmeml(card->mbase+AMCC_INTCSR); rxoff = (dma_addr_t)b1dma_readl(card, AMCC_RXPTR)-card->dma->recvbuf.dmaaddr;
rxlen = b1dma_readl(card, AMCC_RXLEN);
restore_flags(flags); csr = b1dma_readl(card, AMCC_INTCSR);
len += sprintf(page+len, "%-16s 0x%lx\n", len += sprintf(page+len, "%-16s 0x%lx\n",
"csr (cached)", (unsigned long)card->csr); "csr (cached)", (unsigned long)card->csr);
......
...@@ -258,6 +258,7 @@ static int b1pciv4_add_card(struct capi_driver *driver, ...@@ -258,6 +258,7 @@ static int b1pciv4_add_card(struct capi_driver *driver,
goto err; goto err;
} }
memset(card, 0, sizeof(avmcard)); memset(card, 0, sizeof(avmcard));
spin_lock_init(&card->lock);
card->dma = avmcard_dma_alloc(driver->name, dev, 2048+128, 2048+128); card->dma = avmcard_dma_alloc(driver->name, dev, 2048+128, 2048+128);
if (!card->dma) { if (!card->dma) {
......
...@@ -66,6 +66,8 @@ static int t1pci_add_card(struct capi_driver *driver, ...@@ -66,6 +66,8 @@ static int t1pci_add_card(struct capi_driver *driver,
goto err; goto err;
} }
memset(card, 0, sizeof(avmcard)); memset(card, 0, sizeof(avmcard));
spin_lock_init(&card->lock);
card->dma = avmcard_dma_alloc(driver->name, dev, 2048+128, 2048+128); card->dma = avmcard_dma_alloc(driver->name, dev, 2048+128, 2048+128);
if (!card->dma) { if (!card->dma) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment