Commit 664fd502 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/CAPI: Have hardware driver alloc struct capi_drv

The hardware driver needs to alloc mem anyway, and now can
fill in fields before registering with the CAPI layer.

Basically the same way struct net_device is handled.
parent b6e4a415
......@@ -434,33 +434,28 @@ static void controllercb_resume_output(struct capi_ctr *card)
/* ------------------------------------------------------------- */
struct capi_ctr *
attach_capi_ctr(struct capi_driver *driver, char *name, void *driverdata)
int
attach_capi_ctr(struct capi_ctr *card)
{
struct capi_ctr *card;
int i;
for (i=0; i < CAPI_MAXCONTR; i++) {
for (i = 0; i < CAPI_MAXCONTR; i++) {
if (capi_cards[i] == NULL)
break;
}
if (i == CAPI_MAXCONTR) {
printk(KERN_ERR "kcapi: out of controller slots\n");
return NULL;
return -EBUSY;
}
card = kmalloc(sizeof(*card), GFP_KERNEL);
if (!card)
return NULL;
capi_cards[i] = card;
memset(card, 0, sizeof(struct capi_ctr));
card->driver = driver;
card->nrecvctlpkt = 0;
card->nrecvdatapkt = 0;
card->nsentctlpkt = 0;
card->nsentdatapkt = 0;
card->cnr = i + 1;
strncpy(card->name, name, sizeof(card->name));
card->cardstate = CARD_DETECTED;
card->blocked = 0;
card->driverdata = driverdata;
card->traceflag = showcapimsgs;
card->ready = controllercb_ready;
......@@ -469,21 +464,21 @@ attach_capi_ctr(struct capi_driver *driver, char *name, void *driverdata)
card->resume_output = controllercb_resume_output;
card->handle_capimsg = controllercb_handle_capimsg;
list_add_tail(&card->driver_list, &driver->contr_head);
driver->ncontroller++;
list_add_tail(&card->driver_list, &card->driver->contr_head);
card->driver->ncontroller++;
sprintf(card->procfn, "capi/controllers/%d", card->cnr);
card->procent = create_proc_entry(card->procfn, 0, 0);
if (card->procent) {
card->procent->read_proc =
(int (*)(char *,char **,off_t,int,int *,void *))
driver->ctr_read_proc;
card->driver->ctr_read_proc;
card->procent->data = card;
}
ncards++;
printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n",
card->cnr, card->name);
return card;
return 0;
}
EXPORT_SYMBOL(attach_capi_ctr);
......
......@@ -67,7 +67,7 @@ typedef struct avmctrl_info {
char infobuf[128]; /* for function procinfo */
struct avmcard *card;
struct capi_ctr *capi_ctrl;
struct capi_ctr capi_ctrl;
struct list_head ncci_head;
} avmctrl_info;
......@@ -93,6 +93,7 @@ typedef struct avmcard {
struct avmctrl_info *ctrlinfo;
int nr_controllers;
int nlogcontr;
} avmcard;
......
......@@ -99,6 +99,7 @@ avmcard *b1_alloc_card(int nr_controllers)
cinfo[i].card = card;
}
spin_lock_init(&card->lock);
card->nr_controllers = nr_controllers;
return card;
}
......@@ -433,7 +434,7 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
void b1_parse_version(avmctrl_info *cinfo)
{
struct capi_ctr *ctrl = cinfo->capi_ctrl;
struct capi_ctr *ctrl = &cinfo->capi_ctrl;
avmcard *card = cinfo->card;
capi_profile *profp;
u8 *dversion;
......@@ -509,7 +510,7 @@ void b1_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{
avmcard *card = devptr;
avmctrl_info *cinfo = &card->ctrlinfo[0];
struct capi_ctr *ctrl = cinfo->capi_ctrl;
struct capi_ctr *ctrl = &cinfo->capi_ctrl;
unsigned char b1cmd;
struct sk_buff *skb;
......
......@@ -447,7 +447,7 @@ static void b1dma_handle_rx(avmcard *card)
{
avmctrl_info *cinfo = &card->ctrlinfo[0];
avmcard_dmainfo *dma = card->dma;
struct capi_ctr *ctrl = cinfo->capi_ctrl;
struct capi_ctr *ctrl = &cinfo->capi_ctrl;
struct sk_buff *skb;
void *p = dma->recvbuf.dmabuf+4;
u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
......
......@@ -46,7 +46,7 @@ static void b1isa_remove(struct pci_dev *pdev)
b1_reset(port);
b1_reset(port);
detach_capi_ctr(cinfo->capi_ctrl);
detach_capi_ctr(&cinfo->capi_ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card);
......@@ -106,10 +106,12 @@ static int __init b1isa_probe(struct pci_dev *pdev)
b1_reset(card->port);
b1_getrevision(card);
cinfo->capi_ctrl = attach_capi_ctr(&b1isa_driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = &b1isa_driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "b1isa: attach controller failed.\n");
retval = -EBUSY;
goto err_free_irq;
}
......
......@@ -107,11 +107,13 @@ static int b1pci_probe(struct capi_driver *driver,
goto err_release_region;
}
cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "%s: attach controller failed.\n",
driver->name);
retval = -EBUSY;
goto err_free_irq;
}
......@@ -147,7 +149,7 @@ static void b1pci_remove(struct pci_dev *pdev)
b1_reset(port);
b1_reset(port);
detach_capi_ctr(cinfo->capi_ctrl);
detach_capi_ctr(&cinfo->capi_ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card);
......@@ -256,13 +258,15 @@ static int b1pciv4_probe(struct capi_driver *driver,
goto err_unmap;
}
cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
retval = -EBUSY;
goto err_free_irq;
}
card->cardnr = cinfo->capi_ctrl->cnr;
card->cardnr = cinfo->capi_ctrl.cnr;
printk(KERN_INFO
"%s: AVM B1 PCI V4 at i/o %#x, irq %d, mem %#lx, revision %d (dma)\n",
......@@ -294,7 +298,7 @@ static void b1pciv4_remove(struct pci_dev *pdev)
b1dma_reset(card);
detach_capi_ctr(cinfo->capi_ctrl);
detach_capi_ctr(&cinfo->capi_ctrl);
free_irq(card->irq, card);
iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN);
......
......@@ -95,11 +95,13 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
b1_reset(card->port);
b1_getrevision(card);
cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "%s: attach controller failed.\n",
driver->name);
retval = -EBUSY;
goto err_free_irq;
}
switch (cardtype) {
......@@ -112,7 +114,7 @@ static int b1pcmcia_add_card(struct capi_driver *driver,
"%s: AVM %s at i/o %#x, irq %d, revision %d\n",
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);
......
......@@ -523,7 +523,7 @@ static void c4_handle_rx(avmcard *card)
DataB3Len = _get_slice(&p, card->databuf);
cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;
if (cidx >= card->nlogcontr) cidx = 0;
ctrl = card->ctrlinfo[cidx].capi_ctrl;
ctrl = &card->ctrlinfo[cidx].capi_ctrl;
if (MsgLen < 30) { /* not CAPI 64Bit */
memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
......@@ -547,7 +547,7 @@ static void c4_handle_rx(avmcard *card)
cidx = CAPIMSG_CONTROLLER(card->msgbuf)-card->cardnr;
if (cidx >= card->nlogcontr) cidx = 0;
cinfo = &card->ctrlinfo[cidx];
ctrl = card->ctrlinfo[cidx].capi_ctrl;
ctrl = &card->ctrlinfo[cidx].capi_ctrl;
if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
printk(KERN_ERR "%s: incoming packet dropped\n",
......@@ -593,16 +593,16 @@ static void c4_handle_rx(avmcard *card)
#endif
if (!suppress_pollack)
queue_pollack(card);
for (cidx=0; cidx < 4; cidx++) {
ctrl = card->ctrlinfo[cidx].capi_ctrl;
for (cidx=0; cidx < card->nr_controllers; cidx++) {
ctrl = &card->ctrlinfo[cidx].capi_ctrl;
if (ctrl)
ctrl->resume_output(ctrl);
}
break;
case RECEIVE_STOP:
for (cidx=0; cidx < 4; cidx++) {
ctrl = card->ctrlinfo[cidx].capi_ctrl;
for (cidx=0; cidx < card->nr_controllers; cidx++) {
ctrl = &card->ctrlinfo[cidx].capi_ctrl;
if (ctrl)
ctrl->suspend_output(ctrl);
}
......@@ -611,21 +611,21 @@ static void c4_handle_rx(avmcard *card)
case RECEIVE_INIT:
cidx = card->nlogcontr;
if (cidx >= 4 || !card->ctrlinfo[cidx].capi_ctrl) {
if (cidx >= card->nr_controllers) {
printk(KERN_ERR "%s: card with %d controllers ??\n",
card->name, cidx+1);
break;
}
card->nlogcontr++;
cinfo = &card->ctrlinfo[cidx];
ctrl = cinfo->capi_ctrl;
ctrl = &cinfo->capi_ctrl;
cinfo->versionlen = _get_slice(&p, cinfo->versionbuf);
b1_parse_version(cinfo);
printk(KERN_INFO "%s: %s-card (%s) now active\n",
card->name,
cinfo->version[VER_CARDTYPE],
cinfo->version[VER_DRIVER]);
ctrl->ready(cinfo->capi_ctrl);
ctrl->ready(&cinfo->capi_ctrl);
break;
case RECEIVE_TASK_READY:
......@@ -673,12 +673,11 @@ static void c4_handle_interrupt(avmcard *card)
if (card->nlogcontr == 0)
return;
printk(KERN_ERR "%s: unexpected reset\n", card->name);
for (i=0; i < 4; i++) {
for (i=0; i < card->nr_controllers; i++) {
avmctrl_info *cinfo = &card->ctrlinfo[i];
memset(cinfo->version, 0, sizeof(cinfo->version));
capilib_release(&cinfo->ncci_head);
if (cinfo->capi_ctrl)
cinfo->capi_ctrl->reseted(cinfo->capi_ctrl);
cinfo->capi_ctrl.reseted(&cinfo->capi_ctrl);
}
card->nlogcontr = 0;
return;
......@@ -888,11 +887,10 @@ void c4_reset_ctr(struct capi_ctr *ctrl)
c4_reset(card);
for (i=0; i < 4; i++) {
for (i=0; i < card->nr_controllers; i++) {
cinfo = &card->ctrlinfo[i];
memset(cinfo->version, 0, sizeof(cinfo->version));
if (cinfo->capi_ctrl)
cinfo->capi_ctrl->reseted(cinfo->capi_ctrl);
cinfo->capi_ctrl.reseted(&cinfo->capi_ctrl);
}
card->nlogcontr = 0;
}
......@@ -905,12 +903,9 @@ static void c4_remove(struct pci_dev *pdev)
c4_reset(card);
for (i=0; i < 4; i++) {
for (i=0; i < card->nr_controllers; i++) {
cinfo = &card->ctrlinfo[i];
if (cinfo->capi_ctrl) {
detach_capi_ctr(cinfo->capi_ctrl);
cinfo->capi_ctrl = NULL;
}
detach_capi_ctr(&cinfo->capi_ctrl);
}
free_irq(card->irq, card);
......@@ -1168,22 +1163,25 @@ static int c4_add_card(struct capi_driver *driver,
for (i=0; i < nr_controllers ; i++) {
cinfo = &card->ctrlinfo[i];
cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "%s: attach controller failed (%d).\n",
driver->name, i);
for (i--; i >= 0; i--) {
cinfo = &card->ctrlinfo[i];
detach_capi_ctr(cinfo->capi_ctrl);
detach_capi_ctr(&cinfo->capi_ctrl);
}
goto err_free_irq;
}
if (i == 0)
card->cardnr = cinfo->capi_ctrl->cnr;
card->cardnr = cinfo->capi_ctrl.cnr;
}
printk(KERN_INFO "%s: AVM C%d at i/o %#x, irq %d, mem %#lx\n",
driver->name, nr_controllers, card->port, card->irq,
driver->name, nr_controllers, card->port, card->irq,
card->membase);
return 0;
......
......@@ -132,7 +132,7 @@ static void t1isa_interrupt(int interrupt, void *devptr, struct pt_regs *regs)
{
avmcard *card = devptr;
avmctrl_info *cinfo = &card->ctrlinfo[0];
struct capi_ctr *ctrl = cinfo->capi_ctrl;
struct capi_ctr *ctrl = &cinfo->capi_ctrl;
unsigned char b1cmd;
struct sk_buff *skb;
......@@ -337,7 +337,7 @@ static void t1isa_remove(struct pci_dev *pdev)
b1_reset(port);
t1_reset(port);
detach_capi_ctr(cinfo->capi_ctrl);
detach_capi_ctr(&cinfo->capi_ctrl);
free_irq(card->irq, card);
release_region(card->port, AVMB1_PORTLEN);
b1_free_card(card);
......@@ -400,11 +400,13 @@ static int __init t1isa_probe(struct pci_dev *pdev, int cardnr)
t1_disable_irq(card->port);
b1_reset(card->port);
cinfo->capi_ctrl = attach_capi_ctr(&t1isa_driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = &t1isa_driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_INFO "%s: attach controller failed.\n",
t1isa_driver.name);
retval = -EBUSY;
goto err_free_irq;
}
......
......@@ -113,13 +113,16 @@ static int t1pci_add_card(struct capi_driver *driver,
goto err_unmap;
}
cinfo->capi_ctrl = attach_capi_ctr(driver, card->name, cinfo);
if (!cinfo->capi_ctrl) {
cinfo->capi_ctrl.driver = driver;
cinfo->capi_ctrl.driverdata = cinfo;
strcpy(cinfo->capi_ctrl.name, card->name);
retval = attach_capi_ctr(&cinfo->capi_ctrl);
if (retval) {
printk(KERN_ERR "%s: attach controller failed.\n", driver->name);
retval = -EBUSY;
goto err_free_irq;
}
card->cardnr = cinfo->capi_ctrl->cnr;
card->cardnr = cinfo->capi_ctrl.cnr;
printk(KERN_INFO
"%s: AVM T1 PCI at i/o %#x, irq %d, mem %#lx\n",
......@@ -151,7 +154,7 @@ static void t1pci_remove(struct pci_dev *pdev)
b1dma_reset(card);
detach_capi_ctr(cinfo->capi_ctrl);
detach_capi_ctr(&cinfo->capi_ctrl);
free_irq(card->irq, card);
iounmap(card->mbase);
release_region(card->port, AVMB1_PORTLEN);
......
......@@ -98,7 +98,7 @@ struct capi_driver {
void attach_capi_driver(struct capi_driver *driver);
void detach_capi_driver(struct capi_driver *driver);
struct capi_ctr *attach_capi_ctr(struct capi_driver *driver, char *name, void *data);
int attach_capi_ctr(struct capi_ctr *);
int detach_capi_ctr(struct capi_ctr *);
......
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