Commit f0a83a45 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-isdn.bkbits.net/linux-2.5.isdn

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 325fb800 d0e068dc
...@@ -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
...@@ -55,8 +57,24 @@ typedef struct avmcard_dmainfo { ...@@ -55,8 +57,24 @@ typedef struct avmcard_dmainfo {
struct pci_dev *pcidev; struct pci_dev *pcidev;
} avmcard_dmainfo; } avmcard_dmainfo;
typedef struct avmctrl_info {
char cardname[32];
int versionlen;
char versionbuf[1024];
char *version[AVM_MAXVERSION];
char infobuf[128]; /* for function procinfo */
struct avmcard *card;
struct capi_ctr *capi_ctrl;
} avmctrl_info;
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;
...@@ -68,31 +86,15 @@ typedef struct avmcard { ...@@ -68,31 +86,15 @@ typedef struct avmcard {
char msgbuf[128]; /* capimsg msg part */ char msgbuf[128]; /* capimsg msg part */
char databuf[2048]; /* capimsg data part */ char databuf[2048]; /* capimsg data part */
int interrupt;
void *mbase; void *mbase;
volatile u32 csr; volatile u32 csr;
avmcard_dmainfo *dma; avmcard_dmainfo *dma;
struct avmctrl_info { struct avmctrl_info *ctrlinfo;
char cardname[32];
int versionlen;
char versionbuf[1024];
char *version[AVM_MAXVERSION];
char infobuf[128]; /* for function procinfo */
struct avmcard *card;
struct capi_ctr *capi_ctrl;
} *ctrlinfo;
int nlogcontr; int nlogcontr;
} avmcard; } avmcard;
typedef struct avmctrl_info avmctrl_info;
extern int b1_irq_table[16]; extern int b1_irq_table[16];
/* /*
...@@ -534,6 +536,8 @@ static inline void b1_setinterrupt(unsigned int base, unsigned irq, ...@@ -534,6 +536,8 @@ static inline void b1_setinterrupt(unsigned int base, unsigned irq,
} }
/* b1.c */ /* b1.c */
avmcard *b1_alloc_card(int nr_controllers);
void b1_free_card(avmcard *card);
int b1_detect(unsigned int base, enum avmcardtype cardtype); int b1_detect(unsigned int base, enum avmcardtype cardtype);
void b1_getrevision(avmcard *card); void b1_getrevision(avmcard *card);
int b1_load_t4file(avmcard *card, capiloaddatapart * t4file); int b1_load_t4file(avmcard *card, capiloaddatapart * t4file);
...@@ -547,7 +551,7 @@ void b1_register_appl(struct capi_ctr *ctrl, u16 appl, ...@@ -547,7 +551,7 @@ void b1_register_appl(struct capi_ctr *ctrl, u16 appl,
void b1_release_appl(struct capi_ctr *ctrl, u16 appl); void b1_release_appl(struct capi_ctr *ctrl, u16 appl);
void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb);
void b1_parse_version(avmctrl_info *card); void b1_parse_version(avmctrl_info *card);
void b1_handle_interrupt(avmcard * card); void b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs);
int b1ctl_read_proc(char *page, char **start, off_t off, int b1ctl_read_proc(char *page, char **start, off_t off,
int count, int *eof, struct capi_ctr *ctrl); int count, int *eof, struct capi_ctr *ctrl);
......
...@@ -59,6 +59,44 @@ int b1_irq_table[16] = ...@@ -59,6 +59,44 @@ int b1_irq_table[16] =
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
avmcard *b1_alloc_card(int nr_controllers)
{
avmcard *card;
avmctrl_info *cinfo;
int i;
card = kmalloc(sizeof(*card), GFP_KERNEL);
if (!card)
return 0;
memset(card, 0, sizeof(*card));
cinfo = kmalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL);
if (!cinfo) {
kfree(card);
return 0;
}
memset(cinfo, 0, sizeof(*cinfo));
card->ctrlinfo = cinfo;
for (i = 0; i < nr_controllers; i++) {
cinfo[i].card = card;
}
spin_lock_init(&card->lock);
return card;
}
/* ------------------------------------------------------------- */
void b1_free_card(avmcard *card)
{
kfree(card->ctrlinfo);
kfree(card);
}
/* ------------------------------------------------------------- */
int b1_detect(unsigned int base, enum avmcardtype cardtype) int b1_detect(unsigned int base, enum avmcardtype cardtype)
{ {
int onoff, i; int onoff, i;
...@@ -438,8 +476,9 @@ void b1_parse_version(avmctrl_info *cinfo) ...@@ -438,8 +476,9 @@ void b1_parse_version(avmctrl_info *cinfo)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
void b1_handle_interrupt(avmcard * card) void b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{ {
avmcard *card = devptr;
avmctrl_info *cinfo = &card->ctrlinfo[0]; avmctrl_info *cinfo = &card->ctrlinfo[0];
struct capi_ctr *ctrl = cinfo->capi_ctrl; struct capi_ctr *ctrl = cinfo->capi_ctrl;
unsigned char b1cmd; unsigned char b1cmd;
...@@ -701,6 +740,8 @@ EXPORT_SYMBOL(avmcard_dma_free); ...@@ -701,6 +740,8 @@ EXPORT_SYMBOL(avmcard_dma_free);
EXPORT_SYMBOL(b1_irq_table); EXPORT_SYMBOL(b1_irq_table);
EXPORT_SYMBOL(b1_alloc_card);
EXPORT_SYMBOL(b1_free_card);
EXPORT_SYMBOL(b1_detect); EXPORT_SYMBOL(b1_detect);
EXPORT_SYMBOL(b1_getrevision); EXPORT_SYMBOL(b1_getrevision);
EXPORT_SYMBOL(b1_load_t4file); EXPORT_SYMBOL(b1_load_t4file);
...@@ -713,7 +754,7 @@ EXPORT_SYMBOL(b1_release_appl); ...@@ -713,7 +754,7 @@ EXPORT_SYMBOL(b1_release_appl);
EXPORT_SYMBOL(b1_send_message); EXPORT_SYMBOL(b1_send_message);
EXPORT_SYMBOL(b1_parse_version); EXPORT_SYMBOL(b1_parse_version);
EXPORT_SYMBOL(b1_handle_interrupt); EXPORT_SYMBOL(b1_interrupt);
EXPORT_SYMBOL(b1ctl_read_proc); EXPORT_SYMBOL(b1ctl_read_proc);
......
...@@ -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,37 +347,34 @@ int b1pciv4_detect(avmcard *card) ...@@ -350,37 +347,34 @@ 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;
u32 txlen; u32 txlen;
int inint;
void *p; void *p;
save_flags(flags);
cli();
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);
...@@ -401,8 +395,7 @@ static void b1dma_dispatch_tx(avmcard *card) ...@@ -401,8 +395,7 @@ static void b1dma_dispatch_tx(avmcard *card)
} }
txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf; txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
#ifdef CONFIG_B1DMA_DEBUG #ifdef CONFIG_B1DMA_DEBUG
printk(KERN_DEBUG "tx(%d): put msg len=%d\n", printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
inint, txlen);
#endif #endif
} else { } else {
txlen = skb->len-2; txlen = skb->len-2;
...@@ -411,22 +404,18 @@ static void b1dma_dispatch_tx(avmcard *card) ...@@ -411,22 +404,18 @@ static void b1dma_dispatch_tx(avmcard *card)
printk(KERN_INFO "%s: send ack\n", card->name); printk(KERN_INFO "%s: send ack\n", card->name);
#endif #endif
#ifdef CONFIG_B1DMA_DEBUG #ifdef CONFIG_B1DMA_DEBUG
printk(KERN_DEBUG "tx(%d): put 0x%x len=%d\n", printk(KERN_DEBUG "tx: put 0x%x len=%d\n",
inint, skb->data[2], txlen); skb->data[2], txlen);
#endif #endif
memcpy(dma->sendbuf.dmabuf, skb->data+2, skb->len-2); memcpy(dma->sendbuf.dmabuf, skb->data+2, skb->len-2);
} }
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 +438,7 @@ static void queue_pollack(avmcard *card) ...@@ -449,8 +438,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 +573,7 @@ static void b1dma_handle_rx(avmcard *card) ...@@ -585,7 +573,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 +582,7 @@ static void b1dma_handle_interrupt(avmcard *card) ...@@ -594,7 +582,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,45 +590,34 @@ static void b1dma_handle_interrupt(avmcard *card) ...@@ -602,45 +590,34 @@ 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) {
if (skb_queue_empty(&card->dma->send_queue))
card->csr &= ~EN_TX_TC_INT; card->csr &= ~EN_TX_TC_INT;
else
b1dma_dispatch_tx(card); 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)
{ {
avmcard *card; avmcard *card = devptr;
card = (avmcard *) devptr;
if (!card) {
printk(KERN_WARNING "b1dma: interrupt: wrong device\n");
return;
}
if (card->interrupt) {
printk(KERN_ERR "%s: reentering interrupt hander\n", card->name);
return;
}
card->interrupt = 1;
b1dma_handle_interrupt(card); b1dma_handle_interrupt(card);
card->interrupt = 0;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -697,15 +674,13 @@ static void b1dma_send_init(avmcard *card) ...@@ -697,15 +674,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 +707,19 @@ int b1dma_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) ...@@ -732,24 +707,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 +773,7 @@ void b1dma_register_appl(struct capi_ctr *ctrl, ...@@ -803,8 +773,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 +800,8 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl) ...@@ -831,8 +800,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 +810,8 @@ void b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) ...@@ -841,8 +810,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 +821,6 @@ int b1dmactl_read_proc(char *page, char **start, off_t off, ...@@ -852,7 +821,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 +877,13 @@ int b1dmactl_read_proc(char *page, char **start, off_t off, ...@@ -909,18 +877,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);
......
...@@ -34,29 +34,6 @@ MODULE_LICENSE("GPL"); ...@@ -34,29 +34,6 @@ MODULE_LICENSE("GPL");
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static void b1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{
avmcard *card;
card = (avmcard *) devptr;
if (!card) {
printk(KERN_WARNING "b1_interrupt: wrong device\n");
return;
}
if (card->interrupt) {
printk(KERN_ERR "b1_interrupt: reentering interrupt hander (%s)\n", card->name);
return;
}
card->interrupt = 1;
b1_handle_interrupt(card);
card->interrupt = 0;
}
/* ------------------------------------------------------------- */
static struct capi_driver_interface *di; static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -73,8 +50,7 @@ static void b1isa_remove_ctr(struct capi_ctr *ctrl) ...@@ -73,8 +50,7 @@ static void b1isa_remove_ctr(struct capi_ctr *ctrl)
di->detach_ctr(ctrl); di->detach_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
kfree(card->ctrlinfo); b1_free_card(card);
kfree(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -89,86 +65,57 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -89,86 +65,57 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); card = b1_alloc_card(1);
if (!card) { if (!card) {
printk(KERN_WARNING "b1isa: no memory.\n"); printk(KERN_WARNING "b1isa: no memory.\n");
MOD_DEC_USE_COUNT; retval = -ENOMEM;
return -ENOMEM; goto err;
}
memset(card, 0, sizeof(avmcard));
cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
if (!cinfo) {
printk(KERN_WARNING "b1isa: no memory.\n");
kfree(card);
MOD_DEC_USE_COUNT;
return -ENOMEM;
} }
memset(cinfo, 0, sizeof(avmctrl_info));
card->ctrlinfo = cinfo; cinfo = card->ctrlinfo;
cinfo->card = card;
sprintf(card->name, "b1isa-%x", p->port); sprintf(card->name, "b1isa-%x", p->port);
card->port = p->port; card->port = p->port;
card->irq = p->irq; card->irq = p->irq;
card->cardtype = avm_b1isa; card->cardtype = avm_b1isa;
if (check_region(card->port, AVMB1_PORTLEN)) { if ( card->port != 0x150 && card->port != 0x250
printk(KERN_WARNING && card->port != 0x300 && card->port != 0x340) {
"b1isa: ports 0x%03x-0x%03x in use.\n", printk(KERN_WARNING "b1isa: illegal port 0x%x.\n", card->port);
card->port, card->port + AVMB1_PORTLEN); retval = -EINVAL;
kfree(card->ctrlinfo); goto err_free;
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
if (b1_irq_table[card->irq & 0xf] == 0) { if (b1_irq_table[card->irq & 0xf] == 0) {
printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq); printk(KERN_WARNING "b1isa: irq %d not valid.\n", card->irq);
kfree(card->ctrlinfo); retval = -EINVAL;
kfree(card); goto err_free;
MOD_DEC_USE_COUNT;
return -EINVAL;
} }
if ( card->port != 0x150 && card->port != 0x250 if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
&& card->port != 0x300 && card->port != 0x340) { printk(KERN_WARNING "b1isa: ports 0x%03x-0x%03x in use.\n",
printk(KERN_WARNING "b1isa: illegal port 0x%x.\n", card->port); card->port, card->port + AVMB1_PORTLEN);
kfree(card->ctrlinfo); retval = -EBUSY;
kfree(card); goto err_free;
MOD_DEC_USE_COUNT; }
return -EINVAL; retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
if (retval) {
printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq);
goto err_release_region;
} }
b1_reset(card->port); b1_reset(card->port);
if ((retval = b1_detect(card->port, card->cardtype)) != 0) { if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n", printk(KERN_NOTICE "b1isa: NO card at 0x%x (%d)\n",
card->port, retval); card->port, retval);
kfree(card->ctrlinfo); retval = -ENODEV;
kfree(card); goto err_free_irq;
MOD_DEC_USE_COUNT;
return -EIO;
} }
b1_reset(card->port); b1_reset(card->port);
b1_getrevision(card); b1_getrevision(card);
request_region(p->port, AVMB1_PORTLEN, card->name);
retval = request_irq(card->irq, b1isa_interrupt, 0, card->name, card);
if (retval) {
printk(KERN_ERR "b1isa: unable to get IRQ %d.\n", card->irq);
release_region(card->port, AVMB1_PORTLEN);
kfree(card->ctrlinfo);
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
}
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "b1isa: attach controller failed.\n"); printk(KERN_ERR "b1isa: attach controller failed.\n");
free_irq(card->irq, card); retval = -EBUSY;
release_region(card->port, AVMB1_PORTLEN); goto err_free_irq;
kfree(card->ctrlinfo);
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
printk(KERN_INFO printk(KERN_INFO
...@@ -176,6 +123,16 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -176,6 +123,16 @@ static int b1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
driver->name, card->port, card->irq, card->revision); driver->name, card->port, card->irq, card->revision);
return 0; return 0;
err_free_irq:
free_irq(card->irq, card);
err_release_region:
release_region(card->port, AVMB1_PORTLEN);
err_free:
b1_free_card(card);
err:
MOD_DEC_USE_COUNT;
return retval;
} }
static char *b1isa_procinfo(struct capi_ctr *ctrl) static char *b1isa_procinfo(struct capi_ctr *ctrl)
......
...@@ -46,30 +46,6 @@ static struct capi_driver_interface *di; ...@@ -46,30 +46,6 @@ static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static void b1pci_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{
avmcard *card;
card = (avmcard *) devptr;
if (!card) {
printk(KERN_WARNING "b1pci: interrupt: wrong device\n");
return;
}
if (card->interrupt) {
printk(KERN_ERR "%s: reentering interrupt hander.\n", card->name);
return;
}
card->interrupt = 1;
b1_handle_interrupt(card);
card->interrupt = 0;
}
/* ------------------------------------------------------------- */
static char *b1pci_procinfo(struct capi_ctr *ctrl) static char *b1pci_procinfo(struct capi_ctr *ctrl)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -98,22 +74,14 @@ static int b1pci_add_card(struct capi_driver *driver, ...@@ -98,22 +74,14 @@ static int b1pci_add_card(struct capi_driver *driver,
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
retval = -ENOMEM; card = b1_alloc_card(1);
card = kmalloc(sizeof(avmcard), GFP_KERNEL);
if (!card) { if (!card) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
retval = -ENOMEM;
goto err; goto err;
} }
memset(card, 0, sizeof(avmcard));
cinfo = kmalloc(sizeof(avmctrl_info), GFP_KERNEL); cinfo = card->ctrlinfo;
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
goto err_kfree;
}
memset(cinfo, 0, sizeof(avmctrl_info));
card->ctrlinfo = cinfo;
cinfo->card = card;
sprintf(card->name, "b1pci-%x", p->port); sprintf(card->name, "b1pci-%x", p->port);
card->port = p->port; card->port = p->port;
card->irq = p->irq; card->irq = p->irq;
...@@ -123,20 +91,21 @@ static int b1pci_add_card(struct capi_driver *driver, ...@@ -123,20 +91,21 @@ static int b1pci_add_card(struct capi_driver *driver,
printk(KERN_WARNING printk(KERN_WARNING
"%s: ports 0x%03x-0x%03x in use.\n", "%s: ports 0x%03x-0x%03x in use.\n",
driver->name, card->port, card->port + AVMB1_PORTLEN); driver->name, card->port, card->port + AVMB1_PORTLEN);
goto err_kfree_ctrlinfo; retval = -EBUSY;
goto err_free;
} }
b1_reset(card->port); b1_reset(card->port);
retval = b1_detect(card->port, card->cardtype); retval = b1_detect(card->port, card->cardtype);
if (retval) { if (retval) {
printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
driver->name, card->port, retval); driver->name, card->port, retval);
retval = -EIO; retval = -ENODEV;
goto err_release_region; goto err_release_region;
} }
b1_reset(card->port); b1_reset(card->port);
b1_getrevision(card); b1_getrevision(card);
retval = request_irq(card->irq, b1pci_interrupt, SA_SHIRQ, card->name, card); retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card);
if (retval) { if (retval) {
printk(KERN_ERR "%s: unable to get IRQ %d.\n", printk(KERN_ERR "%s: unable to get IRQ %d.\n",
driver->name, card->irq); driver->name, card->irq);
...@@ -168,10 +137,8 @@ static int b1pci_add_card(struct capi_driver *driver, ...@@ -168,10 +137,8 @@ static int b1pci_add_card(struct capi_driver *driver,
free_irq(card->irq, card); free_irq(card->irq, card);
err_release_region: err_release_region:
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
err_kfree_ctrlinfo: err_free:
kfree(card->ctrlinfo); b1_free_card(card);
err_kfree:
kfree(card);
err: err:
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
...@@ -190,8 +157,7 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl) ...@@ -190,8 +157,7 @@ static void b1pci_remove_ctr(struct capi_ctr *ctrl)
free_irq(card->irq, card); free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
ctrl->driverdata = 0; ctrl->driverdata = 0;
kfree(card->ctrlinfo); b1_free_card(card);
kfree(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -251,27 +217,21 @@ static int b1pciv4_add_card(struct capi_driver *driver, ...@@ -251,27 +217,21 @@ static int b1pciv4_add_card(struct capi_driver *driver,
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
retval = -ENOMEM; card = b1_alloc_card(1);
card = kmalloc(sizeof(avmcard), GFP_KERNEL);
if (!card) { if (!card) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
retval = -ENOMEM;
goto err; goto err;
} }
memset(card, 0, sizeof(avmcard));
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: dma alloc.\n", driver->name); printk(KERN_WARNING "%s: dma alloc.\n", driver->name);
goto err_kfree; retval = -ENOMEM;
} goto err_free;
cinfo = kmalloc(sizeof(avmctrl_info), GFP_KERNEL);
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
goto err_dma_free;
} }
memset(cinfo, 0, sizeof(avmctrl_info));
card->ctrlinfo = cinfo; cinfo = card->ctrlinfo;
cinfo->card = card;
sprintf(card->name, "b1pciv4-%x", p->port); sprintf(card->name, "b1pciv4-%x", p->port);
card->port = p->port; card->port = p->port;
card->irq = p->irq; card->irq = p->irq;
...@@ -283,14 +243,14 @@ static int b1pciv4_add_card(struct capi_driver *driver, ...@@ -283,14 +243,14 @@ static int b1pciv4_add_card(struct capi_driver *driver,
"%s: ports 0x%03x-0x%03x in use.\n", "%s: ports 0x%03x-0x%03x in use.\n",
driver->name, card->port, card->port + AVMB1_PORTLEN); driver->name, card->port, card->port + AVMB1_PORTLEN);
retval = -EBUSY; retval = -EBUSY;
goto err_kfree_ctrlinfo; goto err_free_dma;
} }
card->mbase = ioremap_nocache(card->membase, 64); card->mbase = ioremap_nocache(card->membase, 64);
if (!card->mbase) { if (!card->mbase) {
printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n", printk(KERN_NOTICE "%s: can't remap memory at 0x%lx\n",
driver->name, card->membase); driver->name, card->membase);
retval = -EIO; retval = -ENOMEM;
goto err_release_region; goto err_release_region;
} }
...@@ -300,7 +260,7 @@ static int b1pciv4_add_card(struct capi_driver *driver, ...@@ -300,7 +260,7 @@ static int b1pciv4_add_card(struct capi_driver *driver,
if (retval) { if (retval) {
printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
driver->name, card->port, retval); driver->name, card->port, retval);
retval = -EIO; retval = -ENODEV;
goto err_unmap; goto err_unmap;
} }
b1dma_reset(card); b1dma_reset(card);
...@@ -335,12 +295,10 @@ static int b1pciv4_add_card(struct capi_driver *driver, ...@@ -335,12 +295,10 @@ static int b1pciv4_add_card(struct capi_driver *driver,
iounmap(card->mbase); iounmap(card->mbase);
err_release_region: err_release_region:
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
err_kfree_ctrlinfo: err_free_dma:
kfree(card->ctrlinfo);
err_dma_free:
avmcard_dma_free(card->dma); avmcard_dma_free(card->dma);
err_kfree: err_free:
kfree(card); b1_free_card(card);
err: err:
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
...@@ -359,9 +317,8 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl) ...@@ -359,9 +317,8 @@ static void b1pciv4_remove_ctr(struct capi_ctr *ctrl)
iounmap(card->mbase); iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
ctrl->driverdata = 0; ctrl->driverdata = 0;
kfree(card->ctrlinfo);
avmcard_dma_free(card->dma); avmcard_dma_free(card->dma);
kfree(card); b1_free_card(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
......
...@@ -39,30 +39,6 @@ static struct capi_driver_interface *di; ...@@ -39,30 +39,6 @@ static struct capi_driver_interface *di;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static void b1pcmcia_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{
avmcard *card;
card = (avmcard *) devptr;
if (!card) {
printk(KERN_WARNING "b1pcmcia: interrupt: wrong device\n");
return;
}
if (card->interrupt) {
printk(KERN_ERR "%s: reentering interrupt hander.\n",
card->name);
return;
}
card->interrupt = 1;
b1_handle_interrupt(card);
card->interrupt = 0;
}
/* ------------------------------------------------------------- */
static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -74,10 +50,7 @@ static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl) ...@@ -74,10 +50,7 @@ static void b1pcmcia_remove_ctr(struct capi_ctr *ctrl)
di->detach_ctr(ctrl); di->detach_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
/* io addrsses managent by CardServices b1_free_card(card);
* release_region(card->port, AVMB1_PORTLEN);
*/
kfree(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -96,24 +69,14 @@ static int b1pcmcia_add_card(struct capi_driver *driver, ...@@ -96,24 +69,14 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); card = b1_alloc_card(1);
if (!card) { if (!card) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
MOD_DEC_USE_COUNT; retval = -ENOMEM;
return -ENOMEM; goto err;
}
memset(card, 0, sizeof(avmcard));
cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
kfree(card);
MOD_DEC_USE_COUNT;
return -ENOMEM;
} }
memset(cinfo, 0, sizeof(avmctrl_info)); cinfo = card->ctrlinfo;
card->ctrlinfo = cinfo;
cinfo->card = card;
switch (cardtype) { switch (cardtype) {
case avm_m1: sprintf(card->name, "m1-%x", port); break; case avm_m1: sprintf(card->name, "m1-%x", port); break;
case avm_m2: sprintf(card->name, "m2-%x", port); break; case avm_m2: sprintf(card->name, "m2-%x", port); break;
...@@ -123,37 +86,29 @@ static int b1pcmcia_add_card(struct capi_driver *driver, ...@@ -123,37 +86,29 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
card->irq = irq; card->irq = irq;
card->cardtype = cardtype; card->cardtype = cardtype;
retval = request_irq(card->irq, b1_interrupt, 0, card->name, card);
if (retval) {
printk(KERN_ERR "%s: unable to get IRQ %d.\n",
driver->name, card->irq);
retval = -EBUSY;
goto err_free;
}
b1_reset(card->port); b1_reset(card->port);
if ((retval = b1_detect(card->port, card->cardtype)) != 0) { if ((retval = b1_detect(card->port, card->cardtype)) != 0) {
printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
driver->name, card->port, retval); driver->name, card->port, retval);
kfree(card->ctrlinfo); retval = -ENODEV;
kfree(card); goto err_free_irq;
MOD_DEC_USE_COUNT;
return -EIO;
} }
b1_reset(card->port); b1_reset(card->port);
b1_getrevision(card); b1_getrevision(card);
retval = request_irq(card->irq, b1pcmcia_interrupt, 0, card->name, card);
if (retval) {
printk(KERN_ERR "%s: unable to get IRQ %d.\n",
driver->name, card->irq);
kfree(card->ctrlinfo);
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
}
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", printk(KERN_ERR "%s: attach controller failed.\n",
driver->name); driver->name);
free_irq(card->irq, card); retval = -EBUSY;
kfree(card->ctrlinfo); goto err_free_irq;
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
switch (cardtype) { switch (cardtype) {
case avm_m1: cardname = "M1"; break; case avm_m1: cardname = "M1"; break;
...@@ -166,6 +121,14 @@ static int b1pcmcia_add_card(struct capi_driver *driver, ...@@ -166,6 +121,14 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
driver->name, cardname, card->port, card->irq, card->revision); driver->name, cardname, card->port, card->irq, card->revision);
return cinfo->capi_ctrl->cnr; return cinfo->capi_ctrl->cnr;
err_free_irq:
free_irq(card->irq, card);
err_free:
b1_free_card(card);
err:
MOD_DEC_USE_COUNT;
return retval;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
......
...@@ -719,25 +719,9 @@ static void c4_handle_interrupt(avmcard *card) ...@@ -719,25 +719,9 @@ static void c4_handle_interrupt(avmcard *card)
static void c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs) static void c4_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{ {
avmcard *card; avmcard *card = devptr;
card = (avmcard *) devptr;
if (!card) {
printk(KERN_WARNING "%s: interrupt: wrong device\n", card->name);
return;
}
if (card->interrupt) {
printk(KERN_ERR "%s: reentering interrupt hander\n",
card->name);
return;
}
card->interrupt = 1;
c4_handle_interrupt(card); c4_handle_interrupt(card);
card->interrupt = 0;
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
...@@ -943,9 +927,8 @@ static void c4_remove_ctr(struct capi_ctr *ctrl) ...@@ -943,9 +927,8 @@ static void c4_remove_ctr(struct capi_ctr *ctrl)
iounmap(card->mbase); iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
ctrl->driverdata = 0; ctrl->driverdata = 0;
kfree(card->ctrlinfo);
avmcard_dma_free(card->dma); avmcard_dma_free(card->dma);
kfree(card); b1_free_card(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -1124,51 +1107,40 @@ static int c4_read_proc(char *page, char **start, off_t off, ...@@ -1124,51 +1107,40 @@ static int c4_read_proc(char *page, char **start, off_t off,
static int c4_add_card(struct capi_driver *driver, static int c4_add_card(struct capi_driver *driver,
struct capicardparams *p, struct capicardparams *p,
struct pci_dev *dev, struct pci_dev *dev,
int nr) int nr_controllers)
{ {
avmctrl_info *cinfo;
avmcard *card; avmcard *card;
avmctrl_info *cinfo;
int retval; int retval;
int i; int i;
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
retval = -ENOMEM; card = b1_alloc_card(nr_controllers);
card = kmalloc(sizeof(avmcard), GFP_ATOMIC);
if (!card) { if (!card) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
retval = -ENOMEM;
goto err; goto err;
} }
memset(card, 0, sizeof(avmcard));
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);
goto err_kfree; retval = -ENOMEM;
} goto err_free;
cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info)*4, GFP_ATOMIC);
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
goto err_dma_free;
}
memset(cinfo, 0, sizeof(avmctrl_info)*4);
card->ctrlinfo = cinfo;
for (i=0; i < 4; i++) {
cinfo = &card->ctrlinfo[i];
cinfo->card = card;
} }
sprintf(card->name, "%s-%x", driver->name, p->port); sprintf(card->name, "%s-%x", driver->name, p->port);
card->port = p->port; card->port = p->port;
card->irq = p->irq; card->irq = p->irq;
card->membase = p->membase; card->membase = p->membase;
card->cardtype = nr == 4 ? avm_c4 : avm_c2; card->cardtype = (nr_controllers == 4) ? avm_c4 : avm_c2;
if (!request_region(card->port, AVMB1_PORTLEN, card->name)) { if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
printk(KERN_WARNING printk(KERN_WARNING
"%s: ports 0x%03x-0x%03x in use.\n", "%s: ports 0x%03x-0x%03x in use.\n",
driver->name, card->port, card->port + AVMB1_PORTLEN); driver->name, card->port, card->port + AVMB1_PORTLEN);
retval = -EBUSY; retval = -EBUSY;
goto err_kfree_ctrlinfo; goto err_free_dma;
} }
card->mbase = ioremap_nocache(card->membase, 128); card->mbase = ioremap_nocache(card->membase, 128);
...@@ -1196,9 +1168,8 @@ static int c4_add_card(struct capi_driver *driver, ...@@ -1196,9 +1168,8 @@ static int c4_add_card(struct capi_driver *driver,
goto err_unmap; goto err_unmap;
} }
for (i=0; i < nr ; i++) { for (i=0; i < nr_controllers ; i++) {
cinfo = &card->ctrlinfo[i]; cinfo = &card->ctrlinfo[i];
cinfo->card = card;
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed (%d).\n", printk(KERN_ERR "%s: attach controller failed (%d).\n",
...@@ -1213,9 +1184,9 @@ static int c4_add_card(struct capi_driver *driver, ...@@ -1213,9 +1184,9 @@ static int c4_add_card(struct capi_driver *driver,
card->cardnr = cinfo->capi_ctrl->cnr; card->cardnr = cinfo->capi_ctrl->cnr;
} }
printk(KERN_INFO printk(KERN_INFO "%s: AVM C%d at i/o %#x, irq %d, mem %#lx\n",
"%s: AVM C%d at i/o %#x, irq %d, mem %#lx\n", driver->name, nr_controllers, card->port, card->irq,
driver->name, nr, card->port, card->irq, card->membase); card->membase);
return 0; return 0;
...@@ -1225,12 +1196,10 @@ static int c4_add_card(struct capi_driver *driver, ...@@ -1225,12 +1196,10 @@ static int c4_add_card(struct capi_driver *driver,
iounmap(card->mbase); iounmap(card->mbase);
err_release_region: err_release_region:
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
err_kfree_ctrlinfo: err_free_dma:
kfree(card->ctrlinfo);
err_dma_free:
avmcard_dma_free(card->dma); avmcard_dma_free(card->dma);
err_kfree: err_free:
kfree(card); b1_free_card(card);
err: err:
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
......
...@@ -128,8 +128,9 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr) ...@@ -128,8 +128,9 @@ static int t1_detectandinit(unsigned int base, unsigned irq, int cardnr)
return 0; return 0;
} }
static void t1_handle_interrupt(avmcard * card) static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{ {
avmcard *card = devptr;
avmctrl_info *cinfo = &card->ctrlinfo[0]; avmctrl_info *cinfo = &card->ctrlinfo[0];
struct capi_ctr *ctrl = cinfo->capi_ctrl; struct capi_ctr *ctrl = cinfo->capi_ctrl;
unsigned char b1cmd; unsigned char b1cmd;
...@@ -261,30 +262,6 @@ static void t1_handle_interrupt(avmcard * card) ...@@ -261,30 +262,6 @@ static void t1_handle_interrupt(avmcard * card)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{
avmcard *card;
card = (avmcard *) devptr;
if (!card) {
printk(KERN_WARNING "t1isa: interrupt: wrong device\n");
return;
}
if (card->interrupt) {
printk(KERN_ERR "%s: reentering interrupt hander.\n",
card->name);
return;
}
card->interrupt = 1;
t1_handle_interrupt(card);
card->interrupt = 0;
}
/* ------------------------------------------------------------- */
static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) static int t1isa_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
{ {
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
...@@ -357,8 +334,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl) ...@@ -357,8 +334,7 @@ static void t1isa_remove_ctr(struct capi_ctr *ctrl)
di->detach_ctr(ctrl); di->detach_ctr(ctrl);
free_irq(card->irq, card); free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
kfree(card->ctrlinfo); b1_free_card(card);
kfree(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -374,24 +350,14 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -374,24 +350,14 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
card = (avmcard *) kmalloc(sizeof(avmcard), GFP_ATOMIC); card = b1_alloc_card(1);
if (!card) { if (!card) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
MOD_DEC_USE_COUNT; retval = -ENOMEM;
return -ENOMEM; goto err;
}
memset(card, 0, sizeof(avmcard));
cinfo = (avmctrl_info *) kmalloc(sizeof(avmctrl_info), GFP_ATOMIC);
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
kfree(card);
MOD_DEC_USE_COUNT;
return -ENOMEM;
} }
memset(cinfo, 0, sizeof(avmctrl_info));
card->ctrlinfo = cinfo; cinfo = card->ctrlinfo;
cinfo->card = card;
sprintf(card->name, "t1isa-%x", p->port); sprintf(card->name, "t1isa-%x", p->port);
card->port = p->port; card->port = p->port;
card->irq = p->irq; card->irq = p->irq;
...@@ -401,74 +367,53 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -401,74 +367,53 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) { if (!(((card->port & 0x7) == 0) && ((card->port & 0x30) != 0x30))) {
printk(KERN_WARNING "%s: illegal port 0x%x.\n", printk(KERN_WARNING "%s: illegal port 0x%x.\n",
driver->name, card->port); driver->name, card->port);
kfree(card->ctrlinfo); retval = -EINVAL;
kfree(card); goto err_free;
MOD_DEC_USE_COUNT;
return -EINVAL;
}
if (check_region(card->port, AVMB1_PORTLEN)) {
printk(KERN_WARNING
"%s: ports 0x%03x-0x%03x in use.\n",
driver->name, card->port, card->port + AVMB1_PORTLEN);
kfree(card->ctrlinfo);
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
if (hema_irq_table[card->irq & 0xf] == 0) { if (hema_irq_table[card->irq & 0xf] == 0) {
printk(KERN_WARNING "%s: irq %d not valid.\n", printk(KERN_WARNING "%s: irq %d not valid.\n",
driver->name, card->irq); driver->name, card->irq);
kfree(card->ctrlinfo); retval = -EINVAL;
kfree(card); goto err_free;
MOD_DEC_USE_COUNT;
return -EINVAL;
} }
for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) { for (ctrl = driver->controller; ctrl; ctrl = ctrl->next) {
avmcard *cardp = ((avmctrl_info *)(ctrl->driverdata))->card; avmcard *cardp = ((avmctrl_info *)(ctrl->driverdata))->card;
if (cardp->cardnr == card->cardnr) { if (cardp->cardnr == card->cardnr) {
printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n", printk(KERN_WARNING "%s: card with number %d already installed at 0x%x.\n",
driver->name, card->cardnr, cardp->port); driver->name, card->cardnr, cardp->port);
kfree(card->ctrlinfo); retval = -EINVAL;
kfree(card); goto err_free;
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
} }
if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) { if (!request_region(card->port, AVMB1_PORTLEN, card->name)) {
printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n", printk(KERN_WARNING "%s: ports 0x%03x-0x%03x in use.\n",
driver->name, card->port, retval); driver->name, card->port, card->port + AVMB1_PORTLEN);
kfree(card->ctrlinfo); retval = -EBUSY;
kfree(card); goto err_free;
MOD_DEC_USE_COUNT;
return -EIO;
} }
t1_disable_irq(card->port);
b1_reset(card->port);
request_region(p->port, AVMB1_PORTLEN, card->name);
retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card); retval = request_irq(card->irq, t1isa_interrupt, 0, card->name, card);
if (retval) { if (retval) {
printk(KERN_ERR "%s: unable to get IRQ %d.\n", printk(KERN_ERR "%s: unable to get IRQ %d.\n",
driver->name, card->irq); driver->name, card->irq);
release_region(card->port, AVMB1_PORTLEN); retval = -EBUSY;
kfree(card->ctrlinfo); goto err_release_region;
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
if ((retval = t1_detectandinit(card->port, card->irq, card->cardnr)) != 0) {
printk(KERN_NOTICE "%s: NO card at 0x%x (%d)\n",
driver->name, card->port, retval);
retval = -ENODEV;
goto err_free_irq;
}
t1_disable_irq(card->port);
b1_reset(card->port);
cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo); cinfo->capi_ctrl = di->attach_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) { if (!cinfo->capi_ctrl) {
printk(KERN_ERR "%s: attach controller failed.\n", printk(KERN_ERR "%s: attach controller failed.\n",
driver->name); driver->name);
free_irq(card->irq, card); retval = -EBUSY;
release_region(card->port, AVMB1_PORTLEN); goto err_free_irq;
kfree(card->ctrlinfo);
kfree(card);
MOD_DEC_USE_COUNT;
return -EBUSY;
} }
printk(KERN_INFO printk(KERN_INFO
...@@ -476,6 +421,16 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p) ...@@ -476,6 +421,16 @@ static int t1isa_add_card(struct capi_driver *driver, struct capicardparams *p)
driver->name, card->port, card->irq, card->cardnr); driver->name, card->port, card->irq, card->cardnr);
return 0; return 0;
err_free_irq:
free_irq(card->irq, card);
err_release_region:
release_region(card->port, AVMB1_PORTLEN);
err_free:
b1_free_card(card);
err:
MOD_DEC_USE_COUNT;
return retval;
} }
static void t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) static void t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
......
...@@ -59,26 +59,21 @@ static int t1pci_add_card(struct capi_driver *driver, ...@@ -59,26 +59,21 @@ static int t1pci_add_card(struct capi_driver *driver,
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
retval = -ENOMEM; card = b1_alloc_card(1);
card = kmalloc(sizeof(avmcard), GFP_KERNEL);
if (!card) { if (!card) {
printk(KERN_WARNING "%s: no memory.\n", driver->name); printk(KERN_WARNING "%s: no memory.\n", driver->name);
retval = -ENOMEM;
goto err; goto err;
} }
memset(card, 0, sizeof(avmcard));
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);
goto err_kfree; retval = -ENOMEM;
} goto err_free;
cinfo = kmalloc(sizeof(avmctrl_info), GFP_KERNEL);
if (!cinfo) {
printk(KERN_WARNING "%s: no memory.\n", driver->name);
goto err_dma_free;
} }
memset(cinfo, 0, sizeof(avmctrl_info));
card->ctrlinfo = cinfo; cinfo = card->ctrlinfo;
cinfo->card = card;
sprintf(card->name, "t1pci-%x", p->port); sprintf(card->name, "t1pci-%x", p->port);
card->port = p->port; card->port = p->port;
card->irq = p->irq; card->irq = p->irq;
...@@ -90,7 +85,7 @@ static int t1pci_add_card(struct capi_driver *driver, ...@@ -90,7 +85,7 @@ static int t1pci_add_card(struct capi_driver *driver,
"%s: ports 0x%03x-0x%03x in use.\n", "%s: ports 0x%03x-0x%03x in use.\n",
driver->name, card->port, card->port + AVMB1_PORTLEN); driver->name, card->port, card->port + AVMB1_PORTLEN);
retval = -EBUSY; retval = -EBUSY;
goto err_kfree_ctrlinfo; goto err_free_dma;
} }
card->mbase = ioremap_nocache(card->membase, 64); card->mbase = ioremap_nocache(card->membase, 64);
...@@ -144,12 +139,10 @@ static int t1pci_add_card(struct capi_driver *driver, ...@@ -144,12 +139,10 @@ static int t1pci_add_card(struct capi_driver *driver,
iounmap(card->mbase); iounmap(card->mbase);
err_release_region: err_release_region:
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
err_kfree_ctrlinfo: err_free_dma:
kfree(card->ctrlinfo);
err_dma_free:
avmcard_dma_free(card->dma); avmcard_dma_free(card->dma);
err_kfree: err_free:
kfree(card); b1_free_card(card);
err: err:
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return retval; return retval;
...@@ -169,9 +162,8 @@ static void t1pci_remove_ctr(struct capi_ctr *ctrl) ...@@ -169,9 +162,8 @@ static void t1pci_remove_ctr(struct capi_ctr *ctrl)
iounmap(card->mbase); iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN); release_region(card->port, AVMB1_PORTLEN);
ctrl->driverdata = 0; ctrl->driverdata = 0;
kfree(card->ctrlinfo);
avmcard_dma_free(card->dma); avmcard_dma_free(card->dma);
kfree(card); b1_free_card(card);
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
......
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