aboutsummaryrefslogtreecommitdiffstats
path: root/linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
blob: bb94d342fcc8f1b9a84bdec259d264504379f4df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
This experimental patch splits one E1 card into three virtual cards,

TS 1,2,3,4,5 is card 0
TS 6,7,8,9,10 is card 1
TS 11,12,13,14 is card 2

This allows you to run one L2 TEI handler on each of the virtual cards,
which is required if you want to run multiple BTS on a single E1 link.

Thanks to Andreas Eversberg for this patch.

diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
index 0c77386..02dd4a1 100644
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
@@ -209,14 +209,17 @@ struct hfc_multi {
 	u_long		ledstate; /* save last state of leds */
 	int		opticalsupport; /* has the e1 board */
 					/* an optical Interface */
-	int		dslot;	/* channel # of d-channel (E1) default 16 */
+
+	u_int		bmask[32]; /* bitmask of bchannels for port */
+	u_char		dnum[32]; /* array of used dchannel numbers for port */
+	u_char		created[32]; /* what port is created */
+	u_int		activity[32]; 	/* if there is any action on this */
+					/* port (will be cleared after */
+					/* showing led-states) */
 
 	u_long		wdcount; 	/* every 500 ms we need to */
 					/* send the watchdog a signal */
 	u_char		wdbyte; /* watchdog toggle byte */
-	u_int		activity[8]; 	/* if there is any action on this */
-					/* port (will be cleared after */
-					/* showing led-states) */
 	int		e1_state; /* keep track of last state */
 	int		e1_getclock; /* if sync is retrieved from interface */
 	int		syncronized; /* keep track of existing sync interface */
@@ -233,7 +236,6 @@ struct hfc_multi {
 	 * the bch->channel is equvalent to the hfc-channel
 	 */
 	struct hfc_chan	chan[32];
-	u_char		created[8]; /* what port is created */
 	signed char	slot_owner[256]; /* owner channel of slot */
 };
 
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index e1dab30..4fe2d27 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -1619,8 +1619,8 @@ hfcmulti_leds(struct hfc_multi *hc)
 		 * left red:       frame sync, but no L1
 		 * right green:    L2 active
 		 */
-		if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
-			if (hc->chan[hc->dslot].dch->dev.D.protocol
+		if (hc->chan[hc->dnum[0]].sync != 2) { /* no frame sync */
+			if (hc->chan[hc->dnum[0]].dch->dev.D.protocol
 				!= ISDN_P_NT_E1) {
 				led[0] = 1;
 				led[1] = 1;
@@ -2428,55 +2428,56 @@ handle_timer_irq(struct hfc_multi *hc)
 			}
 		}
 	if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
-		dch = hc->chan[hc->dslot].dch;
-		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
+#warning todo: put interface parameters to hc
+		dch = hc->chan[hc->dnum[0]].dch;
+		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
 			/* LOS */
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
-			if (!temp && hc->chan[hc->dslot].los)
+			if (!temp && hc->chan[hc->dnum[0]].los)
 				signal_state_up(dch, L1_SIGNAL_LOS_ON,
 				    "LOS detected");
-			if (temp && !hc->chan[hc->dslot].los)
+			if (temp && !hc->chan[hc->dnum[0]].los)
 				signal_state_up(dch, L1_SIGNAL_LOS_OFF,
 				    "LOS gone");
-			hc->chan[hc->dslot].los = temp;
+			hc->chan[hc->dnum[0]].los = temp;
 		}
-		if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
+		if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
 			/* AIS */
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
-			if (!temp && hc->chan[hc->dslot].ais)
+			if (!temp && hc->chan[hc->dnum[0]].ais)
 				signal_state_up(dch, L1_SIGNAL_AIS_ON,
 				    "AIS detected");
-			if (temp && !hc->chan[hc->dslot].ais)
+			if (temp && !hc->chan[hc->dnum[0]].ais)
 				signal_state_up(dch, L1_SIGNAL_AIS_OFF,
 				    "AIS gone");
-			hc->chan[hc->dslot].ais = temp;
+			hc->chan[hc->dnum[0]].ais = temp;
 		}
