aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/isdn/hardware/mISDN/hfc_multi.h6
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c396
2 files changed, 236 insertions, 166 deletions
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index 09e4e77811f1..c601f880141e 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -208,7 +208,10 @@ struct hfc_multi {
208 u_long ledstate; /* save last state of leds */ 208 u_long ledstate; /* save last state of leds */
209 int opticalsupport; /* has the e1 board */ 209 int opticalsupport; /* has the e1 board */
210 /* an optical Interface */ 210 /* an optical Interface */
211 int dslot; /* channel # of d-channel (E1) default 16 */ 211
212 u_int bmask[32]; /* bitmask of bchannels for port */
213 u_char dnum[32]; /* array of used dchannel numbers for port */
214 u_char created[32]; /* what port is created */
212 u_int activity_tx; /* if there is data TX / RX */ 215 u_int activity_tx; /* if there is data TX / RX */
213 u_int activity_rx; /* bitmask according to port number */ 216 u_int activity_rx; /* bitmask according to port number */
214 /* (will be cleared after */ 217 /* (will be cleared after */
@@ -234,7 +237,6 @@ struct hfc_multi {
234 * the bch->channel is equvalent to the hfc-channel 237 * the bch->channel is equvalent to the hfc-channel
235 */ 238 */
236 struct hfc_chan chan[32]; 239 struct hfc_chan chan[32];
237 u_char created[8]; /* what port is created */
238 signed char slot_owner[256]; /* owner channel of slot */ 240 signed char slot_owner[256]; /* owner channel of slot */
239}; 241};
240 242
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 876f7d0db26f..43013316b9b0 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -103,14 +103,26 @@
103 * Omit this value, if all cards are interconnected or none is connected. 103 * Omit this value, if all cards are interconnected or none is connected.
104 * If unsure, don't give this parameter. 104 * If unsure, don't give this parameter.
105 * 105 *
106 * dslot: 106 * dmask and bmask:
107 * NOTE: only one dslot value must be given for every card. 107 * NOTE: One dmask value must be given for every HFC-E1 card.
108 * Also this value must be given for non-E1 cards. If omitted, the E1 108 * If omitted, the E1 card has D-channel on time slot 16, which is default.
109 * card has D-channel on time slot 16, which is default. 109 * dmask is a 32 bit mask. The bit must be set for an alternate time slot.
110 * If 1..15 or 17..31, an alternate time slot is used for D-channel. 110 * If multiple bits are set, multiple virtual card fragments are created.
111 * In this case, the application must be able to handle this. 111 * For each bit set, a bmask value must be given. Each bit on the bmask
112 * If -1 is given, the D-channel is disabled and all 31 slots can be used 112 * value stands for a B-channel. The bmask may not overlap with dmask or
113 * for B-channel. (only for specific applications) 113 * with other bmask values for that card.
114 * Example: dmask=0x00020002 bmask=0x0000fffc,0xfffc0000
115 * This will create one fragment with D-channel on slot 1 with
116 * B-channels on slots 2..15, and a second fragment with D-channel
117 * on slot 17 with B-channels on slot 18..31. Slot 16 is unused.
118 * If bit 0 is set (dmask=0x00000001) the D-channel is on slot 0 and will
119 * not function.
120 * Example: dmask=0x00000001 bmask=0xfffffffe
121 * This will create a port with all 31 usable timeslots as
122 * B-channels.
123 * If no bits are set on bmask, no B-channel is created for that fragment.
124 * Example: dmask=0xfffffffe bmask=0,0,0,0.... (31 0-values for bmask)
125 * This will create 31 ports with one D-channel only.
114 * If you don't know how to use it, you don't need it! 126 * If you don't know how to use it, you don't need it!
115 * 127 *
116 * iomode: 128 * iomode:
@@ -172,6 +184,7 @@
172 184
173#define MAX_CARDS 8 185#define MAX_CARDS 8
174#define MAX_PORTS (8 * MAX_CARDS) 186#define MAX_PORTS (8 * MAX_CARDS)
187#define MAX_FRAGS (32 * MAX_CARDS)
175 188
176static LIST_HEAD(HFClist); 189static LIST_HEAD(HFClist);
177static spinlock_t HFClock; /* global hfc list lock */ 190static spinlock_t HFClock; /* global hfc list lock */
@@ -203,7 +216,8 @@ static int nt_t1_count[] = { 3840, 1920, 960, 480, 240, 120, 60, 30 };
203 216
204static uint type[MAX_CARDS]; 217static uint type[MAX_CARDS];
205static int pcm[MAX_CARDS]; 218static int pcm[MAX_CARDS];
206static int dslot[MAX_CARDS]; 219static uint dmask[MAX_CARDS];
220static uint bmask[MAX_FRAGS];
207static uint iomode[MAX_CARDS]; 221static uint iomode[MAX_CARDS];
208static uint port[MAX_PORTS]; 222static uint port[MAX_PORTS];
209static uint debug; 223static uint debug;
@@ -218,7 +232,7 @@ static uint clockdelay_nt = CLKDEL_NT;
218#define HWID_MINIP16 3 232#define HWID_MINIP16 3
219static uint hwid = HWID_NONE; 233static uint hwid = HWID_NONE;
220 234
221static int HFC_cnt, Port_cnt, PCM_cnt = 99; 235static int HFC_cnt, E1_cnt, bmask_cnt, Port_cnt, PCM_cnt = 99;
222 236
223MODULE_AUTHOR("Andreas Eversberg"); 237MODULE_AUTHOR("Andreas Eversberg");
224MODULE_LICENSE("GPL"); 238MODULE_LICENSE("GPL");
@@ -231,7 +245,8 @@ module_param(clockdelay_te, uint, S_IRUGO | S_IWUSR);
231module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR); 245module_param(clockdelay_nt, uint, S_IRUGO | S_IWUSR);
232module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR); 246module_param_array(type, uint, NULL, S_IRUGO | S_IWUSR);
233module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR); 247module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
234module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR); 248module_param_array(dmask, uint, NULL, S_IRUGO | S_IWUSR);
249module_param_array(bmask, uint, NULL, S_IRUGO | S_IWUSR);
235module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); 250module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
236module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); 251module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
237module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */ 252module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
@@ -1619,9 +1634,9 @@ hfcmulti_leds(struct hfc_multi *hc)
1619 led[1] = 0; 1634 led[1] = 0;
1620 led[2] = 0; 1635 led[2] = 0;
1621 led[3] = 0; 1636 led[3] = 0;
1622 dch = hc->chan[hc->dslot].dch; 1637 dch = hc->chan[hc->dnum[0]].dch;
1623 if (dch) { 1638 if (dch) {
1624 if (hc->chan[hc->dslot].los) 1639 if (hc->chan[hc->dnum[0]].los)
1625 led[1] = 1; 1640 led[1] = 1;
1626 if (hc->e1_state != 1) { 1641 if (hc->e1_state != 1) {
1627 led[0] = 1; 1642 led[0] = 1;
@@ -2453,55 +2468,55 @@ handle_timer_irq(struct hfc_multi *hc)
2453 } 2468 }
2454 } 2469 }
2455 if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) { 2470 if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
2456 dch = hc->chan[hc->dslot].dch; 2471 dch = hc->chan[hc->dnum[0]].dch;
2457 if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { 2472 /* LOS */
2458 /* LOS */ 2473 temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
2459 temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS; 2474 hc->chan[hc->dnum[0]].los = temp;
2460 if (!temp && hc->chan[hc->dslot].los) 2475 if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
2476 if (!temp && hc->chan[hc->dnum[0]].los)
2461 signal_state_up(dch, L1_SIGNAL_LOS_ON, 2477 signal_state_up(dch, L1_SIGNAL_LOS_ON,
2462 "LOS detected"); 2478 "LOS detected");
2463 if (temp && !hc->chan[hc->dslot].los) 2479 if (temp && !hc->chan[hc->dnum[0]].los)
2464 signal_state_up(dch, L1_SIGNAL_LOS_OFF, 2480 signal_state_up(dch, L1_SIGNAL_LOS_OFF,
2465 "LOS gone"); 2481 "LOS gone");
2466 hc->chan[hc->dslot].los = temp;
2467 } 2482 }
2468 if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) { 2483 if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
2469 /* AIS */ 2484 /* AIS */
2470 temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS; 2485 temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
2471 if (!temp && hc->chan[hc->dslot].ais) 2486 if (!temp && hc->chan[hc->dnum[0]].ais)
2472 signal_state_up(dch, L1_SIGNAL_AIS_ON, 2487 signal_state_up(dch, L1_SIGNAL_AIS_ON,
2473 "AIS detected"); 2488 "AIS detected");
2474 if (temp && !hc->chan[hc->dslot].ais) 2489 if (temp && !hc->chan[hc->dnum[0]].ais)
2475 signal_state_up(dch, L1_SIGNAL_AIS_OFF, 2490 signal_state_up(dch, L1_SIGNAL_AIS_OFF,
2476 "AIS gone"); 2491 "AIS gone");
2477 hc->chan[hc->dslot].ais = temp; 2492 hc->chan[hc->dnum[0]].ais = temp;
2478 } 2493 }
2479 if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) { 2494 if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
2480 /* SLIP */ 2495 /* SLIP */
2481 temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX; 2496 temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
2482 if (!temp && hc->chan[hc->dslot].slip_rx) 2497 if (!temp && hc->chan[hc->dnum[0]].slip_rx)
2483 signal_state_up(dch, L1_SIGNAL_SLIP_RX, 2498 signal_state_up(dch, L1_SIGNAL_SLIP_RX,
2484 " bit SLIP detected RX"); 2499 " bit SLIP detected RX");
2485 hc->chan[hc->dslot].slip_rx = temp; 2500 hc->chan[hc->dnum[0]].slip_rx = temp;
2486 temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX; 2501 temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
2487 if (!temp && hc->chan[hc->dslot].slip_tx) 2502 if (!temp && hc->chan[hc->dnum[0]].slip_tx)
2488 signal_state_up(dch, L1_SIGNAL_SLIP_TX, 2503 signal_state_up(dch, L1_SIGNAL_SLIP_TX,
2489 " bit SLIP detected TX"); 2504 " bit SLIP detected TX");
2490 hc->chan[hc->dslot].slip_tx = temp; 2505 hc->chan[hc->dnum[0]].slip_tx = temp;
2491 } 2506 }
2492 if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) { 2507 if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
2493 /* RDI */ 2508 /* RDI */
2494 temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A; 2509 temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
2495 if (!temp && hc->chan[hc->dslot].rdi) 2510 if (!temp && hc->chan[hc->dnum[0]].rdi)
2496 signal_state_up(dch, L1_SIGNAL_RDI_ON, 2511 signal_state_up(dch, L1_SIGNAL_RDI_ON,
2497 "RDI detected"); 2512 "RDI detected");
2498 if (temp && !hc->chan[hc->dslot].rdi) 2513 if (temp && !hc->chan[hc->dnum[0]].rdi)
2499 signal_state_up(dch, L1_SIGNAL_RDI_OFF, 2514 signal_state_up(dch, L1_SIGNAL_RDI_OFF,
2500 "RDI gone"); 2515 "RDI gone");
2501 hc->chan[hc->dslot].rdi = temp; 2516 hc->chan[hc->dnum[0]].rdi = temp;
2502 } 2517 }
2503 temp = HFC_inb_nodebug(hc, R_JATT_DIR); 2518 temp = HFC_inb_nodebug(hc, R_JATT_DIR);
2504 switch (hc->chan[hc->dslot].sync) { 2519 switch (hc->chan[hc->dnum[0]].sync) {
2505 case 0: 2520 case 0:
2506 if ((temp & 0x60) == 0x60) { 2521 if ((temp & 0x60) == 0x60) {
2507 if (debug & DEBUG_HFCMULTI_SYNC) 2522 if (debug & DEBUG_HFCMULTI_SYNC)
@@ -2510,10 +2525,10 @@ handle_timer_irq(struct hfc_multi *hc)
2510 "in clock sync\n", 2525 "in clock sync\n",
2511 __func__, hc->id); 2526 __func__, hc->id);
2512 HFC_outb(hc, R_RX_OFF, 2527 HFC_outb(hc, R_RX_OFF,
2513 hc->chan[hc->dslot].jitter | V_RX_INIT); 2528 hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
2514 HFC_outb(hc, R_TX_OFF, 2529 HFC_outb(hc, R_TX_OFF,
2515 hc->chan[hc->dslot].jitter | V_RX_INIT); 2530 hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
2516 hc->chan[hc->dslot].sync = 1; 2531 hc->chan[hc->dnum[0]].sync = 1;
2517 goto check_framesync; 2532 goto check_framesync;
2518 } 2533 }
2519 break; 2534 break;
@@ -2524,7 +2539,7 @@ handle_timer_irq(struct hfc_multi *hc)
2524 "%s: (id=%d) E1 " 2539 "%s: (id=%d) E1 "
2525 "lost clock sync\n", 2540 "lost clock sync\n",
2526 __func__, hc->id); 2541 __func__, hc->id);
2527 hc->chan[hc->dslot].sync = 0; 2542 hc->chan[hc->dnum[0]].sync = 0;
2528 break; 2543 break;
2529 } 2544 }
2530 check_framesync: 2545 check_framesync:
@@ -2535,7 +2550,7 @@ handle_timer_irq(struct hfc_multi *hc)
2535 "%s: (id=%d) E1 " 2550 "%s: (id=%d) E1 "
2536 "now in frame sync\n", 2551 "now in frame sync\n",
2537 __func__, hc->id); 2552 __func__, hc->id);
2538 hc->chan[hc->dslot].sync = 2; 2553 hc->chan[hc->dnum[0]].sync = 2;
2539 } 2554 }
2540 break; 2555 break;
2541 case 2: 2556 case 2:
@@ -2545,7 +2560,7 @@ handle_timer_irq(struct hfc_multi *hc)
2545 "%s: (id=%d) E1 lost " 2560 "%s: (id=%d) E1 lost "
2546 "clock & frame sync\n", 2561 "clock & frame sync\n",
2547 __func__, hc->id); 2562 __func__, hc->id);
2548 hc->chan[hc->dslot].sync = 0; 2563 hc->chan[hc->dnum[0]].sync = 0;
2549 break; 2564 break;
2550 } 2565 }
2551 temp = HFC_inb_nodebug(hc, R_SYNC_STA); 2566 temp = HFC_inb_nodebug(hc, R_SYNC_STA);
@@ -2555,7 +2570,7 @@ handle_timer_irq(struct hfc_multi *hc)
2555 "%s: (id=%d) E1 " 2570 "%s: (id=%d) E1 "
2556 "lost frame sync\n", 2571 "lost frame sync\n",
2557 __func__, hc->id); 2572 __func__, hc->id);
2558 hc->chan[hc->dslot].sync = 1; 2573 hc->chan[hc->dnum[0]].sync = 1;
2559 } 2574 }
2560 break; 2575 break;
2561 } 2576 }
@@ -2696,7 +2711,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
2696 int i; 2711 int i;
2697 void __iomem *plx_acc; 2712 void __iomem *plx_acc;
2698 u_short wval; 2713 u_short wval;
2699 u_char e1_syncsta, temp; 2714 u_char e1_syncsta, temp, temp2;
2700 u_long flags; 2715 u_long flags;
2701 2716
2702 if (!hc) { 2717 if (!hc) {
@@ -2771,7 +2786,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
2771 if (r_irq_misc & V_STA_IRQ) { 2786 if (r_irq_misc & V_STA_IRQ) {
2772 if (hc->ctype == HFC_TYPE_E1) { 2787 if (hc->ctype == HFC_TYPE_E1) {
2773 /* state machine */ 2788 /* state machine */
2774 dch = hc->chan[hc->dslot].dch; 2789 dch = hc->chan[hc->dnum[0]].dch;
2775 e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); 2790 e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
2776 if (test_bit(HFC_CHIP_PLXSD, &hc->chip) 2791 if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
2777 && hc->e1_getclock) { 2792 && hc->e1_getclock) {
@@ -2781,23 +2796,26 @@ hfcmulti_interrupt(int intno, void *dev_id)
2781 hc->syncronized = 0; 2796 hc->syncronized = 0;
2782 } 2797 }
2783 /* undocumented: status changes during read */ 2798 /* undocumented: status changes during read */
2784 dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA); 2799 temp = HFC_inb_nodebug(hc, R_E1_RD_STA);
2785 while (dch->state != (temp = 2800 while (temp != (temp2 =
2786 HFC_inb_nodebug(hc, R_E1_RD_STA))) { 2801 HFC_inb_nodebug(hc, R_E1_RD_STA))) {
2787 if (debug & DEBUG_HFCMULTI_STATE) 2802 if (debug & DEBUG_HFCMULTI_STATE)
2788 printk(KERN_DEBUG "%s: reread " 2803 printk(KERN_DEBUG "%s: reread "
2789 "STATE because %d!=%d\n", 2804 "STATE because %d!=%d\n",
2790 __func__, temp, 2805 __func__, temp, temp2);
2791 dch->state); 2806 temp = temp2; /* repeat */
2792 dch->state = temp; /* repeat */
2793 } 2807 }
2794 dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA) 2808 /* broadcast state change to all fragments */
2795 & 0x7;
2796 schedule_event(dch, FLG_PHCHANGE);
2797 if (debug & DEBUG_HFCMULTI_STATE) 2809 if (debug & DEBUG_HFCMULTI_STATE)
2798 printk(KERN_DEBUG 2810 printk(KERN_DEBUG
2799 "%s: E1 (id=%d) newstate %x\n", 2811 "%s: E1 (id=%d) newstate %x\n",
2800 __func__, hc->id, dch->state); 2812 __func__, hc->id, temp & 0x7);
2813 for (i = 0; i < hc->ports; i++) {
2814 dch = hc->chan[hc->dnum[i]].dch;
2815 dch->state = temp & 0x7;
2816 schedule_event(dch, FLG_PHCHANGE);
2817 }
2818
2801 if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) 2819 if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
2802 plxsd_checksync(hc, 0); 2820 plxsd_checksync(hc, 0);
2803 } 2821 }
@@ -3870,31 +3888,37 @@ hfcmulti_initmode(struct dchannel *dch)
3870 if (debug & DEBUG_HFCMULTI_INIT) 3888 if (debug & DEBUG_HFCMULTI_INIT)
3871 printk(KERN_DEBUG "%s: entered\n", __func__); 3889 printk(KERN_DEBUG "%s: entered\n", __func__);
3872 3890
3891 i = dch->slot;
3892 pt = hc->chan[i].port;
3873 if (hc->ctype == HFC_TYPE_E1) { 3893 if (hc->ctype == HFC_TYPE_E1) {
3874 hc->chan[hc->dslot].slot_tx = -1; 3894 /* E1 */
3875 hc->chan[hc->dslot].slot_rx = -1; 3895 hc->chan[hc->dnum[pt]].slot_tx = -1;
3876 hc->chan[hc->dslot].conf = -1; 3896 hc->chan[hc->dnum[pt]].slot_rx = -1;
3877 if (hc->dslot) { 3897 hc->chan[hc->dnum[pt]].conf = -1;
3878 mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol, 3898 if (hc->dnum[pt]) {
3899 mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
3879 -1, 0, -1, 0); 3900 -1, 0, -1, 0);
3880 dch->timer.function = (void *) hfcmulti_dbusy_timer; 3901 dch->timer.function = (void *) hfcmulti_dbusy_timer;
3881 dch->timer.data = (long) dch; 3902 dch->timer.data = (long) dch;
3882 init_timer(&dch->timer); 3903 init_timer(&dch->timer);
3883 } 3904 }
3884 for (i = 1; i <= 31; i++) { 3905 for (i = 1; i <= 31; i++) {
3885 if (i == hc->dslot) 3906 if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
3886 continue; 3907 continue;
3887 hc->chan[i].slot_tx = -1; 3908 hc->chan[i].slot_tx = -1;
3888 hc->chan[i].slot_rx = -1; 3909 hc->chan[i].slot_rx = -1;
3889 hc->chan[i].conf = -1; 3910 hc->chan[i].conf = -1;
3890 mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0); 3911 mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
3891 } 3912 }
3892 /* E1 */ 3913 }
3893 if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { 3914 if (hc->ctype == HFC_TYPE_E1 && pt == 0) {
3915 /* E1, port 0 */
3916 dch = hc->chan[hc->dnum[0]].dch;
3917 if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
3894 HFC_outb(hc, R_LOS0, 255); /* 2 ms */ 3918 HFC_outb(hc, R_LOS0, 255); /* 2 ms */
3895 HFC_outb(hc, R_LOS1, 255); /* 512 ms */ 3919 HFC_outb(hc, R_LOS1, 255); /* 512 ms */
3896 } 3920 }
3897 if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) { 3921 if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[0]].cfg)) {
3898 HFC_outb(hc, R_RX0, 0); 3922 HFC_outb(hc, R_RX0, 0);
3899 hc->hw.r_tx0 = 0 | V_OUT_EN; 3923 hc->hw.r_tx0 = 0 | V_OUT_EN;
3900 } else { 3924 } else {
@@ -3907,12 +3931,12 @@ hfcmulti_initmode(struct dchannel *dch)
3907 HFC_outb(hc, R_TX_FR0, 0x00); 3931 HFC_outb(hc, R_TX_FR0, 0x00);
3908 HFC_outb(hc, R_TX_FR1, 0xf8); 3932 HFC_outb(hc, R_TX_FR1, 0xf8);
3909 3933
3910 if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg)) 3934 if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
3911 HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E); 3935 HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
3912 3936
3913 HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0); 3937 HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
3914 3938
3915 if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg)) 3939 if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[0]].cfg))
3916 HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC); 3940 HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
3917 3941
3918 if (dch->dev.D.protocol == ISDN_P_NT_E1) { 3942 if (dch->dev.D.protocol == ISDN_P_NT_E1) {
@@ -3975,13 +3999,14 @@ hfcmulti_initmode(struct dchannel *dch)
3975 hc->syncronized = 0; 3999 hc->syncronized = 0;
3976 plxsd_checksync(hc, 0); 4000 plxsd_checksync(hc, 0);
3977 } 4001 }
3978 } else { 4002 }
3979 i = dch->slot; 4003 if (hc->ctype != HFC_TYPE_E1) {
4004 /* ST */
3980 hc->chan[i].slot_tx = -1; 4005 hc->chan[i].slot_tx = -1;
3981 hc->chan[i].slot_rx = -1; 4006 hc->chan[i].slot_rx = -1;
3982 hc->chan[i].conf = -1; 4007 hc->chan[i].conf = -1;
3983 mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0); 4008 mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0);
3984 dch->timer.function = (void *)hfcmulti_dbusy_timer; 4009 dch->timer.function = (void *) hfcmulti_dbusy_timer;
3985 dch->timer.data = (long) dch; 4010 dch->timer.data = (long) dch;
3986 init_timer(&dch->timer); 4011 init_timer(&dch->timer);
3987 hc->chan[i - 2].slot_tx = -1; 4012 hc->chan[i - 2].slot_tx = -1;
@@ -3992,8 +4017,6 @@ hfcmulti_initmode(struct dchannel *dch)
3992 hc->chan[i - 1].slot_rx = -1; 4017 hc->chan[i - 1].slot_rx = -1;
3993 hc->chan[i - 1].conf = -1; 4018 hc->chan[i - 1].conf = -1;
3994 mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0); 4019 mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
3995 /* ST */
3996 pt = hc->chan[i].port;
3997 /* select interface */ 4020 /* select interface */
3998 HFC_outb(hc, R_ST_SEL, pt); 4021 HFC_outb(hc, R_ST_SEL, pt);
3999 /* undocumented: delay after R_ST_SEL */ 4022 /* undocumented: delay after R_ST_SEL */
@@ -4571,6 +4594,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
4571 } 4594 }
4572 /* free channels */ 4595 /* free channels */
4573 for (i = 0; i <= 31; i++) { 4596 for (i = 0; i <= 31; i++) {
4597 if (!((1 << i) & hc->bmask[pt])) /* skip unused chan */
4598 continue;
4574 if (hc->chan[i].bch) { 4599 if (hc->chan[i].bch) {
4575 if (debug & DEBUG_HFCMULTI_INIT) 4600 if (debug & DEBUG_HFCMULTI_INIT)
4576 printk(KERN_DEBUG 4601 printk(KERN_DEBUG
@@ -4626,7 +4651,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
4626 spin_unlock_irqrestore(&hc->lock, flags); 4651 spin_unlock_irqrestore(&hc->lock, flags);
4627 4652
4628 if (debug & DEBUG_HFCMULTI_INIT) 4653 if (debug & DEBUG_HFCMULTI_INIT)
4629 printk(KERN_DEBUG "%s: free port %d channel D\n", __func__, pt); 4654 printk(KERN_DEBUG "%s: free port %d channel D(%d)\n", __func__,
4655 pt+1, ci);
4630 mISDN_freedchannel(dch); 4656 mISDN_freedchannel(dch);
4631 kfree(dch); 4657 kfree(dch);
4632 4658
@@ -4648,15 +4674,19 @@ release_card(struct hfc_multi *hc)
4648 if (hc->iclock) 4674 if (hc->iclock)
4649 mISDN_unregister_clock(hc->iclock); 4675 mISDN_unregister_clock(hc->iclock);
4650 4676
4651 /* disable irq */ 4677 /* disable and free irq */
4652 spin_lock_irqsave(&hc->lock, flags); 4678 spin_lock_irqsave(&hc->lock, flags);
4653 disable_hwirq(hc); 4679 disable_hwirq(hc);
4654 spin_unlock_irqrestore(&hc->lock, flags); 4680 spin_unlock_irqrestore(&hc->lock, flags);
4655 udelay(1000); 4681 udelay(1000);
4682 if (hc->irq) {
4683 if (debug & DEBUG_HFCMULTI_INIT)
4684 printk(KERN_DEBUG "%s: free irq %d (hc=%p)\n",
4685 __func__, hc->irq, hc);
4686 free_irq(hc->irq, hc);
4687 hc->irq = 0;
4656 4688
4657 /* dimm leds */ 4689 }
4658 if (hc->leds)
4659 hfcmulti_leds(hc);
4660 4690
4661 /* disable D-channels & B-channels */ 4691 /* disable D-channels & B-channels */
4662 if (debug & DEBUG_HFCMULTI_INIT) 4692 if (debug & DEBUG_HFCMULTI_INIT)
@@ -4667,15 +4697,11 @@ release_card(struct hfc_multi *hc)
4667 release_port(hc, hc->chan[ch].dch); 4697 release_port(hc, hc->chan[ch].dch);
4668 } 4698 }
4669 4699
4670 /* release hardware & irq */ 4700 /* dimm leds */
4671 if (hc->irq) { 4701 if (hc->leds)
4672 if (debug & DEBUG_HFCMULTI_INIT) 4702 hfcmulti_leds(hc);
4673 printk(KERN_DEBUG "%s: free irq %d\n",
4674 __func__, hc->irq);
4675 free_irq(hc->irq, hc);
4676 hc->irq = 0;
4677 4703
4678 } 4704 /* release hardware */
4679 release_io_hfcmulti(hc); 4705 release_io_hfcmulti(hc);
4680 4706
4681 if (debug & DEBUG_HFCMULTI_INIT) 4707 if (debug & DEBUG_HFCMULTI_INIT)
@@ -4693,61 +4719,9 @@ release_card(struct hfc_multi *hc)
4693 __func__); 4719 __func__);
4694} 4720}
4695 4721
4696static int 4722static void
4697init_e1_port(struct hfc_multi *hc, struct hm_map *m) 4723init_e1_port_hw(struct hfc_multi *hc, struct hm_map *m)
4698{ 4724{
4699 struct dchannel *dch;
4700 struct bchannel *bch;
4701 int ch, ret = 0;
4702 char name[MISDN_MAX_IDLEN];
4703
4704 dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
4705 if (!dch)
4706 return -ENOMEM;
4707 dch->debug = debug;
4708 mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
4709 dch->hw = hc;
4710 dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
4711 dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
4712 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
4713 dch->dev.D.send = handle_dmsg;
4714 dch->dev.D.ctrl = hfcm_dctrl;
4715 dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
4716 dch->slot = hc->dslot;
4717 hc->chan[hc->dslot].dch = dch;
4718 hc->chan[hc->dslot].port = 0;
4719 hc->chan[hc->dslot].nt_timer = -1;
4720 for (ch = 1; ch <= 31; ch++) {
4721 if (ch == hc->dslot) /* skip dchannel */
4722 continue;
4723 bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
4724 if (!bch) {
4725 printk(KERN_ERR "%s: no memory for bchannel\n",
4726 __func__);
4727 ret = -ENOMEM;
4728 goto free_chan;
4729 }
4730 hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
4731 if (!hc->chan[ch].coeff) {
4732 printk(KERN_ERR "%s: no memory for coeffs\n",
4733 __func__);
4734 ret = -ENOMEM;
4735 kfree(bch);
4736 goto free_chan;
4737 }
4738 bch->nr = ch;
4739 bch->slot = ch;
4740 bch->debug = debug;
4741 mISDN_initbchannel(bch, MAX_DATA_MEM);
4742 bch->hw = hc;
4743 bch->ch.send = handle_bmsg;
4744 bch->ch.ctrl = hfcm_bctrl;
4745 bch->ch.nr = ch;
4746 list_add(&bch->ch.list, &dch->dev.bchannels);
4747 hc->chan[ch].bch = bch;
4748 hc->chan[ch].port = 0;
4749 set_channelmap(bch->nr, dch->dev.channelmap);
4750 }
4751 /* set optical line type */ 4725 /* set optical line type */
4752 if (port[Port_cnt] & 0x001) { 4726 if (port[Port_cnt] & 0x001) {
4753 if (!m->opticalsupport) { 4727 if (!m->opticalsupport) {
@@ -4763,7 +4737,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4763 __func__, 4737 __func__,
4764 HFC_cnt + 1, 1); 4738 HFC_cnt + 1, 1);
4765 test_and_set_bit(HFC_CFG_OPTICAL, 4739 test_and_set_bit(HFC_CFG_OPTICAL,
4766 &hc->chan[hc->dslot].cfg); 4740 &hc->chan[hc->dnum[0]].cfg);
4767 } 4741 }
4768 } 4742 }
4769 /* set LOS report */ 4743 /* set LOS report */
@@ -4773,7 +4747,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4773 "LOS report: card(%d) port(%d)\n", 4747 "LOS report: card(%d) port(%d)\n",
4774 __func__, HFC_cnt + 1, 1); 4748 __func__, HFC_cnt + 1, 1);
4775 test_and_set_bit(HFC_CFG_REPORT_LOS, 4749 test_and_set_bit(HFC_CFG_REPORT_LOS,
4776 &hc->chan[hc->dslot].cfg); 4750 &hc->chan[hc->dnum[0]].cfg);
4777 } 4751 }
4778 /* set AIS report */ 4752 /* set AIS report */
4779 if (port[Port_cnt] & 0x008) { 4753 if (port[Port_cnt] & 0x008) {
@@ -4782,7 +4756,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4782 "AIS report: card(%d) port(%d)\n", 4756 "AIS report: card(%d) port(%d)\n",
4783 __func__, HFC_cnt + 1, 1); 4757 __func__, HFC_cnt + 1, 1);
4784 test_and_set_bit(HFC_CFG_REPORT_AIS, 4758 test_and_set_bit(HFC_CFG_REPORT_AIS,
4785 &hc->chan[hc->dslot].cfg); 4759 &hc->chan[hc->dnum[0]].cfg);
4786 } 4760 }
4787 /* set SLIP report */ 4761 /* set SLIP report */
4788 if (port[Port_cnt] & 0x010) { 4762 if (port[Port_cnt] & 0x010) {
@@ -4792,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4792 "card(%d) port(%d)\n", 4766 "card(%d) port(%d)\n",
4793 __func__, HFC_cnt + 1, 1); 4767 __func__, HFC_cnt + 1, 1);
4794 test_and_set_bit(HFC_CFG_REPORT_SLIP, 4768 test_and_set_bit(HFC_CFG_REPORT_SLIP,
4795 &hc->chan[hc->dslot].cfg); 4769 &hc->chan[hc->dnum[0]].cfg);
4796 } 4770 }
4797 /* set RDI report */ 4771 /* set RDI report */
4798 if (port[Port_cnt] & 0x020) { 4772 if (port[Port_cnt] & 0x020) {
@@ -4802,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4802 "card(%d) port(%d)\n", 4776 "card(%d) port(%d)\n",
4803 __func__, HFC_cnt + 1, 1); 4777 __func__, HFC_cnt + 1, 1);
4804 test_and_set_bit(HFC_CFG_REPORT_RDI, 4778 test_and_set_bit(HFC_CFG_REPORT_RDI,
4805 &hc->chan[hc->dslot].cfg); 4779 &hc->chan[hc->dnum[0]].cfg);
4806 } 4780 }
4807 /* set CRC-4 Mode */ 4781 /* set CRC-4 Mode */
4808 if (!(port[Port_cnt] & 0x100)) { 4782 if (!(port[Port_cnt] & 0x100)) {
@@ -4811,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4811 " card(%d) port(%d)\n", 4785 " card(%d) port(%d)\n",
4812 __func__, HFC_cnt + 1, 1); 4786 __func__, HFC_cnt + 1, 1);
4813 test_and_set_bit(HFC_CFG_CRC4, 4787 test_and_set_bit(HFC_CFG_CRC4,
4814 &hc->chan[hc->dslot].cfg); 4788 &hc->chan[hc->dnum[0]].cfg);
4815 } else { 4789 } else {
4816 if (debug & DEBUG_HFCMULTI_INIT) 4790 if (debug & DEBUG_HFCMULTI_INIT)
4817 printk(KERN_DEBUG "%s: PORT turn off CRC4" 4791 printk(KERN_DEBUG "%s: PORT turn off CRC4"
@@ -4843,20 +4817,85 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
4843 } 4817 }
4844 /* set elastic jitter buffer */ 4818 /* set elastic jitter buffer */
4845 if (port[Port_cnt] & 0x3000) { 4819 if (port[Port_cnt] & 0x3000) {
4846 hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3; 4820 hc->chan[hc->dnum[0]].jitter = (port[Port_cnt]>>12) & 0x3;
4847 if (debug & DEBUG_HFCMULTI_INIT) 4821 if (debug & DEBUG_HFCMULTI_INIT)
4848 printk(KERN_DEBUG 4822 printk(KERN_DEBUG
4849 "%s: PORT set elastic " 4823 "%s: PORT set elastic "
4850 "buffer to %d: card(%d) port(%d)\n", 4824 "buffer to %d: card(%d) port(%d)\n",
4851 __func__, hc->chan[hc->dslot].jitter, 4825 __func__, hc->chan[hc->dnum[0]].jitter,
4852 HFC_cnt + 1, 1); 4826 HFC_cnt + 1, 1);
4853 } else 4827 } else
4854 hc->chan[hc->dslot].jitter = 2; /* default */ 4828 hc->chan[hc->dnum[0]].jitter = 2; /* default */
4855 snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1); 4829}
4830
4831static int
4832init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
4833{
4834 struct dchannel *dch;
4835 struct bchannel *bch;
4836 int ch, ret = 0;
4837 char name[MISDN_MAX_IDLEN];
4838 int bcount = 0;
4839
4840 dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
4841 if (!dch)
4842 return -ENOMEM;
4843 dch->debug = debug;
4844 mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change);
4845 dch->hw = hc;
4846 dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1);
4847 dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
4848 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
4849 dch->dev.D.send = handle_dmsg;
4850 dch->dev.D.ctrl = hfcm_dctrl;
4851 dch->slot = hc->dnum[pt];
4852 hc->chan[hc->dnum[pt]].dch = dch;
4853 hc->chan[hc->dnum[pt]].port = pt;
4854 hc->chan[hc->dnum[pt]].nt_timer = -1;
4855 for (ch = 1; ch <= 31; ch++) {
4856 if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
4857 continue;
4858 bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
4859 if (!bch) {
4860 printk(KERN_ERR "%s: no memory for bchannel\n",
4861 __func__);
4862 ret = -ENOMEM;
4863 goto free_chan;
4864 }
4865 hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL);
4866 if (!hc->chan[ch].coeff) {
4867 printk(KERN_ERR "%s: no memory for coeffs\n",
4868 __func__);
4869 ret = -ENOMEM;
4870 kfree(bch);
4871 goto free_chan;
4872 }
4873 bch->nr = ch;
4874 bch->slot = ch;
4875 bch->debug = debug;
4876 mISDN_initbchannel(bch, MAX_DATA_MEM);
4877 bch->hw = hc;
4878 bch->ch.send = handle_bmsg;
4879 bch->ch.ctrl = hfcm_bctrl;
4880 bch->ch.nr = ch;
4881 list_add(&bch->ch.list, &dch->dev.bchannels);
4882 hc->chan[ch].bch = bch;
4883 hc->chan[ch].port = pt;
4884 set_channelmap(bch->nr, dch->dev.channelmap);
4885 bcount++;
4886 }
4887 dch->dev.nrbchan = bcount;
4888 if (pt == 0)
4889 init_e1_port_hw(hc, m);
4890 if (hc->ports > 1)
4891 snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d",
4892 HFC_cnt + 1, pt+1);
4893 else
4894 snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
4856 ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); 4895 ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
4857 if (ret) 4896 if (ret)
4858 goto free_chan; 4897 goto free_chan;
4859 hc->created[0] = 1; 4898 hc->created[pt] = 1;
4860 return ret; 4899 return ret;
4861free_chan: 4900free_chan:
4862 release_port(hc, dch); 4901 release_port(hc, dch);
@@ -4989,7 +5028,8 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
4989 struct hfc_multi *hc; 5028 struct hfc_multi *hc;
4990 u_long flags; 5029 u_long flags;
4991 u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */ 5030 u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */
4992 int i; 5031 int i, ch;
5032 u_int maskcheck;
4993 5033
4994 if (HFC_cnt >= MAX_CARDS) { 5034 if (HFC_cnt >= MAX_CARDS) {
4995 printk(KERN_ERR "too many cards (max=%d).\n", 5035 printk(KERN_ERR "too many cards (max=%d).\n",
@@ -5023,18 +5063,36 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
5023 hc->id = HFC_cnt; 5063 hc->id = HFC_cnt;
5024 hc->pcm = pcm[HFC_cnt]; 5064 hc->pcm = pcm[HFC_cnt];
5025 hc->io_mode = iomode[HFC_cnt]; 5065 hc->io_mode = iomode[HFC_cnt];
5026 if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) { 5066 if (hc->ctype == HFC_TYPE_E1 && dmask[E1_cnt]) {
5027 hc->dslot = 0; 5067 /* fragment card */
5028 printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " 5068 pt = 0;
5029 "31 B-channels\n"); 5069 maskcheck = 0;
5030 } 5070 for (ch = 0; ch <= 31; ch++) {
5031 if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 5071 if (!((1 << ch) & dmask[E1_cnt]))
5032 && hc->ctype == HFC_TYPE_E1) { 5072 continue;
5033 hc->dslot = dslot[HFC_cnt]; 5073 hc->dnum[pt] = ch;
5034 printk(KERN_INFO "HFC-E1 card has alternating D-channel on " 5074 hc->bmask[pt] = bmask[bmask_cnt++];
5035 "time slot %d\n", dslot[HFC_cnt]); 5075 if ((maskcheck & hc->bmask[pt])
5036 } else 5076 || (dmask[E1_cnt] & hc->bmask[pt])) {
5037 hc->dslot = 16; 5077 printk(KERN_INFO
5078 "HFC-E1 #%d has overlapping B-channels on fragment #%d\n",
5079 E1_cnt + 1, pt);
5080 return -EINVAL;
5081 }
5082 maskcheck |= hc->bmask[pt];
5083 printk(KERN_INFO
5084 "HFC-E1 #%d uses D-channel on slot %d and a B-channel map of 0x%08x\n",
5085 E1_cnt + 1, ch, hc->bmask[pt]);
5086 pt++;
5087 }
5088 hc->ports = pt;
5089 }
5090 if (hc->ctype == HFC_TYPE_E1 && !dmask[E1_cnt]) {
5091 /* default card layout */
5092 hc->dnum[0] = 16;
5093 hc->bmask[0] = 0xfffefffe;
5094 hc->ports = 1;
5095 }
5038 5096
5039 /* set chip specific features */ 5097 /* set chip specific features */
5040 hc->masterclk = -1; 5098 hc->masterclk = -1;
@@ -5117,23 +5175,33 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
5117 goto free_card; 5175 goto free_card;
5118 } 5176 }
5119 if (hc->ctype == HFC_TYPE_E1) 5177 if (hc->ctype == HFC_TYPE_E1)
5120 ret_err = init_e1_port(hc, m); 5178 ret_err = init_e1_port(hc, m, pt);
5121 else 5179 else
5122 ret_err = init_multi_port(hc, pt); 5180 ret_err = init_multi_port(hc, pt);
5123 if (debug & DEBUG_HFCMULTI_INIT) 5181 if (debug & DEBUG_HFCMULTI_INIT)
5124 printk(KERN_DEBUG 5182 printk(KERN_DEBUG
5125 "%s: Registering D-channel, card(%d) port(%d)" 5183 "%s: Registering D-channel, card(%d) port(%d) "
5126 "result %d\n", 5184 "result %d\n",
5127 __func__, HFC_cnt + 1, pt, ret_err); 5185 __func__, HFC_cnt + 1, pt + 1, ret_err);
5128 5186
5129 if (ret_err) { 5187 if (ret_err) {
5130 while (pt) { /* release already registered ports */ 5188 while (pt) { /* release already registered ports */
5131 pt--; 5189 pt--;
5132 release_port(hc, hc->chan[(pt << 2) + 2].dch); 5190 if (hc->ctype == HFC_TYPE_E1)
5191 release_port(hc,
5192 hc->chan[hc->dnum[pt]].dch);
5193 else
5194 release_port(hc,
5195 hc->chan[(pt << 2) + 2].dch);
5133 } 5196 }
5134 goto free_card; 5197 goto free_card;
5135 } 5198 }
5136 Port_cnt++; 5199 if (hc->ctype != HFC_TYPE_E1)
5200 Port_cnt++; /* for each S0 port */
5201 }
5202 if (hc->ctype == HFC_TYPE_E1) {
5203 Port_cnt++; /* for each E1 port */
5204 E1_cnt++;
5137 } 5205 }
5138 5206
5139 /* disp switches */ 5207 /* disp switches */