config.c
来自「linux 内核源代码」· C语言 代码 · 共 1,979 行 · 第 1/4 页
C
1,979 行
case ISDN_CTYPE_W6692: ret = setup_w6692(card); break;#endif#if CARD_NETJET_U case ISDN_CTYPE_NETJET_U: ret = setup_netjet_u(card); break;#endif#if CARD_FN_ENTERNOW_PCI case ISDN_CTYPE_ENTERNOW: ret = setup_enternow_pci(card); break;#endif case ISDN_CTYPE_DYNAMIC: ret = 2; break; default: printk(KERN_WARNING "HiSax: Support for %s Card not selected\n", CardType[card->typ]); 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 (!(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); goto outf_cs; } cs->rcvidx = 0; cs->tx_skb = NULL; cs->tx_cnt = 0; cs->event = 0; skb_queue_head_init(&cs->rq); skb_queue_head_init(&cs->sq); init_bcstate(cs, 0); init_bcstate(cs, 1); /* init_card only handles interrupts which are not */ /* used here for the loadable driver */ switch (card->typ) { case ISDN_CTYPE_DYNAMIC: ret = 0; break; default: ret = init_card(cs); break; } if (ret) { closecard(cardnr); goto outf_cs; } init_tei(cs, cs->protocol); ret = CallcNewChan(cs); if (ret) { closecard(cardnr); goto outf_cs; } /* ISAR needs firmware download first */ if (!test_bit(HW_ISAR, &cs->HW_Flags)) ll_run(cs, 0); 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_cs: kfree(cs); card->cs = NULL; out: return ret;}static void HiSax_shiftcards(int idx){ int i; for (i = idx; i < (HISAX_MAX_CARDS - 1); i++) memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));}static int HiSax_inithardware(int *busy_flag){ int foundcards = 0; int i = 0; int t = ','; int flg = 0; char *id; char *next_id = HiSax_id; char ids[20]; if (strchr(HiSax_id, ',')) t = ','; else if (strchr(HiSax_id, '%')) t = '%'; while (i < nrcards) { if (cards[i].typ < 1) break; id = next_id; if ((next_id = strchr(id, t))) { *next_id++ = 0; strcpy(ids, id); flg = i + 1; } else { next_id = id; if (flg >= i) strcpy(ids, id); else sprintf(ids, "%s%d", id, i); } if (checkcard(i, ids, busy_flag, THIS_MODULE)) { foundcards++; i++; } else { /* make sure we don't oops the module */ if (cards[i].typ > 0 && cards[i].typ <= ISDN_CTYPE_COUNT) { printk(KERN_WARNING "HiSax: Card %s not installed !\n", CardType[cards[i].typ]); } HiSax_shiftcards(i); nrcards--; } } return foundcards;}void HiSax_closecard(int cardnr){ int i, last = nrcards - 1; if (cardnr > last || cardnr < 0) return; if (cards[cardnr].cs) { ll_stop(cards[cardnr].cs); release_tei(cards[cardnr].cs); CallcFreeChan(cards[cardnr].cs); closecard(cardnr); if (cards[cardnr].cs->irq) free_irq(cards[cardnr].cs->irq, cards[cardnr].cs); kfree((void *) cards[cardnr].cs); cards[cardnr].cs = NULL; } i = cardnr; while (i <= last) { cards[i] = cards[i + 1]; i++; } nrcards--;}void HiSax_reportcard(int cardnr, int sel){ struct IsdnCardState *cs = cards[cardnr].cs; printk(KERN_DEBUG "HiSax: reportcard No %d\n", cardnr + 1); printk(KERN_DEBUG "HiSax: Type %s\n", CardType[cs->typ]); printk(KERN_DEBUG "HiSax: debuglevel %x\n", cs->debug); printk(KERN_DEBUG "HiSax: HiSax_reportcard address 0x%lX\n", (ulong) & HiSax_reportcard); printk(KERN_DEBUG "HiSax: cs 0x%lX\n", (ulong) cs); printk(KERN_DEBUG "HiSax: HW_Flags %lx bc0 flg %lx bc1 flg %lx\n", cs->HW_Flags, cs->bcs[0].Flag, cs->bcs[1].Flag); printk(KERN_DEBUG "HiSax: bcs 0 mode %d ch%d\n", cs->bcs[0].mode, cs->bcs[0].channel); printk(KERN_DEBUG "HiSax: bcs 1 mode %d ch%d\n", cs->bcs[1].mode, cs->bcs[1].channel);#ifdef ERROR_STATISTIC printk(KERN_DEBUG "HiSax: dc errors(rx,crc,tx) %d,%d,%d\n", cs->err_rx, cs->err_crc, cs->err_tx); printk(KERN_DEBUG "HiSax: bc0 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n", cs->bcs[0].err_inv, cs->bcs[0].err_rdo, cs->bcs[0].err_crc, cs->bcs[0].err_tx); printk(KERN_DEBUG "HiSax: bc1 errors(inv,rdo,crc,tx) %d,%d,%d,%d\n", cs->bcs[1].err_inv, cs->bcs[1].err_rdo, cs->bcs[1].err_crc, cs->bcs[1].err_tx); if (sel == 99) { cs->err_rx = 0; cs->err_crc = 0; cs->err_tx = 0; cs->bcs[0].err_inv = 0; cs->bcs[0].err_rdo = 0; cs->bcs[0].err_crc = 0; cs->bcs[0].err_tx = 0; cs->bcs[1].err_inv = 0; cs->bcs[1].err_rdo = 0; cs->bcs[1].err_crc = 0; cs->bcs[1].err_tx = 0; }#endif}static int __init HiSax_init(void){ int i, retval;#ifdef MODULE int j; int nzproto = 0;#endif HiSaxVersion(); retval = CallcNew(); if (retval) goto out; retval = Isdnl3New(); if (retval) goto out_callc; retval = Isdnl2New(); if (retval) goto out_isdnl3; retval = TeiNew(); if (retval) goto out_isdnl2; retval = Isdnl1New(); if (retval) goto out_tei;#ifdef MODULE if (!type[0]) { /* We 'll register drivers later, but init basic functions */ for (i = 0; i < HISAX_MAX_CARDS; i++) cards[i].typ = 0; return 0; }#ifdef CONFIG_HISAX_ELSA if (type[0] == ISDN_CTYPE_ELSA_PCMCIA) { /* we have exported and return in this case */ return 0; }#endif#ifdef CONFIG_HISAX_SEDLBAUER if (type[0] == ISDN_CTYPE_SEDLBAUER_PCMCIA) { /* we have to export and return in this case */ return 0; }#endif#ifdef CONFIG_HISAX_AVM_A1_PCMCIA if (type[0] == ISDN_CTYPE_A1_PCMCIA) { /* we have to export and return in this case */ return 0; }#endif#ifdef CONFIG_HISAX_HFC_SX if (type[0] == ISDN_CTYPE_HFC_SP_PCMCIA) { /* we have to export and return in this case */ return 0; }#endif#endif nrcards = 0;#ifdef MODULE if (id) /* If id= string used */ HiSax_id = id; for (i = j = 0; j < HISAX_MAX_CARDS; i++) { cards[j].typ = type[i]; if (protocol[i]) { cards[j].protocol = protocol[i]; nzproto++; } else { cards[j].protocol = DEFAULT_PROTO; } switch (type[i]) { case ISDN_CTYPE_16_0: cards[j].para[0] = irq[i]; cards[j].para[1] = mem[i]; cards[j].para[2] = io[i]; break; case ISDN_CTYPE_8_0: cards[j].para[0] = irq[i]; cards[j].para[1] = mem[i]; break;#ifdef IO0_IO1 case ISDN_CTYPE_PNP: case ISDN_CTYPE_NICCY: cards[j].para[0] = irq[i]; cards[j].para[1] = io0[i]; cards[j].para[2] = io1[i]; break; case ISDN_CTYPE_COMPAQ_ISA: cards[j].para[0] = irq[i]; cards[j].para[1] = io0[i]; cards[j].para[2] = io1[i]; cards[j].para[3] = io[i]; break;#endif case ISDN_CTYPE_ELSA: case ISDN_CTYPE_HFC_PCI: cards[j].para[0] = io[i]; break; case ISDN_CTYPE_16_3: case ISDN_CTYPE_TELESPCMCIA: case ISDN_CTYPE_A1: case ISDN_CTYPE_A1_PCMCIA: case ISDN_CTYPE_ELSA_PNP: case ISDN_CTYPE_ELSA_PCMCIA: case ISDN_CTYPE_IX1MICROR2: case ISDN_CTYPE_DIEHLDIVA: case ISDN_CTYPE_ASUSCOM: case ISDN_CTYPE_TELEINT: case ISDN_CTYPE_SEDLBAUER: case ISDN_CTYPE_SEDLBAUER_PCMCIA: case ISDN_CTYPE_SEDLBAUER_FAX: case ISDN_CTYPE_SPORTSTER: case ISDN_CTYPE_MIC: case ISDN_CTYPE_TELES3C: case ISDN_CTYPE_ACERP10: case ISDN_CTYPE_S0BOX: case ISDN_CTYPE_FRITZPCI: case ISDN_CTYPE_HSTSAPHIR: case ISDN_CTYPE_GAZEL: case ISDN_CTYPE_HFC_SX: case ISDN_CTYPE_HFC_SP_PCMCIA: cards[j].para[0] = irq[i]; cards[j].para[1] = io[i]; break; case ISDN_CTYPE_ISURF: cards[j].para[0] = irq[i]; cards[j].para[1] = io[i]; cards[j].para[2] = mem[i]; break; case ISDN_CTYPE_ELSA_PCI: case ISDN_CTYPE_NETJET_S: case ISDN_CTYPE_TELESPCI: case ISDN_CTYPE_W6692: case ISDN_CTYPE_NETJET_U: break; case ISDN_CTYPE_BKM_A4T: break; case ISDN_CTYPE_SCT_QUADRO: if (irq[i]) { cards[j].para[0] = irq[i]; } else { /* QUADRO is a 4 BRI card */ cards[j++].para[0] = 1; /* we need to check if further cards can be added */ if (j < HISAX_MAX_CARDS) { cards[j].typ = ISDN_CTYPE_SCT_QUADRO; cards[j].protocol = protocol[i]; cards[j++].para[0] = 2; } if (j < HISAX_MAX_CARDS) { cards[j].typ = ISDN_CTYPE_SCT_QUADRO; cards[j].protocol = protocol[i]; cards[j++].para[0] = 3; } if (j < HISAX_MAX_CARDS) { cards[j].typ = ISDN_CTYPE_SCT_QUADRO; cards[j].protocol = protocol[i]; cards[j].para[0] = 4; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?