-		if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
+		if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
 			/* SLIP */
 			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
-			if (!temp && hc->chan[hc->dslot].slip_rx)
+			if (!temp && hc->chan[hc->dnum[0]].slip_rx)
 				signal_state_up(dch, L1_SIGNAL_SLIP_RX,
 				    " bit SLIP detected RX");
-			hc->chan[hc->dslot].slip_rx = temp;
+			hc->chan[hc->dnum[0]].slip_rx = temp;
 			temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
-			if (!temp && hc->chan[hc->dslot].slip_tx)
+			if (!temp && hc->chan[hc->dnum[0]].slip_tx)
 				signal_state_up(dch, L1_SIGNAL_SLIP_TX,
 				    " bit SLIP detected TX");
-			hc->chan[hc->dslot].slip_tx = temp;
+			hc->chan[hc->dnum[0]].slip_tx = temp;
 		}
-		if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
+		if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
 			/* RDI */
 			temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
-			if (!temp && hc->chan[hc->dslot].rdi)
+			if (!temp && hc->chan[hc->dnum[0]].rdi)
 				signal_state_up(dch, L1_SIGNAL_RDI_ON,
 				    "RDI detected");
-			if (temp && !hc->chan[hc->dslot].rdi)
+			if (temp && !hc->chan[hc->dnum[0]].rdi)
 				signal_state_up(dch, L1_SIGNAL_RDI_OFF,
 				    "RDI gone");
-			hc->chan[hc->dslot].rdi = temp;
+			hc->chan[hc->dnum[0]].rdi = temp;
 		}
 		temp = HFC_inb_nodebug(hc, R_JATT_DIR);
-		switch (hc->chan[hc->dslot].sync) {
+		switch (hc->chan[hc->dnum[0]].sync) {
 		case 0:
 			if ((temp & 0x60) == 0x60) {
 				if (debug & DEBUG_HFCMULTI_SYNC)
@@ -2485,10 +2486,10 @@ handle_timer_irq(struct hfc_multi *hc)
 					    "in clock sync\n",
 					    __func__, hc->id);
 				HFC_outb(hc, R_RX_OFF,
-				    hc->chan[hc->dslot].jitter | V_RX_INIT);
+				    hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
 				HFC_outb(hc, R_TX_OFF,
-				    hc->chan[hc->dslot].jitter | V_RX_INIT);
-				hc->chan[hc->dslot].sync = 1;
+				    hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
+				hc->chan[hc->dnum[0]].sync = 1;
 				goto check_framesync;
 			}
 			break;
@@ -2499,7 +2500,7 @@ handle_timer_irq(struct hfc_multi *hc)
 					    "%s: (id=%d) E1 "
 					    "lost clock sync\n",
 					    __func__, hc->id);
-				hc->chan[hc->dslot].sync = 0;
+				hc->chan[hc->dnum[0]].sync = 0;
 				break;
 			}
 check_framesync:
@@ -2510,7 +2511,7 @@ check_framesync:
 					    "%s: (id=%d) E1 "
 					    "now in frame sync\n",
 					    __func__, hc->id);
-				hc->chan[hc->dslot].sync = 2;
+				hc->chan[hc->dnum[0]].sync = 2;
 			}
 			break;
 		case 2:
@@ -2520,7 +2521,7 @@ check_framesync:
 					    "%s: (id=%d) E1 lost "
 					    "clock & frame sync\n",
 					    __func__, hc->id);
-				hc->chan[hc->dslot].sync = 0;
+				hc->chan[hc->dnum[0]].sync = 0;
 				break;
 			}
 			temp = HFC_inb_nodebug(hc, R_SYNC_STA);
