diff options
Diffstat (limited to 'drivers/isdn/hisax/config.c')
-rw-r--r-- | drivers/isdn/hisax/config.c | 245 |
1 files changed, 145 insertions, 100 deletions
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 8d53a7fd267..97097ef3491 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -361,11 +361,11 @@ module_param_array(io1, int, NULL, 0); int nrcards; -extern char *l1_revision; -extern char *l2_revision; -extern char *l3_revision; -extern char *lli_revision; -extern char *tei_revision; +extern const char *l1_revision; +extern const char *l2_revision; +extern const char *l3_revision; +extern const char *lli_revision; +extern const char *tei_revision; char *HiSax_getrev(const char *revision) { @@ -847,95 +847,10 @@ static int init_card(struct IsdnCardState *cs) return 3; } -static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockowner) +static int hisax_cs_setup_card(struct IsdnCard *card) { - int ret = 0; - struct IsdnCard *card = cards + cardnr; - struct IsdnCardState *cs; - - cs = kzalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); - if (!cs) { - printk(KERN_WARNING - "HiSax: No memory for IsdnCardState(card %d)\n", - cardnr + 1); - goto out; - } - card->cs = cs; - spin_lock_init(&cs->statlock); - spin_lock_init(&cs->lock); - cs->chanlimit = 2; /* maximum B-channel number */ - cs->logecho = 0; /* No echo logging */ - cs->cardnr = cardnr; - cs->debug = L1_DEB_WARN; - cs->HW_Flags = 0; - cs->busy_flag = busy_flag; - cs->irq_flags = I4L_IRQ_FLAG; -#if TEI_PER_CARD - if (card->protocol == ISDN_PTYPE_NI1) - test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); -#else - test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); -#endif - cs->protocol = card->protocol; - - if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) { - printk(KERN_WARNING - "HiSax: Card Type %d out of range\n", card->typ); - goto outf_cs; - } - if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for dlog(card %d)\n", cardnr + 1); - goto outf_cs; - } - if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { - printk(KERN_WARNING - "HiSax: No memory for status_buf(card %d)\n", - cardnr + 1); - goto outf_dlog; - } - cs->stlist = NULL; - cs->status_read = cs->status_buf; - cs->status_write = cs->status_buf; - cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; - cs->typ = card->typ; -#ifdef MODULE - cs->iif.owner = lockowner; -#endif - strcpy(cs->iif.id, id); - cs->iif.channels = 2; - cs->iif.maxbufsize = MAX_DATA_SIZE; - cs->iif.hl_hdrlen = MAX_HEADER_LEN; - cs->iif.features = - ISDN_FEATURE_L2_X75I | - ISDN_FEATURE_L2_HDLC | - ISDN_FEATURE_L2_HDLC_56K | - ISDN_FEATURE_L2_TRANS | - ISDN_FEATURE_L3_TRANS | -#ifdef CONFIG_HISAX_1TR6 - ISDN_FEATURE_P_1TR6 | -#endif -#ifdef CONFIG_HISAX_EURO - ISDN_FEATURE_P_EURO | -#endif -#ifdef CONFIG_HISAX_NI1 - ISDN_FEATURE_P_NI1 | -#endif - 0; + int ret; - cs->iif.command = HiSax_command; - cs->iif.writecmd = NULL; - cs->iif.writebuf_skb = HiSax_writebuf_skb; - cs->iif.readstat = HiSax_readstatus; - register_isdn(&cs->iif); - cs->myid = cs->iif.channels; - printk(KERN_INFO - "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, - (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : - (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : - (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : - (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : - "NONE", cs->iif.id, cs->myid); switch (card->typ) { #if CARD_TELES0 case ISDN_CTYPE_16_0: @@ -1094,13 +1009,115 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow printk(KERN_WARNING "HiSax: Support for %s Card not selected\n", CardType[card->typ]); - ll_unload(cs); + ret = 0; + break; + } + + return ret; +} + +static int hisax_cs_new(int cardnr, char *id, struct IsdnCard *card, + struct IsdnCardState **cs_out, int *busy_flag, + struct module *lockowner) +{ + struct IsdnCardState *cs; + + *cs_out = NULL; + + cs = kzalloc(sizeof(struct IsdnCardState), GFP_ATOMIC); + if (!cs) { + printk(KERN_WARNING + "HiSax: No memory for IsdnCardState(card %d)\n", + cardnr + 1); + goto out; + } + card->cs = cs; + spin_lock_init(&cs->statlock); + spin_lock_init(&cs->lock); + cs->chanlimit = 2; /* maximum B-channel number */ + cs->logecho = 0; /* No echo logging */ + cs->cardnr = cardnr; + cs->debug = L1_DEB_WARN; + cs->HW_Flags = 0; + cs->busy_flag = busy_flag; + cs->irq_flags = I4L_IRQ_FLAG; +#if TEI_PER_CARD + if (card->protocol == ISDN_PTYPE_NI1) + test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); +#else + test_and_set_bit(FLG_TWO_DCHAN, &cs->HW_Flags); +#endif + cs->protocol = card->protocol; + + if (card->typ <= 0 || card->typ > ISDN_CTYPE_COUNT) { + printk(KERN_WARNING + "HiSax: Card Type %d out of range\n", card->typ); goto outf_cs; } - if (!ret) { - ll_unload(cs); + if (!(cs->dlog = kmalloc(MAX_DLOG_SPACE, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for dlog(card %d)\n", cardnr + 1); goto outf_cs; } + if (!(cs->status_buf = kmalloc(HISAX_STATUS_BUFSIZE, GFP_ATOMIC))) { + printk(KERN_WARNING + "HiSax: No memory for status_buf(card %d)\n", + cardnr + 1); + goto outf_dlog; + } + cs->stlist = NULL; + cs->status_read = cs->status_buf; + cs->status_write = cs->status_buf; + cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1; + cs->typ = card->typ; +#ifdef MODULE + cs->iif.owner = lockowner; +#endif + strcpy(cs->iif.id, id); + cs->iif.channels = 2; + cs->iif.maxbufsize = MAX_DATA_SIZE; + cs->iif.hl_hdrlen = MAX_HEADER_LEN; + cs->iif.features = + ISDN_FEATURE_L2_X75I | + ISDN_FEATURE_L2_HDLC | + ISDN_FEATURE_L2_HDLC_56K | + ISDN_FEATURE_L2_TRANS | + ISDN_FEATURE_L3_TRANS | +#ifdef CONFIG_HISAX_1TR6 + ISDN_FEATURE_P_1TR6 | +#endif +#ifdef CONFIG_HISAX_EURO + ISDN_FEATURE_P_EURO | +#endif +#ifdef CONFIG_HISAX_NI1 + ISDN_FEATURE_P_NI1 | +#endif + 0; + + cs->iif.command = HiSax_command; + cs->iif.writecmd = NULL; + cs->iif.writebuf_skb = HiSax_writebuf_skb; + cs->iif.readstat = HiSax_readstatus; + register_isdn(&cs->iif); + cs->myid = cs->iif.channels; + + *cs_out = cs; + return 1; /* success */ + +outf_dlog: + kfree(cs->dlog); +outf_cs: + kfree(cs); + card->cs = NULL; +out: + return 0; /* error */ +} + +static int hisax_cs_setup(int cardnr, struct IsdnCard *card, + struct IsdnCardState *cs) +{ + int ret; + if (!(cs->rcvbuf = kmalloc(MAX_DFRAME_LEN_L1, GFP_ATOMIC))) { printk(KERN_WARNING "HiSax: No memory for isac rcvbuf\n"); ll_unload(cs); @@ -1129,25 +1146,53 @@ static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockow } if (ret) { closecard(cardnr); - ret = 0; goto outf_cs; } init_tei(cs, cs->protocol); ret = CallcNewChan(cs); if (ret) { closecard(cardnr); - ret = 0; goto outf_cs; } /* ISAR needs firmware download first */ if (!test_bit(HW_ISAR, &cs->HW_Flags)) ll_run(cs, 0); - ret = 1; + return 1; + +outf_cs: + kfree(cs); + card->cs = NULL; + return 0; +} + +static int checkcard(int cardnr, char *id, int *busy_flag, struct module *lockowner) +{ + int ret; + struct IsdnCard *card = cards + cardnr; + struct IsdnCardState *cs; + + ret = hisax_cs_new(cardnr, id, card, &cs, busy_flag, lockowner); + if (!ret) + return 0; + + printk(KERN_INFO + "HiSax: Card %d Protocol %s Id=%s (%d)\n", cardnr + 1, + (card->protocol == ISDN_PTYPE_1TR6) ? "1TR6" : + (card->protocol == ISDN_PTYPE_EURO) ? "EDSS1" : + (card->protocol == ISDN_PTYPE_LEASED) ? "LEASED" : + (card->protocol == ISDN_PTYPE_NI1) ? "NI1" : + "NONE", cs->iif.id, cs->myid); + + ret = hisax_cs_setup_card(card); + if (!ret) { + ll_unload(cs); + goto outf_cs; + } + + ret = hisax_cs_setup(cardnr, card, cs); goto out; - outf_dlog: - kfree(cs->dlog); outf_cs: kfree(cs); card->cs = NULL; |