@@ -2530,7 +2531,7 @@ check_framesync:
 					    "%s: (id=%d) E1 "
 					    "lost frame sync\n",
 					    __func__, hc->id);
-				hc->chan[hc->dslot].sync = 1;
+				hc->chan[hc->dnum[0]].sync = 1;
 			}
 			break;
 		}
@@ -2746,7 +2747,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
 		if (r_irq_misc & V_STA_IRQ) {
 			if (hc->ctype == HFC_TYPE_E1) {
 				/* state machine */
-				dch = hc->chan[hc->dslot].dch;
+#warning todo
+				dch = hc->chan[hc->dnum[0]].dch;
 				e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
 				if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
 				 && hc->e1_getclock) {
@@ -2768,7 +2770,15 @@ hfcmulti_interrupt(int intno, void *dev_id)
 				}
 				dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
 					& 0x7;
+#warning todo hack!!! broadcast state change!!!
+				dch = hc->chan[hc->dnum[0]].dch;
 				schedule_event(dch, FLG_PHCHANGE);
+				dch = hc->chan[hc->dnum[1]].dch;
+				dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
+					& 0x7;
+				schedule_event(dch, FLG_PHCHANGE);
+
+
 				if (debug & DEBUG_HFCMULTI_STATE)
 					printk(KERN_DEBUG
 					    "%s: E1 (id=%d) newstate %x\n",
@@ -3851,31 +3861,35 @@ hfcmulti_initmode(struct dchannel *dch)
 	if (debug & DEBUG_HFCMULTI_INIT)
 		printk(KERN_DEBUG "%s: entered\n", __func__);
 
+	i = dch->slot;
+	pt = hc->chan[i].port;
 	if (hc->ctype == HFC_TYPE_E1) {
-		hc->chan[hc->dslot].slot_tx = -1;
-		hc->chan[hc->dslot].slot_rx = -1;
-		hc->chan[hc->dslot].conf = -1;
-		if (hc->dslot) {
-			mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
+		/* E1 */
+#warning todo: don''t do it if dnum == 0
+		hc->chan[hc->dnum[pt]].slot_tx = -1;
+		hc->chan[hc->dnum[pt]].slot_rx = -1;
+		hc->chan[hc->dnum[pt]].conf = -1;
+		if (hc->dnum[pt]) {
+			mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
 				-1, 0, -1, 0);
 			dch->timer.function = (void *) hfcmulti_dbusy_timer;
 			dch->timer.data = (long) dch;
 			init_timer(&dch->timer);
 		}
 		for (i = 1; i <= 31; i++) {
-			if (i == hc->dslot)
+			if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
 				continue;
 			hc->chan[i].slot_tx = -1;
 			hc->chan[i].slot_rx = -1;
 			hc->chan[i].conf = -1;
 			mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
 		}
-		/* E1 */
-		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
+#warning todo (global)
+		if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[pt]].cfg)) {
 			HFC_outb(hc, R_LOS0, 255); /* 2 ms */
 			HFC_outb(hc, R_LOS1, 255); /* 512 ms */
 		}
-		if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
+		if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[pt]].cfg)) {
 			HFC_outb(hc, R_RX0, 0);
 			hc->hw.r_tx0 = 0 | V_OUT_EN;
 		} else {
@@ -3888,12 +3902,12 @@ hfcmulti_initmode(struct dchannel *dch)
 		HFC_outb(hc, R_TX_FR0, 0x00);
 		HFC_outb(hc, R_TX_FR1, 0xf8);
 
-		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
 			HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
 
 		HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
 
-		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
+		if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
 			HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
 
 		if (dch->dev.D.protocol == ISDN_P_NT_E1) {
@@ -3957,7 +3971,7 @@ hfcmulti_initmode(struct dchannel *dch)
 			plxsd_checksync(hc, 0);
 		}
 	} else {
-		i = dch->slot;
+		/* ST */
 		hc->chan[i].slot_tx = -1;
 		hc->chan[i].slot_rx = -1;
 		hc->chan[i].conf = -1;
@@ -3973,8 +3987,6 @@ hfcmulti_initmode(struct dchannel *dch)
 		hc->chan[i - 1].slot_rx = -1;
 		hc->chan[i - 1].conf = -1;
 		mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
-		/* ST */
-		pt = hc->chan[i].port;
 		/* select interface */
 		HFC_outb(hc, R_ST_SEL, pt);
 		/* undocumented: delay after R_ST_SEL */
@@ -4557,6 +4569,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
 		}
 		/* free channels */
 		for (i = 0; i <= 31; i++) {
+			if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
+				continue;
 			if (hc->chan[i].bch) {
 				if (debug & DEBUG_HFCMULTI_INIT)
 					printk(KERN_DEBUG
@@ -4680,12 +4694,13 @@ release_card(struct hfc_multi *hc)
 }
 
 static int
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
 {
 	struct dchannel	*dch;
 	struct bchannel	*bch;
 	int		ch, ret = 0;
 	char		name[MISDN_MAX_IDLEN];
+	int		bcount = 0;
 
 	dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
 	if (!dch)
@@ -4698,13 +4713,12 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 	    (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
 	dch->dev.D.send = handle_dmsg;
 	dch->dev.D.ctrl = hfcm_dctrl;
-	dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
-	dch->slot = hc->dslot;
-	hc->chan[hc->dslot].dch = dch;
-	hc->chan[hc->dslot].port = 0;
-	hc->chan[hc->dslot].nt_timer = -1;
+	dch->slot = hc->dnum[pt];
+	hc->chan[hc->dnum[pt]].dch = dch;
+	hc->chan[hc->dnum[pt]].port = pt;
+	hc->chan[hc->dnum[pt]].nt_timer = -1;
 	for (ch = 1; ch <= 31; ch++) {
-		if (ch == hc->dslot) /* skip dchannel */
+		if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
 			continue;
 		bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
 		if (!bch) {
@@ -4733,7 +4747,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 		hc->chan[ch].bch = bch;
 		hc->chan[ch].port = 0;
 		set_channelmap(bch->nr, dch->dev.channelmap);
+		bcount++;
 	}
+	dch->dev.nrbchan = bcount;
+#warning todo: must be set globally, and must be a seperate function
 	/* set optical line type */
 	if (port[Port_cnt] & 0x001) {
 		if (!m->opticalsupport)  {
@@ -4749,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 				    __func__,
 				    HFC_cnt + 1, 1);
 			test_and_set_bit(HFC_CFG_OPTICAL,
-			    &hc->chan[hc->dslot].cfg);
+			    &hc->chan[hc->dnum[pt]].cfg);
 		}
 	}
 	/* set LOS report */
@@ -4759,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 			    "LOS report: card(%d) port(%d)\n",
 			    __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_LOS,
-		    &hc->chan[hc->dslot].cfg);
+		    &hc->chan[hc->dnum[pt]].cfg);
 	}
 	/* set AIS report */
 	if (port[Port_cnt] & 0x008) {
@@ -4768,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 			    "AIS report: card(%d) port(%d)\n",
 			    __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_AIS,
-		    &hc->chan[hc->dslot].cfg);
+		    &hc->chan[hc->dnum[pt]].cfg);
 	}
 	/* set SLIP report */
 	if (port[Port_cnt] & 0x010) {
@@ -4778,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 			    "card(%d) port(%d)\n",
 			    __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_SLIP,
-		    &hc->chan[hc->dslot].cfg);
+		    &hc->chan[hc->dnum[pt]].cfg);
 	}
 	/* set RDI report */
 	if (port[Port_cnt] & 0x020) {
@@ -4788,7 +4805,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 			    "card(%d) port(%d)\n",
 			    __func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_REPORT_RDI,
-		    &hc->chan[hc->dslot].cfg);
+		    &hc->chan[hc->dnum[pt]].cfg);
 	}
 	/* set CRC-4 Mode */
 	if (!(port[Port_cnt] & 0x100)) {
@@ -4797,7 +4814,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 				" card(%d) port(%d)\n",
 				__func__, HFC_cnt + 1, 1);
 		test_and_set_bit(HFC_CFG_CRC4,
-		    &hc->chan[hc->dslot].cfg);
+		    &hc->chan[hc->dnum[pt]].cfg);
 	} else {
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG "%s: PORT turn off CRC4"
@@ -4829,20 +4846,23 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
 	}
 	/* set elastic jitter buffer */
 	if (port[Port_cnt] & 0x3000) {
-		hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
+		hc->chan[hc->dnum[pt]].jitter = (port[Port_cnt]>>12) & 0x3;
 		if (debug & DEBUG_HFCMULTI_INIT)
 			printk(KERN_DEBUG
 			    "%s: PORT set elastic "
 			    "buffer to %d: card(%d) port(%d)\n",
-			    __func__, hc->chan[hc->dslot].jitter,
+			    __func__, hc->chan[hc->dnum[pt]].jitter,
 			    HFC_cnt + 1, 1);
 	} else
-		hc->chan[hc->dslot].jitter = 2; /* default */
-	snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
+		hc->chan[hc->dnum[pt]].jitter = 2; /* default */
+	if (hc->ports > 1)
+		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", HFC_cnt + 1, pt+1);
+	else
+		snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
 	ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
 	if (ret)
 		goto free_chan;
-	hc->created[0] = 1;
+	hc->created[pt] = 1;
 	return ret;
 free_chan:
 	release_port(hc, dch);
@@ -5009,18 +5029,30 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 	hc->id = HFC_cnt;
 	hc->pcm = pcm[HFC_cnt];
 	hc->io_mode = iomode[HFC_cnt];
+#warning todo: rework module parameters for customizing e1 fragments.... yea, let''s call it: fragments
 	if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
-		hc->dslot = 0;
+		hc->dnum[0] = 0;
 		printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
 			"31 B-channels\n");
 	}
 	if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
 	    && hc->ctype == HFC_TYPE_E1) {
-		hc->dslot = dslot[HFC_cnt];
+		hc->dnum[0] = dslot[HFC_cnt];
 		printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
 			"time slot %d\n", dslot[HFC_cnt]);
 	} else
-		hc->dslot = 16;
+		hc->dnum[0] = 16;
+
+#warning todo HACK!!! just a small map of two "fragments"
+	if (hc->ctype == HFC_TYPE_E1) {
+		hc->dnum[0] = 1;
+		hc->bmask[0] = 0x0000003c;
+		hc->dnum[1] = 6;
+		hc->bmask[1] = 0x00000780;
+		hc->dnum[2] = 11;
+		hc->bmask[2] = 0x00007800;
+		hc->ports = 3;
+	}
 
 	/* set chip specific features */
 	hc->masterclk = -1;
@@ -5103,7 +5135,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 			goto free_card;
 		}
 		if (hc->ctype == HFC_TYPE_E1)
-			ret_err = init_e1_port(hc, m);
+			ret_err = init_e1_port(hc, m, pt);
 		else
 			ret_err = init_multi_port(hc, pt);
 		if (debug & DEBUG_HFCMULTI_INIT)
@@ -5115,10 +5147,14 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
 		if (ret_err) {
 			while (pt) { /* release already registered ports */
 				pt--;
-				release_port(hc, hc->chan[(pt << 2) + 2].dch);
+				if (hc->ctype == HFC_TYPE_E1)
+					release_port(hc, hc->chan[hc->dnum[pt]].dch);
+				else
+					release_port(hc, hc->chan[(pt << 2) + 2].dch);
 			}
 			goto free_card;
 		}
+#warning todo: count it right, add additional "fragment" counter...
 		Port_cnt++;
 	}