aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/Kconfig6
-rw-r--r--drivers/isdn/act2000/capi.c3
-rw-r--r--drivers/isdn/act2000/module.c31
-rw-r--r--drivers/isdn/gigaset/ev-layer.c44
-rw-r--r--drivers/isdn/gigaset/isocdata.c6
-rw-r--r--drivers/isdn/hardware/eicon/message.c4
-rw-r--r--drivers/isdn/hardware/eicon/os_4bri.c3
-rw-r--r--drivers/isdn/hardware/mISDN/Kconfig51
-rw-r--r--drivers/isdn/hardware/mISDN/Makefile8
-rw-r--r--drivers/isdn/hardware/mISDN/avmfritz.c1152
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c23
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c16
-rw-r--r--drivers/isdn/hardware/mISDN/hfcsusb.c16
-rw-r--r--drivers/isdn/hardware/mISDN/iohelper.h109
-rw-r--r--drivers/isdn/hardware/mISDN/ipac.h405
-rw-r--r--drivers/isdn/hardware/mISDN/isar.h269
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNinfineon.c1178
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNipac.c1655
-rw-r--r--drivers/isdn/hardware/mISDN/mISDNisar.c1726
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.c1156
-rw-r--r--drivers/isdn/hardware/mISDN/netjet.h58
-rw-r--r--drivers/isdn/hardware/mISDN/speedfax.c526
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.c1440
-rw-r--r--drivers/isdn/hardware/mISDN/w6692.h190
-rw-r--r--drivers/isdn/hisax/Kconfig6
-rw-r--r--drivers/isdn/hisax/Makefile4
-rw-r--r--drivers/isdn/hisax/amd7930_fn.c2
-rw-r--r--drivers/isdn/hisax/callc.c4
-rw-r--r--drivers/isdn/hisax/hfc_pci.c2
-rw-r--r--drivers/isdn/hisax/hfc_sx.c2
-rw-r--r--drivers/isdn/hisax/icc.c2
-rw-r--r--drivers/isdn/hisax/isac.c2
-rw-r--r--drivers/isdn/hisax/isdnhdlc.h70
-rw-r--r--drivers/isdn/hisax/isdnl1.c12
-rw-r--r--drivers/isdn/hisax/isdnl2.c4
-rw-r--r--drivers/isdn/hisax/isdnl3.c4
-rw-r--r--drivers/isdn/hisax/l3_1tr6.c20
-rw-r--r--drivers/isdn/hisax/l3dss1.c26
-rw-r--r--drivers/isdn/hisax/l3ni1.c26
-rw-r--r--drivers/isdn/hisax/q931.c24
-rw-r--r--drivers/isdn/hisax/st5481.h2
-rw-r--r--drivers/isdn/hisax/st5481_b.c5
-rw-r--r--drivers/isdn/hisax/st5481_d.c2
-rw-r--r--drivers/isdn/hisax/st5481_usb.c11
-rw-r--r--drivers/isdn/hisax/tei.c4
-rw-r--r--drivers/isdn/hisax/w6692.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_net.c2
-rw-r--r--drivers/isdn/i4l/Kconfig11
-rw-r--r--drivers/isdn/i4l/Makefile1
-rw-r--r--drivers/isdn/i4l/isdn_net.c16
-rw-r--r--drivers/isdn/i4l/isdn_ppp.c6
-rw-r--r--drivers/isdn/i4l/isdnhdlc.c (renamed from drivers/isdn/hisax/isdnhdlc.c)429
-rw-r--r--drivers/isdn/mISDN/hwchannel.c15
-rw-r--r--drivers/isdn/mISDN/layer2.c2
54 files changed, 10290 insertions, 503 deletions
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig
index 02bdca6f95c3..022a19452953 100644
--- a/drivers/isdn/Kconfig
+++ b/drivers/isdn/Kconfig
@@ -21,8 +21,6 @@ menuconfig ISDN
21 21
22if ISDN 22if ISDN
23 23
24source "drivers/isdn/mISDN/Kconfig"
25
26menuconfig ISDN_I4L 24menuconfig ISDN_I4L
27 tristate "Old ISDN4Linux (deprecated)" 25 tristate "Old ISDN4Linux (deprecated)"
28 ---help--- 26 ---help---
@@ -41,9 +39,9 @@ menuconfig ISDN_I4L
41 It is still available, though, for use with adapters that are not 39 It is still available, though, for use with adapters that are not
42 supported by the new CAPI subsystem yet. 40 supported by the new CAPI subsystem yet.
43 41
44if ISDN_I4L 42source "drivers/isdn/mISDN/Kconfig"
43
45source "drivers/isdn/i4l/Kconfig" 44source "drivers/isdn/i4l/Kconfig"
46endif
47 45
48menuconfig ISDN_CAPI 46menuconfig ISDN_CAPI
49 tristate "CAPI 2.0 subsystem" 47 tristate "CAPI 2.0 subsystem"
diff --git a/drivers/isdn/act2000/capi.c b/drivers/isdn/act2000/capi.c
index 946c38cf6f8a..1f0a94906465 100644
--- a/drivers/isdn/act2000/capi.c
+++ b/drivers/isdn/act2000/capi.c
@@ -78,7 +78,6 @@ static actcapi_msgdsc valid_msg[] = {
78#endif 78#endif
79 {{ 0x00, 0x00}, NULL}, 79 {{ 0x00, 0x00}, NULL},
80}; 80};
81#define num_valid_msg (sizeof(valid_msg)/sizeof(actcapi_msgdsc))
82#define num_valid_imsg 27 /* MANUFACTURER_IND */ 81#define num_valid_imsg 27 /* MANUFACTURER_IND */
83 82
84/* 83/*
@@ -1025,7 +1024,7 @@ actcapi_debug_msg(struct sk_buff *skb, int direction)
1025#ifdef DEBUG_DUMP_SKB 1024#ifdef DEBUG_DUMP_SKB
1026 dump_skb(skb); 1025 dump_skb(skb);
1027#endif 1026#endif
1028 for (i = 0; i < num_valid_msg; i++) 1027 for (i = 0; i < ARRAY_SIZE(valid_msg); i++)
1029 if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) && 1028 if ((msg->hdr.cmd.cmd == valid_msg[i].cmd.cmd) &&
1030 (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) { 1029 (msg->hdr.cmd.subcmd == valid_msg[i].cmd.subcmd)) {
1031 descr = valid_msg[i].description; 1030 descr = valid_msg[i].description;
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c
index 8325022e2bed..f774e12bb64d 100644
--- a/drivers/isdn/act2000/module.c
+++ b/drivers/isdn/act2000/module.c
@@ -23,7 +23,6 @@ static unsigned short act2000_isa_ports[] =
23 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380, 23 0x0200, 0x0240, 0x0280, 0x02c0, 0x0300, 0x0340, 0x0380,
24 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60, 24 0xcfe0, 0xcfa0, 0xcf60, 0xcf20, 0xcee0, 0xcea0, 0xce60,
25}; 25};
26#define ISA_NRPORTS (sizeof(act2000_isa_ports)/sizeof(unsigned short))
27 26
28static act2000_card *cards = (act2000_card *) NULL; 27static act2000_card *cards = (act2000_card *) NULL;
29 28
@@ -686,21 +685,21 @@ act2000_addcard(int bus, int port, int irq, char *id)
686 * This may result in more than one card detected. 685 * This may result in more than one card detected.
687 */ 686 */
688 switch (bus) { 687 switch (bus) {
689 case ACT2000_BUS_ISA: 688 case ACT2000_BUS_ISA:
690 for (i = 0; i < ISA_NRPORTS; i++) 689 for (i = 0; i < ARRAY_SIZE(act2000_isa_ports); i++)
691 if (act2000_isa_detect(act2000_isa_ports[i])) { 690 if (act2000_isa_detect(act2000_isa_ports[i])) {
692 printk(KERN_INFO 691 printk(KERN_INFO "act2000: Detected "
693 "act2000: Detected ISA card at port 0x%x\n", 692 "ISA card at port 0x%x\n",
694 act2000_isa_ports[i]); 693 act2000_isa_ports[i]);
695 act2000_alloccard(bus, act2000_isa_ports[i], irq, id); 694 act2000_alloccard(bus,
696 } 695 act2000_isa_ports[i], irq, id);
697 break; 696 }
698 case ACT2000_BUS_MCA: 697 break;
699 case ACT2000_BUS_PCMCIA: 698 case ACT2000_BUS_MCA:
700 default: 699 case ACT2000_BUS_PCMCIA:
701 printk(KERN_WARNING 700 default:
702 "act2000: addcard: Invalid BUS type %d\n", 701 printk(KERN_WARNING
703 bus); 702 "act2000: addcard: Invalid BUS type %d\n", bus);
704 } 703 }
705 } 704 }
706 if (!cards) 705 if (!cards)
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index ec5169604a6a..2d91049571a4 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -294,32 +294,33 @@ struct reply_t gigaset_tab_cid[] =
294 {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}}, 294 {RSP_OK, 604,604, -1, 605, 5, {ACT_CMD+AT_MSN}},
295 {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, 295 {RSP_OK, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}},
296 {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}}, 296 {RSP_NULL, 605,605, -1, 606, 5, {ACT_CMD+AT_ISO}},
297 {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"}, /* set "Endgeraetemodus" */ 297 {RSP_OK, 606,606, -1, 607, 5, {0}, "+VLS=17\r"},
298 {RSP_OK, 607,607, -1, 608,-1}, 298 {RSP_OK, 607,607, -1, 608,-1},
299 //{RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 608, 0, {ACT_ERROR}},//DELETE
300 {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}}, 299 {RSP_ZSAU, 608,608,ZSAU_PROCEEDING, 609, 5, {ACT_CMD+AT_DIAL}},
301 {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}}, 300 {RSP_OK, 609,609, -1, 650, 0, {ACT_DIALING}},
302 301
303 {RSP_ZVLS, 608,608, 17, -1,-1, {ACT_DEBUG}},
304 {RSP_ZCTP, 609,609, -1, -1,-1, {ACT_DEBUG}},
305 {RSP_ZCPN, 609,609, -1, -1,-1, {ACT_DEBUG}},
306 {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, 302 {RSP_ERROR, 601,609, -1, 0, 0, {ACT_ABORTDIAL}},
307 {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}}, 303 {EV_TIMEOUT, 601,609, -1, 0, 0, {ACT_ABORTDIAL}},
308 304
309 /* dialing */ 305 /* optional dialing responses */
310 {RSP_ZCTP, 650,650, -1, -1,-1, {ACT_DEBUG}}, 306 {EV_BC_OPEN, 650,650, -1, 651,-1},
311 {RSP_ZCPN, 650,650, -1, -1,-1, {ACT_DEBUG}}, 307 {RSP_ZVLS, 608,651, 17, -1,-1, {ACT_DEBUG}},
312 {RSP_ZSAU, 650,650,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}}, /* some devices don't send this */ 308 {RSP_ZCTP, 609,651, -1, -1,-1, {ACT_DEBUG}},
313 309 {RSP_ZCPN, 609,651, -1, -1,-1, {ACT_DEBUG}},
314 /* connection established */ 310 {RSP_ZSAU, 650,651,ZSAU_CALL_DELIVERED, -1,-1, {ACT_DEBUG}},
315 {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1 311
316 {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}}, //FIXME -> DLE1 312 /* connect */
317 313 {RSP_ZSAU, 650,650,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}},
318 {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}}, //FIXME new constate + timeout 314 {RSP_ZSAU, 651,651,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT,
315 ACT_NOTIFY_BC_UP}},
316 {RSP_ZSAU, 750,750,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT}},
317 {RSP_ZSAU, 751,751,ZSAU_ACTIVE, 800,-1, {ACT_CONNECT,
318 ACT_NOTIFY_BC_UP}},
319 {EV_BC_OPEN, 800,800, -1, 800,-1, {ACT_NOTIFY_BC_UP}},
319 320
320 /* remote hangup */ 321 /* remote hangup */
321 {RSP_ZSAU, 650,650,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}}, 322 {RSP_ZSAU, 650,651,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEREJECT}},
322 {RSP_ZSAU, 750,750,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, 323 {RSP_ZSAU, 750,751,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
323 {RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}}, 324 {RSP_ZSAU, 800,800,ZSAU_DISCONNECT_IND, 0, 0, {ACT_REMOTEHUP}},
324 325
325 /* hangup */ 326 /* hangup */
@@ -358,7 +359,8 @@ struct reply_t gigaset_tab_cid[] =
358 {RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}}, 359 {RSP_ZSAU, 700,729,ZSAU_ACTIVE, 0, 0, {ACT_ABORTACCEPT}},
359 {RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}}, 360 {RSP_ZSAU, 700,729,ZSAU_DISCONNECT_IND, 0, 0, {ACT_ABORTACCEPT}},
360 361
361 {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, 362 {EV_BC_OPEN, 750,750, -1, 751,-1},
363 {EV_TIMEOUT, 750,751, -1, 0, 0, {ACT_CONNTIMEOUT}},
362 364
363 /* B channel closed (general case) */ 365 /* B channel closed (general case) */
364 {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME 366 {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
@@ -876,12 +878,6 @@ static void bchannel_down(struct bc_state *bcs)
876 878
877static void bchannel_up(struct bc_state *bcs) 879static void bchannel_up(struct bc_state *bcs)
878{ 880{
879 if (!(bcs->chstate & CHS_D_UP)) {
880 dev_notice(bcs->cs->dev, "%s: D channel not up\n", __func__);
881 bcs->chstate |= CHS_D_UP;
882 gigaset_i4l_channel_cmd(bcs, ISDN_STAT_DCONN);
883 }
884
885 if (bcs->chstate & CHS_B_UP) { 881 if (bcs->chstate & CHS_B_UP) {
886 dev_notice(bcs->cs->dev, "%s: B channel already up\n", 882 dev_notice(bcs->cs->dev, "%s: B channel already up\n",
887 __func__); 883 __func__);
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index db3a1e4cd489..bed38fcc432b 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -174,12 +174,6 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size)
174 pr_err("invalid size %d\n", size); 174 pr_err("invalid size %d\n", size);
175 return -EINVAL; 175 return -EINVAL;
176 } 176 }
177 src = iwb->read;
178 if (unlikely(limit >= BAS_OUTBUFSIZE + BAS_OUTBUFPAD ||
179 (read < src && limit >= src))) {
180 pr_err("isoc write buffer frame reservation violated\n");
181 return -EFAULT;
182 }
183#endif 177#endif
184 178
185 if (read < write) { 179 if (read < write) {
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c
index 31f91c18c698..27d5dd68f4fb 100644
--- a/drivers/isdn/hardware/eicon/message.c
+++ b/drivers/isdn/hardware/eicon/message.c
@@ -551,9 +551,7 @@ word api_put(APPL * appl, CAPI_MSG * msg)
551 dbug(1,dprintf("com=%x",msg->header.command)); 551 dbug(1,dprintf("com=%x",msg->header.command));
552 552
553 for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0; 553 for(j=0;j<MAX_MSG_PARMS+1;j++) msg_parms[j].length = 0;
554 for(i=0, ret = _BAD_MSG; 554 for(i=0, ret = _BAD_MSG; i < ARRAY_SIZE(ftable); i++) {
555 i<(sizeof(ftable)/sizeof(struct _ftable));
556 i++) {
557 555
558 if(ftable[i].command==msg->header.command) { 556 if(ftable[i].command==msg->header.command) {
559 /* break loop if the message is correct, otherwise continue scan */ 557 /* break loop if the message is correct, otherwise continue scan */
diff --git a/drivers/isdn/hardware/eicon/os_4bri.c b/drivers/isdn/hardware/eicon/os_4bri.c
index c964b8d91ada..cb7616c5b60a 100644
--- a/drivers/isdn/hardware/eicon/os_4bri.c
+++ b/drivers/isdn/hardware/eicon/os_4bri.c
@@ -149,8 +149,7 @@ int diva_4bri_init_card(diva_os_xdi_adapter_t * a)
149 diva_os_xdi_adapter_t *diva_current; 149 diva_os_xdi_adapter_t *diva_current;
150 diva_os_xdi_adapter_t *adapter_list[4]; 150 diva_os_xdi_adapter_t *adapter_list[4];
151 PISDN_ADAPTER Slave; 151 PISDN_ADAPTER Slave;
152 unsigned long bar_length[sizeof(_4bri_bar_length) / 152 unsigned long bar_length[ARRAY_SIZE(_4bri_bar_length)];
153 sizeof(_4bri_bar_length[0])];
154 int v2 = _4bri_is_rev_2_card(a->CardOrdinal); 153 int v2 = _4bri_is_rev_2_card(a->CardOrdinal);
155 int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT; 154 int tasks = _4bri_is_rev_2_bri_card(a->CardOrdinal) ? 1 : MQ_INSTANCE_COUNT;
156 int factor = (tasks == 1) ? 1 : 2; 155 int factor = (tasks == 1) ? 1 : 2;
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig
index 3024566dd099..bde55d7287fa 100644
--- a/drivers/isdn/hardware/mISDN/Kconfig
+++ b/drivers/isdn/hardware/mISDN/Kconfig
@@ -39,3 +39,54 @@ config MISDN_HFCUSB
39 Enable support for USB ISDN TAs with Cologne Chip AG's 39 Enable support for USB ISDN TAs with Cologne Chip AG's
40 HFC-S USB ISDN Controller 40 HFC-S USB ISDN Controller
41 41
42config MISDN_AVMFRITZ
43 tristate "Support for AVM FRITZ!CARD PCI"
44 depends on MISDN
45 depends on PCI
46 select MISDN_IPAC
47 help
48 Enable support for AVMs FRITZ!CARD PCI cards
49
50config MISDN_SPEEDFAX
51 tristate "Support for Sedlbauer Speedfax+"
52 depends on MISDN
53 depends on PCI
54 select MISDN_IPAC
55 select MISDN_ISAR
56 help
57 Enable support for Sedlbauer Speedfax+.
58
59config MISDN_INFINEON
60 tristate "Support for cards with Infineon chipset"
61 depends on MISDN
62 depends on PCI
63 select MISDN_IPAC
64 help
65 Enable support for cards with ISAC + HSCX, IPAC or IPAC-SX
66 chip from Infineon (former manufacturer Siemens).
67
68config MISDN_W6692
69 tristate "Support for cards with Winbond 6692"
70 depends on MISDN
71 depends on PCI
72 help
73 Enable support for Winbond 6692 PCI chip based cards.
74
75config MISDN_NETJET
76 tristate "Support for NETJet cards"
77 depends on MISDN
78 depends on PCI
79 select MISDN_IPAC
80 select ISDN_HDLC
81 help
82 Enable support for Traverse Technologies NETJet PCI cards.
83
84
85config MISDN_IPAC
86 tristate
87 depends on MISDN
88
89config MISDN_ISAR
90 tristate
91 depends on MISDN
92
diff --git a/drivers/isdn/hardware/mISDN/Makefile b/drivers/isdn/hardware/mISDN/Makefile
index b0403526bbba..2987d990993f 100644
--- a/drivers/isdn/hardware/mISDN/Makefile
+++ b/drivers/isdn/hardware/mISDN/Makefile
@@ -6,3 +6,11 @@
6obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o 6obj-$(CONFIG_MISDN_HFCPCI) += hfcpci.o
7obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o 7obj-$(CONFIG_MISDN_HFCMULTI) += hfcmulti.o
8obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o 8obj-$(CONFIG_MISDN_HFCUSB) += hfcsusb.o
9obj-$(CONFIG_MISDN_AVMFRITZ) += avmfritz.o
10obj-$(CONFIG_MISDN_SPEEDFAX) += speedfax.o
11obj-$(CONFIG_MISDN_INFINEON) += mISDNinfineon.o
12obj-$(CONFIG_MISDN_W6692) += w6692.o
13obj-$(CONFIG_MISDN_NETJET) += netjet.o
14# chip modules
15obj-$(CONFIG_MISDN_IPAC) += mISDNipac.o
16obj-$(CONFIG_MISDN_ISAR) += mISDNisar.o
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c
new file mode 100644
index 000000000000..81ac541d40d9
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/avmfritz.c
@@ -0,0 +1,1152 @@
1/*
2 * avm_fritz.c low level stuff for AVM FRITZ!CARD PCI ISDN cards
3 * Thanks to AVM, Berlin for informations
4 *
5 * Author Karsten Keil <keil@isdn4linux.de>
6 *
7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23#include <linux/module.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26#include <linux/mISDNhw.h>
27#include <asm/unaligned.h>
28#include "ipac.h"
29
30
31#define AVMFRITZ_REV "2.1"
32
33static int AVM_cnt;
34static int debug;
35
36enum {
37 AVM_FRITZ_PCI,
38 AVM_FRITZ_PCIV2,
39};
40
41#define HDLC_FIFO 0x0
42#define HDLC_STATUS 0x4
43#define CHIP_WINDOW 0x10
44
45#define CHIP_INDEX 0x4
46#define AVM_HDLC_1 0x00
47#define AVM_HDLC_2 0x01
48#define AVM_ISAC_FIFO 0x02
49#define AVM_ISAC_REG_LOW 0x04
50#define AVM_ISAC_REG_HIGH 0x06
51
52#define AVM_STATUS0_IRQ_ISAC 0x01
53#define AVM_STATUS0_IRQ_HDLC 0x02
54#define AVM_STATUS0_IRQ_TIMER 0x04
55#define AVM_STATUS0_IRQ_MASK 0x07
56
57#define AVM_STATUS0_RESET 0x01
58#define AVM_STATUS0_DIS_TIMER 0x02
59#define AVM_STATUS0_RES_TIMER 0x04
60#define AVM_STATUS0_ENA_IRQ 0x08
61#define AVM_STATUS0_TESTBIT 0x10
62
63#define AVM_STATUS1_INT_SEL 0x0f
64#define AVM_STATUS1_ENA_IOM 0x80
65
66#define HDLC_MODE_ITF_FLG 0x01
67#define HDLC_MODE_TRANS 0x02
68#define HDLC_MODE_CCR_7 0x04
69#define HDLC_MODE_CCR_16 0x08
70#define HDLC_MODE_TESTLOOP 0x80
71
72#define HDLC_INT_XPR 0x80
73#define HDLC_INT_XDU 0x40
74#define HDLC_INT_RPR 0x20
75#define HDLC_INT_MASK 0xE0
76
77#define HDLC_STAT_RME 0x01
78#define HDLC_STAT_RDO 0x10
79#define HDLC_STAT_CRCVFRRAB 0x0E
80#define HDLC_STAT_CRCVFR 0x06
81#define HDLC_STAT_RML_MASK 0x3f00
82
83#define HDLC_CMD_XRS 0x80
84#define HDLC_CMD_XME 0x01
85#define HDLC_CMD_RRS 0x20
86#define HDLC_CMD_XML_MASK 0x3f00
87#define HDLC_FIFO_SIZE 32
88
89/* Fritz PCI v2.0 */
90
91#define AVM_HDLC_FIFO_1 0x10
92#define AVM_HDLC_FIFO_2 0x18
93
94#define AVM_HDLC_STATUS_1 0x14
95#define AVM_HDLC_STATUS_2 0x1c
96
97#define AVM_ISACX_INDEX 0x04
98#define AVM_ISACX_DATA 0x08
99
100/* data struct */
101#define LOG_SIZE 63
102
103struct hdlc_stat_reg {
104#ifdef __BIG_ENDIAN
105 u8 fill;
106 u8 mode;
107 u8 xml;
108 u8 cmd;
109#else
110 u8 cmd;
111 u8 xml;
112 u8 mode;
113 u8 fill;
114#endif
115} __attribute__((packed));
116
117struct hdlc_hw {
118 union {
119 u32 ctrl;
120 struct hdlc_stat_reg sr;
121 } ctrl;
122 u32 stat;
123};
124
125struct fritzcard {
126 struct list_head list;
127 struct pci_dev *pdev;
128 char name[MISDN_MAX_IDLEN];
129 u8 type;
130 u8 ctrlreg;
131 u16 irq;
132 u32 irqcnt;
133 u32 addr;
134 spinlock_t lock; /* hw lock */
135 struct isac_hw isac;
136 struct hdlc_hw hdlc[2];
137 struct bchannel bch[2];
138 char log[LOG_SIZE + 1];
139};
140
141static LIST_HEAD(Cards);
142static DEFINE_RWLOCK(card_lock); /* protect Cards */
143
144static void
145_set_debug(struct fritzcard *card)
146{
147 card->isac.dch.debug = debug;
148 card->bch[0].debug = debug;
149 card->bch[1].debug = debug;
150}
151
152static int
153set_debug(const char *val, struct kernel_param *kp)
154{
155 int ret;
156 struct fritzcard *card;
157
158 ret = param_set_uint(val, kp);
159 if (!ret) {
160 read_lock(&card_lock);
161 list_for_each_entry(card, &Cards, list)
162 _set_debug(card);
163 read_unlock(&card_lock);
164 }
165 return ret;
166}
167
168MODULE_AUTHOR("Karsten Keil");
169MODULE_LICENSE("GPL v2");
170MODULE_VERSION(AVMFRITZ_REV);
171module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
172MODULE_PARM_DESC(debug, "avmfritz debug mask");
173
174/* Interface functions */
175
176static u8
177ReadISAC_V1(void *p, u8 offset)
178{
179 struct fritzcard *fc = p;
180 u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
181
182 outb(idx, fc->addr + CHIP_INDEX);
183 return inb(fc->addr + CHIP_WINDOW + (offset & 0xf));
184}
185
186static void
187WriteISAC_V1(void *p, u8 offset, u8 value)
188{
189 struct fritzcard *fc = p;
190 u8 idx = (offset > 0x2f) ? AVM_ISAC_REG_HIGH : AVM_ISAC_REG_LOW;
191
192 outb(idx, fc->addr + CHIP_INDEX);
193 outb(value, fc->addr + CHIP_WINDOW + (offset & 0xf));
194}
195
196static void
197ReadFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
198{
199 struct fritzcard *fc = p;
200
201 outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
202 insb(fc->addr + CHIP_WINDOW, data, size);
203}
204
205static void
206WriteFiFoISAC_V1(void *p, u8 off, u8 *data, int size)
207{
208 struct fritzcard *fc = p;
209
210 outb(AVM_ISAC_FIFO, fc->addr + CHIP_INDEX);
211 outsb(fc->addr + CHIP_WINDOW, data, size);
212}
213
214static u8
215ReadISAC_V2(void *p, u8 offset)
216{
217 struct fritzcard *fc = p;
218
219 outl(offset, fc->addr + AVM_ISACX_INDEX);
220 return 0xff & inl(fc->addr + AVM_ISACX_DATA);
221}
222
223static void
224WriteISAC_V2(void *p, u8 offset, u8 value)
225{
226 struct fritzcard *fc = p;
227
228 outl(offset, fc->addr + AVM_ISACX_INDEX);
229 outl(value, fc->addr + AVM_ISACX_DATA);
230}
231
232static void
233ReadFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
234{
235 struct fritzcard *fc = p;
236 int i;
237
238 outl(off, fc->addr + AVM_ISACX_INDEX);
239 for (i = 0; i < size; i++)
240 data[i] = 0xff & inl(fc->addr + AVM_ISACX_DATA);
241}
242
243static void
244WriteFiFoISAC_V2(void *p, u8 off, u8 *data, int size)
245{
246 struct fritzcard *fc = p;
247 int i;
248
249 outl(off, fc->addr + AVM_ISACX_INDEX);
250 for (i = 0; i < size; i++)
251 outl(data[i], fc->addr + AVM_ISACX_DATA);
252}
253
254static struct bchannel *
255Sel_BCS(struct fritzcard *fc, u32 channel)
256{
257 if (test_bit(FLG_ACTIVE, &fc->bch[0].Flags) &&
258 (fc->bch[0].nr & channel))
259 return &fc->bch[0];
260 else if (test_bit(FLG_ACTIVE, &fc->bch[1].Flags) &&
261 (fc->bch[1].nr & channel))
262 return &fc->bch[1];
263 else
264 return NULL;
265}
266
267static inline void
268__write_ctrl_pci(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
269 u32 idx = channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1;
270
271 outl(idx, fc->addr + CHIP_INDEX);
272 outl(hdlc->ctrl.ctrl, fc->addr + CHIP_WINDOW + HDLC_STATUS);
273}
274
275static inline void
276__write_ctrl_pciv2(struct fritzcard *fc, struct hdlc_hw *hdlc, u32 channel) {
277 outl(hdlc->ctrl.ctrl, fc->addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
278 AVM_HDLC_STATUS_1));
279}
280
281void
282write_ctrl(struct bchannel *bch, int which) {
283 struct fritzcard *fc = bch->hw;
284 struct hdlc_hw *hdlc;
285
286 hdlc = &fc->hdlc[(bch->nr - 1) & 1];
287 pr_debug("%s: hdlc %c wr%x ctrl %x\n", fc->name, '@' + bch->nr,
288 which, hdlc->ctrl.ctrl);
289 switch (fc->type) {
290 case AVM_FRITZ_PCIV2:
291 __write_ctrl_pciv2(fc, hdlc, bch->nr);
292 break;
293 case AVM_FRITZ_PCI:
294 __write_ctrl_pci(fc, hdlc, bch->nr);
295 break;
296 }
297}
298
299
300static inline u32
301__read_status_pci(u_long addr, u32 channel)
302{
303 outl(channel == 2 ? AVM_HDLC_2 : AVM_HDLC_1, addr + CHIP_INDEX);
304 return inl(addr + CHIP_WINDOW + HDLC_STATUS);
305}
306
307static inline u32
308__read_status_pciv2(u_long addr, u32 channel)
309{
310 return inl(addr + (channel == 2 ? AVM_HDLC_STATUS_2 :
311 AVM_HDLC_STATUS_1));
312}
313
314
315static u32
316read_status(struct fritzcard *fc, u32 channel)
317{
318 switch (fc->type) {
319 case AVM_FRITZ_PCIV2:
320 return __read_status_pciv2(fc->addr, channel);
321 case AVM_FRITZ_PCI:
322 return __read_status_pci(fc->addr, channel);
323 }
324 /* dummy */
325 return 0;
326}
327
328static void
329enable_hwirq(struct fritzcard *fc)
330{
331 fc->ctrlreg |= AVM_STATUS0_ENA_IRQ;
332 outb(fc->ctrlreg, fc->addr + 2);
333}
334
335static void
336disable_hwirq(struct fritzcard *fc)
337{
338 fc->ctrlreg &= ~AVM_STATUS0_ENA_IRQ;
339 outb(fc->ctrlreg, fc->addr + 2);
340}
341
342static int
343modehdlc(struct bchannel *bch, int protocol)
344{
345 struct fritzcard *fc = bch->hw;
346 struct hdlc_hw *hdlc;
347
348 hdlc = &fc->hdlc[(bch->nr - 1) & 1];
349 pr_debug("%s: hdlc %c protocol %x-->%x ch %d\n", fc->name,
350 '@' + bch->nr, bch->state, protocol, bch->nr);
351 hdlc->ctrl.ctrl = 0;
352 switch (protocol) {
353 case -1: /* used for init */
354 bch->state = -1;
355 case ISDN_P_NONE:
356 if (bch->state == ISDN_P_NONE)
357 break;
358 hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
359 hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
360 write_ctrl(bch, 5);
361 bch->state = ISDN_P_NONE;
362 test_and_clear_bit(FLG_HDLC, &bch->Flags);
363 test_and_clear_bit(FLG_TRANSPARENT, &bch->Flags);
364 break;
365 case ISDN_P_B_RAW:
366 bch->state = protocol;
367 hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
368 hdlc->ctrl.sr.mode = HDLC_MODE_TRANS;
369 write_ctrl(bch, 5);
370 hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
371 write_ctrl(bch, 1);
372 hdlc->ctrl.sr.cmd = 0;
373 test_and_set_bit(FLG_TRANSPARENT, &bch->Flags);
374 break;
375 case ISDN_P_B_HDLC:
376 bch->state = protocol;
377 hdlc->ctrl.sr.cmd = HDLC_CMD_XRS | HDLC_CMD_RRS;
378 hdlc->ctrl.sr.mode = HDLC_MODE_ITF_FLG;
379 write_ctrl(bch, 5);
380 hdlc->ctrl.sr.cmd = HDLC_CMD_XRS;
381 write_ctrl(bch, 1);
382 hdlc->ctrl.sr.cmd = 0;
383 test_and_set_bit(FLG_HDLC, &bch->Flags);
384 break;
385 default:
386 pr_info("%s: protocol not known %x\n", fc->name, protocol);
387 return -ENOPROTOOPT;
388 }
389 return 0;
390}
391
392static void
393hdlc_empty_fifo(struct bchannel *bch, int count)
394{
395 u32 *ptr;
396 u8 *p;
397 u32 val, addr;
398 int cnt = 0;
399 struct fritzcard *fc = bch->hw;
400
401 pr_debug("%s: %s %d\n", fc->name, __func__, count);
402 if (!bch->rx_skb) {
403 bch->rx_skb = mI_alloc_skb(bch->maxlen, GFP_ATOMIC);
404 if (!bch->rx_skb) {
405 pr_info("%s: B receive out of memory\n",
406 fc->name);
407 return;
408 }
409 }
410 if ((bch->rx_skb->len + count) > bch->maxlen) {
411 pr_debug("%s: overrun %d\n", fc->name,
412 bch->rx_skb->len + count);
413 return;
414 }
415 p = skb_put(bch->rx_skb, count);
416 ptr = (u32 *)p;
417 if (AVM_FRITZ_PCIV2 == fc->type)
418 addr = fc->addr + (bch->nr == 2 ?
419 AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
420 else {
421 addr = fc->addr + CHIP_WINDOW;
422 outl(bch->nr == 2 ? AVM_HDLC_2 : AVM_HDLC_1, fc->addr);
423 }
424 while (cnt < count) {
425 val = le32_to_cpu(inl(addr));
426 put_unaligned(val, ptr);
427 ptr++;
428 cnt += 4;
429 }
430 if (debug & DEBUG_HW_BFIFO) {
431 snprintf(fc->log, LOG_SIZE, "B%1d-recv %s %d ",
432 bch->nr, fc->name, count);
433 print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
434 }
435}
436
437static void
438hdlc_fill_fifo(struct bchannel *bch)
439{
440 struct fritzcard *fc = bch->hw;
441 struct hdlc_hw *hdlc;
442 int count, cnt = 0;
443 u8 *p;
444 u32 *ptr, val, addr;
445
446 hdlc = &fc->hdlc[(bch->nr - 1) & 1];
447 if (!bch->tx_skb)
448 return;
449 count = bch->tx_skb->len - bch->tx_idx;
450 if (count <= 0)
451 return;
452 p = bch->tx_skb->data + bch->tx_idx;
453 hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XME;
454 if (count > HDLC_FIFO_SIZE) {
455 count = HDLC_FIFO_SIZE;
456 } else {
457 if (test_bit(FLG_HDLC, &bch->Flags))
458 hdlc->ctrl.sr.cmd |= HDLC_CMD_XME;
459 }
460 pr_debug("%s: %s %d/%d/%d", fc->name, __func__, count,
461 bch->tx_idx, bch->tx_skb->len);
462 ptr = (u32 *)p;
463 bch->tx_idx += count;
464 hdlc->ctrl.sr.xml = ((count == HDLC_FIFO_SIZE) ? 0 : count);
465 if (AVM_FRITZ_PCIV2 == fc->type) {
466 __write_ctrl_pciv2(fc, hdlc, bch->nr);
467 addr = fc->addr + (bch->nr == 2 ?
468 AVM_HDLC_FIFO_2 : AVM_HDLC_FIFO_1);
469 } else {
470 __write_ctrl_pci(fc, hdlc, bch->nr);
471 addr = fc->addr + CHIP_WINDOW;
472 }
473 while (cnt < count) {
474 val = get_unaligned(ptr);
475 outl(cpu_to_le32(val), addr);
476 ptr++;
477 cnt += 4;
478 }
479 if (debug & DEBUG_HW_BFIFO) {
480 snprintf(fc->log, LOG_SIZE, "B%1d-send %s %d ",
481 bch->nr, fc->name, count);
482 print_hex_dump_bytes(fc->log, DUMP_PREFIX_OFFSET, p, count);
483 }
484}
485
486static void
487HDLC_irq_xpr(struct bchannel *bch)
488{
489 if (bch->tx_skb && bch->tx_idx < bch->tx_skb->len)
490 hdlc_fill_fifo(bch);
491 else {
492 if (bch->tx_skb) {
493 /* send confirm, on trans, free on hdlc. */
494 if (test_bit(FLG_TRANSPARENT, &bch->Flags))
495 confirm_Bsend(bch);
496 dev_kfree_skb(bch->tx_skb);
497 }
498 if (get_next_bframe(bch))
499 hdlc_fill_fifo(bch);
500 }
501}
502
503static void
504HDLC_irq(struct bchannel *bch, u32 stat)
505{
506 struct fritzcard *fc = bch->hw;
507 int len;
508 struct hdlc_hw *hdlc;
509
510 hdlc = &fc->hdlc[(bch->nr - 1) & 1];
511 pr_debug("%s: ch%d stat %#x\n", fc->name, bch->nr, stat);
512 if (stat & HDLC_INT_RPR) {
513 if (stat & HDLC_STAT_RDO) {
514 hdlc->ctrl.sr.xml = 0;
515 hdlc->ctrl.sr.cmd |= HDLC_CMD_RRS;
516 write_ctrl(bch, 1);
517 hdlc->ctrl.sr.cmd &= ~HDLC_CMD_RRS;
518 write_ctrl(bch, 1);
519 if (bch->rx_skb)
520 skb_trim(bch->rx_skb, 0);
521 } else {
522 len = (stat & HDLC_STAT_RML_MASK) >> 8;
523 if (!len)
524 len = 32;
525 hdlc_empty_fifo(bch, len);
526 if (!bch->rx_skb)
527 goto handle_tx;
528 if ((stat & HDLC_STAT_RME) || test_bit(FLG_TRANSPARENT,
529 &bch->Flags)) {
530 if (((stat & HDLC_STAT_CRCVFRRAB) ==
531 HDLC_STAT_CRCVFR) ||
532 test_bit(FLG_TRANSPARENT, &bch->Flags)) {
533 recv_Bchannel(bch, 0);
534 } else {
535 pr_debug("%s: got invalid frame\n",
536 fc->name);
537 skb_trim(bch->rx_skb, 0);
538 }
539 }
540 }
541 }
542handle_tx:
543 if (stat & HDLC_INT_XDU) {
544 /* Here we lost an TX interrupt, so
545 * restart transmitting the whole frame on HDLC
546 * in transparent mode we send the next data
547 */
548 if (bch->tx_skb)
549 pr_debug("%s: ch%d XDU len(%d) idx(%d) Flags(%lx)\n",
550 fc->name, bch->nr, bch->tx_skb->len,
551 bch->tx_idx, bch->Flags);
552 else
553 pr_debug("%s: ch%d XDU no tx_skb Flags(%lx)\n",
554 fc->name, bch->nr, bch->Flags);
555 if (bch->tx_skb && bch->tx_skb->len) {
556 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
557 bch->tx_idx = 0;
558 }
559 hdlc->ctrl.sr.xml = 0;
560 hdlc->ctrl.sr.cmd |= HDLC_CMD_XRS;
561 write_ctrl(bch, 1);
562 hdlc->ctrl.sr.cmd &= ~HDLC_CMD_XRS;
563 HDLC_irq_xpr(bch);
564 return;
565 } else if (stat & HDLC_INT_XPR)
566 HDLC_irq_xpr(bch);
567}
568
569static inline void
570HDLC_irq_main(struct fritzcard *fc)
571{
572 u32 stat;
573 struct bchannel *bch;
574
575 stat = read_status(fc, 1);
576 if (stat & HDLC_INT_MASK) {
577 bch = Sel_BCS(fc, 1);
578 if (bch)
579 HDLC_irq(bch, stat);
580 else
581 pr_debug("%s: spurious ch1 IRQ\n", fc->name);
582 }
583 stat = read_status(fc, 2);
584 if (stat & HDLC_INT_MASK) {
585 bch = Sel_BCS(fc, 2);
586 if (bch)
587 HDLC_irq(bch, stat);
588 else
589 pr_debug("%s: spurious ch2 IRQ\n", fc->name);
590 }
591}
592
593static irqreturn_t
594avm_fritz_interrupt(int intno, void *dev_id)
595{
596 struct fritzcard *fc = dev_id;
597 u8 val;
598 u8 sval;
599
600 spin_lock(&fc->lock);
601 sval = inb(fc->addr + 2);
602 pr_debug("%s: irq stat0 %x\n", fc->name, sval);
603 if ((sval & AVM_STATUS0_IRQ_MASK) == AVM_STATUS0_IRQ_MASK) {
604 /* shared IRQ from other HW */
605 spin_unlock(&fc->lock);
606 return IRQ_NONE;
607 }
608 fc->irqcnt++;
609
610 if (!(sval & AVM_STATUS0_IRQ_ISAC)) {
611 val = ReadISAC_V1(fc, ISAC_ISTA);
612 mISDNisac_irq(&fc->isac, val);
613 }
614 if (!(sval & AVM_STATUS0_IRQ_HDLC))
615 HDLC_irq_main(fc);
616 spin_unlock(&fc->lock);
617 return IRQ_HANDLED;
618}
619
620static irqreturn_t
621avm_fritzv2_interrupt(int intno, void *dev_id)
622{
623 struct fritzcard *fc = dev_id;
624 u8 val;
625 u8 sval;
626
627 spin_lock(&fc->lock);
628 sval = inb(fc->addr + 2);
629 pr_debug("%s: irq stat0 %x\n", fc->name, sval);
630 if (!(sval & AVM_STATUS0_IRQ_MASK)) {
631 /* shared IRQ from other HW */
632 spin_unlock(&fc->lock);
633 return IRQ_NONE;
634 }
635 fc->irqcnt++;
636
637 if (sval & AVM_STATUS0_IRQ_HDLC)
638 HDLC_irq_main(fc);
639 if (sval & AVM_STATUS0_IRQ_ISAC) {
640 val = ReadISAC_V2(fc, ISACX_ISTA);
641 mISDNisac_irq(&fc->isac, val);
642 }
643 if (sval & AVM_STATUS0_IRQ_TIMER) {
644 pr_debug("%s: timer irq\n", fc->name);
645 outb(fc->ctrlreg | AVM_STATUS0_RES_TIMER, fc->addr + 2);
646 udelay(1);
647 outb(fc->ctrlreg, fc->addr + 2);
648 }
649 spin_unlock(&fc->lock);
650 return IRQ_HANDLED;
651}
652
653static int
654avm_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
655{
656 struct bchannel *bch = container_of(ch, struct bchannel, ch);
657 struct fritzcard *fc = bch->hw;
658 int ret = -EINVAL;
659 struct mISDNhead *hh = mISDN_HEAD_P(skb);
660 u32 id;
661 u_long flags;
662
663 switch (hh->prim) {
664 case PH_DATA_REQ:
665 spin_lock_irqsave(&fc->lock, flags);
666 ret = bchannel_senddata(bch, skb);
667 if (ret > 0) { /* direct TX */
668 id = hh->id; /* skb can be freed */
669 hdlc_fill_fifo(bch);
670 ret = 0;
671 spin_unlock_irqrestore(&fc->lock, flags);
672 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
673 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
674 } else
675 spin_unlock_irqrestore(&fc->lock, flags);
676 return ret;
677 case PH_ACTIVATE_REQ:
678 spin_lock_irqsave(&fc->lock, flags);
679 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
680 ret = modehdlc(bch, ch->protocol);
681 else
682 ret = 0;
683 spin_unlock_irqrestore(&fc->lock, flags);
684 if (!ret)
685 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
686 NULL, GFP_KERNEL);
687 break;
688 case PH_DEACTIVATE_REQ:
689 spin_lock_irqsave(&fc->lock, flags);
690 mISDN_clear_bchannel(bch);
691 modehdlc(bch, ISDN_P_NONE);
692 spin_unlock_irqrestore(&fc->lock, flags);
693 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
694 NULL, GFP_KERNEL);
695 ret = 0;
696 break;
697 }
698 if (!ret)
699 dev_kfree_skb(skb);
700 return ret;
701}
702
703static void
704inithdlc(struct fritzcard *fc)
705{
706 modehdlc(&fc->bch[0], -1);
707 modehdlc(&fc->bch[1], -1);
708}
709
710void
711clear_pending_hdlc_ints(struct fritzcard *fc)
712{
713 u32 val;
714
715 val = read_status(fc, 1);
716 pr_debug("%s: HDLC 1 STA %x\n", fc->name, val);
717 val = read_status(fc, 2);
718 pr_debug("%s: HDLC 2 STA %x\n", fc->name, val);
719}
720
721static void
722reset_avm(struct fritzcard *fc)
723{
724 switch (fc->type) {
725 case AVM_FRITZ_PCI:
726 fc->ctrlreg = AVM_STATUS0_RESET | AVM_STATUS0_DIS_TIMER;
727 break;
728 case AVM_FRITZ_PCIV2:
729 fc->ctrlreg = AVM_STATUS0_RESET;
730 break;
731 }
732 if (debug & DEBUG_HW)
733 pr_notice("%s: reset\n", fc->name);
734 disable_hwirq(fc);
735 mdelay(5);
736 switch (fc->type) {
737 case AVM_FRITZ_PCI:
738 fc->ctrlreg = AVM_STATUS0_DIS_TIMER | AVM_STATUS0_RES_TIMER;
739 disable_hwirq(fc);
740 outb(AVM_STATUS1_ENA_IOM, fc->addr + 3);
741 break;
742 case AVM_FRITZ_PCIV2:
743 fc->ctrlreg = 0;
744 disable_hwirq(fc);
745 break;
746 }
747 mdelay(1);
748 if (debug & DEBUG_HW)
749 pr_notice("%s: S0/S1 %x/%x\n", fc->name,
750 inb(fc->addr + 2), inb(fc->addr + 3));
751}
752
753static int
754init_card(struct fritzcard *fc)
755{
756 int ret, cnt = 3;
757 u_long flags;
758
759 reset_avm(fc); /* disable IRQ */
760 if (fc->type == AVM_FRITZ_PCIV2)
761 ret = request_irq(fc->irq, avm_fritzv2_interrupt,
762 IRQF_SHARED, fc->name, fc);
763 else
764 ret = request_irq(fc->irq, avm_fritz_interrupt,
765 IRQF_SHARED, fc->name, fc);
766 if (ret) {
767 pr_info("%s: couldn't get interrupt %d\n",
768 fc->name, fc->irq);
769 return ret;
770 }
771 while (cnt--) {
772 spin_lock_irqsave(&fc->lock, flags);
773 ret = fc->isac.init(&fc->isac);
774 if (ret) {
775 spin_unlock_irqrestore(&fc->lock, flags);
776 pr_info("%s: ISAC init failed with %d\n",
777 fc->name, ret);
778 break;
779 }
780 clear_pending_hdlc_ints(fc);
781 inithdlc(fc);
782 enable_hwirq(fc);
783 /* RESET Receiver and Transmitter */
784 if (AVM_FRITZ_PCIV2 == fc->type) {
785 WriteISAC_V2(fc, ISACX_MASK, 0);
786 WriteISAC_V2(fc, ISACX_CMDRD, 0x41);
787 } else {
788 WriteISAC_V1(fc, ISAC_MASK, 0);
789 WriteISAC_V1(fc, ISAC_CMDR, 0x41);
790 }
791 spin_unlock_irqrestore(&fc->lock, flags);
792 /* Timeout 10ms */
793 msleep_interruptible(10);
794 if (debug & DEBUG_HW)
795 pr_notice("%s: IRQ %d count %d\n", fc->name,
796 fc->irq, fc->irqcnt);
797 if (!fc->irqcnt) {
798 pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
799 fc->name, fc->irq, 3 - cnt);
800 reset_avm(fc);
801 } else
802 return 0;
803 }
804 free_irq(fc->irq, fc);
805 return -EIO;
806}
807
808static int
809channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
810{
811 int ret = 0;
812 struct fritzcard *fc = bch->hw;
813
814 switch (cq->op) {
815 case MISDN_CTRL_GETOP:
816 cq->op = 0;
817 break;
818 /* Nothing implemented yet */
819 case MISDN_CTRL_FILL_EMPTY:
820 default:
821 pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
822 ret = -EINVAL;
823 break;
824 }
825 return ret;
826}
827
828static int
829avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
830{
831 struct bchannel *bch = container_of(ch, struct bchannel, ch);
832 struct fritzcard *fc = bch->hw;
833 int ret = -EINVAL;
834 u_long flags;
835
836 pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
837 switch (cmd) {
838 case CLOSE_CHANNEL:
839 test_and_clear_bit(FLG_OPEN, &bch->Flags);
840 if (test_bit(FLG_ACTIVE, &bch->Flags)) {
841 spin_lock_irqsave(&fc->lock, flags);
842 mISDN_freebchannel(bch);
843 test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
844 test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
845 modehdlc(bch, ISDN_P_NONE);
846 spin_unlock_irqrestore(&fc->lock, flags);
847 }
848 ch->protocol = ISDN_P_NONE;
849 ch->peer = NULL;
850 module_put(THIS_MODULE);
851 ret = 0;
852 break;
853 case CONTROL_CHANNEL:
854 ret = channel_bctrl(bch, arg);
855 break;
856 default:
857 pr_info("%s: %s unknown prim(%x)\n", fc->name, __func__, cmd);
858 }
859 return ret;
860}
861
862static int
863channel_ctrl(struct fritzcard *fc, struct mISDN_ctrl_req *cq)
864{
865 int ret = 0;
866
867 switch (cq->op) {
868 case MISDN_CTRL_GETOP:
869 cq->op = MISDN_CTRL_LOOP;
870 break;
871 case MISDN_CTRL_LOOP:
872 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
873 if (cq->channel < 0 || cq->channel > 3) {
874 ret = -EINVAL;
875 break;
876 }
877 ret = fc->isac.ctrl(&fc->isac, HW_TESTLOOP, cq->channel);
878 break;
879 default:
880 pr_info("%s: %s unknown Op %x\n", fc->name, __func__, cq->op);
881 ret = -EINVAL;
882 break;
883 }
884 return ret;
885}
886
887static int
888open_bchannel(struct fritzcard *fc, struct channel_req *rq)
889{
890 struct bchannel *bch;
891
892 if (rq->adr.channel > 2)
893 return -EINVAL;
894 if (rq->protocol == ISDN_P_NONE)
895 return -EINVAL;
896 bch = &fc->bch[rq->adr.channel - 1];
897 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
898 return -EBUSY; /* b-channel can be only open once */
899 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
900 bch->ch.protocol = rq->protocol;
901 rq->ch = &bch->ch;
902 return 0;
903}
904
905/*
906 * device control function
907 */
908static int
909avm_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
910{
911 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
912 struct dchannel *dch = container_of(dev, struct dchannel, dev);
913 struct fritzcard *fc = dch->hw;
914 struct channel_req *rq;
915 int err = 0;
916
917 pr_debug("%s: %s cmd:%x %p\n", fc->name, __func__, cmd, arg);
918 switch (cmd) {
919 case OPEN_CHANNEL:
920 rq = arg;
921 if (rq->protocol == ISDN_P_TE_S0)
922 err = fc->isac.open(&fc->isac, rq);
923 else
924 err = open_bchannel(fc, rq);
925 if (err)
926 break;
927 if (!try_module_get(THIS_MODULE))
928 pr_info("%s: cannot get module\n", fc->name);
929 break;
930 case CLOSE_CHANNEL:
931 pr_debug("%s: dev(%d) close from %p\n", fc->name, dch->dev.id,
932 __builtin_return_address(0));
933 module_put(THIS_MODULE);
934 break;
935 case CONTROL_CHANNEL:
936 err = channel_ctrl(fc, arg);
937 break;
938 default:
939 pr_debug("%s: %s unknown command %x\n",
940 fc->name, __func__, cmd);
941 return -EINVAL;
942 }
943 return err;
944}
945
946int
947setup_fritz(struct fritzcard *fc)
948{
949 u32 val, ver;
950
951 if (!request_region(fc->addr, 32, fc->name)) {
952 pr_info("%s: AVM config port %x-%x already in use\n",
953 fc->name, fc->addr, fc->addr + 31);
954 return -EIO;
955 }
956 switch (fc->type) {
957 case AVM_FRITZ_PCI:
958 val = inl(fc->addr);
959 outl(AVM_HDLC_1, fc->addr + CHIP_INDEX);
960 ver = inl(fc->addr + CHIP_WINDOW + HDLC_STATUS) >> 24;
961 if (debug & DEBUG_HW) {
962 pr_notice("%s: PCI stat %#x\n", fc->name, val);
963 pr_notice("%s: PCI Class %X Rev %d\n", fc->name,
964 val & 0xff, (val >> 8) & 0xff);
965 pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
966 }
967 ASSIGN_FUNC(V1, ISAC, fc->isac);
968 fc->isac.type = IPAC_TYPE_ISAC;
969 break;
970 case AVM_FRITZ_PCIV2:
971 val = inl(fc->addr);
972 ver = inl(fc->addr + AVM_HDLC_STATUS_1) >> 24;
973 if (debug & DEBUG_HW) {
974 pr_notice("%s: PCI V2 stat %#x\n", fc->name, val);
975 pr_notice("%s: PCI V2 Class %X Rev %d\n", fc->name,
976 val & 0xff, (val>>8) & 0xff);
977 pr_notice("%s: HDLC version %x\n", fc->name, ver & 0xf);
978 }
979 ASSIGN_FUNC(V2, ISAC, fc->isac);
980 fc->isac.type = IPAC_TYPE_ISACX;
981 break;
982 default:
983 release_region(fc->addr, 32);
984 pr_info("%s: AVM unknown type %d\n", fc->name, fc->type);
985 return -ENODEV;
986 }
987 pr_notice("%s: %s config irq:%d base:0x%X\n", fc->name,
988 (fc->type == AVM_FRITZ_PCI) ? "AVM Fritz!CARD PCI" :
989 "AVM Fritz!CARD PCIv2", fc->irq, fc->addr);
990 return 0;
991}
992
993static void
994release_card(struct fritzcard *card)
995{
996 u_long flags;
997
998 disable_hwirq(card);
999 spin_lock_irqsave(&card->lock, flags);
1000 modehdlc(&card->bch[0], ISDN_P_NONE);
1001 modehdlc(&card->bch[1], ISDN_P_NONE);
1002 spin_unlock_irqrestore(&card->lock, flags);
1003 card->isac.release(&card->isac);
1004 free_irq(card->irq, card);
1005 mISDN_freebchannel(&card->bch[1]);
1006 mISDN_freebchannel(&card->bch[0]);
1007 mISDN_unregister_device(&card->isac.dch.dev);
1008 release_region(card->addr, 32);
1009 pci_disable_device(card->pdev);
1010 pci_set_drvdata(card->pdev, NULL);
1011 write_lock_irqsave(&card_lock, flags);
1012 list_del(&card->list);
1013 write_unlock_irqrestore(&card_lock, flags);
1014 kfree(card);
1015 AVM_cnt--;
1016}
1017
1018static int __devinit
1019setup_instance(struct fritzcard *card)
1020{
1021 int i, err;
1022 u_long flags;
1023
1024 snprintf(card->name, MISDN_MAX_IDLEN - 1, "AVM.%d", AVM_cnt + 1);
1025 write_lock_irqsave(&card_lock, flags);
1026 list_add_tail(&card->list, &Cards);
1027 write_unlock_irqrestore(&card_lock, flags);
1028
1029 _set_debug(card);
1030 card->isac.name = card->name;
1031 spin_lock_init(&card->lock);
1032 card->isac.hwlock = &card->lock;
1033 mISDNisac_init(&card->isac, card);
1034
1035 card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1036 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1037 card->isac.dch.dev.D.ctrl = avm_dctrl;
1038 for (i = 0; i < 2; i++) {
1039 card->bch[i].nr = i + 1;
1040 set_channelmap(i + 1, card->isac.dch.dev.channelmap);
1041 mISDN_initbchannel(&card->bch[i], MAX_DATA_MEM);
1042 card->bch[i].hw = card;
1043 card->bch[i].ch.send = avm_l2l1B;
1044 card->bch[i].ch.ctrl = avm_bctrl;
1045 card->bch[i].ch.nr = i + 1;
1046 list_add(&card->bch[i].ch.list, &card->isac.dch.dev.bchannels);
1047 }
1048 err = setup_fritz(card);
1049 if (err)
1050 goto error;
1051 err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
1052 card->name);
1053 if (err)
1054 goto error_reg;
1055 err = init_card(card);
1056 if (!err) {
1057 AVM_cnt++;
1058 pr_notice("AVM %d cards installed DEBUG\n", AVM_cnt);
1059 return 0;
1060 }
1061 mISDN_unregister_device(&card->isac.dch.dev);
1062error_reg:
1063 release_region(card->addr, 32);
1064error:
1065 card->isac.release(&card->isac);
1066 mISDN_freebchannel(&card->bch[1]);
1067 mISDN_freebchannel(&card->bch[0]);
1068 write_lock_irqsave(&card_lock, flags);
1069 list_del(&card->list);
1070 write_unlock_irqrestore(&card_lock, flags);
1071 kfree(card);
1072 return err;
1073}
1074
1075static int __devinit
1076fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1077{
1078 int err = -ENOMEM;
1079 struct fritzcard *card;
1080
1081 card = kzalloc(sizeof(struct fritzcard), GFP_KERNEL);
1082 if (!card) {
1083 pr_info("No kmem for fritzcard\n");
1084 return err;
1085 }
1086 if (pdev->device == PCI_DEVICE_ID_AVM_A1_V2)
1087 card->type = AVM_FRITZ_PCIV2;
1088 else
1089 card->type = AVM_FRITZ_PCI;
1090 card->pdev = pdev;
1091 err = pci_enable_device(pdev);
1092 if (err) {
1093 kfree(card);
1094 return err;
1095 }
1096
1097 pr_notice("mISDN: found adapter %s at %s\n",
1098 (char *) ent->driver_data, pci_name(pdev));
1099
1100 card->addr = pci_resource_start(pdev, 1);
1101 card->irq = pdev->irq;
1102 pci_set_drvdata(pdev, card);
1103 err = setup_instance(card);
1104 if (err)
1105 pci_set_drvdata(pdev, NULL);
1106 return err;
1107}
1108
1109static void __devexit
1110fritz_remove_pci(struct pci_dev *pdev)
1111{
1112 struct fritzcard *card = pci_get_drvdata(pdev);
1113
1114 if (card)
1115 release_card(card);
1116 else
1117 if (debug)
1118 pr_info("%s: drvdata allready removed\n", __func__);
1119}
1120
1121static struct pci_device_id fcpci_ids[] __devinitdata = {
1122 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1, PCI_ANY_ID, PCI_ANY_ID,
1123 0, 0, (unsigned long) "Fritz!Card PCI"},
1124 { PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_A1_V2, PCI_ANY_ID, PCI_ANY_ID,
1125 0, 0, (unsigned long) "Fritz!Card PCI v2" },
1126 { }
1127};
1128MODULE_DEVICE_TABLE(pci, fcpci_ids);
1129
1130static struct pci_driver fcpci_driver = {
1131 .name = "fcpci",
1132 .probe = fritzpci_probe,
1133 .remove = __devexit_p(fritz_remove_pci),
1134 .id_table = fcpci_ids,
1135};
1136
1137static int __init AVM_init(void)
1138{
1139 int err;
1140
1141 pr_notice("AVM Fritz PCI driver Rev. %s\n", AVMFRITZ_REV);
1142 err = pci_register_driver(&fcpci_driver);
1143 return err;
1144}
1145
1146static void __exit AVM_cleanup(void)
1147{
1148 pci_unregister_driver(&fcpci_driver);
1149}
1150
1151module_init(AVM_init);
1152module_exit(AVM_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index e1dab30aed30..faed794cf75a 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3416,22 +3416,8 @@ deactivate_bchannel(struct bchannel *bch)
3416 u_long flags; 3416 u_long flags;
3417 3417
3418 spin_lock_irqsave(&hc->lock, flags); 3418 spin_lock_irqsave(&hc->lock, flags);
3419 if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) { 3419 mISDN_clear_bchannel(bch);
3420 dev_kfree_skb(bch->next_skb);
3421 bch->next_skb = NULL;
3422 }
3423 if (bch->tx_skb) {
3424 dev_kfree_skb(bch->tx_skb);
3425 bch->tx_skb = NULL;
3426 }
3427 bch->tx_idx = 0;
3428 if (bch->rx_skb) {
3429 dev_kfree_skb(bch->rx_skb);
3430 bch->rx_skb = NULL;
3431 }
3432 hc->chan[bch->slot].coeff_count = 0; 3420 hc->chan[bch->slot].coeff_count = 0;
3433 test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
3434 test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
3435 hc->chan[bch->slot].rx_off = 0; 3421 hc->chan[bch->slot].rx_off = 0;
3436 hc->chan[bch->slot].conf = -1; 3422 hc->chan[bch->slot].conf = -1;
3437 mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0); 3423 mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0);
@@ -5384,9 +5370,10 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5384 ent->device == PCI_DEVICE_ID_CCD_HFC8S || 5370 ent->device == PCI_DEVICE_ID_CCD_HFC8S ||
5385 ent->device == PCI_DEVICE_ID_CCD_HFCE1)) { 5371 ent->device == PCI_DEVICE_ID_CCD_HFCE1)) {
5386 printk(KERN_ERR 5372 printk(KERN_ERR
5387 "Unknown HFC multiport controller (vendor:%x device:%x " 5373 "Unknown HFC multiport controller (vendor:%04x device:%04x "
5388 "subvendor:%x subdevice:%x)\n", ent->vendor, ent->device, 5374 "subvendor:%04x subdevice:%04x)\n", pdev->vendor,
5389 ent->subvendor, ent->subdevice); 5375 pdev->device, pdev->subsystem_vendor,
5376 pdev->subsystem_device);
5390 printk(KERN_ERR 5377 printk(KERN_ERR
5391 "Please contact the driver maintainer for support.\n"); 5378 "Please contact the driver maintainer for support.\n");
5392 return -ENODEV; 5379 return -ENODEV;
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 228ffbed1286..70e6b0e01121 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -1522,22 +1522,8 @@ deactivate_bchannel(struct bchannel *bch)
1522 u_long flags; 1522 u_long flags;
1523 1523
1524 spin_lock_irqsave(&hc->lock, flags); 1524 spin_lock_irqsave(&hc->lock, flags);
1525 if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) { 1525 mISDN_clear_bchannel(bch);
1526 dev_kfree_skb(bch->next_skb);
1527 bch->next_skb = NULL;
1528 }
1529 if (bch->tx_skb) {
1530 dev_kfree_skb(bch->tx_skb);
1531 bch->tx_skb = NULL;
1532 }
1533 bch->tx_idx = 0;
1534 if (bch->rx_skb) {
1535 dev_kfree_skb(bch->rx_skb);
1536 bch->rx_skb = NULL;
1537 }
1538 mode_hfcpci(bch, bch->nr, ISDN_P_NONE); 1526 mode_hfcpci(bch, bch->nr, ISDN_P_NONE);
1539 test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
1540 test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
1541 spin_unlock_irqrestore(&hc->lock, flags); 1527 spin_unlock_irqrestore(&hc->lock, flags);
1542} 1528}
1543 1529
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c
index 6b7704c41b94..fc46a26cb14f 100644
--- a/drivers/isdn/hardware/mISDN/hfcsusb.c
+++ b/drivers/isdn/hardware/mISDN/hfcsusb.c
@@ -1809,21 +1809,7 @@ deactivate_bchannel(struct bchannel *bch)
1809 hw->name, __func__, bch->nr); 1809 hw->name, __func__, bch->nr);
1810 1810
1811 spin_lock_irqsave(&hw->lock, flags); 1811 spin_lock_irqsave(&hw->lock, flags);
1812 if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) { 1812 mISDN_clear_bchannel(bch);
1813 dev_kfree_skb(bch->next_skb);
1814 bch->next_skb = NULL;
1815 }
1816 if (bch->tx_skb) {
1817 dev_kfree_skb(bch->tx_skb);
1818 bch->tx_skb = NULL;
1819 }
1820 bch->tx_idx = 0;
1821 if (bch->rx_skb) {
1822 dev_kfree_skb(bch->rx_skb);
1823 bch->rx_skb = NULL;
1824 }
1825 clear_bit(FLG_ACTIVE, &bch->Flags);
1826 clear_bit(FLG_TX_BUSY, &bch->Flags);
1827 spin_unlock_irqrestore(&hw->lock, flags); 1813 spin_unlock_irqrestore(&hw->lock, flags);
1828 hfcsusb_setup_bch(bch, ISDN_P_NONE); 1814 hfcsusb_setup_bch(bch, ISDN_P_NONE);
1829 hfcsusb_stop_endpoint(hw, bch->nr); 1815 hfcsusb_stop_endpoint(hw, bch->nr);
diff --git a/drivers/isdn/hardware/mISDN/iohelper.h b/drivers/isdn/hardware/mISDN/iohelper.h
new file mode 100644
index 000000000000..b438981107ae
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/iohelper.h
@@ -0,0 +1,109 @@
1/*
2 * iohelper.h
3 * helper for define functions to access ISDN hardware
4 * supported are memory mapped IO
5 * indirect port IO (one port for address, one for data)
6 *
7 * Author Karsten Keil <keil@isdn4linux.de>
8 *
9 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26#ifndef _IOHELPER_H
27#define _IOHELPER_H
28
29typedef u8 (read_reg_func)(void *hwp, u8 offset);
30typedef void (write_reg_func)(void *hwp, u8 offset, u8 value);
31typedef void (fifo_func)(void *hwp, u8 offset, u8 *datap, int size);
32
33struct _ioport {
34 u32 port;
35 u32 ale;
36};
37
38#define IOFUNC_IO(name, hws, ap) \
39 static u8 Read##name##_IO(void *p, u8 off) {\
40 struct hws *hw = p;\
41 return inb(hw->ap.port + off);\
42 } \
43 static void Write##name##_IO(void *p, u8 off, u8 val) {\
44 struct hws *hw = p;\
45 outb(val, hw->ap.port + off);\
46 } \
47 static void ReadFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) {\
48 struct hws *hw = p;\
49 insb(hw->ap.port + off, dp, size);\
50 } \
51 static void WriteFiFo##name##_IO(void *p, u8 off, u8 *dp, int size) {\
52 struct hws *hw = p;\
53 outsb(hw->ap.port + off, dp, size);\
54 }
55
56#define IOFUNC_IND(name, hws, ap) \
57 static u8 Read##name##_IND(void *p, u8 off) {\
58 struct hws *hw = p;\
59 outb(off, hw->ap.ale);\
60 return inb(hw->ap.port);\
61 } \
62 static void Write##name##_IND(void *p, u8 off, u8 val) {\
63 struct hws *hw = p;\
64 outb(off, hw->ap.ale);\
65 outb(val, hw->ap.port);\
66 } \
67 static void ReadFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) {\
68 struct hws *hw = p;\
69 outb(off, hw->ap.ale);\
70 insb(hw->ap.port, dp, size);\
71 } \
72 static void WriteFiFo##name##_IND(void *p, u8 off, u8 *dp, int size) {\
73 struct hws *hw = p;\
74 outb(off, hw->ap.ale);\
75 outsb(hw->ap.port, dp, size);\
76 }
77
78#define IOFUNC_MEMIO(name, hws, typ, adr) \
79 static u8 Read##name##_MIO(void *p, u8 off) {\
80 struct hws *hw = p;\
81 return readb(((typ *)hw->adr) + off);\
82 } \
83 static void Write##name##_MIO(void *p, u8 off, u8 val) {\
84 struct hws *hw = p;\
85 writeb(val, ((typ *)hw->adr) + off);\
86 } \
87 static void ReadFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) {\
88 struct hws *hw = p;\
89 while (size--)\
90 *dp++ = readb(((typ *)hw->adr) + off);\
91 } \
92 static void WriteFiFo##name##_MIO(void *p, u8 off, u8 *dp, int size) {\
93 struct hws *hw = p;\
94 while (size--)\
95 writeb(*dp++, ((typ *)hw->adr) + off);\
96 }
97
98#define ASSIGN_FUNC(typ, name, dest) do {\
99 dest.read_reg = &Read##name##_##typ;\
100 dest.write_reg = &Write##name##_##typ;\
101 dest.read_fifo = &ReadFiFo##name##_##typ;\
102 dest.write_fifo = &WriteFiFo##name##_##typ;\
103 } while (0)
104#define ASSIGN_FUNC_IPAC(typ, target) do {\
105 ASSIGN_FUNC(typ, ISAC, target.isac);\
106 ASSIGN_FUNC(typ, IPAC, target);\
107 } while (0)
108
109#endif
diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h
new file mode 100644
index 000000000000..74a6ccf9065c
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/ipac.h
@@ -0,0 +1,405 @@
1/*
2 *
3 * ipac.h Defines for the Infineon (former Siemens) ISDN
4 * chip series
5 *
6 * Author Karsten Keil <keil@isdn4linux.de>
7 *
8 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include "iohelper.h"
26
27struct isac_hw {
28 struct dchannel dch;
29 u32 type;
30 u32 off; /* offset to isac regs */
31 char *name;
32 spinlock_t *hwlock; /* lock HW acccess */
33 read_reg_func *read_reg;
34 write_reg_func *write_reg;
35 fifo_func *read_fifo;
36 fifo_func *write_fifo;
37 int (*monitor)(void *, u32, u8 *, int);
38 void (*release)(struct isac_hw *);
39 int (*init)(struct isac_hw *);
40 int (*ctrl)(struct isac_hw *, u32, u_long);
41 int (*open)(struct isac_hw *, struct channel_req *);
42 u8 *mon_tx;
43 u8 *mon_rx;
44 int mon_txp;
45 int mon_txc;
46 int mon_rxp;
47 struct arcofi_msg *arcofi_list;
48 struct timer_list arcofitimer;
49 wait_queue_head_t arcofi_wait;
50 u8 arcofi_bc;
51 u8 arcofi_state;
52 u8 mocr;
53 u8 adf2;
54 u8 state;
55};
56
57struct ipac_hw;
58
59struct hscx_hw {
60 struct bchannel bch;
61 struct ipac_hw *ip;
62 u8 fifo_size;
63 u8 off; /* offset to ICA or ICB */
64 u8 slot;
65 char log[64];
66};
67
68struct ipac_hw {
69 struct isac_hw isac;
70 struct hscx_hw hscx[2];
71 char *name;
72 void *hw;
73 spinlock_t *hwlock; /* lock HW acccess */
74 struct module *owner;
75 u32 type;
76 read_reg_func *read_reg;
77 write_reg_func *write_reg;
78 fifo_func *read_fifo;
79 fifo_func *write_fifo;
80 void (*release)(struct ipac_hw *);
81 int (*init)(struct ipac_hw *);
82 int (*ctrl)(struct ipac_hw *, u32, u_long);
83 u8 conf;
84};
85
86#define IPAC_TYPE_ISAC 0x0010
87#define IPAC_TYPE_IPAC 0x0020
88#define IPAC_TYPE_ISACX 0x0040
89#define IPAC_TYPE_IPACX 0x0080
90#define IPAC_TYPE_HSCX 0x0100
91
92#define ISAC_USE_ARCOFI 0x1000
93
94/* Monitor functions */
95#define MONITOR_RX_0 0x1000
96#define MONITOR_RX_1 0x1001
97#define MONITOR_TX_0 0x2000
98#define MONITOR_TX_1 0x2001
99
100/* All registers original Siemens Spec */
101/* IPAC/ISAC registers */
102#define ISAC_MASK 0x20
103#define ISAC_ISTA 0x20
104#define ISAC_STAR 0x21
105#define ISAC_CMDR 0x21
106#define ISAC_EXIR 0x24
107#define ISAC_ADF2 0x39
108#define ISAC_SPCR 0x30
109#define ISAC_ADF1 0x38
110#define ISAC_CIR0 0x31
111#define ISAC_CIX0 0x31
112#define ISAC_CIR1 0x33
113#define ISAC_CIX1 0x33
114#define ISAC_STCR 0x37
115#define ISAC_MODE 0x22
116#define ISAC_RSTA 0x27
117#define ISAC_RBCL 0x25
118#define ISAC_RBCH 0x2A
119#define ISAC_TIMR 0x23
120#define ISAC_SQXR 0x3b
121#define ISAC_SQRR 0x3b
122#define ISAC_MOSR 0x3a
123#define ISAC_MOCR 0x3a
124#define ISAC_MOR0 0x32
125#define ISAC_MOX0 0x32
126#define ISAC_MOR1 0x34
127#define ISAC_MOX1 0x34
128
129#define ISAC_RBCH_XAC 0x80
130
131#define IPAC_D_TIN2 0x01
132
133/* IPAC/HSCX */
134#define IPAC_ISTAB 0x20 /* RD */
135#define IPAC_MASKB 0x20 /* WR */
136#define IPAC_STARB 0x21 /* RD */
137#define IPAC_CMDRB 0x21 /* WR */
138#define IPAC_MODEB 0x22 /* R/W */
139#define IPAC_EXIRB 0x24 /* RD */
140#define IPAC_RBCLB 0x25 /* RD */
141#define IPAC_RAH1 0x26 /* WR */
142#define IPAC_RAH2 0x27 /* WR */
143#define IPAC_RSTAB 0x27 /* RD */
144#define IPAC_RAL1 0x28 /* R/W */
145#define IPAC_RAL2 0x29 /* WR */
146#define IPAC_RHCRB 0x29 /* RD */
147#define IPAC_XBCL 0x2A /* WR */
148#define IPAC_CCR2 0x2C /* R/W */
149#define IPAC_RBCHB 0x2D /* RD */
150#define IPAC_XBCH 0x2D /* WR */
151#define HSCX_VSTR 0x2E /* RD */
152#define IPAC_RLCR 0x2E /* WR */
153#define IPAC_CCR1 0x2F /* R/W */
154#define IPAC_TSAX 0x30 /* WR */
155#define IPAC_TSAR 0x31 /* WR */
156#define IPAC_XCCR 0x32 /* WR */
157#define IPAC_RCCR 0x33 /* WR */
158
159/* IPAC_ISTAB/IPAC_MASKB bits */
160#define IPAC_B_XPR 0x10
161#define IPAC_B_RPF 0x40
162#define IPAC_B_RME 0x80
163#define IPAC_B_ON 0x2F
164
165/* IPAC_EXIRB bits */
166#define IPAC_B_RFS 0x04
167#define IPAC_B_RFO 0x10
168#define IPAC_B_XDU 0x40
169#define IPAC_B_XMR 0x80
170
171/* IPAC special registers */
172#define IPAC_CONF 0xC0 /* R/W */
173#define IPAC_ISTA 0xC1 /* RD */
174#define IPAC_MASK 0xC1 /* WR */
175#define IPAC_ID 0xC2 /* RD */
176#define IPAC_ACFG 0xC3 /* R/W */
177#define IPAC_AOE 0xC4 /* R/W */
178#define IPAC_ARX 0xC5 /* RD */
179#define IPAC_ATX 0xC5 /* WR */
180#define IPAC_PITA1 0xC6 /* R/W */
181#define IPAC_PITA2 0xC7 /* R/W */
182#define IPAC_POTA1 0xC8 /* R/W */
183#define IPAC_POTA2 0xC9 /* R/W */
184#define IPAC_PCFG 0xCA /* R/W */
185#define IPAC_SCFG 0xCB /* R/W */
186#define IPAC_TIMR2 0xCC /* R/W */
187
188/* IPAC_ISTA/_MASK bits */
189#define IPAC__EXB 0x01
190#define IPAC__ICB 0x02
191#define IPAC__EXA 0x04
192#define IPAC__ICA 0x08
193#define IPAC__EXD 0x10
194#define IPAC__ICD 0x20
195#define IPAC__INT0 0x40
196#define IPAC__INT1 0x80
197#define IPAC__ON 0xC0
198
199/* HSCX ISTA/MASK bits */
200#define HSCX__EXB 0x01
201#define HSCX__EXA 0x02
202#define HSCX__ICA 0x04
203
204/* ISAC/ISACX/IPAC/IPACX L1 commands */
205#define ISAC_CMD_TIM 0x0
206#define ISAC_CMD_RS 0x1
207#define ISAC_CMD_SCZ 0x4
208#define ISAC_CMD_SSZ 0x2
209#define ISAC_CMD_AR8 0x8
210#define ISAC_CMD_AR10 0x9
211#define ISAC_CMD_ARL 0xA
212#define ISAC_CMD_DUI 0xF
213
214/* ISAC/ISACX/IPAC/IPACX L1 indications */
215#define ISAC_IND_RS 0x1
216#define ISAC_IND_PU 0x7
217#define ISAC_IND_DR 0x0
218#define ISAC_IND_SD 0x2
219#define ISAC_IND_DIS 0x3
220#define ISAC_IND_EI 0x6
221#define ISAC_IND_RSY 0x4
222#define ISAC_IND_ARD 0x8
223#define ISAC_IND_TI 0xA
224#define ISAC_IND_ATI 0xB
225#define ISAC_IND_AI8 0xC
226#define ISAC_IND_AI10 0xD
227#define ISAC_IND_DID 0xF
228
229/* the new ISACX / IPACX */
230/* D-channel registers */
231#define ISACX_RFIFOD 0x00 /* RD */
232#define ISACX_XFIFOD 0x00 /* WR */
233#define ISACX_ISTAD 0x20 /* RD */
234#define ISACX_MASKD 0x20 /* WR */
235#define ISACX_STARD 0x21 /* RD */
236#define ISACX_CMDRD 0x21 /* WR */
237#define ISACX_MODED 0x22 /* R/W */
238#define ISACX_EXMD1 0x23 /* R/W */
239#define ISACX_TIMR1 0x24 /* R/W */
240#define ISACX_SAP1 0x25 /* WR */
241#define ISACX_SAP2 0x26 /* WR */
242#define ISACX_RBCLD 0x26 /* RD */
243#define ISACX_RBCHD 0x27 /* RD */
244#define ISACX_TEI1 0x27 /* WR */
245#define ISACX_TEI2 0x28 /* WR */
246#define ISACX_RSTAD 0x28 /* RD */
247#define ISACX_TMD 0x29 /* R/W */
248#define ISACX_CIR0 0x2E /* RD */
249#define ISACX_CIX0 0x2E /* WR */
250#define ISACX_CIR1 0x2F /* RD */
251#define ISACX_CIX1 0x2F /* WR */
252
253/* Transceiver registers */
254#define ISACX_TR_CONF0 0x30 /* R/W */
255#define ISACX_TR_CONF1 0x31 /* R/W */
256#define ISACX_TR_CONF2 0x32 /* R/W */
257#define ISACX_TR_STA 0x33 /* RD */
258#define ISACX_TR_CMD 0x34 /* R/W */
259#define ISACX_SQRR1 0x35 /* RD */
260#define ISACX_SQXR1 0x35 /* WR */
261#define ISACX_SQRR2 0x36 /* RD */
262#define ISACX_SQXR2 0x36 /* WR */
263#define ISACX_SQRR3 0x37 /* RD */
264#define ISACX_SQXR3 0x37 /* WR */
265#define ISACX_ISTATR 0x38 /* RD */
266#define ISACX_MASKTR 0x39 /* R/W */
267#define ISACX_TR_MODE 0x3A /* R/W */
268#define ISACX_ACFG1 0x3C /* R/W */
269#define ISACX_ACFG2 0x3D /* R/W */
270#define ISACX_AOE 0x3E /* R/W */
271#define ISACX_ARX 0x3F /* RD */
272#define ISACX_ATX 0x3F /* WR */
273
274/* IOM: Timeslot, DPS, CDA */
275#define ISACX_CDA10 0x40 /* R/W */
276#define ISACX_CDA11 0x41 /* R/W */
277#define ISACX_CDA20 0x42 /* R/W */
278#define ISACX_CDA21 0x43 /* R/W */
279#define ISACX_CDA_TSDP10 0x44 /* R/W */
280#define ISACX_CDA_TSDP11 0x45 /* R/W */
281#define ISACX_CDA_TSDP20 0x46 /* R/W */
282#define ISACX_CDA_TSDP21 0x47 /* R/W */
283#define ISACX_BCHA_TSDP_BC1 0x48 /* R/W */
284#define ISACX_BCHA_TSDP_BC2 0x49 /* R/W */
285#define ISACX_BCHB_TSDP_BC1 0x4A /* R/W */
286#define ISACX_BCHB_TSDP_BC2 0x4B /* R/W */
287#define ISACX_TR_TSDP_BC1 0x4C /* R/W */
288#define ISACX_TR_TSDP_BC2 0x4D /* R/W */
289#define ISACX_CDA1_CR 0x4E /* R/W */
290#define ISACX_CDA2_CR 0x4F /* R/W */
291
292/* IOM: Contol, Sync transfer, Monitor */
293#define ISACX_TR_CR 0x50 /* R/W */
294#define ISACX_TRC_CR 0x50 /* R/W */
295#define ISACX_BCHA_CR 0x51 /* R/W */
296#define ISACX_BCHB_CR 0x52 /* R/W */
297#define ISACX_DCI_CR 0x53 /* R/W */
298#define ISACX_DCIC_CR 0x53 /* R/W */
299#define ISACX_MON_CR 0x54 /* R/W */
300#define ISACX_SDS1_CR 0x55 /* R/W */
301#define ISACX_SDS2_CR 0x56 /* R/W */
302#define ISACX_IOM_CR 0x57 /* R/W */
303#define ISACX_STI 0x58 /* RD */
304#define ISACX_ASTI 0x58 /* WR */
305#define ISACX_MSTI 0x59 /* R/W */
306#define ISACX_SDS_CONF 0x5A /* R/W */
307#define ISACX_MCDA 0x5B /* RD */
308#define ISACX_MOR 0x5C /* RD */
309#define ISACX_MOX 0x5C /* WR */
310#define ISACX_MOSR 0x5D /* RD */
311#define ISACX_MOCR 0x5E /* R/W */
312#define ISACX_MSTA 0x5F /* RD */
313#define ISACX_MCONF 0x5F /* WR */
314
315/* Interrupt and general registers */
316#define ISACX_ISTA 0x60 /* RD */
317#define ISACX_MASK 0x60 /* WR */
318#define ISACX_AUXI 0x61 /* RD */
319#define ISACX_AUXM 0x61 /* WR */
320#define ISACX_MODE1 0x62 /* R/W */
321#define ISACX_MODE2 0x63 /* R/W */
322#define ISACX_ID 0x64 /* RD */
323#define ISACX_SRES 0x64 /* WR */
324#define ISACX_TIMR2 0x65 /* R/W */
325
326/* Register Bits */
327/* ISACX/IPACX _ISTAD (R) and _MASKD (W) */
328#define ISACX_D_XDU 0x04
329#define ISACX_D_XMR 0x08
330#define ISACX_D_XPR 0x10
331#define ISACX_D_RFO 0x20
332#define ISACX_D_RPF 0x40
333#define ISACX_D_RME 0x80
334
335/* ISACX/IPACX _ISTA (R) and _MASK (W) */
336#define ISACX__ICD 0x01
337#define ISACX__MOS 0x02
338#define ISACX__TRAN 0x04
339#define ISACX__AUX 0x08
340#define ISACX__CIC 0x10
341#define ISACX__ST 0x20
342#define IPACX__ICB 0x40
343#define IPACX__ICA 0x80
344#define IPACX__ON 0x2C
345
346/* ISACX/IPACX _CMDRD (W) */
347#define ISACX_CMDRD_XRES 0x01
348#define ISACX_CMDRD_XME 0x02
349#define ISACX_CMDRD_XTF 0x08
350#define ISACX_CMDRD_STI 0x10
351#define ISACX_CMDRD_RRES 0x40
352#define ISACX_CMDRD_RMC 0x80
353
354/* ISACX/IPACX _RSTAD (R) */
355#define ISACX_RSTAD_TA 0x01
356#define ISACX_RSTAD_CR 0x02
357#define ISACX_RSTAD_SA0 0x04
358#define ISACX_RSTAD_SA1 0x08
359#define ISACX_RSTAD_RAB 0x10
360#define ISACX_RSTAD_CRC 0x20
361#define ISACX_RSTAD_RDO 0x40
362#define ISACX_RSTAD_VFR 0x80
363
364/* ISACX/IPACX _CIR0 (R) */
365#define ISACX_CIR0_BAS 0x01
366#define ISACX_CIR0_SG 0x08
367#define ISACX_CIR0_CIC1 0x08
368#define ISACX_CIR0_CIC0 0x08
369
370/* B-channel registers */
371#define IPACX_OFF_ICA 0x70
372#define IPACX_OFF_ICB 0x80
373
374/* ICA: IPACX_OFF_ICA + Reg ICB: IPACX_OFF_ICB + Reg */
375
376#define IPACX_ISTAB 0x00 /* RD */
377#define IPACX_MASKB 0x00 /* WR */
378#define IPACX_STARB 0x01 /* RD */
379#define IPACX_CMDRB 0x01 /* WR */
380#define IPACX_MODEB 0x02 /* R/W */
381#define IPACX_EXMB 0x03 /* R/W */
382#define IPACX_RAH1 0x05 /* WR */
383#define IPACX_RAH2 0x06 /* WR */
384#define IPACX_RBCLB 0x06 /* RD */
385#define IPACX_RBCHB 0x07 /* RD */
386#define IPACX_RAL1 0x07 /* WR */
387#define IPACX_RAL2 0x08 /* WR */
388#define IPACX_RSTAB 0x08 /* RD */
389#define IPACX_TMB 0x09 /* R/W */
390#define IPACX_RFIFOB 0x0A /* RD */
391#define IPACX_XFIFOB 0x0A /* WR */
392
393/* IPACX_ISTAB / IPACX_MASKB bits */
394#define IPACX_B_XDU 0x04
395#define IPACX_B_XPR 0x10
396#define IPACX_B_RFO 0x20
397#define IPACX_B_RPF 0x40
398#define IPACX_B_RME 0x80
399
400#define IPACX_B_ON 0x0B
401
402extern int mISDNisac_init(struct isac_hw *, void *);
403extern irqreturn_t mISDNisac_irq(struct isac_hw *, u8);
404extern u32 mISDNipac_init(struct ipac_hw *, void *);
405extern irqreturn_t mISDNipac_irq(struct ipac_hw *, int);
diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h
new file mode 100644
index 000000000000..4a134acd44d0
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/isar.h
@@ -0,0 +1,269 @@
1/*
2 *
3 * isar.h ISAR (Siemens PSB 7110) specific defines
4 *
5 * Author Karsten Keil (keil@isdn4linux.de)
6 *
7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "iohelper.h"
25
26struct isar_hw;
27
28struct isar_ch {
29 struct bchannel bch;
30 struct isar_hw *is;
31 struct timer_list ftimer;
32 u8 nr;
33 u8 dpath;
34 u8 mml;
35 u8 state;
36 u8 cmd;
37 u8 mod;
38 u8 newcmd;
39 u8 newmod;
40 u8 try_mod;
41 u8 conmsg[16];
42};
43
44struct isar_hw {
45 struct isar_ch ch[2];
46 void *hw;
47 spinlock_t *hwlock; /* lock HW acccess */
48 char *name;
49 struct module *owner;
50 read_reg_func *read_reg;
51 write_reg_func *write_reg;
52 fifo_func *read_fifo;
53 fifo_func *write_fifo;
54 int (*ctrl)(void *, u32, u_long);
55 void (*release)(struct isar_hw *);
56 int (*init)(struct isar_hw *);
57 int (*open)(struct isar_hw *, struct channel_req *);
58 int (*firmware)(struct isar_hw *, const u8 *, int);
59 unsigned long Flags;
60 int version;
61 u8 bstat;
62 u8 iis;
63 u8 cmsb;
64 u8 clsb;
65 u8 buf[256];
66 u8 log[256];
67};
68
69#define ISAR_IRQMSK 0x04
70#define ISAR_IRQSTA 0x04
71#define ISAR_IRQBIT 0x75
72#define ISAR_CTRL_H 0x61
73#define ISAR_CTRL_L 0x60
74#define ISAR_IIS 0x58
75#define ISAR_IIA 0x58
76#define ISAR_HIS 0x50
77#define ISAR_HIA 0x50
78#define ISAR_MBOX 0x4c
79#define ISAR_WADR 0x4a
80#define ISAR_RADR 0x48
81
82#define ISAR_HIS_VNR 0x14
83#define ISAR_HIS_DKEY 0x02
84#define ISAR_HIS_FIRM 0x1e
85#define ISAR_HIS_STDSP 0x08
86#define ISAR_HIS_DIAG 0x05
87#define ISAR_HIS_P0CFG 0x3c
88#define ISAR_HIS_P12CFG 0x24
89#define ISAR_HIS_SARTCFG 0x25
90#define ISAR_HIS_PUMPCFG 0x26
91#define ISAR_HIS_PUMPCTRL 0x2a
92#define ISAR_HIS_IOM2CFG 0x27
93#define ISAR_HIS_IOM2REQ 0x07
94#define ISAR_HIS_IOM2CTRL 0x2b
95#define ISAR_HIS_BSTREQ 0x0c
96#define ISAR_HIS_PSTREQ 0x0e
97#define ISAR_HIS_SDATA 0x20
98#define ISAR_HIS_DPS1 0x40
99#define ISAR_HIS_DPS2 0x80
100#define SET_DPS(x) ((x<<6) & 0xc0)
101
102#define ISAR_IIS_MSCMSD 0x3f
103#define ISAR_IIS_VNR 0x15
104#define ISAR_IIS_DKEY 0x03
105#define ISAR_IIS_FIRM 0x1f
106#define ISAR_IIS_STDSP 0x09
107#define ISAR_IIS_DIAG 0x25
108#define ISAR_IIS_GSTEV 0x00
109#define ISAR_IIS_BSTEV 0x28
110#define ISAR_IIS_BSTRSP 0x2c
111#define ISAR_IIS_PSTRSP 0x2e
112#define ISAR_IIS_PSTEV 0x2a
113#define ISAR_IIS_IOM2RSP 0x27
114#define ISAR_IIS_RDATA 0x20
115#define ISAR_IIS_INVMSG 0x3f
116
117#define ISAR_CTRL_SWVER 0x10
118#define ISAR_CTRL_STST 0x40
119
120#define ISAR_MSG_HWVER 0x20
121
122#define ISAR_DP1_USE 1
123#define ISAR_DP2_USE 2
124#define ISAR_RATE_REQ 3
125
126#define PMOD_DISABLE 0
127#define PMOD_FAX 1
128#define PMOD_DATAMODEM 2
129#define PMOD_HALFDUPLEX 3
130#define PMOD_V110 4
131#define PMOD_DTMF 5
132#define PMOD_DTMF_TRANS 6
133#define PMOD_BYPASS 7
134
135#define PCTRL_ORIG 0x80
136#define PV32P2_V23R 0x40
137#define PV32P2_V22A 0x20
138#define PV32P2_V22B 0x10
139#define PV32P2_V22C 0x08
140#define PV32P2_V21 0x02
141#define PV32P2_BEL 0x01
142
143/* LSB MSB in ISAR doc wrong !!! Arghhh */
144#define PV32P3_AMOD 0x80
145#define PV32P3_V32B 0x02
146#define PV32P3_V23B 0x01
147#define PV32P4_48 0x11
148#define PV32P5_48 0x05
149#define PV32P4_UT48 0x11
150#define PV32P5_UT48 0x0d
151#define PV32P4_96 0x11
152#define PV32P5_96 0x03
153#define PV32P4_UT96 0x11
154#define PV32P5_UT96 0x0f
155#define PV32P4_B96 0x91
156#define PV32P5_B96 0x0b
157#define PV32P4_UTB96 0xd1
158#define PV32P5_UTB96 0x0f
159#define PV32P4_120 0xb1
160#define PV32P5_120 0x09
161#define PV32P4_UT120 0xf1
162#define PV32P5_UT120 0x0f
163#define PV32P4_144 0x99
164#define PV32P5_144 0x09
165#define PV32P4_UT144 0xf9
166#define PV32P5_UT144 0x0f
167#define PV32P6_CTN 0x01
168#define PV32P6_ATN 0x02
169
170#define PFAXP2_CTN 0x01
171#define PFAXP2_ATN 0x04
172
173#define PSEV_10MS_TIMER 0x02
174#define PSEV_CON_ON 0x18
175#define PSEV_CON_OFF 0x19
176#define PSEV_V24_OFF 0x20
177#define PSEV_CTS_ON 0x21
178#define PSEV_CTS_OFF 0x22
179#define PSEV_DCD_ON 0x23
180#define PSEV_DCD_OFF 0x24
181#define PSEV_DSR_ON 0x25
182#define PSEV_DSR_OFF 0x26
183#define PSEV_REM_RET 0xcc
184#define PSEV_REM_REN 0xcd
185#define PSEV_GSTN_CLR 0xd4
186
187#define PSEV_RSP_READY 0xbc
188#define PSEV_LINE_TX_H 0xb3
189#define PSEV_LINE_TX_B 0xb2
190#define PSEV_LINE_RX_H 0xb1
191#define PSEV_LINE_RX_B 0xb0
192#define PSEV_RSP_CONN 0xb5
193#define PSEV_RSP_DISC 0xb7
194#define PSEV_RSP_FCERR 0xb9
195#define PSEV_RSP_SILDET 0xbe
196#define PSEV_RSP_SILOFF 0xab
197#define PSEV_FLAGS_DET 0xba
198
199#define PCTRL_CMD_TDTMF 0x5a
200
201#define PCTRL_CMD_FTH 0xa7
202#define PCTRL_CMD_FRH 0xa5
203#define PCTRL_CMD_FTM 0xa8
204#define PCTRL_CMD_FRM 0xa6
205#define PCTRL_CMD_SILON 0xac
206#define PCTRL_CMD_CONT 0xa2
207#define PCTRL_CMD_ESC 0xa4
208#define PCTRL_CMD_SILOFF 0xab
209#define PCTRL_CMD_HALT 0xa9
210
211#define PCTRL_LOC_RET 0xcf
212#define PCTRL_LOC_REN 0xce
213
214#define SMODE_DISABLE 0
215#define SMODE_V14 2
216#define SMODE_HDLC 3
217#define SMODE_BINARY 4
218#define SMODE_FSK_V14 5
219
220#define SCTRL_HDMC_BOTH 0x00
221#define SCTRL_HDMC_DTX 0x80
222#define SCTRL_HDMC_DRX 0x40
223#define S_P1_OVSP 0x40
224#define S_P1_SNP 0x20
225#define S_P1_EOP 0x10
226#define S_P1_EDP 0x08
227#define S_P1_NSB 0x04
228#define S_P1_CHS_8 0x03
229#define S_P1_CHS_7 0x02
230#define S_P1_CHS_6 0x01
231#define S_P1_CHS_5 0x00
232
233#define S_P2_BFT_DEF 0x10
234
235#define IOM_CTRL_ENA 0x80
236#define IOM_CTRL_NOPCM 0x00
237#define IOM_CTRL_ALAW 0x02
238#define IOM_CTRL_ULAW 0x04
239#define IOM_CTRL_RCV 0x01
240
241#define IOM_P1_TXD 0x10
242
243#define HDLC_FED 0x40
244#define HDLC_FSD 0x20
245#define HDLC_FST 0x20
246#define HDLC_ERROR 0x1c
247#define HDLC_ERR_FAD 0x10
248#define HDLC_ERR_RER 0x08
249#define HDLC_ERR_CER 0x04
250#define SART_NMD 0x01
251
252#define BSTAT_RDM0 0x1
253#define BSTAT_RDM1 0x2
254#define BSTAT_RDM2 0x4
255#define BSTAT_RDM3 0x8
256#define BSTEV_TBO 0x1f
257#define BSTEV_RBO 0x2f
258
259/* FAX State Machine */
260#define STFAX_NULL 0
261#define STFAX_READY 1
262#define STFAX_LINE 2
263#define STFAX_CONT 3
264#define STFAX_ACTIV 4
265#define STFAX_ESCAPE 5
266#define STFAX_SILDET 6
267
268extern u32 mISDNisar_init(struct isar_hw *, void *);
269extern void mISDNisar_irq(struct isar_hw *);
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
new file mode 100644
index 000000000000..62441ba53b95
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c
@@ -0,0 +1,1178 @@
1/*
2 * mISDNinfineon.c
3 * Support for cards based on following Infineon ISDN chipsets
4 * - ISAC + HSCX
5 * - IPAC and IPAC-X
6 * - ISAC-SX + HSCX
7 *
8 * Supported cards:
9 * - Dialogic Diva 2.0
10 * - Dialogic Diva 2.0U
11 * - Dialogic Diva 2.01
12 * - Dialogic Diva 2.02
13 * - Sedlbauer Speedwin
14 * - HST Saphir3
15 * - Develo (former ELSA) Microlink PCI (Quickstep 1000)
16 * - Develo (former ELSA) Quickstep 3000
17 * - Berkom Scitel BRIX Quadro
18 * - Dr.Neuhaus (Sagem) Niccy
19 *
20 *
21 *
22 * Author Karsten Keil <keil@isdn4linux.de>
23 *
24 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
25 *
26 * This program is free software; you can redistribute it and/or modify
27 * it under the terms of the GNU General Public License version 2 as
28 * published by the Free Software Foundation.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 *
39 */
40
41#include <linux/module.h>
42#include <linux/pci.h>
43#include <linux/delay.h>
44#include <linux/mISDNhw.h>
45#include "ipac.h"
46
47#define INFINEON_REV "1.0"
48
49static int inf_cnt;
50static u32 debug;
51static u32 irqloops = 4;
52
53enum inf_types {
54 INF_NONE,
55 INF_DIVA20,
56 INF_DIVA20U,
57 INF_DIVA201,
58 INF_DIVA202,
59 INF_SPEEDWIN,
60 INF_SAPHIR3,
61 INF_QS1000,
62 INF_QS3000,
63 INF_NICCY,
64 INF_SCT_1,
65 INF_SCT_2,
66 INF_SCT_3,
67 INF_SCT_4,
68 INF_GAZEL_R685,
69 INF_GAZEL_R753
70};
71
72enum addr_mode {
73 AM_NONE = 0,
74 AM_IO,
75 AM_MEMIO,
76 AM_IND_IO,
77};
78
79struct inf_cinfo {
80 enum inf_types typ;
81 const char *full;
82 const char *name;
83 enum addr_mode cfg_mode;
84 enum addr_mode addr_mode;
85 u8 cfg_bar;
86 u8 addr_bar;
87 void *irqfunc;
88};
89
90struct _ioaddr {
91 enum addr_mode mode;
92 union {
93 void __iomem *p;
94 struct _ioport io;
95 } a;
96};
97
98struct _iohandle {
99 enum addr_mode mode;
100 resource_size_t size;
101 resource_size_t start;
102 void __iomem *p;
103};
104
105struct inf_hw {
106 struct list_head list;
107 struct pci_dev *pdev;
108 const struct inf_cinfo *ci;
109 char name[MISDN_MAX_IDLEN];
110 u32 irq;
111 u32 irqcnt;
112 struct _iohandle cfg;
113 struct _iohandle addr;
114 struct _ioaddr isac;
115 struct _ioaddr hscx;
116 spinlock_t lock; /* HW access lock */
117 struct ipac_hw ipac;
118 struct inf_hw *sc[3]; /* slave cards */
119};
120
121
122#define PCI_SUBVENDOR_HST_SAPHIR3 0x52
123#define PCI_SUBVENDOR_SEDLBAUER_PCI 0x53
124#define PCI_SUB_ID_SEDLBAUER 0x01
125
126static struct pci_device_id infineon_ids[] __devinitdata = {
127 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20,
128 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA20},
129 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA20_U,
130 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA20U},
131 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA201,
132 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA201},
133 { PCI_VENDOR_ID_EICON, PCI_DEVICE_ID_EICON_DIVA202,
134 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_DIVA202},
135 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
136 PCI_SUBVENDOR_SEDLBAUER_PCI, PCI_SUB_ID_SEDLBAUER, 0, 0,
137 INF_SPEEDWIN},
138 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
139 PCI_SUBVENDOR_HST_SAPHIR3, PCI_SUB_ID_SEDLBAUER, 0, 0, INF_SAPHIR3},
140 { PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_MICROLINK,
141 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_QS1000},
142 { PCI_VENDOR_ID_ELSA, PCI_DEVICE_ID_ELSA_QS3000,
143 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_QS3000},
144 { PCI_VENDOR_ID_SATSAGEM, PCI_DEVICE_ID_SATSAGEM_NICCY,
145 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_NICCY},
146 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
147 PCI_VENDOR_ID_BERKOM, PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO, 0, 0,
148 INF_SCT_1},
149 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R685,
150 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R685},
151 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_R753,
152 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
153 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_DJINN_ITOO,
154 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
155 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_OLITEC,
156 PCI_ANY_ID, PCI_ANY_ID, 0, 0, INF_GAZEL_R753},
157 { }
158};
159MODULE_DEVICE_TABLE(pci, infineon_ids);
160
161/* PCI interface specific defines */
162/* Diva 2.0/2.0U */
163#define DIVA_HSCX_PORT 0x00
164#define DIVA_HSCX_ALE 0x04
165#define DIVA_ISAC_PORT 0x08
166#define DIVA_ISAC_ALE 0x0C
167#define DIVA_PCI_CTRL 0x10
168
169/* DIVA_PCI_CTRL bits */
170#define DIVA_IRQ_BIT 0x01
171#define DIVA_RESET_BIT 0x08
172#define DIVA_EEPROM_CLK 0x40
173#define DIVA_LED_A 0x10
174#define DIVA_LED_B 0x20
175#define DIVA_IRQ_CLR 0x80
176
177/* Diva 2.01/2.02 */
178/* Siemens PITA */
179#define PITA_ICR_REG 0x00
180#define PITA_INT0_STATUS 0x02
181
182#define PITA_MISC_REG 0x1c
183#define PITA_PARA_SOFTRESET 0x01000000
184#define PITA_SER_SOFTRESET 0x02000000
185#define PITA_PARA_MPX_MODE 0x04000000
186#define PITA_INT0_ENABLE 0x00020000
187
188/* TIGER 100 Registers */
189#define TIGER_RESET_ADDR 0x00
190#define TIGER_EXTERN_RESET 0x01
191#define TIGER_AUX_CTRL 0x02
192#define TIGER_AUX_DATA 0x03
193#define TIGER_AUX_IRQMASK 0x05
194#define TIGER_AUX_STATUS 0x07
195
196/* Tiger AUX BITs */
197#define TIGER_IOMASK 0xdd /* 1 and 5 are inputs */
198#define TIGER_IRQ_BIT 0x02
199
200#define TIGER_IPAC_ALE 0xC0
201#define TIGER_IPAC_PORT 0xC8
202
203/* ELSA (now Develo) PCI cards */
204#define ELSA_IRQ_ADDR 0x4c
205#define ELSA_IRQ_MASK 0x04
206#define QS1000_IRQ_OFF 0x01
207#define QS3000_IRQ_OFF 0x03
208#define QS1000_IRQ_ON 0x41
209#define QS3000_IRQ_ON 0x43
210
211/* Dr Neuhaus/Sagem Niccy */
212#define NICCY_ISAC_PORT 0x00
213#define NICCY_HSCX_PORT 0x01
214#define NICCY_ISAC_ALE 0x02
215#define NICCY_HSCX_ALE 0x03
216
217#define NICCY_IRQ_CTRL_REG 0x38
218#define NICCY_IRQ_ENABLE 0x001f00
219#define NICCY_IRQ_DISABLE 0xff0000
220#define NICCY_IRQ_BIT 0x800000
221
222
223/* Scitel PLX */
224#define SCT_PLX_IRQ_ADDR 0x4c
225#define SCT_PLX_RESET_ADDR 0x50
226#define SCT_PLX_IRQ_ENABLE 0x41
227#define SCT_PLX_RESET_BIT 0x04
228
229/* Gazel */
230#define GAZEL_IPAC_DATA_PORT 0x04
231/* Gazel PLX */
232#define GAZEL_CNTRL 0x50
233#define GAZEL_RESET 0x04
234#define GAZEL_RESET_9050 0x40000000
235#define GAZEL_INCSR 0x4C
236#define GAZEL_ISAC_EN 0x08
237#define GAZEL_INT_ISAC 0x20
238#define GAZEL_HSCX_EN 0x01
239#define GAZEL_INT_HSCX 0x04
240#define GAZEL_PCI_EN 0x40
241#define GAZEL_IPAC_EN 0x03
242
243
244static LIST_HEAD(Cards);
245static DEFINE_RWLOCK(card_lock); /* protect Cards */
246
247static void
248_set_debug(struct inf_hw *card)
249{
250 card->ipac.isac.dch.debug = debug;
251 card->ipac.hscx[0].bch.debug = debug;
252 card->ipac.hscx[1].bch.debug = debug;
253}
254
255static int
256set_debug(const char *val, struct kernel_param *kp)
257{
258 int ret;
259 struct inf_hw *card;
260
261 ret = param_set_uint(val, kp);
262 if (!ret) {
263 read_lock(&card_lock);
264 list_for_each_entry(card, &Cards, list)
265 _set_debug(card);
266 read_unlock(&card_lock);
267 }
268 return ret;
269}
270
271MODULE_AUTHOR("Karsten Keil");
272MODULE_LICENSE("GPL v2");
273MODULE_VERSION(INFINEON_REV);
274module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
275MODULE_PARM_DESC(debug, "infineon debug mask");
276module_param(irqloops, uint, S_IRUGO | S_IWUSR);
277MODULE_PARM_DESC(irqloops, "infineon maximal irqloops (default 4)");
278
279/* Interface functions */
280
281IOFUNC_IO(ISAC, inf_hw, isac.a.io)
282IOFUNC_IO(IPAC, inf_hw, hscx.a.io)
283IOFUNC_IND(ISAC, inf_hw, isac.a.io)
284IOFUNC_IND(IPAC, inf_hw, hscx.a.io)
285IOFUNC_MEMIO(ISAC, inf_hw, u32, isac.a.p)
286IOFUNC_MEMIO(IPAC, inf_hw, u32, hscx.a.p)
287
288static irqreturn_t
289diva_irq(int intno, void *dev_id)
290{
291 struct inf_hw *hw = dev_id;
292 u8 val;
293
294 spin_lock(&hw->lock);
295 val = inb((u32)hw->cfg.start + DIVA_PCI_CTRL);
296 if (!(val & DIVA_IRQ_BIT)) { /* for us or shared ? */
297 spin_unlock(&hw->lock);
298 return IRQ_NONE; /* shared */
299 }
300 hw->irqcnt++;
301 mISDNipac_irq(&hw->ipac, irqloops);
302 spin_unlock(&hw->lock);
303 return IRQ_HANDLED;
304}
305
306static irqreturn_t
307diva20x_irq(int intno, void *dev_id)
308{
309 struct inf_hw *hw = dev_id;
310 u8 val;
311
312 spin_lock(&hw->lock);
313 val = readb(hw->cfg.p);
314 if (!(val & PITA_INT0_STATUS)) { /* for us or shared ? */
315 spin_unlock(&hw->lock);
316 return IRQ_NONE; /* shared */
317 }
318 hw->irqcnt++;
319 mISDNipac_irq(&hw->ipac, irqloops);
320 writeb(PITA_INT0_STATUS, hw->cfg.p); /* ACK PITA INT0 */
321 spin_unlock(&hw->lock);
322 return IRQ_HANDLED;
323}
324
325static irqreturn_t
326tiger_irq(int intno, void *dev_id)
327{
328 struct inf_hw *hw = dev_id;
329 u8 val;
330
331 spin_lock(&hw->lock);
332 val = inb((u32)hw->cfg.start + TIGER_AUX_STATUS);
333 if (val & TIGER_IRQ_BIT) { /* for us or shared ? */
334 spin_unlock(&hw->lock);
335 return IRQ_NONE; /* shared */
336 }
337 hw->irqcnt++;
338 mISDNipac_irq(&hw->ipac, irqloops);
339 spin_unlock(&hw->lock);
340 return IRQ_HANDLED;
341}
342
343static irqreturn_t
344elsa_irq(int intno, void *dev_id)
345{
346 struct inf_hw *hw = dev_id;
347 u8 val;
348
349 spin_lock(&hw->lock);
350 val = inb((u32)hw->cfg.start + ELSA_IRQ_ADDR);
351 if (!(val & ELSA_IRQ_MASK)) {
352 spin_unlock(&hw->lock);
353 return IRQ_NONE; /* shared */
354 }
355 hw->irqcnt++;
356 mISDNipac_irq(&hw->ipac, irqloops);
357 spin_unlock(&hw->lock);
358 return IRQ_HANDLED;
359}
360
361static irqreturn_t
362niccy_irq(int intno, void *dev_id)
363{
364 struct inf_hw *hw = dev_id;
365 u32 val;
366
367 spin_lock(&hw->lock);
368 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
369 if (!(val & NICCY_IRQ_BIT)) { /* for us or shared ? */
370 spin_unlock(&hw->lock);
371 return IRQ_NONE; /* shared */
372 }
373 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
374 hw->irqcnt++;
375 mISDNipac_irq(&hw->ipac, irqloops);
376 spin_unlock(&hw->lock);
377 return IRQ_HANDLED;
378}
379
380static irqreturn_t
381gazel_irq(int intno, void *dev_id)
382{
383 struct inf_hw *hw = dev_id;
384 irqreturn_t ret;
385
386 spin_lock(&hw->lock);
387 ret = mISDNipac_irq(&hw->ipac, irqloops);
388 spin_unlock(&hw->lock);
389 return ret;
390}
391
392static irqreturn_t
393ipac_irq(int intno, void *dev_id)
394{
395 struct inf_hw *hw = dev_id;
396 u8 val;
397
398 spin_lock(&hw->lock);
399 val = hw->ipac.read_reg(hw, IPAC_ISTA);
400 if (!(val & 0x3f)) {
401 spin_unlock(&hw->lock);
402 return IRQ_NONE; /* shared */
403 }
404 hw->irqcnt++;
405 mISDNipac_irq(&hw->ipac, irqloops);
406 spin_unlock(&hw->lock);
407 return IRQ_HANDLED;
408}
409
410static void
411enable_hwirq(struct inf_hw *hw)
412{
413 u16 w;
414 u32 val;
415
416 switch (hw->ci->typ) {
417 case INF_DIVA201:
418 case INF_DIVA202:
419 writel(PITA_INT0_ENABLE, hw->cfg.p);
420 break;
421 case INF_SPEEDWIN:
422 case INF_SAPHIR3:
423 outb(TIGER_IRQ_BIT, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
424 break;
425 case INF_QS1000:
426 outb(QS1000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
427 break;
428 case INF_QS3000:
429 outb(QS3000_IRQ_ON, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
430 break;
431 case INF_NICCY:
432 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
433 val |= NICCY_IRQ_ENABLE;;
434 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
435 break;
436 case INF_SCT_1:
437 w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
438 w |= SCT_PLX_IRQ_ENABLE;
439 outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
440 break;
441 case INF_GAZEL_R685:
442 outb(GAZEL_ISAC_EN + GAZEL_HSCX_EN + GAZEL_PCI_EN,
443 (u32)hw->cfg.start + GAZEL_INCSR);
444 break;
445 case INF_GAZEL_R753:
446 outb(GAZEL_IPAC_EN + GAZEL_PCI_EN,
447 (u32)hw->cfg.start + GAZEL_INCSR);
448 break;
449 default:
450 break;
451 }
452}
453
454static void
455disable_hwirq(struct inf_hw *hw)
456{
457 u16 w;
458 u32 val;
459
460 switch (hw->ci->typ) {
461 case INF_DIVA201:
462 case INF_DIVA202:
463 writel(0, hw->cfg.p);
464 break;
465 case INF_SPEEDWIN:
466 case INF_SAPHIR3:
467 outb(0, (u32)hw->cfg.start + TIGER_AUX_IRQMASK);
468 break;
469 case INF_QS1000:
470 outb(QS1000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
471 break;
472 case INF_QS3000:
473 outb(QS3000_IRQ_OFF, (u32)hw->cfg.start + ELSA_IRQ_ADDR);
474 break;
475 case INF_NICCY:
476 val = inl((u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
477 val &= NICCY_IRQ_DISABLE;
478 outl(val, (u32)hw->cfg.start + NICCY_IRQ_CTRL_REG);
479 break;
480 case INF_SCT_1:
481 w = inw((u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
482 w &= (~SCT_PLX_IRQ_ENABLE);
483 outw(w, (u32)hw->cfg.start + SCT_PLX_IRQ_ADDR);
484 break;
485 case INF_GAZEL_R685:
486 case INF_GAZEL_R753:
487 outb(0, (u32)hw->cfg.start + GAZEL_INCSR);
488 break;
489 default:
490 break;
491 }
492}
493
494static void
495ipac_chip_reset(struct inf_hw *hw)
496{
497 hw->ipac.write_reg(hw, IPAC_POTA2, 0x20);
498 mdelay(5);
499 hw->ipac.write_reg(hw, IPAC_POTA2, 0x00);
500 mdelay(5);
501 hw->ipac.write_reg(hw, IPAC_CONF, hw->ipac.conf);
502 hw->ipac.write_reg(hw, IPAC_MASK, 0xc0);
503}
504
505static void
506reset_inf(struct inf_hw *hw)
507{
508 u16 w;
509 u32 val;
510
511 if (debug & DEBUG_HW)
512 pr_notice("%s: resetting card\n", hw->name);
513 switch (hw->ci->typ) {
514 case INF_DIVA20:
515 case INF_DIVA20U:
516 outb(0, (u32)hw->cfg.start + DIVA_PCI_CTRL);
517 mdelay(10);
518 outb(DIVA_RESET_BIT, (u32)hw->cfg.start + DIVA_PCI_CTRL);
519 mdelay(10);
520 /* Workaround PCI9060 */
521 outb(9, (u32)hw->cfg.start + 0x69);
522 outb(DIVA_RESET_BIT | DIVA_LED_A,
523 (u32)hw->cfg.start + DIVA_PCI_CTRL);
524 break;
525 case INF_DIVA201:
526 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
527 hw->cfg.p + PITA_MISC_REG);
528 mdelay(1);
529 writel(PITA_PARA_MPX_MODE, hw->cfg.p + PITA_MISC_REG);
530 mdelay(10);
531 break;
532 case INF_DIVA202:
533 writel(PITA_PARA_SOFTRESET | PITA_PARA_MPX_MODE,
534 hw->cfg.p + PITA_MISC_REG);
535 mdelay(1);
536 writel(PITA_PARA_MPX_MODE | PITA_SER_SOFTRESET,
537 hw->cfg.p + PITA_MISC_REG);
538 mdelay(10);
539 break;
540 case INF_SPEEDWIN:
541 case INF_SAPHIR3:
542 ipac_chip_reset(hw);
543 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
544 hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
545 hw->ipac.write_reg(hw, IPAC_PCFG, 0x12);
546 break;
547 case INF_QS1000:
548 case INF_QS3000:
549 ipac_chip_reset(hw);
550 hw->ipac.write_reg(hw, IPAC_ACFG, 0x00);
551 hw->ipac.write_reg(hw, IPAC_AOE, 0x3c);
552 hw->ipac.write_reg(hw, IPAC_ATX, 0xff);
553 break;
554 case INF_NICCY:
555 break;
556 case INF_SCT_1:
557 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
558 w &= (~SCT_PLX_RESET_BIT);
559 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
560 mdelay(10);
561 w = inw((u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
562 w |= SCT_PLX_RESET_BIT;
563 outw(w, (u32)hw->cfg.start + SCT_PLX_RESET_ADDR);
564 mdelay(10);
565 break;
566 case INF_GAZEL_R685:
567 val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
568 val |= (GAZEL_RESET_9050 + GAZEL_RESET);
569 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
570 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
571 mdelay(4);
572 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
573 mdelay(10);
574 hw->ipac.isac.adf2 = 0x87;
575 hw->ipac.hscx[0].slot = 0x1f;
576 hw->ipac.hscx[0].slot = 0x23;
577 break;
578 case INF_GAZEL_R753:
579 val = inl((u32)hw->cfg.start + GAZEL_CNTRL);
580 val |= (GAZEL_RESET_9050 + GAZEL_RESET);
581 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
582 val &= ~(GAZEL_RESET_9050 + GAZEL_RESET);
583 mdelay(4);
584 outl(val, (u32)hw->cfg.start + GAZEL_CNTRL);
585 mdelay(10);
586 ipac_chip_reset(hw);
587 hw->ipac.write_reg(hw, IPAC_ACFG, 0xff);
588 hw->ipac.write_reg(hw, IPAC_AOE, 0x00);
589 hw->ipac.conf = 0x01; /* IOM off */
590 break;
591 default:
592 return;
593 }
594 enable_hwirq(hw);
595}
596
597static int
598inf_ctrl(struct inf_hw *hw, u32 cmd, u_long arg)
599{
600 int ret = 0;
601
602 switch (cmd) {
603 case HW_RESET_REQ:
604 reset_inf(hw);
605 break;
606 default:
607 pr_info("%s: %s unknown command %x %lx\n",
608 hw->name, __func__, cmd, arg);
609 ret = -EINVAL;
610 break;
611 }
612 return ret;
613}
614
615static int __devinit
616init_irq(struct inf_hw *hw)
617{
618 int ret, cnt = 3;
619 u_long flags;
620
621 if (!hw->ci->irqfunc)
622 return -EINVAL;
623 ret = request_irq(hw->irq, hw->ci->irqfunc, IRQF_SHARED, hw->name, hw);
624 if (ret) {
625 pr_info("%s: couldn't get interrupt %d\n", hw->name, hw->irq);
626 return ret;
627 }
628 while (cnt--) {
629 spin_lock_irqsave(&hw->lock, flags);
630 reset_inf(hw);
631 ret = hw->ipac.init(&hw->ipac);
632 if (ret) {
633 spin_unlock_irqrestore(&hw->lock, flags);
634 pr_info("%s: ISAC init failed with %d\n",
635 hw->name, ret);
636 break;
637 }
638 spin_unlock_irqrestore(&hw->lock, flags);
639 msleep_interruptible(10);
640 if (debug & DEBUG_HW)
641 pr_notice("%s: IRQ %d count %d\n", hw->name,
642 hw->irq, hw->irqcnt);
643 if (!hw->irqcnt) {
644 pr_info("%s: IRQ(%d) got no requests during init %d\n",
645 hw->name, hw->irq, 3 - cnt);
646 } else
647 return 0;
648 }
649 free_irq(hw->irq, hw);
650 return -EIO;
651}
652
653static void
654release_io(struct inf_hw *hw)
655{
656 if (hw->cfg.mode) {
657 if (hw->cfg.p) {
658 release_mem_region(hw->cfg.start, hw->cfg.size);
659 iounmap(hw->cfg.p);
660 } else
661 release_region(hw->cfg.start, hw->cfg.size);
662 hw->cfg.mode = AM_NONE;
663 }
664 if (hw->addr.mode) {
665 if (hw->addr.p) {
666 release_mem_region(hw->addr.start, hw->addr.size);
667 iounmap(hw->addr.p);
668 } else
669 release_region(hw->addr.start, hw->addr.size);
670 hw->addr.mode = AM_NONE;
671 }
672}
673
674static int __devinit
675setup_io(struct inf_hw *hw)
676{
677 int err = 0;
678
679 if (hw->ci->cfg_mode) {
680 hw->cfg.start = pci_resource_start(hw->pdev, hw->ci->cfg_bar);
681 hw->cfg.size = pci_resource_len(hw->pdev, hw->ci->cfg_bar);
682 if (hw->ci->cfg_mode == AM_MEMIO) {
683 if (!request_mem_region(hw->cfg.start, hw->cfg.size,
684 hw->name))
685 err = -EBUSY;
686 } else {
687 if (!request_region(hw->cfg.start, hw->cfg.size,
688 hw->name))
689 err = -EBUSY;
690 }
691 if (err) {
692 pr_info("mISDN: %s config port %lx (%lu bytes)"
693 "already in use\n", hw->name,
694 (ulong)hw->cfg.start, (ulong)hw->cfg.size);
695 return err;
696 }
697 if (hw->ci->cfg_mode == AM_MEMIO)
698 hw->cfg.p = ioremap(hw->cfg.start, hw->cfg.size);
699 hw->cfg.mode = hw->ci->cfg_mode;
700 if (debug & DEBUG_HW)
701 pr_notice("%s: IO cfg %lx (%lu bytes) mode%d\n",
702 hw->name, (ulong)hw->cfg.start,
703 (ulong)hw->cfg.size, hw->ci->cfg_mode);
704
705 }
706 if (hw->ci->addr_mode) {
707 hw->addr.start = pci_resource_start(hw->pdev, hw->ci->addr_bar);
708 hw->addr.size = pci_resource_len(hw->pdev, hw->ci->addr_bar);
709 if (hw->ci->addr_mode == AM_MEMIO) {
710 if (!request_mem_region(hw->addr.start, hw->addr.size,
711 hw->name))
712 err = -EBUSY;
713 } else {
714 if (!request_region(hw->addr.start, hw->addr.size,
715 hw->name))
716 err = -EBUSY;
717 }
718 if (err) {
719 pr_info("mISDN: %s address port %lx (%lu bytes)"
720 "already in use\n", hw->name,
721 (ulong)hw->addr.start, (ulong)hw->addr.size);
722 return err;
723 }
724 if (hw->ci->addr_mode == AM_MEMIO)
725 hw->addr.p = ioremap(hw->addr.start, hw->addr.size);
726 hw->addr.mode = hw->ci->addr_mode;
727 if (debug & DEBUG_HW)
728 pr_notice("%s: IO addr %lx (%lu bytes) mode%d\n",
729 hw->name, (ulong)hw->addr.start,
730 (ulong)hw->addr.size, hw->ci->addr_mode);
731
732 }
733
734 switch (hw->ci->typ) {
735 case INF_DIVA20:
736 case INF_DIVA20U:
737 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
738 hw->isac.mode = hw->cfg.mode;
739 hw->isac.a.io.ale = (u32)hw->cfg.start + DIVA_ISAC_ALE;
740 hw->isac.a.io.port = (u32)hw->cfg.start + DIVA_ISAC_PORT;
741 hw->hscx.mode = hw->cfg.mode;
742 hw->hscx.a.io.ale = (u32)hw->cfg.start + DIVA_HSCX_ALE;
743 hw->hscx.a.io.port = (u32)hw->cfg.start + DIVA_HSCX_PORT;
744 break;
745 case INF_DIVA201:
746 hw->ipac.type = IPAC_TYPE_IPAC;
747 hw->ipac.isac.off = 0x80;
748 hw->isac.mode = hw->addr.mode;
749 hw->isac.a.p = hw->addr.p;
750 hw->hscx.mode = hw->addr.mode;
751 hw->hscx.a.p = hw->addr.p;
752 break;
753 case INF_DIVA202:
754 hw->ipac.type = IPAC_TYPE_IPACX;
755 hw->isac.mode = hw->addr.mode;
756 hw->isac.a.p = hw->addr.p;
757 hw->hscx.mode = hw->addr.mode;
758 hw->hscx.a.p = hw->addr.p;
759 break;
760 case INF_SPEEDWIN:
761 case INF_SAPHIR3:
762 hw->ipac.type = IPAC_TYPE_IPAC;
763 hw->ipac.isac.off = 0x80;
764 hw->isac.mode = hw->cfg.mode;
765 hw->isac.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
766 hw->isac.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
767 hw->hscx.mode = hw->cfg.mode;
768 hw->hscx.a.io.ale = (u32)hw->cfg.start + TIGER_IPAC_ALE;
769 hw->hscx.a.io.port = (u32)hw->cfg.start + TIGER_IPAC_PORT;
770 outb(0xff, (ulong)hw->cfg.start);
771 mdelay(1);
772 outb(0x00, (ulong)hw->cfg.start);
773 mdelay(1);
774 outb(TIGER_IOMASK, (ulong)hw->cfg.start + TIGER_AUX_CTRL);
775 break;
776 case INF_QS1000:
777 case INF_QS3000:
778 hw->ipac.type = IPAC_TYPE_IPAC;
779 hw->ipac.isac.off = 0x80;
780 hw->isac.a.io.ale = (u32)hw->addr.start;
781 hw->isac.a.io.port = (u32)hw->addr.start + 1;
782 hw->isac.mode = hw->addr.mode;
783 hw->hscx.a.io.ale = (u32)hw->addr.start;
784 hw->hscx.a.io.port = (u32)hw->addr.start + 1;
785 hw->hscx.mode = hw->addr.mode;
786 break;
787 case INF_NICCY:
788 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
789 hw->isac.mode = hw->addr.mode;
790 hw->isac.a.io.ale = (u32)hw->addr.start + NICCY_ISAC_ALE;
791 hw->isac.a.io.port = (u32)hw->addr.start + NICCY_ISAC_PORT;
792 hw->hscx.mode = hw->addr.mode;
793 hw->hscx.a.io.ale = (u32)hw->addr.start + NICCY_HSCX_ALE;
794 hw->hscx.a.io.port = (u32)hw->addr.start + NICCY_HSCX_PORT;
795 break;
796 case INF_SCT_1:
797 hw->ipac.type = IPAC_TYPE_IPAC;
798 hw->ipac.isac.off = 0x80;
799 hw->isac.a.io.ale = (u32)hw->addr.start;
800 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
801 hw->isac.mode = hw->addr.mode;
802 hw->hscx.a.io.ale = hw->isac.a.io.ale;
803 hw->hscx.a.io.port = hw->isac.a.io.port;
804 hw->hscx.mode = hw->addr.mode;
805 break;
806 case INF_SCT_2:
807 hw->ipac.type = IPAC_TYPE_IPAC;
808 hw->ipac.isac.off = 0x80;
809 hw->isac.a.io.ale = (u32)hw->addr.start + 0x08;
810 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
811 hw->isac.mode = hw->addr.mode;
812 hw->hscx.a.io.ale = hw->isac.a.io.ale;
813 hw->hscx.a.io.port = hw->isac.a.io.port;
814 hw->hscx.mode = hw->addr.mode;
815 break;
816 case INF_SCT_3:
817 hw->ipac.type = IPAC_TYPE_IPAC;
818 hw->ipac.isac.off = 0x80;
819 hw->isac.a.io.ale = (u32)hw->addr.start + 0x10;
820 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
821 hw->isac.mode = hw->addr.mode;
822 hw->hscx.a.io.ale = hw->isac.a.io.ale;
823 hw->hscx.a.io.port = hw->isac.a.io.port;
824 hw->hscx.mode = hw->addr.mode;
825 break;
826 case INF_SCT_4:
827 hw->ipac.type = IPAC_TYPE_IPAC;
828 hw->ipac.isac.off = 0x80;
829 hw->isac.a.io.ale = (u32)hw->addr.start + 0x20;
830 hw->isac.a.io.port = hw->isac.a.io.ale + 4;
831 hw->isac.mode = hw->addr.mode;
832 hw->hscx.a.io.ale = hw->isac.a.io.ale;
833 hw->hscx.a.io.port = hw->isac.a.io.port;
834 hw->hscx.mode = hw->addr.mode;
835 break;
836 case INF_GAZEL_R685:
837 hw->ipac.type = IPAC_TYPE_ISAC | IPAC_TYPE_HSCX;
838 hw->ipac.isac.off = 0x80;
839 hw->isac.mode = hw->addr.mode;
840 hw->isac.a.io.port = (u32)hw->addr.start;
841 hw->hscx.mode = hw->addr.mode;
842 hw->hscx.a.io.port = hw->isac.a.io.port;
843 break;
844 case INF_GAZEL_R753:
845 hw->ipac.type = IPAC_TYPE_IPAC;
846 hw->ipac.isac.off = 0x80;
847 hw->isac.mode = hw->addr.mode;
848 hw->isac.a.io.ale = (u32)hw->addr.start;
849 hw->isac.a.io.port = (u32)hw->addr.start + GAZEL_IPAC_DATA_PORT;
850 hw->hscx.mode = hw->addr.mode;
851 hw->hscx.a.io.ale = hw->isac.a.io.ale;
852 hw->hscx.a.io.port = hw->isac.a.io.port;
853 break;
854 default:
855 return -EINVAL;
856 }
857 switch (hw->isac.mode) {
858 case AM_MEMIO:
859 ASSIGN_FUNC_IPAC(MIO, hw->ipac);
860 break;
861 case AM_IND_IO:
862 ASSIGN_FUNC_IPAC(IND, hw->ipac);
863 break;
864 case AM_IO:
865 ASSIGN_FUNC_IPAC(IO, hw->ipac);
866 break;
867 default:
868 return -EINVAL;
869 }
870 return 0;
871}
872
873static void
874release_card(struct inf_hw *card) {
875 ulong flags;
876 int i;
877
878 spin_lock_irqsave(&card->lock, flags);
879 disable_hwirq(card);
880 spin_unlock_irqrestore(&card->lock, flags);
881 card->ipac.isac.release(&card->ipac.isac);
882 free_irq(card->irq, card);
883 mISDN_unregister_device(&card->ipac.isac.dch.dev);
884 release_io(card);
885 write_lock_irqsave(&card_lock, flags);
886 list_del(&card->list);
887 write_unlock_irqrestore(&card_lock, flags);
888 switch (card->ci->typ) {
889 case INF_SCT_2:
890 case INF_SCT_3:
891 case INF_SCT_4:
892 break;
893 case INF_SCT_1:
894 for (i = 0; i < 3; i++) {
895 if (card->sc[i])
896 release_card(card->sc[i]);
897 card->sc[i] = NULL;
898 }
899 default:
900 pci_disable_device(card->pdev);
901 pci_set_drvdata(card->pdev, NULL);
902 break;
903 }
904 kfree(card);
905 inf_cnt--;
906}
907
908static int __devinit
909setup_instance(struct inf_hw *card)
910{
911 int err;
912 ulong flags;
913
914 snprintf(card->name, MISDN_MAX_IDLEN - 1, "%s.%d", card->ci->name,
915 inf_cnt + 1);
916 write_lock_irqsave(&card_lock, flags);
917 list_add_tail(&card->list, &Cards);
918 write_unlock_irqrestore(&card_lock, flags);
919
920 _set_debug(card);
921 card->ipac.isac.name = card->name;
922 card->ipac.name = card->name;
923 card->ipac.owner = THIS_MODULE;
924 spin_lock_init(&card->lock);
925 card->ipac.isac.hwlock = &card->lock;
926 card->ipac.hwlock = &card->lock;
927 card->ipac.ctrl = (void *)&inf_ctrl;
928
929 err = setup_io(card);
930 if (err)
931 goto error_setup;
932
933 card->ipac.isac.dch.dev.Bprotocols =
934 mISDNipac_init(&card->ipac, card);
935
936 if (card->ipac.isac.dch.dev.Bprotocols == 0)
937 goto error_setup;;
938
939 err = mISDN_register_device(&card->ipac.isac.dch.dev,
940 &card->pdev->dev, card->name);
941 if (err)
942 goto error;
943
944 err = init_irq(card);
945 if (!err) {
946 inf_cnt++;
947 pr_notice("Infineon %d cards installed\n", inf_cnt);
948 return 0;
949 }
950 mISDN_unregister_device(&card->ipac.isac.dch.dev);
951error:
952 card->ipac.release(&card->ipac);
953error_setup:
954 release_io(card);
955 write_lock_irqsave(&card_lock, flags);
956 list_del(&card->list);
957 write_unlock_irqrestore(&card_lock, flags);
958 return err;
959}
960
961static const struct inf_cinfo inf_card_info[] = {
962 {
963 INF_DIVA20,
964 "Dialogic Diva 2.0",
965 "diva20",
966 AM_IND_IO, AM_NONE, 2, 0,
967 &diva_irq
968 },
969 {
970 INF_DIVA20U,
971 "Dialogic Diva 2.0U",
972 "diva20U",
973 AM_IND_IO, AM_NONE, 2, 0,
974 &diva_irq
975 },
976 {
977 INF_DIVA201,
978 "Dialogic Diva 2.01",
979 "diva201",
980 AM_MEMIO, AM_MEMIO, 0, 1,
981 &diva20x_irq
982 },
983 {
984 INF_DIVA202,
985 "Dialogic Diva 2.02",
986 "diva202",
987 AM_MEMIO, AM_MEMIO, 0, 1,
988 &diva20x_irq
989 },
990 {
991 INF_SPEEDWIN,
992 "Sedlbauer SpeedWin PCI",
993 "speedwin",
994 AM_IND_IO, AM_NONE, 0, 0,
995 &tiger_irq
996 },
997 {
998 INF_SAPHIR3,
999 "HST Saphir 3",
1000 "saphir",
1001 AM_IND_IO, AM_NONE, 0, 0,
1002 &tiger_irq
1003 },
1004 {
1005 INF_QS1000,
1006 "Develo Microlink PCI",
1007 "qs1000",
1008 AM_IO, AM_IND_IO, 1, 3,
1009 &elsa_irq
1010 },
1011 {
1012 INF_QS3000,
1013 "Develo QuickStep 3000",
1014 "qs3000",
1015 AM_IO, AM_IND_IO, 1, 3,
1016 &elsa_irq
1017 },
1018 {
1019 INF_NICCY,
1020 "Sagem NICCY",
1021 "niccy",
1022 AM_IO, AM_IND_IO, 0, 1,
1023 &niccy_irq
1024 },
1025 {
1026 INF_SCT_1,
1027 "SciTel Quadro",
1028 "p1_scitel",
1029 AM_IO, AM_IND_IO, 1, 5,
1030 &ipac_irq
1031 },
1032 {
1033 INF_SCT_2,
1034 "SciTel Quadro",
1035 "p2_scitel",
1036 AM_NONE, AM_IND_IO, 0, 4,
1037 &ipac_irq
1038 },
1039 {
1040 INF_SCT_3,
1041 "SciTel Quadro",
1042 "p3_scitel",
1043 AM_NONE, AM_IND_IO, 0, 3,
1044 &ipac_irq
1045 },
1046 {
1047 INF_SCT_4,
1048 "SciTel Quadro",
1049 "p4_scitel",
1050 AM_NONE, AM_IND_IO, 0, 2,
1051 &ipac_irq
1052 },
1053 {
1054 INF_GAZEL_R685,
1055 "Gazel R685",
1056 "gazel685",
1057 AM_IO, AM_IO, 1, 2,
1058 &gazel_irq
1059 },
1060 {
1061 INF_GAZEL_R753,
1062 "Gazel R753",
1063 "gazel753",
1064 AM_IO, AM_IND_IO, 1, 2,
1065 &ipac_irq
1066 },
1067 {
1068 INF_NONE,
1069 }
1070};
1071
1072static const struct inf_cinfo * __devinit
1073get_card_info(enum inf_types typ)
1074{
1075 const struct inf_cinfo *ci = inf_card_info;
1076
1077 while (ci->typ != INF_NONE) {
1078 if (ci->typ == typ)
1079 return ci;
1080 ci++;
1081 }
1082 return NULL;
1083}
1084
1085static int __devinit
1086inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1087{
1088 int err = -ENOMEM;
1089 struct inf_hw *card;
1090
1091 card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1092 if (!card) {
1093 pr_info("No memory for Infineon ISDN card\n");
1094 return err;
1095 }
1096 card->pdev = pdev;
1097 err = pci_enable_device(pdev);
1098 if (err) {
1099 kfree(card);
1100 return err;
1101 }
1102 card->ci = get_card_info(ent->driver_data);
1103 if (!card->ci) {
1104 pr_info("mISDN: do not have informations about adapter at %s\n",
1105 pci_name(pdev));
1106 kfree(card);
1107 return -EINVAL;
1108 } else
1109 pr_notice("mISDN: found adapter %s at %s\n",
1110 card->ci->full, pci_name(pdev));
1111
1112 card->irq = pdev->irq;
1113 pci_set_drvdata(pdev, card);
1114 err = setup_instance(card);
1115 if (err) {
1116 pci_disable_device(card->pdev);
1117 kfree(card);
1118 pci_set_drvdata(pdev, NULL);
1119 } else if (ent->driver_data == INF_SCT_1) {
1120 int i;
1121 struct inf_hw *sc;
1122
1123 for (i = 1; i < 4; i++) {
1124 sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL);
1125 if (!sc) {
1126 release_card(card);
1127 return -ENOMEM;
1128 }
1129 sc->irq = card->irq;
1130 sc->pdev = card->pdev;
1131 sc->ci = card->ci + i;
1132 err = setup_instance(sc);
1133 if (err) {
1134 kfree(sc);
1135 release_card(card);
1136 } else
1137 card->sc[i - 1] = sc;
1138 }
1139 }
1140 return err;
1141}
1142
1143static void __devexit
1144inf_remove(struct pci_dev *pdev)
1145{
1146 struct inf_hw *card = pci_get_drvdata(pdev);
1147
1148 if (card)
1149 release_card(card);
1150 else
1151 pr_debug("%s: drvdata allready removed\n", __func__);
1152}
1153
1154static struct pci_driver infineon_driver = {
1155 .name = "ISDN Infineon pci",
1156 .probe = inf_probe,
1157 .remove = __devexit_p(inf_remove),
1158 .id_table = infineon_ids,
1159};
1160
1161static int __init
1162infineon_init(void)
1163{
1164 int err;
1165
1166 pr_notice("Infineon ISDN Driver Rev. %s\n", INFINEON_REV);
1167 err = pci_register_driver(&infineon_driver);
1168 return err;
1169}
1170
1171static void __exit
1172infineon_cleanup(void)
1173{
1174 pci_unregister_driver(&infineon_driver);
1175}
1176
1177module_init(infineon_init);
1178module_exit(infineon_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c
new file mode 100644
index 000000000000..613ba0435372
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/mISDNipac.c
@@ -0,0 +1,1655 @@
1/*
2 * isac.c ISAC specific routines
3 *
4 * Author Karsten Keil <keil@isdn4linux.de>
5 *
6 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/mISDNhw.h>
25#include "ipac.h"
26
27
28#define DBUSY_TIMER_VALUE 80
29#define ARCOFI_USE 1
30
31#define ISAC_REV "2.0"
32
33MODULE_AUTHOR("Karsten Keil");
34MODULE_VERSION(ISAC_REV);
35MODULE_LICENSE("GPL v2");
36
37#define ReadISAC(is, o) (is->read_reg(is->dch.hw, o + is->off))
38#define WriteISAC(is, o, v) (is->write_reg(is->dch.hw, o + is->off, v))
39#define ReadHSCX(h, o) (h->ip->read_reg(h->ip->hw, h->off + o))
40#define WriteHSCX(h, o, v) (h->ip->write_reg(h->ip->hw, h->off + o, v))
41#define ReadIPAC(ip, o) (ip->read_reg(ip->hw, o))
42#define WriteIPAC(ip, o, v) (ip->write_reg(ip->hw, o, v))
43
44static inline void
45ph_command(struct isac_hw *isac, u8 command)
46{
47 pr_debug("%s: ph_command %x\n", isac->name, command);
48 if (isac->type & IPAC_TYPE_ISACX)
49 WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
50 else
51 WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
52}
53
54static void
55isac_ph_state_change(struct isac_hw *isac)
56{
57 switch (isac->state) {
58 case (ISAC_IND_RS):
59 case (ISAC_IND_EI):
60 ph_command(isac, ISAC_CMD_DUI);
61 }
62 schedule_event(&isac->dch, FLG_PHCHANGE);
63}
64
65static void
66isac_ph_state_bh(struct dchannel *dch)
67{
68 struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
69
70 switch (isac->state) {
71 case ISAC_IND_RS:
72 case ISAC_IND_EI:
73 dch->state = 0;
74 l1_event(dch->l1, HW_RESET_IND);
75 break;
76 case ISAC_IND_DID:
77 dch->state = 3;
78 l1_event(dch->l1, HW_DEACT_CNF);
79 break;
80 case ISAC_IND_DR:
81 dch->state = 3;
82 l1_event(dch->l1, HW_DEACT_IND);
83 break;
84 case ISAC_IND_PU:
85 dch->state = 4;
86 l1_event(dch->l1, HW_POWERUP_IND);
87 break;
88 case ISAC_IND_RSY:
89 if (dch->state <= 5) {
90 dch->state = 5;
91 l1_event(dch->l1, ANYSIGNAL);
92 } else {
93 dch->state = 8;
94 l1_event(dch->l1, LOSTFRAMING);
95 }
96 break;
97 case ISAC_IND_ARD:
98 dch->state = 6;
99 l1_event(dch->l1, INFO2);
100 break;
101 case ISAC_IND_AI8:
102 dch->state = 7;
103 l1_event(dch->l1, INFO4_P8);
104 break;
105 case ISAC_IND_AI10:
106 dch->state = 7;
107 l1_event(dch->l1, INFO4_P10);
108 break;
109 }
110 pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
111}
112
113void
114isac_empty_fifo(struct isac_hw *isac, int count)
115{
116 u8 *ptr;
117
118 pr_debug("%s: %s %d\n", isac->name, __func__, count);
119
120 if (!isac->dch.rx_skb) {
121 isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
122 if (!isac->dch.rx_skb) {
123 pr_info("%s: D receive out of memory\n", isac->name);
124 WriteISAC(isac, ISAC_CMDR, 0x80);
125 return;
126 }
127 }
128 if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
129 pr_debug("%s: %s overrun %d\n", isac->name, __func__,
130 isac->dch.rx_skb->len + count);
131 WriteISAC(isac, ISAC_CMDR, 0x80);
132 return;
133 }
134 ptr = skb_put(isac->dch.rx_skb, count);
135 isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
136 WriteISAC(isac, ISAC_CMDR, 0x80);
137 if (isac->dch.debug & DEBUG_HW_DFIFO) {
138 char pfx[MISDN_MAX_IDLEN + 16];
139
140 snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
141 isac->name, count);
142 print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
143 }
144}
145
146static void
147isac_fill_fifo(struct isac_hw *isac)
148{
149 int count, more;
150 u8 *ptr;
151
152 if (!isac->dch.tx_skb)
153 return;
154 count = isac->dch.tx_skb->len - isac->dch.tx_idx;
155 if (count <= 0)
156 return;
157
158 more = 0;
159 if (count > 32) {
160 more = !0;
161 count = 32;
162 }
163 pr_debug("%s: %s %d\n", isac->name, __func__, count);
164 ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
165 isac->dch.tx_idx += count;
166 isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
167 WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
168 if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
169 pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
170 del_timer(&isac->dch.timer);
171 }
172 init_timer(&isac->dch.timer);
173 isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
174 add_timer(&isac->dch.timer);
175 if (isac->dch.debug & DEBUG_HW_DFIFO) {
176 char pfx[MISDN_MAX_IDLEN + 16];
177
178 snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
179 isac->name, count);
180 print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
181 }
182}
183
184static void
185isac_rme_irq(struct isac_hw *isac)
186{
187 u8 val, count;
188
189 val = ReadISAC(isac, ISAC_RSTA);
190 if ((val & 0x70) != 0x20) {
191 if (val & 0x40) {
192 pr_debug("%s: ISAC RDO\n", isac->name);
193#ifdef ERROR_STATISTIC
194 isac->dch.err_rx++;
195#endif
196 }
197 if (!(val & 0x20)) {
198 pr_debug("%s: ISAC CRC error\n", isac->name);
199#ifdef ERROR_STATISTIC
200 isac->dch.err_crc++;
201#endif
202 }
203 WriteISAC(isac, ISAC_CMDR, 0x80);
204 if (isac->dch.rx_skb)
205 dev_kfree_skb(isac->dch.rx_skb);
206 isac->dch.rx_skb = NULL;
207 } else {
208 count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
209 if (count == 0)
210 count = 32;
211 isac_empty_fifo(isac, count);
212 recv_Dchannel(&isac->dch);
213 }
214}
215
216static void
217isac_xpr_irq(struct isac_hw *isac)
218{
219 if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
220 del_timer(&isac->dch.timer);
221 if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
222 isac_fill_fifo(isac);
223 } else {
224 if (isac->dch.tx_skb)
225 dev_kfree_skb(isac->dch.tx_skb);
226 if (get_next_dframe(&isac->dch))
227 isac_fill_fifo(isac);
228 }
229}
230
231static void
232isac_retransmit(struct isac_hw *isac)
233{
234 if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
235 del_timer(&isac->dch.timer);
236 if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
237 /* Restart frame */
238 isac->dch.tx_idx = 0;
239 isac_fill_fifo(isac);
240 } else if (isac->dch.tx_skb) { /* should not happen */
241 pr_info("%s: tx_skb exist but not busy\n", isac->name);
242 test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
243 isac->dch.tx_idx = 0;
244 isac_fill_fifo(isac);
245 } else {
246 pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
247 if (get_next_dframe(&isac->dch))
248 isac_fill_fifo(isac);
249 }
250}
251
252static void
253isac_mos_irq(struct isac_hw *isac)
254{
255 u8 val;
256 int ret;
257
258 val = ReadISAC(isac, ISAC_MOSR);
259 pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
260#if ARCOFI_USE
261 if (val & 0x08) {
262 if (!isac->mon_rx) {
263 isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
264 if (!isac->mon_rx) {
265 pr_info("%s: ISAC MON RX out of memory!\n",
266 isac->name);
267 isac->mocr &= 0xf0;
268 isac->mocr |= 0x0a;
269 WriteISAC(isac, ISAC_MOCR, isac->mocr);
270 goto afterMONR0;
271 } else
272 isac->mon_rxp = 0;
273 }
274 if (isac->mon_rxp >= MAX_MON_FRAME) {
275 isac->mocr &= 0xf0;
276 isac->mocr |= 0x0a;
277 WriteISAC(isac, ISAC_MOCR, isac->mocr);
278 isac->mon_rxp = 0;
279 pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
280 goto afterMONR0;
281 }
282 isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
283 pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
284 isac->mon_rx[isac->mon_rxp - 1]);
285 if (isac->mon_rxp == 1) {
286 isac->mocr |= 0x04;
287 WriteISAC(isac, ISAC_MOCR, isac->mocr);
288 }
289 }
290afterMONR0:
291 if (val & 0x80) {
292 if (!isac->mon_rx) {
293 isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
294 if (!isac->mon_rx) {
295 pr_info("%s: ISAC MON RX out of memory!\n",
296 isac->name);
297 isac->mocr &= 0x0f;
298 isac->mocr |= 0xa0;
299 WriteISAC(isac, ISAC_MOCR, isac->mocr);
300 goto afterMONR1;
301 } else
302 isac->mon_rxp = 0;
303 }
304 if (isac->mon_rxp >= MAX_MON_FRAME) {
305 isac->mocr &= 0x0f;
306 isac->mocr |= 0xa0;
307 WriteISAC(isac, ISAC_MOCR, isac->mocr);
308 isac->mon_rxp = 0;
309 pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
310 goto afterMONR1;
311 }
312 isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
313 pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
314 isac->mon_rx[isac->mon_rxp - 1]);
315 isac->mocr |= 0x40;
316 WriteISAC(isac, ISAC_MOCR, isac->mocr);
317 }
318afterMONR1:
319 if (val & 0x04) {
320 isac->mocr &= 0xf0;
321 WriteISAC(isac, ISAC_MOCR, isac->mocr);
322 isac->mocr |= 0x0a;
323 WriteISAC(isac, ISAC_MOCR, isac->mocr);
324 if (isac->monitor) {
325 ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
326 isac->mon_rx, isac->mon_rxp);
327 if (ret)
328 kfree(isac->mon_rx);
329 } else {
330 pr_info("%s: MONITOR 0 received %d but no user\n",
331 isac->name, isac->mon_rxp);
332 kfree(isac->mon_rx);
333 }
334 isac->mon_rx = NULL;
335 isac->mon_rxp = 0;
336 }
337 if (val & 0x40) {
338 isac->mocr &= 0x0f;
339 WriteISAC(isac, ISAC_MOCR, isac->mocr);
340 isac->mocr |= 0xa0;
341 WriteISAC(isac, ISAC_MOCR, isac->mocr);
342 if (isac->monitor) {
343 ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
344 isac->mon_rx, isac->mon_rxp);
345 if (ret)
346 kfree(isac->mon_rx);
347 } else {
348 pr_info("%s: MONITOR 1 received %d but no user\n",
349 isac->name, isac->mon_rxp);
350 kfree(isac->mon_rx);
351 }
352 isac->mon_rx = NULL;
353 isac->mon_rxp = 0;
354 }
355 if (val & 0x02) {
356 if ((!isac->mon_tx) || (isac->mon_txc &&
357 (isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
358 isac->mocr &= 0xf0;
359 WriteISAC(isac, ISAC_MOCR, isac->mocr);
360 isac->mocr |= 0x0a;
361 WriteISAC(isac, ISAC_MOCR, isac->mocr);
362 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
363 if (isac->monitor)
364 ret = isac->monitor(isac->dch.hw,
365 MONITOR_TX_0, NULL, 0);
366 }
367 kfree(isac->mon_tx);
368 isac->mon_tx = NULL;
369 isac->mon_txc = 0;
370 isac->mon_txp = 0;
371 goto AfterMOX0;
372 }
373 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
374 if (isac->monitor)
375 ret = isac->monitor(isac->dch.hw,
376 MONITOR_TX_0, NULL, 0);
377 kfree(isac->mon_tx);
378 isac->mon_tx = NULL;
379 isac->mon_txc = 0;
380 isac->mon_txp = 0;
381 goto AfterMOX0;
382 }
383 WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
384 pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
385 isac->mon_tx[isac->mon_txp - 1]);
386 }
387AfterMOX0:
388 if (val & 0x20) {
389 if ((!isac->mon_tx) || (isac->mon_txc &&
390 (isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
391 isac->mocr &= 0x0f;
392 WriteISAC(isac, ISAC_MOCR, isac->mocr);
393 isac->mocr |= 0xa0;
394 WriteISAC(isac, ISAC_MOCR, isac->mocr);
395 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
396 if (isac->monitor)
397 ret = isac->monitor(isac->dch.hw,
398 MONITOR_TX_1, NULL, 0);
399 }
400 kfree(isac->mon_tx);
401 isac->mon_tx = NULL;
402 isac->mon_txc = 0;
403 isac->mon_txp = 0;
404 goto AfterMOX1;
405 }
406 if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
407 if (isac->monitor)
408 ret = isac->monitor(isac->dch.hw,
409 MONITOR_TX_1, NULL, 0);
410 kfree(isac->mon_tx);
411 isac->mon_tx = NULL;
412 isac->mon_txc = 0;
413 isac->mon_txp = 0;
414 goto AfterMOX1;
415 }
416 WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
417 pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
418 isac->mon_tx[isac->mon_txp - 1]);
419 }
420AfterMOX1:
421 val = 0; /* dummy to avoid warning */
422#endif
423}
424
425static void
426isac_cisq_irq(struct isac_hw *isac) {
427 u8 val;
428
429 val = ReadISAC(isac, ISAC_CIR0);
430 pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
431 if (val & 2) {
432 pr_debug("%s: ph_state change %x->%x\n", isac->name,
433 isac->state, (val >> 2) & 0xf);
434 isac->state = (val >> 2) & 0xf;
435 isac_ph_state_change(isac);
436 }
437 if (val & 1) {
438 val = ReadISAC(isac, ISAC_CIR1);
439 pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
440 }
441}
442
443static void
444isacsx_cic_irq(struct isac_hw *isac)
445{
446 u8 val;
447
448 val = ReadISAC(isac, ISACX_CIR0);
449 pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
450 if (val & ISACX_CIR0_CIC0) {
451 pr_debug("%s: ph_state change %x->%x\n", isac->name,
452 isac->state, val >> 4);
453 isac->state = val >> 4;
454 isac_ph_state_change(isac);
455 }
456}
457
458static void
459isacsx_rme_irq(struct isac_hw *isac)
460{
461 int count;
462 u8 val;
463
464 val = ReadISAC(isac, ISACX_RSTAD);
465 if ((val & (ISACX_RSTAD_VFR |
466 ISACX_RSTAD_RDO |
467 ISACX_RSTAD_CRC |
468 ISACX_RSTAD_RAB))
469 != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
470 pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
471#ifdef ERROR_STATISTIC
472 if (val & ISACX_RSTAD_CRC)
473 isac->dch.err_rx++;
474 else
475 isac->dch.err_crc++;
476#endif
477 WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
478 if (isac->dch.rx_skb)
479 dev_kfree_skb(isac->dch.rx_skb);
480 isac->dch.rx_skb = NULL;
481 } else {
482 count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
483 if (count == 0)
484 count = 32;
485 isac_empty_fifo(isac, count);
486 if (isac->dch.rx_skb) {
487 skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
488 pr_debug("%s: dchannel received %d\n", isac->name,
489 isac->dch.rx_skb->len);
490 recv_Dchannel(&isac->dch);
491 }
492 }
493}
494
495irqreturn_t
496mISDNisac_irq(struct isac_hw *isac, u8 val)
497{
498 if (unlikely(!val))
499 return IRQ_NONE;
500 pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
501 if (isac->type & IPAC_TYPE_ISACX) {
502 if (val & ISACX__CIC)
503 isacsx_cic_irq(isac);
504 if (val & ISACX__ICD) {
505 val = ReadISAC(isac, ISACX_ISTAD);
506 pr_debug("%s: ISTAD %02x\n", isac->name, val);
507 if (val & ISACX_D_XDU) {
508 pr_debug("%s: ISAC XDU\n", isac->name);
509#ifdef ERROR_STATISTIC
510 isac->dch.err_tx++;
511#endif
512 isac_retransmit(isac);
513 }
514 if (val & ISACX_D_XMR) {
515 pr_debug("%s: ISAC XMR\n", isac->name);
516#ifdef ERROR_STATISTIC
517 isac->dch.err_tx++;
518#endif
519 isac_retransmit(isac);
520 }
521 if (val & ISACX_D_XPR)
522 isac_xpr_irq(isac);
523 if (val & ISACX_D_RFO) {
524 pr_debug("%s: ISAC RFO\n", isac->name);
525 WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
526 }
527 if (val & ISACX_D_RME)
528 isacsx_rme_irq(isac);
529 if (val & ISACX_D_RPF)
530 isac_empty_fifo(isac, 0x20);
531 }
532 } else {
533 if (val & 0x80) /* RME */
534 isac_rme_irq(isac);
535 if (val & 0x40) /* RPF */
536 isac_empty_fifo(isac, 32);
537 if (val & 0x10) /* XPR */
538 isac_xpr_irq(isac);
539 if (val & 0x04) /* CISQ */
540 isac_cisq_irq(isac);
541 if (val & 0x20) /* RSC - never */
542 pr_debug("%s: ISAC RSC interrupt\n", isac->name);
543 if (val & 0x02) /* SIN - never */
544 pr_debug("%s: ISAC SIN interrupt\n", isac->name);
545 if (val & 0x01) { /* EXI */
546 val = ReadISAC(isac, ISAC_EXIR);
547 pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
548 if (val & 0x80) /* XMR */
549 pr_debug("%s: ISAC XMR\n", isac->name);
550 if (val & 0x40) { /* XDU */
551 pr_debug("%s: ISAC XDU\n", isac->name);
552#ifdef ERROR_STATISTIC
553 isac->dch.err_tx++;
554#endif
555 isac_retransmit(isac);
556 }
557 if (val & 0x04) /* MOS */
558 isac_mos_irq(isac);
559 }
560 }
561 return IRQ_HANDLED;
562}
563EXPORT_SYMBOL(mISDNisac_irq);
564
565static int
566isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
567{
568 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
569 struct dchannel *dch = container_of(dev, struct dchannel, dev);
570 struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
571 int ret = -EINVAL;
572 struct mISDNhead *hh = mISDN_HEAD_P(skb);
573 u32 id;
574 u_long flags;
575
576 switch (hh->prim) {
577 case PH_DATA_REQ:
578 spin_lock_irqsave(isac->hwlock, flags);
579 ret = dchannel_senddata(dch, skb);
580 if (ret > 0) { /* direct TX */
581 id = hh->id; /* skb can be freed */
582 isac_fill_fifo(isac);
583 ret = 0;
584 spin_unlock_irqrestore(isac->hwlock, flags);
585 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
586 } else
587 spin_unlock_irqrestore(isac->hwlock, flags);
588 return ret;
589 case PH_ACTIVATE_REQ:
590 ret = l1_event(dch->l1, hh->prim);
591 break;
592 case PH_DEACTIVATE_REQ:
593 test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
594 ret = l1_event(dch->l1, hh->prim);
595 break;
596 }
597
598 if (!ret)
599 dev_kfree_skb(skb);
600 return ret;
601}
602
603static int
604isac_ctrl(struct isac_hw *isac, u32 cmd, u_long para)
605{
606 u8 tl = 0;
607 u_long flags;
608
609 switch (cmd) {
610 case HW_TESTLOOP:
611 spin_lock_irqsave(isac->hwlock, flags);
612 if (!(isac->type & IPAC_TYPE_ISACX)) {
613 /* TODO: implement for IPAC_TYPE_ISACX */
614 if (para & 1) /* B1 */
615 tl |= 0x0c;
616 else if (para & 2) /* B2 */
617 tl |= 0x3;
618 /* we only support IOM2 mode */
619 WriteISAC(isac, ISAC_SPCR, tl);
620 if (tl)
621 WriteISAC(isac, ISAC_ADF1, 0x8);
622 else
623 WriteISAC(isac, ISAC_ADF1, 0x0);
624 }
625 spin_unlock_irqrestore(isac->hwlock, flags);
626 break;
627 default:
628 pr_debug("%s: %s unknown command %x %lx\n", isac->name,
629 __func__, cmd, para);
630 return -1;
631 }
632 return 0;
633}
634
635static int
636isac_l1cmd(struct dchannel *dch, u32 cmd)
637{
638 struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
639 u_long flags;
640
641 pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
642 switch (cmd) {
643 case INFO3_P8:
644 spin_lock_irqsave(isac->hwlock, flags);
645 ph_command(isac, ISAC_CMD_AR8);
646 spin_unlock_irqrestore(isac->hwlock, flags);
647 break;
648 case INFO3_P10:
649 spin_lock_irqsave(isac->hwlock, flags);
650 ph_command(isac, ISAC_CMD_AR10);
651 spin_unlock_irqrestore(isac->hwlock, flags);
652 break;
653 case HW_RESET_REQ:
654 spin_lock_irqsave(isac->hwlock, flags);
655 if ((isac->state == ISAC_IND_EI) ||
656 (isac->state == ISAC_IND_DR) ||
657 (isac->state == ISAC_IND_RS))
658 ph_command(isac, ISAC_CMD_TIM);
659 else
660 ph_command(isac, ISAC_CMD_RS);
661 spin_unlock_irqrestore(isac->hwlock, flags);
662 break;
663 case HW_DEACT_REQ:
664 skb_queue_purge(&dch->squeue);
665 if (dch->tx_skb) {
666 dev_kfree_skb(dch->tx_skb);
667 dch->tx_skb = NULL;
668 }
669 dch->tx_idx = 0;
670 if (dch->rx_skb) {
671 dev_kfree_skb(dch->rx_skb);
672 dch->rx_skb = NULL;
673 }
674 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
675 if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
676 del_timer(&dch->timer);
677 break;
678 case HW_POWERUP_REQ:
679 spin_lock_irqsave(isac->hwlock, flags);
680 ph_command(isac, ISAC_CMD_TIM);
681 spin_unlock_irqrestore(isac->hwlock, flags);
682 break;
683 case PH_ACTIVATE_IND:
684 test_and_set_bit(FLG_ACTIVE, &dch->Flags);
685 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
686 GFP_ATOMIC);
687 break;
688 case PH_DEACTIVATE_IND:
689 test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
690 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
691 GFP_ATOMIC);
692 break;
693 default:
694 pr_debug("%s: %s unknown command %x\n", isac->name,
695 __func__, cmd);
696 return -1;
697 }
698 return 0;
699}
700
701static void
702isac_release(struct isac_hw *isac)
703{
704 if (isac->type & IPAC_TYPE_ISACX)
705 WriteISAC(isac, ISACX_MASK, 0xff);
706 else
707 WriteISAC(isac, ISAC_MASK, 0xff);
708 if (isac->dch.timer.function != NULL) {
709 del_timer(&isac->dch.timer);
710 isac->dch.timer.function = NULL;
711 }
712 kfree(isac->mon_rx);
713 isac->mon_rx = NULL;
714 kfree(isac->mon_tx);
715 isac->mon_tx = NULL;
716 if (isac->dch.l1)
717 l1_event(isac->dch.l1, CLOSE_CHANNEL);
718 mISDN_freedchannel(&isac->dch);
719}
720
721static void
722dbusy_timer_handler(struct isac_hw *isac)
723{
724 int rbch, star;
725 u_long flags;
726
727 if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
728 spin_lock_irqsave(isac->hwlock, flags);
729 rbch = ReadISAC(isac, ISAC_RBCH);
730 star = ReadISAC(isac, ISAC_STAR);
731 pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
732 isac->name, rbch, star);
733 if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
734 test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
735 else {
736 /* discard frame; reset transceiver */
737 test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
738 if (isac->dch.tx_idx)
739 isac->dch.tx_idx = 0;
740 else
741 pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
742 isac->name);
743 /* Transmitter reset */
744 WriteISAC(isac, ISAC_CMDR, 0x01);
745 }
746 spin_unlock_irqrestore(isac->hwlock, flags);
747 }
748}
749
750static int
751open_dchannel(struct isac_hw *isac, struct channel_req *rq)
752{
753 pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
754 isac->dch.dev.id, __builtin_return_address(1));
755 if (rq->protocol != ISDN_P_TE_S0)
756 return -EINVAL;
757 if (rq->adr.channel == 1)
758 /* E-Channel not supported */
759 return -EINVAL;
760 rq->ch = &isac->dch.dev.D;
761 rq->ch->protocol = rq->protocol;
762 if (isac->dch.state == 7)
763 _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
764 0, NULL, GFP_KERNEL);
765 return 0;
766}
767
768static const char *ISACVer[] =
769{"2086/2186 V1.1", "2085 B1", "2085 B2",
770 "2085 V2.3"};
771
772static int
773isac_init(struct isac_hw *isac)
774{
775 u8 val;
776 int err = 0;
777
778 if (!isac->dch.l1) {
779 err = create_l1(&isac->dch, isac_l1cmd);
780 if (err)
781 return err;
782 }
783 isac->mon_tx = NULL;
784 isac->mon_rx = NULL;
785 isac->dch.timer.function = (void *) dbusy_timer_handler;
786 isac->dch.timer.data = (long)isac;
787 init_timer(&isac->dch.timer);
788 isac->mocr = 0xaa;
789 if (isac->type & IPAC_TYPE_ISACX) {
790 /* Disable all IRQ */
791 WriteISAC(isac, ISACX_MASK, 0xff);
792 val = ReadISAC(isac, ISACX_STARD);
793 pr_debug("%s: ISACX STARD %x\n", isac->name, val);
794 val = ReadISAC(isac, ISACX_ISTAD);
795 pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
796 val = ReadISAC(isac, ISACX_ISTA);
797 pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
798 /* clear LDD */
799 WriteISAC(isac, ISACX_TR_CONF0, 0x00);
800 /* enable transmitter */
801 WriteISAC(isac, ISACX_TR_CONF2, 0x00);
802 /* transparent mode 0, RAC, stop/go */
803 WriteISAC(isac, ISACX_MODED, 0xc9);
804 /* all HDLC IRQ unmasked */
805 val = ReadISAC(isac, ISACX_ID);
806 if (isac->dch.debug & DEBUG_HW)
807 pr_notice("%s: ISACX Design ID %x\n",
808 isac->name, val & 0x3f);
809 val = ReadISAC(isac, ISACX_CIR0);
810 pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
811 isac->state = val >> 4;
812 isac_ph_state_change(isac);
813 ph_command(isac, ISAC_CMD_RS);
814 WriteISAC(isac, ISACX_MASK, IPACX__ON);
815 WriteISAC(isac, ISACX_MASKD, 0x00);
816 } else { /* old isac */
817 WriteISAC(isac, ISAC_MASK, 0xff);
818 val = ReadISAC(isac, ISAC_STAR);
819 pr_debug("%s: ISAC STAR %x\n", isac->name, val);
820 val = ReadISAC(isac, ISAC_MODE);
821 pr_debug("%s: ISAC MODE %x\n", isac->name, val);
822 val = ReadISAC(isac, ISAC_ADF2);
823 pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
824 val = ReadISAC(isac, ISAC_ISTA);
825 pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
826 if (val & 0x01) {
827 val = ReadISAC(isac, ISAC_EXIR);
828 pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
829 }
830 val = ReadISAC(isac, ISAC_RBCH);
831 if (isac->dch.debug & DEBUG_HW)
832 pr_notice("%s: ISAC version (%x): %s\n", isac->name,
833 val, ISACVer[(val >> 5) & 3]);
834 isac->type |= ((val >> 5) & 3);
835 if (!isac->adf2)
836 isac->adf2 = 0x80;
837 if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
838 pr_info("%s: only support IOM2 mode but adf2=%02x\n",
839 isac->name, isac->adf2);
840 isac_release(isac);
841 return -EINVAL;
842 }
843 WriteISAC(isac, ISAC_ADF2, isac->adf2);
844 WriteISAC(isac, ISAC_SQXR, 0x2f);
845 WriteISAC(isac, ISAC_SPCR, 0x00);
846 WriteISAC(isac, ISAC_STCR, 0x70);
847 WriteISAC(isac, ISAC_MODE, 0xc9);
848 WriteISAC(isac, ISAC_TIMR, 0x00);
849 WriteISAC(isac, ISAC_ADF1, 0x00);
850 val = ReadISAC(isac, ISAC_CIR0);
851 pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
852 isac->state = (val >> 2) & 0xf;
853 isac_ph_state_change(isac);
854 ph_command(isac, ISAC_CMD_RS);
855 WriteISAC(isac, ISAC_MASK, 0);
856 }
857 return err;
858}
859
860int
861mISDNisac_init(struct isac_hw *isac, void *hw)
862{
863 mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
864 isac->dch.hw = hw;
865 isac->dch.dev.D.send = isac_l1hw;
866 isac->init = isac_init;
867 isac->release = isac_release;
868 isac->ctrl = isac_ctrl;
869 isac->open = open_dchannel;
870 isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
871 isac->dch.dev.nrbchan = 2;
872 return 0;
873}
874EXPORT_SYMBOL(mISDNisac_init);
875
876static void
877waitforCEC(struct hscx_hw *hx)
878{
879 u8 starb, to = 50;
880
881 while (to) {
882 starb = ReadHSCX(hx, IPAC_STARB);
883 if (!(starb & 0x04))
884 break;
885 udelay(1);
886 to--;
887 }
888 if (to < 50)
889 pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
890 50 - to);
891 if (!to)
892 pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
893}
894
895
896static void
897waitforXFW(struct hscx_hw *hx)
898{
899 u8 starb, to = 50;
900
901 while (to) {
902 starb = ReadHSCX(hx, IPAC_STARB);
903 if ((starb & 0x44) == 0x40)
904 break;
905 udelay(1);
906 to--;
907 }
908 if (to < 50)
909 pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
910 50 - to);
911 if (!to)
912 pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
913}
914
915static void
916hscx_cmdr(struct hscx_hw *hx, u8 cmd)
917{
918 if (hx->ip->type & IPAC_TYPE_IPACX)
919 WriteHSCX(hx, IPACX_CMDRB, cmd);
920 else {
921 waitforCEC(hx);
922 WriteHSCX(hx, IPAC_CMDRB, cmd);
923 }
924}
925
926static void
927hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
928{
929 u8 *p;
930
931 pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
932 if (!hscx->bch.rx_skb) {
933 hscx->bch.rx_skb = mI_alloc_skb(hscx->bch.maxlen, GFP_ATOMIC);
934 if (!hscx->bch.rx_skb) {
935 pr_info("%s: B receive out of memory\n",
936 hscx->ip->name);
937 hscx_cmdr(hscx, 0x80); /* RMC */
938 return;
939 }
940 }
941 if ((hscx->bch.rx_skb->len + count) > hscx->bch.maxlen) {
942 pr_debug("%s: overrun %d\n", hscx->ip->name,
943 hscx->bch.rx_skb->len + count);
944 skb_trim(hscx->bch.rx_skb, 0);
945 hscx_cmdr(hscx, 0x80); /* RMC */
946 return;
947 }
948 p = skb_put(hscx->bch.rx_skb, count);
949
950 if (hscx->ip->type & IPAC_TYPE_IPACX)
951 hscx->ip->read_fifo(hscx->ip->hw,
952 hscx->off + IPACX_RFIFOB, p, count);
953 else
954 hscx->ip->read_fifo(hscx->ip->hw,
955 hscx->off, p, count);
956
957 hscx_cmdr(hscx, 0x80); /* RMC */
958
959 if (hscx->bch.debug & DEBUG_HW_BFIFO) {
960 snprintf(hscx->log, 64, "B%1d-recv %s %d ",
961 hscx->bch.nr, hscx->ip->name, count);
962 print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
963 }
964}
965
966static void
967hscx_fill_fifo(struct hscx_hw *hscx)
968{
969 int count, more;
970 u8 *p;
971
972 if (!hscx->bch.tx_skb)
973 return;
974 count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
975 if (count <= 0)
976 return;
977 p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
978
979 more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
980 if (count > hscx->fifo_size) {
981 count = hscx->fifo_size;
982 more = 1;
983 }
984 pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr, count,
985 hscx->bch.tx_idx, hscx->bch.tx_skb->len);
986 hscx->bch.tx_idx += count;
987
988 if (hscx->ip->type & IPAC_TYPE_IPACX)
989 hscx->ip->write_fifo(hscx->ip->hw,
990 hscx->off + IPACX_XFIFOB, p, count);
991 else {
992 waitforXFW(hscx);
993 hscx->ip->write_fifo(hscx->ip->hw,
994 hscx->off, p, count);
995 }
996 hscx_cmdr(hscx, more ? 0x08 : 0x0a);
997
998 if (hscx->bch.debug & DEBUG_HW_BFIFO) {
999 snprintf(hscx->log, 64, "B%1d-send %s %d ",
1000 hscx->bch.nr, hscx->ip->name, count);
1001 print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
1002 }
1003}
1004
1005static void
1006hscx_xpr(struct hscx_hw *hx)
1007{
1008 if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len)
1009 hscx_fill_fifo(hx);
1010 else {
1011 if (hx->bch.tx_skb) {
1012 /* send confirm, on trans, free on hdlc. */
1013 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
1014 confirm_Bsend(&hx->bch);
1015 dev_kfree_skb(hx->bch.tx_skb);
1016 }
1017 if (get_next_bframe(&hx->bch))
1018 hscx_fill_fifo(hx);
1019 }
1020}
1021
1022static void
1023ipac_rme(struct hscx_hw *hx)
1024{
1025 int count;
1026 u8 rstab;
1027
1028 if (hx->ip->type & IPAC_TYPE_IPACX)
1029 rstab = ReadHSCX(hx, IPACX_RSTAB);
1030 else
1031 rstab = ReadHSCX(hx, IPAC_RSTAB);
1032 pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
1033 if ((rstab & 0xf0) != 0xa0) {
1034 /* !(VFR && !RDO && CRC && !RAB) */
1035 if (!(rstab & 0x80)) {
1036 if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1037 pr_notice("%s: B%1d invalid frame\n",
1038 hx->ip->name, hx->bch.nr);
1039 }
1040 if (rstab & 0x40) {
1041 if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1042 pr_notice("%s: B%1d RDO proto=%x\n",
1043 hx->ip->name, hx->bch.nr,
1044 hx->bch.state);
1045 }
1046 if (!(rstab & 0x20)) {
1047 if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1048 pr_notice("%s: B%1d CRC error\n",
1049 hx->ip->name, hx->bch.nr);
1050 }
1051 hscx_cmdr(hx, 0x80); /* Do RMC */
1052 return;
1053 }
1054 if (hx->ip->type & IPAC_TYPE_IPACX)
1055 count = ReadHSCX(hx, IPACX_RBCLB);
1056 else
1057 count = ReadHSCX(hx, IPAC_RBCLB);
1058 count &= (hx->fifo_size - 1);
1059 if (count == 0)
1060 count = hx->fifo_size;
1061 hscx_empty_fifo(hx, count);
1062 if (!hx->bch.rx_skb)
1063 return;
1064 if (hx->bch.rx_skb->len < 2) {
1065 pr_debug("%s: B%1d frame to short %d\n",
1066 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
1067 skb_trim(hx->bch.rx_skb, 0);
1068 } else {
1069 skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
1070 recv_Bchannel(&hx->bch, 0);
1071 }
1072}
1073
1074static void
1075ipac_irq(struct hscx_hw *hx, u8 ista)
1076{
1077 u8 istab, m, exirb = 0;
1078
1079 if (hx->ip->type & IPAC_TYPE_IPACX)
1080 istab = ReadHSCX(hx, IPACX_ISTAB);
1081 else if (hx->ip->type & IPAC_TYPE_IPAC) {
1082 istab = ReadHSCX(hx, IPAC_ISTAB);
1083 m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
1084 if (m & ista) {
1085 exirb = ReadHSCX(hx, IPAC_EXIRB);
1086 pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1087 hx->bch.nr, exirb);
1088 }
1089 } else if (hx->bch.nr & 2) { /* HSCX B */
1090 if (ista & (HSCX__EXA | HSCX__ICA))
1091 ipac_irq(&hx->ip->hscx[0], ista);
1092 if (ista & HSCX__EXB) {
1093 exirb = ReadHSCX(hx, IPAC_EXIRB);
1094 pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1095 hx->bch.nr, exirb);
1096 }
1097 istab = ista & 0xF8;
1098 } else { /* HSCX A */
1099 istab = ReadHSCX(hx, IPAC_ISTAB);
1100 if (ista & HSCX__EXA) {
1101 exirb = ReadHSCX(hx, IPAC_EXIRB);
1102 pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1103 hx->bch.nr, exirb);
1104 }
1105 istab = istab & 0xF8;
1106 }
1107 if (exirb & IPAC_B_XDU)
1108 istab |= IPACX_B_XDU;
1109 if (exirb & IPAC_B_RFO)
1110 istab |= IPACX_B_RFO;
1111 pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
1112
1113 if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
1114 return;
1115
1116 if (istab & IPACX_B_RME)
1117 ipac_rme(hx);
1118
1119 if (istab & IPACX_B_RPF) {
1120 hscx_empty_fifo(hx, hx->fifo_size);
1121 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
1122 /* receive transparent audio data */
1123 if (hx->bch.rx_skb)
1124 recv_Bchannel(&hx->bch, 0);
1125 }
1126 }
1127
1128 if (istab & IPACX_B_RFO) {
1129 pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
1130 hscx_cmdr(hx, 0x40); /* RRES */
1131 }
1132
1133 if (istab & IPACX_B_XPR)
1134 hscx_xpr(hx);
1135
1136 if (istab & IPACX_B_XDU) {
1137 if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
1138 hscx_fill_fifo(hx);
1139 return;
1140 }
1141 pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
1142 hx->bch.nr, hx->bch.tx_idx);
1143 hx->bch.tx_idx = 0;
1144 hscx_cmdr(hx, 0x01); /* XRES */
1145 }
1146}
1147
1148irqreturn_t
1149mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
1150{
1151 int cnt = maxloop + 1;
1152 u8 ista, istad;
1153 struct isac_hw *isac = &ipac->isac;
1154
1155 if (ipac->type & IPAC_TYPE_IPACX) {
1156 ista = ReadIPAC(ipac, ISACX_ISTA);
1157 while (ista && cnt--) {
1158 pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1159 if (ista & IPACX__ICA)
1160 ipac_irq(&ipac->hscx[0], ista);
1161 if (ista & IPACX__ICB)
1162 ipac_irq(&ipac->hscx[1], ista);
1163 if (ista & (ISACX__ICD | ISACX__CIC))
1164 mISDNisac_irq(&ipac->isac, ista);
1165 ista = ReadIPAC(ipac, ISACX_ISTA);
1166 }
1167 } else if (ipac->type & IPAC_TYPE_IPAC) {
1168 ista = ReadIPAC(ipac, IPAC_ISTA);
1169 while (ista && cnt--) {
1170 pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1171 if (ista & (IPAC__ICD | IPAC__EXD)) {
1172 istad = ReadISAC(isac, ISAC_ISTA);
1173 pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1174 if (istad & IPAC_D_TIN2)
1175 pr_debug("%s TIN2 irq\n", ipac->name);
1176 if (ista & IPAC__EXD)
1177 istad |= 1; /* ISAC EXI */
1178 mISDNisac_irq(isac, istad);
1179 }
1180 if (ista & (IPAC__ICA | IPAC__EXA))
1181 ipac_irq(&ipac->hscx[0], ista);
1182 if (ista & (IPAC__ICB | IPAC__EXB))
1183 ipac_irq(&ipac->hscx[1], ista);
1184 ista = ReadIPAC(ipac, IPAC_ISTA);
1185 }
1186 } else if (ipac->type & IPAC_TYPE_HSCX) {
1187 while (cnt) {
1188 ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
1189 pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
1190 if (ista)
1191 ipac_irq(&ipac->hscx[1], ista);
1192 istad = ReadISAC(isac, ISAC_ISTA);
1193 pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1194 if (istad)
1195 mISDNisac_irq(isac, istad);
1196 if (0 == (ista | istad))
1197 break;
1198 cnt--;
1199 }
1200 }
1201 if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
1202 return IRQ_NONE;
1203 if (cnt < maxloop)
1204 pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
1205 maxloop - cnt, smp_processor_id());
1206 if (maxloop && !cnt)
1207 pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
1208 maxloop, smp_processor_id());
1209 return IRQ_HANDLED;
1210}
1211EXPORT_SYMBOL(mISDNipac_irq);
1212
1213static int
1214hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
1215{
1216 pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
1217 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
1218 if (hscx->ip->type & IPAC_TYPE_IPACX) {
1219 if (hscx->bch.nr & 1) { /* B1 and ICA */
1220 WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
1221 WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
1222 } else { /* B2 and ICB */
1223 WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
1224 WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
1225 }
1226 switch (bprotocol) {
1227 case ISDN_P_NONE: /* init */
1228 WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* rec off */
1229 WriteHSCX(hscx, IPACX_EXMB, 0x30); /* std adj. */
1230 WriteHSCX(hscx, IPACX_MASKB, 0xFF); /* ints off */
1231 hscx_cmdr(hscx, 0x41);
1232 test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1233 test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1234 break;
1235 case ISDN_P_B_RAW:
1236 WriteHSCX(hscx, IPACX_MODEB, 0x88); /* ex trans */
1237 WriteHSCX(hscx, IPACX_EXMB, 0x00); /* trans */
1238 hscx_cmdr(hscx, 0x41);
1239 WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1240 test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1241 break;
1242 case ISDN_P_B_HDLC:
1243 WriteHSCX(hscx, IPACX_MODEB, 0xC0); /* trans */
1244 WriteHSCX(hscx, IPACX_EXMB, 0x00); /* hdlc,crc */
1245 hscx_cmdr(hscx, 0x41);
1246 WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1247 test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1248 break;
1249 default:
1250 pr_info("%s: protocol not known %x\n", hscx->ip->name,
1251 bprotocol);
1252 return -ENOPROTOOPT;
1253 }
1254 } else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
1255 WriteHSCX(hscx, IPAC_CCR1, 0x82);
1256 WriteHSCX(hscx, IPAC_CCR2, 0x30);
1257 WriteHSCX(hscx, IPAC_XCCR, 0x07);
1258 WriteHSCX(hscx, IPAC_RCCR, 0x07);
1259 WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1260 WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1261 switch (bprotocol) {
1262 case ISDN_P_NONE:
1263 WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1264 WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1265 WriteHSCX(hscx, IPAC_MODEB, 0x84);
1266 WriteHSCX(hscx, IPAC_CCR1, 0x82);
1267 WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */
1268 test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1269 test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1270 break;
1271 case ISDN_P_B_RAW:
1272 WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */
1273 WriteHSCX(hscx, IPAC_CCR1, 0x82);
1274 hscx_cmdr(hscx, 0x41);
1275 WriteHSCX(hscx, IPAC_MASKB, 0);
1276 test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1277 break;
1278 case ISDN_P_B_HDLC:
1279 WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1280 WriteHSCX(hscx, IPAC_CCR1, 0x8a);
1281 hscx_cmdr(hscx, 0x41);
1282 WriteHSCX(hscx, IPAC_MASKB, 0);
1283 test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1284 break;
1285 default:
1286 pr_info("%s: protocol not known %x\n", hscx->ip->name,
1287 bprotocol);
1288 return -ENOPROTOOPT;
1289 }
1290 } else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
1291 WriteHSCX(hscx, IPAC_CCR1, 0x85);
1292 WriteHSCX(hscx, IPAC_CCR2, 0x30);
1293 WriteHSCX(hscx, IPAC_XCCR, 0x07);
1294 WriteHSCX(hscx, IPAC_RCCR, 0x07);
1295 WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1296 WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1297 switch (bprotocol) {
1298 case ISDN_P_NONE:
1299 WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1300 WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1301 WriteHSCX(hscx, IPAC_MODEB, 0x84);
1302 WriteHSCX(hscx, IPAC_CCR1, 0x85);
1303 WriteHSCX(hscx, IPAC_MASKB, 0xFF); /* ints off */
1304 test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1305 test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1306 break;
1307 case ISDN_P_B_RAW:
1308 WriteHSCX(hscx, IPAC_MODEB, 0xe4); /* ex trans */
1309 WriteHSCX(hscx, IPAC_CCR1, 0x85);
1310 hscx_cmdr(hscx, 0x41);
1311 WriteHSCX(hscx, IPAC_MASKB, 0);
1312 test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1313 break;
1314 case ISDN_P_B_HDLC:
1315 WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1316 WriteHSCX(hscx, IPAC_CCR1, 0x8d);
1317 hscx_cmdr(hscx, 0x41);
1318 WriteHSCX(hscx, IPAC_MASKB, 0);
1319 test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1320 break;
1321 default:
1322 pr_info("%s: protocol not known %x\n", hscx->ip->name,
1323 bprotocol);
1324 return -ENOPROTOOPT;
1325 }
1326 } else
1327 return -EINVAL;
1328 hscx->bch.state = bprotocol;
1329 return 0;
1330}
1331
1332static int
1333hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1334{
1335 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1336 struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch);
1337 int ret = -EINVAL;
1338 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1339 u32 id;
1340 u_long flags;
1341
1342 switch (hh->prim) {
1343 case PH_DATA_REQ:
1344 spin_lock_irqsave(hx->ip->hwlock, flags);
1345 ret = bchannel_senddata(bch, skb);
1346 if (ret > 0) { /* direct TX */
1347 id = hh->id; /* skb can be freed */
1348 ret = 0;
1349 hscx_fill_fifo(hx);
1350 spin_unlock_irqrestore(hx->ip->hwlock, flags);
1351 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
1352 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
1353 } else
1354 spin_unlock_irqrestore(hx->ip->hwlock, flags);
1355 return ret;
1356 case PH_ACTIVATE_REQ:
1357 spin_lock_irqsave(hx->ip->hwlock, flags);
1358 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1359 ret = hscx_mode(hx, ch->protocol);
1360 else
1361 ret = 0;
1362 spin_unlock_irqrestore(hx->ip->hwlock, flags);
1363 if (!ret)
1364 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
1365 NULL, GFP_KERNEL);
1366 break;
1367 case PH_DEACTIVATE_REQ:
1368 spin_lock_irqsave(hx->ip->hwlock, flags);
1369 mISDN_clear_bchannel(bch);
1370 hscx_mode(hx, ISDN_P_NONE);
1371 spin_unlock_irqrestore(hx->ip->hwlock, flags);
1372 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
1373 NULL, GFP_KERNEL);
1374 ret = 0;
1375 break;
1376 default:
1377 pr_info("%s: %s unknown prim(%x,%x)\n",
1378 hx->ip->name, __func__, hh->prim, hh->id);
1379 ret = -EINVAL;
1380 }
1381 if (!ret)
1382 dev_kfree_skb(skb);
1383 return ret;
1384}
1385
1386static int
1387channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1388{
1389 int ret = 0;
1390
1391 switch (cq->op) {
1392 case MISDN_CTRL_GETOP:
1393 cq->op = 0;
1394 break;
1395 /* Nothing implemented yet */
1396 case MISDN_CTRL_FILL_EMPTY:
1397 default:
1398 pr_info("%s: unknown Op %x\n", __func__, cq->op);
1399 ret = -EINVAL;
1400 break;
1401 }
1402 return ret;
1403}
1404
1405static int
1406hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1407{
1408 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1409 struct hscx_hw *hx = container_of(bch, struct hscx_hw, bch);
1410 int ret = -EINVAL;
1411 u_long flags;
1412
1413 pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
1414 switch (cmd) {
1415 case CLOSE_CHANNEL:
1416 test_and_clear_bit(FLG_OPEN, &bch->Flags);
1417 if (test_bit(FLG_ACTIVE, &bch->Flags)) {
1418 spin_lock_irqsave(hx->ip->hwlock, flags);
1419 mISDN_freebchannel(bch);
1420 hscx_mode(hx, ISDN_P_NONE);
1421 spin_unlock_irqrestore(hx->ip->hwlock, flags);
1422 } else {
1423 skb_queue_purge(&bch->rqueue);
1424 bch->rcount = 0;
1425 }
1426 ch->protocol = ISDN_P_NONE;
1427 ch->peer = NULL;
1428 module_put(hx->ip->owner);
1429 ret = 0;
1430 break;
1431 case CONTROL_CHANNEL:
1432 ret = channel_bctrl(bch, arg);
1433 break;
1434 default:
1435 pr_info("%s: %s unknown prim(%x)\n",
1436 hx->ip->name, __func__, cmd);
1437 }
1438 return ret;
1439}
1440
1441static void
1442free_ipac(struct ipac_hw *ipac)
1443{
1444 isac_release(&ipac->isac);
1445}
1446
1447static const char *HSCXVer[] =
1448{"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1449 "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1450
1451
1452
1453static void
1454hscx_init(struct hscx_hw *hx)
1455{
1456 u8 val;
1457
1458 WriteHSCX(hx, IPAC_RAH2, 0xFF);
1459 WriteHSCX(hx, IPAC_XBCH, 0x00);
1460 WriteHSCX(hx, IPAC_RLCR, 0x00);
1461
1462 if (hx->ip->type & IPAC_TYPE_HSCX) {
1463 WriteHSCX(hx, IPAC_CCR1, 0x85);
1464 val = ReadHSCX(hx, HSCX_VSTR);
1465 pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
1466 if (hx->bch.debug & DEBUG_HW)
1467 pr_notice("%s: HSCX version %s\n", hx->ip->name,
1468 HSCXVer[val & 0x0f]);
1469 } else
1470 WriteHSCX(hx, IPAC_CCR1, 0x82);
1471 WriteHSCX(hx, IPAC_CCR2, 0x30);
1472 WriteHSCX(hx, IPAC_XCCR, 0x07);
1473 WriteHSCX(hx, IPAC_RCCR, 0x07);
1474}
1475
1476static int
1477ipac_init(struct ipac_hw *ipac)
1478{
1479 u8 val;
1480
1481 if (ipac->type & IPAC_TYPE_HSCX) {
1482 hscx_init(&ipac->hscx[0]);
1483 hscx_init(&ipac->hscx[1]);
1484 val = ReadIPAC(ipac, IPAC_ID);
1485 } else if (ipac->type & IPAC_TYPE_IPAC) {
1486 hscx_init(&ipac->hscx[0]);
1487 hscx_init(&ipac->hscx[1]);
1488 WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
1489 val = ReadIPAC(ipac, IPAC_CONF);
1490 /* conf is default 0, but can be overwritten by card setup */
1491 pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
1492 val, ipac->conf);
1493 WriteIPAC(ipac, IPAC_CONF, ipac->conf);
1494 val = ReadIPAC(ipac, IPAC_ID);
1495 if (ipac->hscx[0].bch.debug & DEBUG_HW)
1496 pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
1497 }
1498 /* nothing special for IPACX to do here */
1499 return isac_init(&ipac->isac);
1500}
1501
1502static int
1503open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
1504{
1505 struct bchannel *bch;
1506
1507 if (rq->adr.channel > 2)
1508 return -EINVAL;
1509 if (rq->protocol == ISDN_P_NONE)
1510 return -EINVAL;
1511 bch = &ipac->hscx[rq->adr.channel - 1].bch;
1512 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1513 return -EBUSY; /* b-channel can be only open once */
1514 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1515 bch->ch.protocol = rq->protocol;
1516 rq->ch = &bch->ch;
1517 return 0;
1518}
1519
1520static int
1521channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
1522{
1523 int ret = 0;
1524
1525 switch (cq->op) {
1526 case MISDN_CTRL_GETOP:
1527 cq->op = MISDN_CTRL_LOOP;
1528 break;
1529 case MISDN_CTRL_LOOP:
1530 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
1531 if (cq->channel < 0 || cq->channel > 3) {
1532 ret = -EINVAL;
1533 break;
1534 }
1535 ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
1536 break;
1537 default:
1538 pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
1539 ret = -EINVAL;
1540 break;
1541 }
1542 return ret;
1543}
1544
1545static int
1546ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1547{
1548 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1549 struct dchannel *dch = container_of(dev, struct dchannel, dev);
1550 struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
1551 struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
1552 struct channel_req *rq;
1553 int err = 0;
1554
1555 pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
1556 switch (cmd) {
1557 case OPEN_CHANNEL:
1558 rq = arg;
1559 if (rq->protocol == ISDN_P_TE_S0)
1560 err = open_dchannel(isac, rq);
1561 else
1562 err = open_bchannel(ipac, rq);
1563 if (err)
1564 break;
1565 if (!try_module_get(ipac->owner))
1566 pr_info("%s: cannot get module\n", ipac->name);
1567 break;
1568 case CLOSE_CHANNEL:
1569 pr_debug("%s: dev(%d) close from %p\n", ipac->name,
1570 dch->dev.id, __builtin_return_address(0));
1571 module_put(ipac->owner);
1572 break;
1573 case CONTROL_CHANNEL:
1574 err = channel_ctrl(ipac, arg);
1575 break;
1576 default:
1577 pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
1578 return -EINVAL;
1579 }
1580 return err;
1581}
1582
1583u32
1584mISDNipac_init(struct ipac_hw *ipac, void *hw)
1585{
1586 u32 ret;
1587 u8 i;
1588
1589 ipac->hw = hw;
1590 if (ipac->isac.dch.debug & DEBUG_HW)
1591 pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
1592 if (ipac->type & IPAC_TYPE_HSCX) {
1593 ipac->isac.type = IPAC_TYPE_ISAC;
1594 ipac->hscx[0].off = 0;
1595 ipac->hscx[1].off = 0x40;
1596 ipac->hscx[0].fifo_size = 32;
1597 ipac->hscx[1].fifo_size = 32;
1598 } else if (ipac->type & IPAC_TYPE_IPAC) {
1599 ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
1600 ipac->hscx[0].off = 0;
1601 ipac->hscx[1].off = 0x40;
1602 ipac->hscx[0].fifo_size = 64;
1603 ipac->hscx[1].fifo_size = 64;
1604 } else if (ipac->type & IPAC_TYPE_IPACX) {
1605 ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
1606 ipac->hscx[0].off = IPACX_OFF_ICA;
1607 ipac->hscx[1].off = IPACX_OFF_ICB;
1608 ipac->hscx[0].fifo_size = 64;
1609 ipac->hscx[1].fifo_size = 64;
1610 } else
1611 return 0;
1612
1613 mISDNisac_init(&ipac->isac, hw);
1614
1615 ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
1616
1617 for (i = 0; i < 2; i++) {
1618 ipac->hscx[i].bch.nr = i + 1;
1619 set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
1620 list_add(&ipac->hscx[i].bch.ch.list,
1621 &ipac->isac.dch.dev.bchannels);
1622 mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM);
1623 ipac->hscx[i].bch.ch.nr = i + 1;
1624 ipac->hscx[i].bch.ch.send = &hscx_l2l1;
1625 ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
1626 ipac->hscx[i].bch.hw = hw;
1627 ipac->hscx[i].ip = ipac;
1628 /* default values for IOM time slots
1629 * can be overwriten by card */
1630 ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
1631 }
1632
1633 ipac->init = ipac_init;
1634 ipac->release = free_ipac;
1635
1636 ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1637 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1638 return ret;
1639}
1640EXPORT_SYMBOL(mISDNipac_init);
1641
1642static int __init
1643isac_mod_init(void)
1644{
1645 pr_notice("mISDNipac module version %s\n", ISAC_REV);
1646 return 0;
1647}
1648
1649static void __exit
1650isac_mod_cleanup(void)
1651{
1652 pr_notice("mISDNipac module unloaded\n");
1653}
1654module_init(isac_mod_init);
1655module_exit(isac_mod_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c
new file mode 100644
index 000000000000..de352a17673a
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/mISDNisar.c
@@ -0,0 +1,1726 @@
1/*
2 * mISDNisar.c ISAR (Siemens PSB 7110) specific functions
3 *
4 * Author Karsten Keil (keil@isdn4linux.de)
5 *
6 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23/* define this to enable static debug messages, if you kernel supports
24 * dynamic debugging, you should use debugfs for this
25 */
26/* #define DEBUG */
27
28#include <linux/delay.h>
29#include <linux/vmalloc.h>
30#include <linux/mISDNhw.h>
31#include "isar.h"
32
33#define ISAR_REV "2.1"
34
35MODULE_AUTHOR("Karsten Keil");
36MODULE_LICENSE("GPL v2");
37MODULE_VERSION(ISAR_REV);
38
39#define DEBUG_HW_FIRMWARE_FIFO 0x10000
40
41static const u8 faxmodulation_s[] = "3,24,48,72,73,74,96,97,98,121,122,145,146";
42static const u8 faxmodulation[] = {3, 24, 48, 72, 73, 74, 96, 97, 98, 121,
43 122, 145, 146};
44#define FAXMODCNT 13
45
46static void isar_setup(struct isar_hw *);
47
48static inline int
49waitforHIA(struct isar_hw *isar, int timeout)
50{
51 int t = timeout;
52 u8 val = isar->read_reg(isar->hw, ISAR_HIA);
53
54 while ((val & 1) && t) {
55 udelay(1);
56 t--;
57 val = isar->read_reg(isar->hw, ISAR_HIA);
58 }
59 pr_debug("%s: HIA after %dus\n", isar->name, timeout - t);
60 return timeout;
61}
62
63/*
64 * send msg to ISAR mailbox
65 * if msg is NULL use isar->buf
66 */
67static int
68send_mbox(struct isar_hw *isar, u8 his, u8 creg, u8 len, u8 *msg)
69{
70 if (!waitforHIA(isar, 1000))
71 return 0;
72 pr_debug("send_mbox(%02x,%02x,%d)\n", his, creg, len);
73 isar->write_reg(isar->hw, ISAR_CTRL_H, creg);
74 isar->write_reg(isar->hw, ISAR_CTRL_L, len);
75 isar->write_reg(isar->hw, ISAR_WADR, 0);
76 if (!msg)
77 msg = isar->buf;
78 if (msg && len) {
79 isar->write_fifo(isar->hw, ISAR_MBOX, msg, len);
80 if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
81 int l = 0;
82
83 while (l < (int)len) {
84 hex_dump_to_buffer(msg + l, len - l, 32, 1,
85 isar->log, 256, 1);
86 pr_debug("%s: %s %02x: %s\n", isar->name,
87 __func__, l, isar->log);
88 l += 32;
89 }
90 }
91 }
92 isar->write_reg(isar->hw, ISAR_HIS, his);
93 waitforHIA(isar, 1000);
94 return 1;
95}
96
97/*
98 * receive message from ISAR mailbox
99 * if msg is NULL use isar->buf
100 */
101static void
102rcv_mbox(struct isar_hw *isar, u8 *msg)
103{
104 if (!msg)
105 msg = isar->buf;
106 isar->write_reg(isar->hw, ISAR_RADR, 0);
107 if (msg && isar->clsb) {
108 isar->read_fifo(isar->hw, ISAR_MBOX, msg, isar->clsb);
109 if (isar->ch[0].bch.debug & DEBUG_HW_BFIFO) {
110 int l = 0;
111
112 while (l < (int)isar->clsb) {
113 hex_dump_to_buffer(msg + l, isar->clsb - l, 32,
114 1, isar->log, 256, 1);
115 pr_debug("%s: %s %02x: %s\n", isar->name,
116 __func__, l, isar->log);
117 l += 32;
118 }
119 }
120 }
121 isar->write_reg(isar->hw, ISAR_IIA, 0);
122}
123
124static inline void
125get_irq_infos(struct isar_hw *isar)
126{
127 isar->iis = isar->read_reg(isar->hw, ISAR_IIS);
128 isar->cmsb = isar->read_reg(isar->hw, ISAR_CTRL_H);
129 isar->clsb = isar->read_reg(isar->hw, ISAR_CTRL_L);
130 pr_debug("%s: rcv_mbox(%02x,%02x,%d)\n", isar->name,
131 isar->iis, isar->cmsb, isar->clsb);
132}
133
134/*
135 * poll answer message from ISAR mailbox
136 * should be used only with ISAR IRQs disabled before DSP was started
137 *
138 */
139static int
140poll_mbox(struct isar_hw *isar, int maxdelay)
141{
142 int t = maxdelay;
143 u8 irq;
144
145 irq = isar->read_reg(isar->hw, ISAR_IRQBIT);
146 while (t && !(irq & ISAR_IRQSTA)) {
147 udelay(1);
148 t--;
149 }
150 if (t) {
151 get_irq_infos(isar);
152 rcv_mbox(isar, NULL);
153 }
154 pr_debug("%s: pulled %d bytes after %d us\n",
155 isar->name, isar->clsb, maxdelay - t);
156 return t;
157}
158
159static int
160ISARVersion(struct isar_hw *isar)
161{
162 int ver;
163
164 /* disable ISAR IRQ */
165 isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
166 isar->buf[0] = ISAR_MSG_HWVER;
167 isar->buf[1] = 0;
168 isar->buf[2] = 1;
169 if (!send_mbox(isar, ISAR_HIS_VNR, 0, 3, NULL))
170 return -1;
171 if (!poll_mbox(isar, 1000))
172 return -2;
173 if (isar->iis == ISAR_IIS_VNR) {
174 if (isar->clsb == 1) {
175 ver = isar->buf[0] & 0xf;
176 return ver;
177 }
178 return -3;
179 }
180 return -4;
181}
182
183static int
184load_firmware(struct isar_hw *isar, const u8 *buf, int size)
185{
186 u32 saved_debug = isar->ch[0].bch.debug;
187 int ret, cnt;
188 u8 nom, noc;
189 u16 left, val, *sp = (u16 *)buf;
190 u8 *mp;
191 u_long flags;
192
193 struct {
194 u16 sadr;
195 u16 len;
196 u16 d_key;
197 } blk_head;
198
199 if (1 != isar->version) {
200 pr_err("%s: ISAR wrong version %d firmware download aborted\n",
201 isar->name, isar->version);
202 return -EINVAL;
203 }
204 if (!(saved_debug & DEBUG_HW_FIRMWARE_FIFO))
205 isar->ch[0].bch.debug &= ~DEBUG_HW_BFIFO;
206 pr_debug("%s: load firmware %d words (%d bytes)\n",
207 isar->name, size/2, size);
208 cnt = 0;
209 size /= 2;
210 /* disable ISAR IRQ */
211 spin_lock_irqsave(isar->hwlock, flags);
212 isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
213 spin_unlock_irqrestore(isar->hwlock, flags);
214 while (cnt < size) {
215 blk_head.sadr = le16_to_cpu(*sp++);
216 blk_head.len = le16_to_cpu(*sp++);
217 blk_head.d_key = le16_to_cpu(*sp++);
218 cnt += 3;
219 pr_debug("ISAR firmware block (%#x,%d,%#x)\n",
220 blk_head.sadr, blk_head.len, blk_head.d_key & 0xff);
221 left = blk_head.len;
222 if (cnt + left > size) {
223 pr_info("%s: firmware error have %d need %d words\n",
224 isar->name, size, cnt + left);
225 ret = -EINVAL;
226 goto reterrflg;
227 }
228 spin_lock_irqsave(isar->hwlock, flags);
229 if (!send_mbox(isar, ISAR_HIS_DKEY, blk_head.d_key & 0xff,
230 0, NULL)) {
231 pr_info("ISAR send_mbox dkey failed\n");
232 ret = -ETIME;
233 goto reterror;
234 }
235 if (!poll_mbox(isar, 1000)) {
236 pr_warning("ISAR poll_mbox dkey failed\n");
237 ret = -ETIME;
238 goto reterror;
239 }
240 spin_unlock_irqrestore(isar->hwlock, flags);
241 if ((isar->iis != ISAR_IIS_DKEY) || isar->cmsb || isar->clsb) {
242 pr_info("ISAR wrong dkey response (%x,%x,%x)\n",
243 isar->iis, isar->cmsb, isar->clsb);
244 ret = 1;
245 goto reterrflg;
246 }
247 while (left > 0) {
248 if (left > 126)
249 noc = 126;
250 else
251 noc = left;
252 nom = (2 * noc) + 3;
253 mp = isar->buf;
254 /* the ISAR is big endian */
255 *mp++ = blk_head.sadr >> 8;
256 *mp++ = blk_head.sadr & 0xFF;
257 left -= noc;
258 cnt += noc;
259 *mp++ = noc;
260 pr_debug("%s: load %3d words at %04x\n", isar->name,
261 noc, blk_head.sadr);
262 blk_head.sadr += noc;
263 while (noc) {
264 val = le16_to_cpu(*sp++);
265 *mp++ = val >> 8;
266 *mp++ = val & 0xFF;;
267 noc--;
268 }
269 spin_lock_irqsave(isar->hwlock, flags);
270 if (!send_mbox(isar, ISAR_HIS_FIRM, 0, nom, NULL)) {
271 pr_info("ISAR send_mbox prog failed\n");
272 ret = -ETIME;
273 goto reterror;
274 }
275 if (!poll_mbox(isar, 1000)) {
276 pr_info("ISAR poll_mbox prog failed\n");
277 ret = -ETIME;
278 goto reterror;
279 }
280 spin_unlock_irqrestore(isar->hwlock, flags);
281 if ((isar->iis != ISAR_IIS_FIRM) ||
282 isar->cmsb || isar->clsb) {
283 pr_info("ISAR wrong prog response (%x,%x,%x)\n",
284 isar->iis, isar->cmsb, isar->clsb);
285 ret = -EIO;
286 goto reterrflg;
287 }
288 }
289 pr_debug("%s: ISAR firmware block %d words loaded\n",
290 isar->name, blk_head.len);
291 }
292 isar->ch[0].bch.debug = saved_debug;
293 /* 10ms delay */
294 cnt = 10;
295 while (cnt--)
296 mdelay(1);
297 isar->buf[0] = 0xff;
298 isar->buf[1] = 0xfe;
299 isar->bstat = 0;
300 spin_lock_irqsave(isar->hwlock, flags);
301 if (!send_mbox(isar, ISAR_HIS_STDSP, 0, 2, NULL)) {
302 pr_info("ISAR send_mbox start dsp failed\n");
303 ret = -ETIME;
304 goto reterror;
305 }
306 if (!poll_mbox(isar, 1000)) {
307 pr_info("ISAR poll_mbox start dsp failed\n");
308 ret = -ETIME;
309 goto reterror;
310 }
311 if ((isar->iis != ISAR_IIS_STDSP) || isar->cmsb || isar->clsb) {
312 pr_info("ISAR wrong start dsp response (%x,%x,%x)\n",
313 isar->iis, isar->cmsb, isar->clsb);
314 ret = -EIO;
315 goto reterror;
316 } else
317 pr_debug("%s: ISAR start dsp success\n", isar->name);
318
319 /* NORMAL mode entered */
320 /* Enable IRQs of ISAR */
321 isar->write_reg(isar->hw, ISAR_IRQBIT, ISAR_IRQSTA);
322 spin_unlock_irqrestore(isar->hwlock, flags);
323 cnt = 1000; /* max 1s */
324 while ((!isar->bstat) && cnt) {
325 mdelay(1);
326 cnt--;
327 }
328 if (!cnt) {
329 pr_info("ISAR no general status event received\n");
330 ret = -ETIME;
331 goto reterrflg;
332 } else
333 pr_debug("%s: ISAR general status event %x\n",
334 isar->name, isar->bstat);
335 /* 10ms delay */
336 cnt = 10;
337 while (cnt--)
338 mdelay(1);
339 isar->iis = 0;
340 spin_lock_irqsave(isar->hwlock, flags);
341 if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_STST, 0, NULL)) {
342 pr_info("ISAR send_mbox self tst failed\n");
343 ret = -ETIME;
344 goto reterror;
345 }
346 spin_unlock_irqrestore(isar->hwlock, flags);
347 cnt = 10000; /* max 100 ms */
348 while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
349 udelay(10);
350 cnt--;
351 }
352 mdelay(1);
353 if (!cnt) {
354 pr_info("ISAR no self tst response\n");
355 ret = -ETIME;
356 goto reterrflg;
357 }
358 if ((isar->cmsb == ISAR_CTRL_STST) && (isar->clsb == 1)
359 && (isar->buf[0] == 0))
360 pr_debug("%s: ISAR selftest OK\n", isar->name);
361 else {
362 pr_info("ISAR selftest not OK %x/%x/%x\n",
363 isar->cmsb, isar->clsb, isar->buf[0]);
364 ret = -EIO;
365 goto reterrflg;
366 }
367 spin_lock_irqsave(isar->hwlock, flags);
368 isar->iis = 0;
369 if (!send_mbox(isar, ISAR_HIS_DIAG, ISAR_CTRL_SWVER, 0, NULL)) {
370 pr_info("ISAR RQST SVN failed\n");
371 ret = -ETIME;
372 goto reterror;
373 }
374 spin_unlock_irqrestore(isar->hwlock, flags);
375 cnt = 30000; /* max 300 ms */
376 while ((isar->iis != ISAR_IIS_DIAG) && cnt) {
377 udelay(10);
378 cnt--;
379 }
380 mdelay(1);
381 if (!cnt) {
382 pr_info("ISAR no SVN response\n");
383 ret = -ETIME;
384 goto reterrflg;
385 } else {
386 if ((isar->cmsb == ISAR_CTRL_SWVER) && (isar->clsb == 1)) {
387 pr_notice("%s: ISAR software version %#x\n",
388 isar->name, isar->buf[0]);
389 } else {
390 pr_info("%s: ISAR wrong swver response (%x,%x)"
391 " cnt(%d)\n", isar->name, isar->cmsb,
392 isar->clsb, cnt);
393 ret = -EIO;
394 goto reterrflg;
395 }
396 }
397 spin_lock_irqsave(isar->hwlock, flags);
398 isar_setup(isar);
399 spin_unlock_irqrestore(isar->hwlock, flags);
400 ret = 0;
401reterrflg:
402 spin_lock_irqsave(isar->hwlock, flags);
403reterror:
404 isar->ch[0].bch.debug = saved_debug;
405 if (ret)
406 /* disable ISAR IRQ */
407 isar->write_reg(isar->hw, ISAR_IRQBIT, 0);
408 spin_unlock_irqrestore(isar->hwlock, flags);
409 return ret;
410}
411
412static inline void
413deliver_status(struct isar_ch *ch, int status)
414{
415 pr_debug("%s: HL->LL FAXIND %x\n", ch->is->name, status);
416 _queue_data(&ch->bch.ch, PH_CONTROL_IND, status, 0, NULL, GFP_ATOMIC);
417}
418
419static inline void
420isar_rcv_frame(struct isar_ch *ch)
421{
422 u8 *ptr;
423
424 if (!ch->is->clsb) {
425 pr_debug("%s; ISAR zero len frame\n", ch->is->name);
426 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
427 return;
428 }
429 switch (ch->bch.state) {
430 case ISDN_P_NONE:
431 pr_debug("%s: ISAR protocol 0 spurious IIS_RDATA %x/%x/%x\n",
432 ch->is->name, ch->is->iis, ch->is->cmsb, ch->is->clsb);
433 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
434 break;
435 case ISDN_P_B_RAW:
436 case ISDN_P_B_L2DTMF:
437 case ISDN_P_B_MODEM_ASYNC:
438 if (!ch->bch.rx_skb) {
439 ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
440 GFP_ATOMIC);
441 if (unlikely(!ch->bch.rx_skb)) {
442 pr_info("%s: B receive out of memory\n",
443 ch->is->name);
444 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
445 break;
446 }
447 }
448 rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
449 recv_Bchannel(&ch->bch, 0);
450 break;
451 case ISDN_P_B_HDLC:
452 if (!ch->bch.rx_skb) {
453 ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
454 GFP_ATOMIC);
455 if (unlikely(!ch->bch.rx_skb)) {
456 pr_info("%s: B receive out of memory\n",
457 ch->is->name);
458 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
459 break;
460 }
461 }
462 if ((ch->bch.rx_skb->len + ch->is->clsb) >
463 (ch->bch.maxlen + 2)) {
464 pr_debug("%s: incoming packet too large\n",
465 ch->is->name);
466 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
467 skb_trim(ch->bch.rx_skb, 0);
468 break;
469 }
470 if (ch->is->cmsb & HDLC_ERROR) {
471 pr_debug("%s: ISAR frame error %x len %d\n",
472 ch->is->name, ch->is->cmsb, ch->is->clsb);
473#ifdef ERROR_STATISTIC
474 if (ch->is->cmsb & HDLC_ERR_RER)
475 ch->bch.err_inv++;
476 if (ch->is->cmsb & HDLC_ERR_CER)
477 ch->bch.err_crc++;
478#endif
479 skb_trim(ch->bch.rx_skb, 0);
480 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
481 break;
482 }
483 if (ch->is->cmsb & HDLC_FSD)
484 skb_trim(ch->bch.rx_skb, 0);
485 ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
486 rcv_mbox(ch->is, ptr);
487 if (ch->is->cmsb & HDLC_FED) {
488 if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
489 pr_debug("%s: ISAR frame to short %d\n",
490 ch->is->name, ch->bch.rx_skb->len);
491 skb_trim(ch->bch.rx_skb, 0);
492 break;
493 }
494 skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
495 recv_Bchannel(&ch->bch, 0);
496 }
497 break;
498 case ISDN_P_B_T30_FAX:
499 if (ch->state != STFAX_ACTIV) {
500 pr_debug("%s: isar_rcv_frame: not ACTIV\n",
501 ch->is->name);
502 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
503 if (ch->bch.rx_skb)
504 skb_trim(ch->bch.rx_skb, 0);
505 break;
506 }
507 if (!ch->bch.rx_skb) {
508 ch->bch.rx_skb = mI_alloc_skb(ch->bch.maxlen,
509 GFP_ATOMIC);
510 if (unlikely(!ch->bch.rx_skb)) {
511 pr_info("%s: B receive out of memory\n",
512 __func__);
513 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
514 break;
515 }
516 }
517 if (ch->cmd == PCTRL_CMD_FRM) {
518 rcv_mbox(ch->is, skb_put(ch->bch.rx_skb, ch->is->clsb));
519 pr_debug("%s: isar_rcv_frame: %d\n",
520 ch->is->name, ch->bch.rx_skb->len);
521 if (ch->is->cmsb & SART_NMD) { /* ABORT */
522 pr_debug("%s: isar_rcv_frame: no more data\n",
523 ch->is->name);
524 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
525 send_mbox(ch->is, SET_DPS(ch->dpath) |
526 ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
527 0, NULL);
528 ch->state = STFAX_ESCAPE;
529 /* set_skb_flag(skb, DF_NOMOREDATA); */
530 }
531 recv_Bchannel(&ch->bch, 0);
532 if (ch->is->cmsb & SART_NMD)
533 deliver_status(ch, HW_MOD_NOCARR);
534 break;
535 }
536 if (ch->cmd != PCTRL_CMD_FRH) {
537 pr_debug("%s: isar_rcv_frame: unknown fax mode %x\n",
538 ch->is->name, ch->cmd);
539 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
540 if (ch->bch.rx_skb)
541 skb_trim(ch->bch.rx_skb, 0);
542 break;
543 }
544 /* PCTRL_CMD_FRH */
545 if ((ch->bch.rx_skb->len + ch->is->clsb) >
546 (ch->bch.maxlen + 2)) {
547 pr_info("%s: %s incoming packet too large\n",
548 ch->is->name, __func__);
549 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
550 skb_trim(ch->bch.rx_skb, 0);
551 break;
552 } else if (ch->is->cmsb & HDLC_ERROR) {
553 pr_info("%s: ISAR frame error %x len %d\n",
554 ch->is->name, ch->is->cmsb, ch->is->clsb);
555 skb_trim(ch->bch.rx_skb, 0);
556 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
557 break;
558 }
559 if (ch->is->cmsb & HDLC_FSD)
560 skb_trim(ch->bch.rx_skb, 0);
561 ptr = skb_put(ch->bch.rx_skb, ch->is->clsb);
562 rcv_mbox(ch->is, ptr);
563 if (ch->is->cmsb & HDLC_FED) {
564 if (ch->bch.rx_skb->len < 3) { /* last 2 are the FCS */
565 pr_info("%s: ISAR frame to short %d\n",
566 ch->is->name, ch->bch.rx_skb->len);
567 skb_trim(ch->bch.rx_skb, 0);
568 break;
569 }
570 skb_trim(ch->bch.rx_skb, ch->bch.rx_skb->len - 2);
571 recv_Bchannel(&ch->bch, 0);
572 }
573 if (ch->is->cmsb & SART_NMD) { /* ABORT */
574 pr_debug("%s: isar_rcv_frame: no more data\n",
575 ch->is->name);
576 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
577 if (ch->bch.rx_skb)
578 skb_trim(ch->bch.rx_skb, 0);
579 send_mbox(ch->is, SET_DPS(ch->dpath) |
580 ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC, 0, NULL);
581 ch->state = STFAX_ESCAPE;
582 deliver_status(ch, HW_MOD_NOCARR);
583 }
584 break;
585 default:
586 pr_info("isar_rcv_frame protocol (%x)error\n", ch->bch.state);
587 ch->is->write_reg(ch->is->hw, ISAR_IIA, 0);
588 break;
589 }
590}
591
592static void
593isar_fill_fifo(struct isar_ch *ch)
594{
595 int count;
596 u8 msb;
597 u8 *ptr;
598
599 pr_debug("%s: ch%d tx_skb %p tx_idx %d\n",
600 ch->is->name, ch->bch.nr, ch->bch.tx_skb, ch->bch.tx_idx);
601 if (!ch->bch.tx_skb)
602 return;
603 count = ch->bch.tx_skb->len - ch->bch.tx_idx;
604 if (count <= 0)
605 return;
606 if (!(ch->is->bstat &
607 (ch->dpath == 1 ? BSTAT_RDM1 : BSTAT_RDM2)))
608 return;
609 if (count > ch->mml) {
610 msb = 0;
611 count = ch->mml;
612 } else {
613 msb = HDLC_FED;
614 }
615 ptr = ch->bch.tx_skb->data + ch->bch.tx_idx;
616 if (!ch->bch.tx_idx) {
617 pr_debug("%s: frame start\n", ch->is->name);
618 if ((ch->bch.state == ISDN_P_B_T30_FAX) &&
619 (ch->cmd == PCTRL_CMD_FTH)) {
620 if (count > 1) {
621 if ((ptr[0] == 0xff) && (ptr[1] == 0x13)) {
622 /* last frame */
623 test_and_set_bit(FLG_LASTDATA,
624 &ch->bch.Flags);
625 pr_debug("%s: set LASTDATA\n",
626 ch->is->name);
627 if (msb == HDLC_FED)
628 test_and_set_bit(FLG_DLEETX,
629 &ch->bch.Flags);
630 }
631 }
632 }
633 msb |= HDLC_FST;
634 }
635 ch->bch.tx_idx += count;
636 switch (ch->bch.state) {
637 case ISDN_P_NONE:
638 pr_info("%s: wrong protocol 0\n", __func__);
639 break;
640 case ISDN_P_B_RAW:
641 case ISDN_P_B_L2DTMF:
642 case ISDN_P_B_MODEM_ASYNC:
643 send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
644 0, count, ptr);
645 break;
646 case ISDN_P_B_HDLC:
647 send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
648 msb, count, ptr);
649 break;
650 case ISDN_P_B_T30_FAX:
651 if (ch->state != STFAX_ACTIV)
652 pr_debug("%s: not ACTIV\n", ch->is->name);
653 else if (ch->cmd == PCTRL_CMD_FTH)
654 send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
655 msb, count, ptr);
656 else if (ch->cmd == PCTRL_CMD_FTM)
657 send_mbox(ch->is, SET_DPS(ch->dpath) | ISAR_HIS_SDATA,
658 0, count, ptr);
659 else
660 pr_debug("%s: not FTH/FTM\n", ch->is->name);
661 break;
662 default:
663 pr_info("%s: protocol(%x) error\n",
664 __func__, ch->bch.state);
665 break;
666 }
667}
668
669static inline struct isar_ch *
670sel_bch_isar(struct isar_hw *isar, u8 dpath)
671{
672 struct isar_ch *base = &isar->ch[0];
673
674 if ((!dpath) || (dpath > 2))
675 return NULL;
676 if (base->dpath == dpath)
677 return base;
678 base++;
679 if (base->dpath == dpath)
680 return base;
681 return NULL;
682}
683
684static void
685send_next(struct isar_ch *ch)
686{
687 pr_debug("%s: %s ch%d tx_skb %p tx_idx %d\n",
688 ch->is->name, __func__, ch->bch.nr,
689 ch->bch.tx_skb, ch->bch.tx_idx);
690 if (ch->bch.state == ISDN_P_B_T30_FAX) {
691 if (ch->cmd == PCTRL_CMD_FTH) {
692 if (test_bit(FLG_LASTDATA, &ch->bch.Flags)) {
693 pr_debug("set NMD_DATA\n");
694 test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
695 }
696 } else if (ch->cmd == PCTRL_CMD_FTM) {
697 if (test_bit(FLG_DLEETX, &ch->bch.Flags)) {
698 test_and_set_bit(FLG_LASTDATA, &ch->bch.Flags);
699 test_and_set_bit(FLG_NMD_DATA, &ch->bch.Flags);
700 }
701 }
702 }
703 if (ch->bch.tx_skb) {
704 /* send confirm, on trans, free on hdlc. */
705 if (test_bit(FLG_TRANSPARENT, &ch->bch.Flags))
706 confirm_Bsend(&ch->bch);
707 dev_kfree_skb(ch->bch.tx_skb);
708 }
709 if (get_next_bframe(&ch->bch))
710 isar_fill_fifo(ch);
711 else {
712 if (test_and_clear_bit(FLG_DLEETX, &ch->bch.Flags)) {
713 if (test_and_clear_bit(FLG_LASTDATA,
714 &ch->bch.Flags)) {
715 if (test_and_clear_bit(FLG_NMD_DATA,
716 &ch->bch.Flags)) {
717 u8 zd = 0;
718 send_mbox(ch->is, SET_DPS(ch->dpath) |
719 ISAR_HIS_SDATA, 0x01, 1, &zd);
720 }
721 test_and_set_bit(FLG_LL_OK, &ch->bch.Flags);
722 } else {
723 deliver_status(ch, HW_MOD_CONNECT);
724 }
725 }
726 }
727}
728
729static void
730check_send(struct isar_hw *isar, u8 rdm)
731{
732 struct isar_ch *ch;
733
734 pr_debug("%s: rdm %x\n", isar->name, rdm);
735 if (rdm & BSTAT_RDM1) {
736 ch = sel_bch_isar(isar, 1);
737 if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
738 if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
739 ch->bch.tx_idx))
740 isar_fill_fifo(ch);
741 else
742 send_next(ch);
743 }
744 }
745 if (rdm & BSTAT_RDM2) {
746 ch = sel_bch_isar(isar, 2);
747 if (ch && test_bit(FLG_ACTIVE, &ch->bch.Flags)) {
748 if (ch->bch.tx_skb && (ch->bch.tx_skb->len >
749 ch->bch.tx_idx))
750 isar_fill_fifo(ch);
751 else
752 send_next(ch);
753 }
754 }
755}
756
757const char *dmril[] = {"NO SPEED", "1200/75", "NODEF2", "75/1200", "NODEF4",
758 "300", "600", "1200", "2400", "4800", "7200",
759 "9600nt", "9600t", "12000", "14400", "WRONG"};
760const char *dmrim[] = {"NO MOD", "NO DEF", "V32/V32b", "V22", "V21",
761 "Bell103", "V23", "Bell202", "V17", "V29", "V27ter"};
762
763static void
764isar_pump_status_rsp(struct isar_ch *ch) {
765 u8 ril = ch->is->buf[0];
766 u8 rim;
767
768 if (!test_and_clear_bit(ISAR_RATE_REQ, &ch->is->Flags))
769 return;
770 if (ril > 14) {
771 pr_info("%s: wrong pstrsp ril=%d\n", ch->is->name, ril);
772 ril = 15;
773 }
774 switch (ch->is->buf[1]) {
775 case 0:
776 rim = 0;
777 break;
778 case 0x20:
779 rim = 2;
780 break;
781 case 0x40:
782 rim = 3;
783 break;
784 case 0x41:
785 rim = 4;
786 break;
787 case 0x51:
788 rim = 5;
789 break;
790 case 0x61:
791 rim = 6;
792 break;
793 case 0x71:
794 rim = 7;
795 break;
796 case 0x82:
797 rim = 8;
798 break;
799 case 0x92:
800 rim = 9;
801 break;
802 case 0xa2:
803 rim = 10;
804 break;
805 default:
806 rim = 1;
807 break;
808 }
809 sprintf(ch->conmsg, "%s %s", dmril[ril], dmrim[rim]);
810 pr_debug("%s: pump strsp %s\n", ch->is->name, ch->conmsg);
811}
812
813static void
814isar_pump_statev_modem(struct isar_ch *ch, u8 devt) {
815 u8 dps = SET_DPS(ch->dpath);
816
817 switch (devt) {
818 case PSEV_10MS_TIMER:
819 pr_debug("%s: pump stev TIMER\n", ch->is->name);
820 break;
821 case PSEV_CON_ON:
822 pr_debug("%s: pump stev CONNECT\n", ch->is->name);
823 deliver_status(ch, HW_MOD_CONNECT);
824 break;
825 case PSEV_CON_OFF:
826 pr_debug("%s: pump stev NO CONNECT\n", ch->is->name);
827 send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
828 deliver_status(ch, HW_MOD_NOCARR);
829 break;
830 case PSEV_V24_OFF:
831 pr_debug("%s: pump stev V24 OFF\n", ch->is->name);
832 break;
833 case PSEV_CTS_ON:
834 pr_debug("%s: pump stev CTS ON\n", ch->is->name);
835 break;
836 case PSEV_CTS_OFF:
837 pr_debug("%s pump stev CTS OFF\n", ch->is->name);
838 break;
839 case PSEV_DCD_ON:
840 pr_debug("%s: pump stev CARRIER ON\n", ch->is->name);
841 test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
842 send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
843 break;
844 case PSEV_DCD_OFF:
845 pr_debug("%s: pump stev CARRIER OFF\n", ch->is->name);
846 break;
847 case PSEV_DSR_ON:
848 pr_debug("%s: pump stev DSR ON\n", ch->is->name);
849 break;
850 case PSEV_DSR_OFF:
851 pr_debug("%s: pump stev DSR_OFF\n", ch->is->name);
852 break;
853 case PSEV_REM_RET:
854 pr_debug("%s: pump stev REMOTE RETRAIN\n", ch->is->name);
855 break;
856 case PSEV_REM_REN:
857 pr_debug("%s: pump stev REMOTE RENEGOTIATE\n", ch->is->name);
858 break;
859 case PSEV_GSTN_CLR:
860 pr_debug("%s: pump stev GSTN CLEAR\n", ch->is->name);
861 break;
862 default:
863 pr_info("u%s: nknown pump stev %x\n", ch->is->name, devt);
864 break;
865 }
866}
867
868static void
869isar_pump_statev_fax(struct isar_ch *ch, u8 devt) {
870 u8 dps = SET_DPS(ch->dpath);
871 u8 p1;
872
873 switch (devt) {
874 case PSEV_10MS_TIMER:
875 pr_debug("%s: pump stev TIMER\n", ch->is->name);
876 break;
877 case PSEV_RSP_READY:
878 pr_debug("%s: pump stev RSP_READY\n", ch->is->name);
879 ch->state = STFAX_READY;
880 deliver_status(ch, HW_MOD_READY);
881#ifdef AUTOCON
882 if (test_bit(BC_FLG_ORIG, &ch->bch.Flags))
883 isar_pump_cmd(bch, HW_MOD_FRH, 3);
884 else
885 isar_pump_cmd(bch, HW_MOD_FTH, 3);
886#endif
887 break;
888 case PSEV_LINE_TX_H:
889 if (ch->state == STFAX_LINE) {
890 pr_debug("%s: pump stev LINE_TX_H\n", ch->is->name);
891 ch->state = STFAX_CONT;
892 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
893 PCTRL_CMD_CONT, 0, NULL);
894 } else {
895 pr_debug("%s: pump stev LINE_TX_H wrong st %x\n",
896 ch->is->name, ch->state);
897 }
898 break;
899 case PSEV_LINE_RX_H:
900 if (ch->state == STFAX_LINE) {
901 pr_debug("%s: pump stev LINE_RX_H\n", ch->is->name);
902 ch->state = STFAX_CONT;
903 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
904 PCTRL_CMD_CONT, 0, NULL);
905 } else {
906 pr_debug("%s: pump stev LINE_RX_H wrong st %x\n",
907 ch->is->name, ch->state);
908 }
909 break;
910 case PSEV_LINE_TX_B:
911 if (ch->state == STFAX_LINE) {
912 pr_debug("%s: pump stev LINE_TX_B\n", ch->is->name);
913 ch->state = STFAX_CONT;
914 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
915 PCTRL_CMD_CONT, 0, NULL);
916 } else {
917 pr_debug("%s: pump stev LINE_TX_B wrong st %x\n",
918 ch->is->name, ch->state);
919 }
920 break;
921 case PSEV_LINE_RX_B:
922 if (ch->state == STFAX_LINE) {
923 pr_debug("%s: pump stev LINE_RX_B\n", ch->is->name);
924 ch->state = STFAX_CONT;
925 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
926 PCTRL_CMD_CONT, 0, NULL);
927 } else {
928 pr_debug("%s: pump stev LINE_RX_B wrong st %x\n",
929 ch->is->name, ch->state);
930 }
931 break;
932 case PSEV_RSP_CONN:
933 if (ch->state == STFAX_CONT) {
934 pr_debug("%s: pump stev RSP_CONN\n", ch->is->name);
935 ch->state = STFAX_ACTIV;
936 test_and_set_bit(ISAR_RATE_REQ, &ch->is->Flags);
937 send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
938 if (ch->cmd == PCTRL_CMD_FTH) {
939 int delay = (ch->mod == 3) ? 1000 : 200;
940 /* 1s (200 ms) Flags before data */
941 if (test_and_set_bit(FLG_FTI_RUN,
942 &ch->bch.Flags))
943 del_timer(&ch->ftimer);
944 ch->ftimer.expires =
945 jiffies + ((delay * HZ)/1000);
946 test_and_set_bit(FLG_LL_CONN,
947 &ch->bch.Flags);
948 add_timer(&ch->ftimer);
949 } else {
950 deliver_status(ch, HW_MOD_CONNECT);
951 }
952 } else {
953 pr_debug("%s: pump stev RSP_CONN wrong st %x\n",
954 ch->is->name, ch->state);
955 }
956 break;
957 case PSEV_FLAGS_DET:
958 pr_debug("%s: pump stev FLAGS_DET\n", ch->is->name);
959 break;
960 case PSEV_RSP_DISC:
961 pr_debug("%s: pump stev RSP_DISC state(%d)\n",
962 ch->is->name, ch->state);
963 if (ch->state == STFAX_ESCAPE) {
964 p1 = 5;
965 switch (ch->newcmd) {
966 case 0:
967 ch->state = STFAX_READY;
968 break;
969 case PCTRL_CMD_FTM:
970 p1 = 2;
971 case PCTRL_CMD_FTH:
972 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
973 PCTRL_CMD_SILON, 1, &p1);
974 ch->state = STFAX_SILDET;
975 break;
976 case PCTRL_CMD_FRH:
977 case PCTRL_CMD_FRM:
978 ch->mod = ch->newmod;
979 p1 = ch->newmod;
980 ch->newmod = 0;
981 ch->cmd = ch->newcmd;
982 ch->newcmd = 0;
983 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
984 ch->cmd, 1, &p1);
985 ch->state = STFAX_LINE;
986 ch->try_mod = 3;
987 break;
988 default:
989 pr_debug("%s: RSP_DISC unknown newcmd %x\n",
990 ch->is->name, ch->newcmd);
991 break;
992 }
993 } else if (ch->state == STFAX_ACTIV) {
994 if (test_and_clear_bit(FLG_LL_OK, &ch->bch.Flags))
995 deliver_status(ch, HW_MOD_OK);
996 else if (ch->cmd == PCTRL_CMD_FRM)
997 deliver_status(ch, HW_MOD_NOCARR);
998 else
999 deliver_status(ch, HW_MOD_FCERROR);
1000 ch->state = STFAX_READY;
1001 } else if (ch->state != STFAX_SILDET) {
1002 /* ignore in STFAX_SILDET */
1003 ch->state = STFAX_READY;
1004 deliver_status(ch, HW_MOD_FCERROR);
1005 }
1006 break;
1007 case PSEV_RSP_SILDET:
1008 pr_debug("%s: pump stev RSP_SILDET\n", ch->is->name);
1009 if (ch->state == STFAX_SILDET) {
1010 ch->mod = ch->newmod;
1011 p1 = ch->newmod;
1012 ch->newmod = 0;
1013 ch->cmd = ch->newcmd;
1014 ch->newcmd = 0;
1015 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
1016 ch->cmd, 1, &p1);
1017 ch->state = STFAX_LINE;
1018 ch->try_mod = 3;
1019 }
1020 break;
1021 case PSEV_RSP_SILOFF:
1022 pr_debug("%s: pump stev RSP_SILOFF\n", ch->is->name);
1023 break;
1024 case PSEV_RSP_FCERR:
1025 if (ch->state == STFAX_LINE) {
1026 pr_debug("%s: pump stev RSP_FCERR try %d\n",
1027 ch->is->name, ch->try_mod);
1028 if (ch->try_mod--) {
1029 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL,
1030 ch->cmd, 1, &ch->mod);
1031 break;
1032 }
1033 }
1034 pr_debug("%s: pump stev RSP_FCERR\n", ch->is->name);
1035 ch->state = STFAX_ESCAPE;
1036 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, PCTRL_CMD_ESC,
1037 0, NULL);
1038 deliver_status(ch, HW_MOD_FCERROR);
1039 break;
1040 default:
1041 break;
1042 }
1043}
1044
1045void
1046mISDNisar_irq(struct isar_hw *isar)
1047{
1048 struct isar_ch *ch;
1049
1050 get_irq_infos(isar);
1051 switch (isar->iis & ISAR_IIS_MSCMSD) {
1052 case ISAR_IIS_RDATA:
1053 ch = sel_bch_isar(isar, isar->iis >> 6);
1054 if (ch)
1055 isar_rcv_frame(ch);
1056 else {
1057 pr_debug("%s: ISAR spurious IIS_RDATA %x/%x/%x\n",
1058 isar->name, isar->iis, isar->cmsb,
1059 isar->clsb);
1060 isar->write_reg(isar->hw, ISAR_IIA, 0);
1061 }
1062 break;
1063 case ISAR_IIS_GSTEV:
1064 isar->write_reg(isar->hw, ISAR_IIA, 0);
1065 isar->bstat |= isar->cmsb;
1066 check_send(isar, isar->cmsb);
1067 break;
1068 case ISAR_IIS_BSTEV:
1069#ifdef ERROR_STATISTIC
1070 ch = sel_bch_isar(isar, isar->iis >> 6);
1071 if (ch) {
1072 if (isar->cmsb == BSTEV_TBO)
1073 ch->bch.err_tx++;
1074 if (isar->cmsb == BSTEV_RBO)
1075 ch->bch.err_rdo++;
1076 }
1077#endif
1078 pr_debug("%s: Buffer STEV dpath%d msb(%x)\n",
1079 isar->name, isar->iis>>6, isar->cmsb);
1080 isar->write_reg(isar->hw, ISAR_IIA, 0);
1081 break;
1082 case ISAR_IIS_PSTEV:
1083 ch = sel_bch_isar(isar, isar->iis >> 6);
1084 if (ch) {
1085 rcv_mbox(isar, NULL);
1086 if (ch->bch.state == ISDN_P_B_MODEM_ASYNC)
1087 isar_pump_statev_modem(ch, isar->cmsb);
1088 else if (ch->bch.state == ISDN_P_B_T30_FAX)
1089 isar_pump_statev_fax(ch, isar->cmsb);
1090 else if (ch->bch.state == ISDN_P_B_RAW) {
1091 int tt;
1092 tt = isar->cmsb | 0x30;
1093 if (tt == 0x3e)
1094 tt = '*';
1095 else if (tt == 0x3f)
1096 tt = '#';
1097 else if (tt > '9')
1098 tt += 7;
1099 tt |= DTMF_TONE_VAL;
1100 _queue_data(&ch->bch.ch, PH_CONTROL_IND,
1101 MISDN_ID_ANY, sizeof(tt), &tt,
1102 GFP_ATOMIC);
1103 } else
1104 pr_debug("%s: ISAR IIS_PSTEV pm %d sta %x\n",
1105 isar->name, ch->bch.state,
1106 isar->cmsb);
1107 } else {
1108 pr_debug("%s: ISAR spurious IIS_PSTEV %x/%x/%x\n",
1109 isar->name, isar->iis, isar->cmsb,
1110 isar->clsb);
1111 isar->write_reg(isar->hw, ISAR_IIA, 0);
1112 }
1113 break;
1114 case ISAR_IIS_PSTRSP:
1115 ch = sel_bch_isar(isar, isar->iis >> 6);
1116 if (ch) {
1117 rcv_mbox(isar, NULL);
1118 isar_pump_status_rsp(ch);
1119 } else {
1120 pr_debug("%s: ISAR spurious IIS_PSTRSP %x/%x/%x\n",
1121 isar->name, isar->iis, isar->cmsb,
1122 isar->clsb);
1123 isar->write_reg(isar->hw, ISAR_IIA, 0);
1124 }
1125 break;
1126 case ISAR_IIS_DIAG:
1127 case ISAR_IIS_BSTRSP:
1128 case ISAR_IIS_IOM2RSP:
1129 rcv_mbox(isar, NULL);
1130 break;
1131 case ISAR_IIS_INVMSG:
1132 rcv_mbox(isar, NULL);
1133 pr_debug("%s: invalid msg his:%x\n", isar->name, isar->cmsb);
1134 break;
1135 default:
1136 rcv_mbox(isar, NULL);
1137 pr_debug("%s: unhandled msg iis(%x) ctrl(%x/%x)\n",
1138 isar->name, isar->iis, isar->cmsb, isar->clsb);
1139 break;
1140 }
1141}
1142EXPORT_SYMBOL(mISDNisar_irq);
1143
1144static void
1145ftimer_handler(unsigned long data)
1146{
1147 struct isar_ch *ch = (struct isar_ch *)data;
1148
1149 pr_debug("%s: ftimer flags %lx\n", ch->is->name, ch->bch.Flags);
1150 test_and_clear_bit(FLG_FTI_RUN, &ch->bch.Flags);
1151 if (test_and_clear_bit(FLG_LL_CONN, &ch->bch.Flags))
1152 deliver_status(ch, HW_MOD_CONNECT);
1153}
1154
1155static void
1156setup_pump(struct isar_ch *ch) {
1157 u8 dps = SET_DPS(ch->dpath);
1158 u8 ctrl, param[6];
1159
1160 switch (ch->bch.state) {
1161 case ISDN_P_NONE:
1162 case ISDN_P_B_RAW:
1163 case ISDN_P_B_HDLC:
1164 send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, PMOD_BYPASS, 0, NULL);
1165 break;
1166 case ISDN_P_B_L2DTMF:
1167 if (test_bit(FLG_DTMFSEND, &ch->bch.Flags)) {
1168 param[0] = 5; /* TOA 5 db */
1169 send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
1170 PMOD_DTMF_TRANS, 1, param);
1171 } else {
1172 param[0] = 40; /* REL -46 dbm */
1173 send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG,
1174 PMOD_DTMF, 1, param);
1175 }
1176 case ISDN_P_B_MODEM_ASYNC:
1177 ctrl = PMOD_DATAMODEM;
1178 if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
1179 ctrl |= PCTRL_ORIG;
1180 param[5] = PV32P6_CTN;
1181 } else {
1182 param[5] = PV32P6_ATN;
1183 }
1184 param[0] = 6; /* 6 db */
1185 param[1] = PV32P2_V23R | PV32P2_V22A | PV32P2_V22B |
1186 PV32P2_V22C | PV32P2_V21 | PV32P2_BEL;
1187 param[2] = PV32P3_AMOD | PV32P3_V32B | PV32P3_V23B;
1188 param[3] = PV32P4_UT144;
1189 param[4] = PV32P5_UT144;
1190 send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 6, param);
1191 break;
1192 case ISDN_P_B_T30_FAX:
1193 ctrl = PMOD_FAX;
1194 if (test_bit(FLG_ORIGIN, &ch->bch.Flags)) {
1195 ctrl |= PCTRL_ORIG;
1196 param[1] = PFAXP2_CTN;
1197 } else {
1198 param[1] = PFAXP2_ATN;
1199 }
1200 param[0] = 6; /* 6 db */
1201 send_mbox(ch->is, dps | ISAR_HIS_PUMPCFG, ctrl, 2, param);
1202 ch->state = STFAX_NULL;
1203 ch->newcmd = 0;
1204 ch->newmod = 0;
1205 test_and_set_bit(FLG_FTI_RUN, &ch->bch.Flags);
1206 break;
1207 }
1208 udelay(1000);
1209 send_mbox(ch->is, dps | ISAR_HIS_PSTREQ, 0, 0, NULL);
1210 udelay(1000);
1211}
1212
1213static void
1214setup_sart(struct isar_ch *ch) {
1215 u8 dps = SET_DPS(ch->dpath);
1216 u8 ctrl, param[2] = {0, 0};
1217
1218 switch (ch->bch.state) {
1219 case ISDN_P_NONE:
1220 send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_DISABLE,
1221 0, NULL);
1222 break;
1223 case ISDN_P_B_RAW:
1224 case ISDN_P_B_L2DTMF:
1225 send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_BINARY,
1226 2, param);
1227 break;
1228 case ISDN_P_B_HDLC:
1229 case ISDN_P_B_T30_FAX:
1230 send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, SMODE_HDLC,
1231 1, param);
1232 break;
1233 case ISDN_P_B_MODEM_ASYNC:
1234 ctrl = SMODE_V14 | SCTRL_HDMC_BOTH;
1235 param[0] = S_P1_CHS_8;
1236 param[1] = S_P2_BFT_DEF;
1237 send_mbox(ch->is, dps | ISAR_HIS_SARTCFG, ctrl, 2, param);
1238 break;
1239 }
1240 udelay(1000);
1241 send_mbox(ch->is, dps | ISAR_HIS_BSTREQ, 0, 0, NULL);
1242 udelay(1000);
1243}
1244
1245static void
1246setup_iom2(struct isar_ch *ch) {
1247 u8 dps = SET_DPS(ch->dpath);
1248 u8 cmsb = IOM_CTRL_ENA, msg[5] = {IOM_P1_TXD, 0, 0, 0, 0};
1249
1250 if (ch->bch.nr == 2) {
1251 msg[1] = 1;
1252 msg[3] = 1;
1253 }
1254 switch (ch->bch.state) {
1255 case ISDN_P_NONE:
1256 cmsb = 0;
1257 /* dummy slot */
1258 msg[1] = ch->dpath + 2;
1259 msg[3] = ch->dpath + 2;
1260 break;
1261 case ISDN_P_B_RAW:
1262 case ISDN_P_B_HDLC:
1263 break;
1264 case ISDN_P_B_MODEM_ASYNC:
1265 case ISDN_P_B_T30_FAX:
1266 cmsb |= IOM_CTRL_RCV;
1267 case ISDN_P_B_L2DTMF:
1268 if (test_bit(FLG_DTMFSEND, &ch->bch.Flags))
1269 cmsb |= IOM_CTRL_RCV;
1270 cmsb |= IOM_CTRL_ALAW;
1271 break;
1272 }
1273 send_mbox(ch->is, dps | ISAR_HIS_IOM2CFG, cmsb, 5, msg);
1274 udelay(1000);
1275 send_mbox(ch->is, dps | ISAR_HIS_IOM2REQ, 0, 0, NULL);
1276 udelay(1000);
1277}
1278
1279static int
1280modeisar(struct isar_ch *ch, u32 bprotocol)
1281{
1282 /* Here we are selecting the best datapath for requested protocol */
1283 if (ch->bch.state == ISDN_P_NONE) { /* New Setup */
1284 switch (bprotocol) {
1285 case ISDN_P_NONE: /* init */
1286 if (!ch->dpath)
1287 /* no init for dpath 0 */
1288 return 0;
1289 test_and_clear_bit(FLG_HDLC, &ch->bch.Flags);
1290 test_and_clear_bit(FLG_TRANSPARENT, &ch->bch.Flags);
1291 break;
1292 case ISDN_P_B_RAW:
1293 case ISDN_P_B_HDLC:
1294 /* best is datapath 2 */
1295 if (!test_and_set_bit(ISAR_DP2_USE, &ch->is->Flags))
1296 ch->dpath = 2;
1297 else if (!test_and_set_bit(ISAR_DP1_USE,
1298 &ch->is->Flags))
1299 ch->dpath = 1;
1300 else {
1301 pr_info("modeisar both pathes in use\n");
1302 return -EBUSY;
1303 }
1304 if (bprotocol == ISDN_P_B_HDLC)
1305 test_and_set_bit(FLG_HDLC, &ch->bch.Flags);
1306 else
1307 test_and_set_bit(FLG_TRANSPARENT,
1308 &ch->bch.Flags);
1309 break;
1310 case ISDN_P_B_MODEM_ASYNC:
1311 case ISDN_P_B_T30_FAX:
1312 case ISDN_P_B_L2DTMF:
1313 /* only datapath 1 */
1314 if (!test_and_set_bit(ISAR_DP1_USE, &ch->is->Flags))
1315 ch->dpath = 1;
1316 else {
1317 pr_info("%s: ISAR modeisar analog functions"
1318 "only with DP1\n", ch->is->name);
1319 return -EBUSY;
1320 }
1321 break;
1322 default:
1323 pr_info("%s: protocol not known %x\n", ch->is->name,
1324 bprotocol);
1325 return -ENOPROTOOPT;
1326 }
1327 }
1328 pr_debug("%s: ISAR ch%d dp%d protocol %x->%x\n", ch->is->name,
1329 ch->bch.nr, ch->dpath, ch->bch.state, bprotocol);
1330 ch->bch.state = bprotocol;
1331 setup_pump(ch);
1332 setup_iom2(ch);
1333 setup_sart(ch);
1334 if (ch->bch.state == ISDN_P_NONE) {
1335 /* Clear resources */
1336 if (ch->dpath == 1)
1337 test_and_clear_bit(ISAR_DP1_USE, &ch->is->Flags);
1338 else if (ch->dpath == 2)
1339 test_and_clear_bit(ISAR_DP2_USE, &ch->is->Flags);
1340 ch->dpath = 0;
1341 ch->is->ctrl(ch->is->hw, HW_DEACT_IND, ch->bch.nr);
1342 } else
1343 ch->is->ctrl(ch->is->hw, HW_ACTIVATE_IND, ch->bch.nr);
1344 return 0;
1345}
1346
1347static void
1348isar_pump_cmd(struct isar_ch *ch, u32 cmd, u8 para)
1349{
1350 u8 dps = SET_DPS(ch->dpath);
1351 u8 ctrl = 0, nom = 0, p1 = 0;
1352
1353 pr_debug("%s: isar_pump_cmd %x/%x state(%x)\n",
1354 ch->is->name, cmd, para, ch->bch.state);
1355 switch (cmd) {
1356 case HW_MOD_FTM:
1357 if (ch->state == STFAX_READY) {
1358 p1 = para;
1359 ctrl = PCTRL_CMD_FTM;
1360 nom = 1;
1361 ch->state = STFAX_LINE;
1362 ch->cmd = ctrl;
1363 ch->mod = para;
1364 ch->newmod = 0;
1365 ch->newcmd = 0;
1366 ch->try_mod = 3;
1367 } else if ((ch->state == STFAX_ACTIV) &&
1368 (ch->cmd == PCTRL_CMD_FTM) && (ch->mod == para))
1369 deliver_status(ch, HW_MOD_CONNECT);
1370 else {
1371 ch->newmod = para;
1372 ch->newcmd = PCTRL_CMD_FTM;
1373 nom = 0;
1374 ctrl = PCTRL_CMD_ESC;
1375 ch->state = STFAX_ESCAPE;
1376 }
1377 break;
1378 case HW_MOD_FTH:
1379 if (ch->state == STFAX_READY) {
1380 p1 = para;
1381 ctrl = PCTRL_CMD_FTH;
1382 nom = 1;
1383 ch->state = STFAX_LINE;
1384 ch->cmd = ctrl;
1385 ch->mod = para;
1386 ch->newmod = 0;
1387 ch->newcmd = 0;
1388 ch->try_mod = 3;
1389 } else if ((ch->state == STFAX_ACTIV) &&
1390 (ch->cmd == PCTRL_CMD_FTH) && (ch->mod == para))
1391 deliver_status(ch, HW_MOD_CONNECT);
1392 else {
1393 ch->newmod = para;
1394 ch->newcmd = PCTRL_CMD_FTH;
1395 nom = 0;
1396 ctrl = PCTRL_CMD_ESC;
1397 ch->state = STFAX_ESCAPE;
1398 }
1399 break;
1400 case HW_MOD_FRM:
1401 if (ch->state == STFAX_READY) {
1402 p1 = para;
1403 ctrl = PCTRL_CMD_FRM;
1404 nom = 1;
1405 ch->state = STFAX_LINE;
1406 ch->cmd = ctrl;
1407 ch->mod = para;
1408 ch->newmod = 0;
1409 ch->newcmd = 0;
1410 ch->try_mod = 3;
1411 } else if ((ch->state == STFAX_ACTIV) &&
1412 (ch->cmd == PCTRL_CMD_FRM) && (ch->mod == para))
1413 deliver_status(ch, HW_MOD_CONNECT);
1414 else {
1415 ch->newmod = para;
1416 ch->newcmd = PCTRL_CMD_FRM;
1417 nom = 0;
1418 ctrl = PCTRL_CMD_ESC;
1419 ch->state = STFAX_ESCAPE;
1420 }
1421 break;
1422 case HW_MOD_FRH:
1423 if (ch->state == STFAX_READY) {
1424 p1 = para;
1425 ctrl = PCTRL_CMD_FRH;
1426 nom = 1;
1427 ch->state = STFAX_LINE;
1428 ch->cmd = ctrl;
1429 ch->mod = para;
1430 ch->newmod = 0;
1431 ch->newcmd = 0;
1432 ch->try_mod = 3;
1433 } else if ((ch->state == STFAX_ACTIV) &&
1434 (ch->cmd == PCTRL_CMD_FRH) && (ch->mod == para))
1435 deliver_status(ch, HW_MOD_CONNECT);
1436 else {
1437 ch->newmod = para;
1438 ch->newcmd = PCTRL_CMD_FRH;
1439 nom = 0;
1440 ctrl = PCTRL_CMD_ESC;
1441 ch->state = STFAX_ESCAPE;
1442 }
1443 break;
1444 case PCTRL_CMD_TDTMF:
1445 p1 = para;
1446 nom = 1;
1447 ctrl = PCTRL_CMD_TDTMF;
1448 break;
1449 }
1450 if (ctrl)
1451 send_mbox(ch->is, dps | ISAR_HIS_PUMPCTRL, ctrl, nom, &p1);
1452}
1453
1454static void
1455isar_setup(struct isar_hw *isar)
1456{
1457 u8 msg;
1458 int i;
1459
1460 /* Dpath 1, 2 */
1461 msg = 61;
1462 for (i = 0; i < 2; i++) {
1463 /* Buffer Config */
1464 send_mbox(isar, (i ? ISAR_HIS_DPS2 : ISAR_HIS_DPS1) |
1465 ISAR_HIS_P12CFG, 4, 1, &msg);
1466 isar->ch[i].mml = msg;
1467 isar->ch[i].bch.state = 0;
1468 isar->ch[i].dpath = i + 1;
1469 modeisar(&isar->ch[i], ISDN_P_NONE);
1470 }
1471}
1472
1473static int
1474isar_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1475{
1476 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1477 struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
1478 int ret = -EINVAL;
1479 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1480 u32 id, *val;
1481 u_long flags;
1482
1483 switch (hh->prim) {
1484 case PH_DATA_REQ:
1485 spin_lock_irqsave(ich->is->hwlock, flags);
1486 ret = bchannel_senddata(bch, skb);
1487 if (ret > 0) { /* direct TX */
1488 id = hh->id; /* skb can be freed */
1489 ret = 0;
1490 isar_fill_fifo(ich);
1491 spin_unlock_irqrestore(ich->is->hwlock, flags);
1492 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
1493 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
1494 } else
1495 spin_unlock_irqrestore(ich->is->hwlock, flags);
1496 return ret;
1497 case PH_ACTIVATE_REQ:
1498 spin_lock_irqsave(ich->is->hwlock, flags);
1499 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1500 ret = modeisar(ich, ch->protocol);
1501 else
1502 ret = 0;
1503 spin_unlock_irqrestore(ich->is->hwlock, flags);
1504 if (!ret)
1505 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
1506 NULL, GFP_KERNEL);
1507 break;
1508 case PH_DEACTIVATE_REQ:
1509 spin_lock_irqsave(ich->is->hwlock, flags);
1510 mISDN_clear_bchannel(bch);
1511 modeisar(ich, ISDN_P_NONE);
1512 spin_unlock_irqrestore(ich->is->hwlock, flags);
1513 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
1514 NULL, GFP_KERNEL);
1515 ret = 0;
1516 break;
1517 case PH_CONTROL_REQ:
1518 val = (u32 *)skb->data;
1519 pr_debug("%s: PH_CONTROL | REQUEST %x/%x\n", ich->is->name,
1520 hh->id, *val);
1521 if ((hh->id == 0) && ((*val & ~DTMF_TONE_MASK) ==
1522 DTMF_TONE_VAL)) {
1523 if (bch->state == ISDN_P_B_L2DTMF) {
1524 char tt = *val & DTMF_TONE_MASK;
1525
1526 if (tt == '*')
1527 tt = 0x1e;
1528 else if (tt == '#')
1529 tt = 0x1f;
1530 else if (tt > '9')
1531 tt -= 7;
1532 tt &= 0x1f;
1533 spin_lock_irqsave(ich->is->hwlock, flags);
1534 isar_pump_cmd(ich, PCTRL_CMD_TDTMF, tt);
1535 spin_unlock_irqrestore(ich->is->hwlock, flags);
1536 } else {
1537 pr_info("%s: DTMF send wrong protocol %x\n",
1538 __func__, bch->state);
1539 return -EINVAL;
1540 }
1541 } else if ((hh->id == HW_MOD_FRM) || (hh->id == HW_MOD_FRH) ||
1542 (hh->id == HW_MOD_FTM) || (hh->id == HW_MOD_FTH)) {
1543 for (id = 0; id < FAXMODCNT; id++)
1544 if (faxmodulation[id] == *val)
1545 break;
1546 if ((FAXMODCNT > id) &&
1547 test_bit(FLG_INITIALIZED, &bch->Flags)) {
1548 pr_debug("%s: isar: new mod\n", ich->is->name);
1549 isar_pump_cmd(ich, hh->id, *val);
1550 ret = 0;
1551 } else {
1552 pr_info("%s: wrong modulation\n",
1553 ich->is->name);
1554 ret = -EINVAL;
1555 }
1556 } else if (hh->id == HW_MOD_LASTDATA)
1557 test_and_set_bit(FLG_DLEETX, &bch->Flags);
1558 else {
1559 pr_info("%s: unknown PH_CONTROL_REQ %x\n",
1560 ich->is->name, hh->id);
1561 ret = -EINVAL;
1562 }
1563 default:
1564 pr_info("%s: %s unknown prim(%x,%x)\n",
1565 ich->is->name, __func__, hh->prim, hh->id);
1566 ret = -EINVAL;
1567 }
1568 if (!ret)
1569 dev_kfree_skb(skb);
1570 return ret;
1571}
1572
1573static int
1574channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1575{
1576 int ret = 0;
1577
1578 switch (cq->op) {
1579 case MISDN_CTRL_GETOP:
1580 cq->op = 0;
1581 break;
1582 /* Nothing implemented yet */
1583 case MISDN_CTRL_FILL_EMPTY:
1584 default:
1585 pr_info("%s: unknown Op %x\n", __func__, cq->op);
1586 ret = -EINVAL;
1587 break;
1588 }
1589 return ret;
1590}
1591
1592static int
1593isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1594{
1595 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1596 struct isar_ch *ich = container_of(bch, struct isar_ch, bch);
1597 int ret = -EINVAL;
1598 u_long flags;
1599
1600 pr_debug("%s: %s cmd:%x %p\n", ich->is->name, __func__, cmd, arg);
1601 switch (cmd) {
1602 case CLOSE_CHANNEL:
1603 test_and_clear_bit(FLG_OPEN, &bch->Flags);
1604 if (test_bit(FLG_ACTIVE, &bch->Flags)) {
1605 spin_lock_irqsave(ich->is->hwlock, flags);
1606 mISDN_freebchannel(bch);
1607 modeisar(ich, ISDN_P_NONE);
1608 spin_unlock_irqrestore(ich->is->hwlock, flags);
1609 } else {
1610 skb_queue_purge(&bch->rqueue);
1611 bch->rcount = 0;
1612 }
1613 ch->protocol = ISDN_P_NONE;
1614 ch->peer = NULL;
1615 module_put(ich->is->owner);
1616 ret = 0;
1617 break;
1618 case CONTROL_CHANNEL:
1619 ret = channel_bctrl(bch, arg);
1620 break;
1621 default:
1622 pr_info("%s: %s unknown prim(%x)\n",
1623 ich->is->name, __func__, cmd);
1624 }
1625 return ret;
1626}
1627
1628static void
1629free_isar(struct isar_hw *isar)
1630{
1631 modeisar(&isar->ch[0], ISDN_P_NONE);
1632 modeisar(&isar->ch[1], ISDN_P_NONE);
1633 del_timer(&isar->ch[0].ftimer);
1634 del_timer(&isar->ch[1].ftimer);
1635 test_and_clear_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
1636 test_and_clear_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
1637}
1638
1639static int
1640init_isar(struct isar_hw *isar)
1641{
1642 int cnt = 3;
1643
1644 while (cnt--) {
1645 isar->version = ISARVersion(isar);
1646 if (isar->ch[0].bch.debug & DEBUG_HW)
1647 pr_notice("%s: Testing version %d (%d time)\n",
1648 isar->name, isar->version, 3 - cnt);
1649 if (isar->version == 1)
1650 break;
1651 isar->ctrl(isar->hw, HW_RESET_REQ, 0);
1652 }
1653 if (isar->version != 1)
1654 return -EINVAL;
1655 isar->ch[0].ftimer.function = &ftimer_handler;
1656 isar->ch[0].ftimer.data = (long)&isar->ch[0];
1657 init_timer(&isar->ch[0].ftimer);
1658 test_and_set_bit(FLG_INITIALIZED, &isar->ch[0].bch.Flags);
1659 isar->ch[1].ftimer.function = &ftimer_handler;
1660 isar->ch[1].ftimer.data = (long)&isar->ch[1];
1661 init_timer(&isar->ch[1].ftimer);
1662 test_and_set_bit(FLG_INITIALIZED, &isar->ch[1].bch.Flags);
1663 return 0;
1664}
1665
1666static int
1667isar_open(struct isar_hw *isar, struct channel_req *rq)
1668{
1669 struct bchannel *bch;
1670
1671 if (rq->adr.channel > 2)
1672 return -EINVAL;
1673 if (rq->protocol == ISDN_P_NONE)
1674 return -EINVAL;
1675 bch = &isar->ch[rq->adr.channel - 1].bch;
1676 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1677 return -EBUSY; /* b-channel can be only open once */
1678 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1679 bch->ch.protocol = rq->protocol;
1680 rq->ch = &bch->ch;
1681 return 0;
1682}
1683
1684u32
1685mISDNisar_init(struct isar_hw *isar, void *hw)
1686{
1687 u32 ret, i;
1688
1689 isar->hw = hw;
1690 for (i = 0; i < 2; i++) {
1691 isar->ch[i].bch.nr = i + 1;
1692 mISDN_initbchannel(&isar->ch[i].bch, MAX_DATA_MEM);
1693 isar->ch[i].bch.ch.nr = i + 1;
1694 isar->ch[i].bch.ch.send = &isar_l2l1;
1695 isar->ch[i].bch.ch.ctrl = isar_bctrl;
1696 isar->ch[i].bch.hw = hw;
1697 isar->ch[i].is = isar;
1698 }
1699
1700 isar->init = &init_isar;
1701 isar->release = &free_isar;
1702 isar->firmware = &load_firmware;
1703 isar->open = &isar_open;
1704
1705 ret = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1706 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)) |
1707 (1 << (ISDN_P_B_L2DTMF & ISDN_P_B_MASK)) |
1708 (1 << (ISDN_P_B_MODEM_ASYNC & ISDN_P_B_MASK)) |
1709 (1 << (ISDN_P_B_T30_FAX & ISDN_P_B_MASK));
1710
1711 return ret;
1712}
1713EXPORT_SYMBOL(mISDNisar_init);
1714
1715static int isar_mod_init(void)
1716{
1717 pr_notice("mISDN: ISAR driver Rev. %s\n", ISAR_REV);
1718 return 0;
1719}
1720
1721static void isar_mod_cleanup(void)
1722{
1723 pr_notice("mISDN: ISAR module unloaded\n");
1724}
1725module_init(isar_mod_init);
1726module_exit(isar_mod_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c
new file mode 100644
index 000000000000..6c1b164937a9
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/netjet.c
@@ -0,0 +1,1156 @@
1/*
2 * NETJet mISDN driver
3 *
4 * Author Karsten Keil <keil@isdn4linux.de>
5 *
6 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26#include <linux/mISDNhw.h>
27#include "ipac.h"
28#include "iohelper.h"
29#include "netjet.h"
30#include <linux/isdn/hdlc.h>
31
32#define NETJET_REV "2.0"
33
34enum nj_types {
35 NETJET_S_TJ300,
36 NETJET_S_TJ320,
37 ENTERNOW__TJ320,
38};
39
40struct tiger_dma {
41 size_t size;
42 u32 *start;
43 int idx;
44 u32 dmastart;
45 u32 dmairq;
46 u32 dmaend;
47 u32 dmacur;
48};
49
50struct tiger_hw;
51
52struct tiger_ch {
53 struct bchannel bch;
54 struct tiger_hw *nj;
55 int idx;
56 int free;
57 int lastrx;
58 u16 rxstate;
59 u16 txstate;
60 struct isdnhdlc_vars hsend;
61 struct isdnhdlc_vars hrecv;
62 u8 *hsbuf;
63 u8 *hrbuf;
64};
65
66#define TX_INIT 0x0001
67#define TX_IDLE 0x0002
68#define TX_RUN 0x0004
69#define TX_UNDERRUN 0x0100
70#define RX_OVERRUN 0x0100
71
72#define LOG_SIZE 64
73
74struct tiger_hw {
75 struct list_head list;
76 struct pci_dev *pdev;
77 char name[MISDN_MAX_IDLEN];
78 enum nj_types typ;
79 int irq;
80 u32 irqcnt;
81 u32 base;
82 size_t base_s;
83 dma_addr_t dma;
84 void *dma_p;
85 spinlock_t lock; /* lock HW */
86 struct isac_hw isac;
87 struct tiger_dma send;
88 struct tiger_dma recv;
89 struct tiger_ch bc[2];
90 u8 ctrlreg;
91 u8 dmactrl;
92 u8 auxd;
93 u8 last_is0;
94 u8 irqmask0;
95 char log[LOG_SIZE];
96};
97
98static LIST_HEAD(Cards);
99static DEFINE_RWLOCK(card_lock); /* protect Cards */
100static u32 debug;
101static int nj_cnt;
102
103static void
104_set_debug(struct tiger_hw *card)
105{
106 card->isac.dch.debug = debug;
107 card->bc[0].bch.debug = debug;
108 card->bc[1].bch.debug = debug;
109}
110
111static int
112set_debug(const char *val, struct kernel_param *kp)
113{
114 int ret;
115 struct tiger_hw *card;
116
117 ret = param_set_uint(val, kp);
118 if (!ret) {
119 read_lock(&card_lock);
120 list_for_each_entry(card, &Cards, list)
121 _set_debug(card);
122 read_unlock(&card_lock);
123 }
124 return ret;
125}
126
127MODULE_AUTHOR("Karsten Keil");
128MODULE_LICENSE("GPL v2");
129MODULE_VERSION(NETJET_REV);
130module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
131MODULE_PARM_DESC(debug, "Netjet debug mask");
132
133static void
134nj_disable_hwirq(struct tiger_hw *card)
135{
136 outb(0, card->base + NJ_IRQMASK0);
137 outb(0, card->base + NJ_IRQMASK1);
138}
139
140
141static u8
142ReadISAC_nj(void *p, u8 offset)
143{
144 struct tiger_hw *card = p;
145 u8 ret;
146
147 card->auxd &= 0xfc;
148 card->auxd |= (offset >> 4) & 3;
149 outb(card->auxd, card->base + NJ_AUXDATA);
150 ret = inb(card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
151 return ret;
152}
153
154static void
155WriteISAC_nj(void *p, u8 offset, u8 value)
156{
157 struct tiger_hw *card = p;
158
159 card->auxd &= 0xfc;
160 card->auxd |= (offset >> 4) & 3;
161 outb(card->auxd, card->base + NJ_AUXDATA);
162 outb(value, card->base + NJ_ISAC_OFF + ((offset & 0x0f) << 2));
163}
164
165static void
166ReadFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
167{
168 struct tiger_hw *card = p;
169
170 card->auxd &= 0xfc;
171 outb(card->auxd, card->base + NJ_AUXDATA);
172 insb(card->base + NJ_ISAC_OFF, data, size);
173}
174
175static void
176WriteFiFoISAC_nj(void *p, u8 offset, u8 *data, int size)
177{
178 struct tiger_hw *card = p;
179
180 card->auxd &= 0xfc;
181 outb(card->auxd, card->base + NJ_AUXDATA);
182 outsb(card->base + NJ_ISAC_OFF, data, size);
183}
184
185static void
186fill_mem(struct tiger_ch *bc, u32 idx, u32 cnt, u32 fill)
187{
188 struct tiger_hw *card = bc->bch.hw;
189 u32 mask = 0xff, val;
190
191 pr_debug("%s: B%1d fill %02x len %d idx %d/%d\n", card->name,
192 bc->bch.nr, fill, cnt, idx, card->send.idx);
193 if (bc->bch.nr & 2) {
194 fill <<= 8;
195 mask <<= 8;
196 }
197 mask ^= 0xffffffff;
198 while (cnt--) {
199 val = card->send.start[idx];
200 val &= mask;
201 val |= fill;
202 card->send.start[idx++] = val;
203 if (idx >= card->send.size)
204 idx = 0;
205 }
206}
207
208static int
209mode_tiger(struct tiger_ch *bc, u32 protocol)
210{
211 struct tiger_hw *card = bc->bch.hw;
212
213 pr_debug("%s: B%1d protocol %x-->%x\n", card->name,
214 bc->bch.nr, bc->bch.state, protocol);
215 switch (protocol) {
216 case ISDN_P_NONE:
217 if (bc->bch.state == ISDN_P_NONE)
218 break;
219 fill_mem(bc, 0, card->send.size, 0xff);
220 bc->bch.state = protocol;
221 /* only stop dma and interrupts if both channels NULL */
222 if ((card->bc[0].bch.state == ISDN_P_NONE) &&
223 (card->bc[1].bch.state == ISDN_P_NONE)) {
224 card->dmactrl = 0;
225 outb(card->dmactrl, card->base + NJ_DMACTRL);
226 outb(0, card->base + NJ_IRQMASK0);
227 }
228 test_and_clear_bit(FLG_HDLC, &bc->bch.Flags);
229 test_and_clear_bit(FLG_TRANSPARENT, &bc->bch.Flags);
230 bc->txstate = 0;
231 bc->rxstate = 0;
232 bc->lastrx = -1;
233 break;
234 case ISDN_P_B_RAW:
235 test_and_set_bit(FLG_TRANSPARENT, &bc->bch.Flags);
236 bc->bch.state = protocol;
237 bc->idx = 0;
238 bc->free = card->send.size/2;
239 bc->rxstate = 0;
240 bc->txstate = TX_INIT | TX_IDLE;
241 bc->lastrx = -1;
242 if (!card->dmactrl) {
243 card->dmactrl = 1;
244 outb(card->dmactrl, card->base + NJ_DMACTRL);
245 outb(0x0f, card->base + NJ_IRQMASK0);
246 }
247 break;
248 case ISDN_P_B_HDLC:
249 test_and_set_bit(FLG_HDLC, &bc->bch.Flags);
250 bc->bch.state = protocol;
251 bc->idx = 0;
252 bc->free = card->send.size/2;
253 bc->rxstate = 0;
254 bc->txstate = TX_INIT | TX_IDLE;
255 isdnhdlc_rcv_init(&bc->hrecv, 0);
256 isdnhdlc_out_init(&bc->hsend, 0);
257 bc->lastrx = -1;
258 if (!card->dmactrl) {
259 card->dmactrl = 1;
260 outb(card->dmactrl, card->base + NJ_DMACTRL);
261 outb(0x0f, card->base + NJ_IRQMASK0);
262 }
263 break;
264 default:
265 pr_info("%s: %s protocol %x not handled\n", card->name,
266 __func__, protocol);
267 return -ENOPROTOOPT;
268 }
269 card->send.dmacur = inl(card->base + NJ_DMA_READ_ADR);
270 card->recv.dmacur = inl(card->base + NJ_DMA_WRITE_ADR);
271 card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
272 card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
273 pr_debug("%s: %s ctrl %x irq %02x/%02x idx %d/%d\n",
274 card->name, __func__,
275 inb(card->base + NJ_DMACTRL),
276 inb(card->base + NJ_IRQMASK0),
277 inb(card->base + NJ_IRQSTAT0),
278 card->send.idx,
279 card->recv.idx);
280 return 0;
281}
282
283static void
284nj_reset(struct tiger_hw *card)
285{
286 outb(0xff, card->base + NJ_CTRL); /* Reset On */
287 mdelay(1);
288
289 /* now edge triggered for TJ320 GE 13/07/00 */
290 /* see comment in IRQ function */
291 if (card->typ == NETJET_S_TJ320) /* TJ320 */
292 card->ctrlreg = 0x40; /* Reset Off and status read clear */
293 else
294 card->ctrlreg = 0x00; /* Reset Off and status read clear */
295 outb(card->ctrlreg, card->base + NJ_CTRL);
296 mdelay(10);
297
298 /* configure AUX pins (all output except ISAC IRQ pin) */
299 card->auxd = 0;
300 card->dmactrl = 0;
301 outb(~NJ_ISACIRQ, card->base + NJ_AUXCTRL);
302 outb(NJ_ISACIRQ, card->base + NJ_IRQMASK1);
303 outb(card->auxd, card->base + NJ_AUXDATA);
304}
305
306static int
307inittiger(struct tiger_hw *card)
308{
309 int i;
310
311 card->dma_p = pci_alloc_consistent(card->pdev, NJ_DMA_SIZE,
312 &card->dma);
313 if (!card->dma_p) {
314 pr_info("%s: No DMA memory\n", card->name);
315 return -ENOMEM;
316 }
317 if ((u64)card->dma > 0xffffffff) {
318 pr_info("%s: DMA outside 32 bit\n", card->name);
319 return -ENOMEM;
320 }
321 for (i = 0; i < 2; i++) {
322 card->bc[i].hsbuf = kmalloc(NJ_DMA_TXSIZE, GFP_KERNEL);
323 if (!card->bc[i].hsbuf) {
324 pr_info("%s: no B%d send buffer\n", card->name, i + 1);
325 return -ENOMEM;
326 }
327 card->bc[i].hrbuf = kmalloc(NJ_DMA_RXSIZE, GFP_KERNEL);
328 if (!card->bc[i].hrbuf) {
329 pr_info("%s: no B%d recv buffer\n", card->name, i + 1);
330 return -ENOMEM;
331 }
332 }
333 memset(card->dma_p, 0xff, NJ_DMA_SIZE);
334
335 card->send.start = card->dma_p;
336 card->send.dmastart = (u32)card->dma;
337 card->send.dmaend = card->send.dmastart +
338 (4 * (NJ_DMA_TXSIZE - 1));
339 card->send.dmairq = card->send.dmastart +
340 (4 * ((NJ_DMA_TXSIZE / 2) - 1));
341 card->send.size = NJ_DMA_TXSIZE;
342
343 if (debug & DEBUG_HW)
344 pr_notice("%s: send buffer phy %#x - %#x - %#x virt %p"
345 " size %zu u32\n", card->name,
346 card->send.dmastart, card->send.dmairq,
347 card->send.dmaend, card->send.start, card->send.size);
348
349 outl(card->send.dmastart, card->base + NJ_DMA_READ_START);
350 outl(card->send.dmairq, card->base + NJ_DMA_READ_IRQ);
351 outl(card->send.dmaend, card->base + NJ_DMA_READ_END);
352
353 card->recv.start = card->dma_p + (NJ_DMA_SIZE / 2);
354 card->recv.dmastart = (u32)card->dma + (NJ_DMA_SIZE / 2);
355 card->recv.dmaend = card->recv.dmastart +
356 (4 * (NJ_DMA_RXSIZE - 1));
357 card->recv.dmairq = card->recv.dmastart +
358 (4 * ((NJ_DMA_RXSIZE / 2) - 1));
359 card->recv.size = NJ_DMA_RXSIZE;
360
361 if (debug & DEBUG_HW)
362 pr_notice("%s: recv buffer phy %#x - %#x - %#x virt %p"
363 " size %zu u32\n", card->name,
364 card->recv.dmastart, card->recv.dmairq,
365 card->recv.dmaend, card->recv.start, card->recv.size);
366
367 outl(card->recv.dmastart, card->base + NJ_DMA_WRITE_START);
368 outl(card->recv.dmairq, card->base + NJ_DMA_WRITE_IRQ);
369 outl(card->recv.dmaend, card->base + NJ_DMA_WRITE_END);
370 return 0;
371}
372
373static void
374read_dma(struct tiger_ch *bc, u32 idx, int cnt)
375{
376 struct tiger_hw *card = bc->bch.hw;
377 int i, stat;
378 u32 val;
379 u8 *p, *pn;
380
381 if (bc->lastrx == idx) {
382 bc->rxstate |= RX_OVERRUN;
383 pr_info("%s: B%1d overrun at idx %d\n", card->name,
384 bc->bch.nr, idx);
385 }
386 bc->lastrx = idx;
387 if (!bc->bch.rx_skb) {
388 bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen, GFP_ATOMIC);
389 if (!bc->bch.rx_skb) {
390 pr_info("%s: B%1d receive out of memory\n",
391 card->name, bc->bch.nr);
392 return;
393 }
394 }
395
396 if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags)) {
397 if ((bc->bch.rx_skb->len + cnt) > bc->bch.maxlen) {
398 pr_debug("%s: B%1d overrun %d\n", card->name,
399 bc->bch.nr, bc->bch.rx_skb->len + cnt);
400 skb_trim(bc->bch.rx_skb, 0);
401 return;
402 }
403 p = skb_put(bc->bch.rx_skb, cnt);
404 } else
405 p = bc->hrbuf;
406
407 for (i = 0; i < cnt; i++) {
408 val = card->recv.start[idx++];
409 if (bc->bch.nr & 2)
410 val >>= 8;
411 if (idx >= card->recv.size)
412 idx = 0;
413 p[i] = val & 0xff;
414 }
415 pn = bc->hrbuf;
416next_frame:
417 if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
418 stat = isdnhdlc_decode(&bc->hrecv, pn, cnt, &i,
419 bc->bch.rx_skb->data, bc->bch.maxlen);
420 if (stat > 0) /* valid frame received */
421 p = skb_put(bc->bch.rx_skb, stat);
422 else if (stat == -HDLC_CRC_ERROR)
423 pr_info("%s: B%1d receive frame CRC error\n",
424 card->name, bc->bch.nr);
425 else if (stat == -HDLC_FRAMING_ERROR)
426 pr_info("%s: B%1d receive framing error\n",
427 card->name, bc->bch.nr);
428 else if (stat == -HDLC_LENGTH_ERROR)
429 pr_info("%s: B%1d receive frame too long (> %d)\n",
430 card->name, bc->bch.nr, bc->bch.maxlen);
431 } else
432 stat = cnt;
433
434 if (stat > 0) {
435 if (debug & DEBUG_HW_BFIFO) {
436 snprintf(card->log, LOG_SIZE, "B%1d-recv %s %d ",
437 bc->bch.nr, card->name, stat);
438 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET,
439 p, stat);
440 }
441 recv_Bchannel(&bc->bch, 0);
442 }
443 if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
444 pn += i;
445 cnt -= i;
446 if (!bc->bch.rx_skb) {
447 bc->bch.rx_skb = mI_alloc_skb(bc->bch.maxlen,
448 GFP_ATOMIC);
449 if (!bc->bch.rx_skb) {
450 pr_info("%s: B%1d receive out of memory\n",
451 card->name, bc->bch.nr);
452 return;
453 }
454 }
455 if (cnt > 0)
456 goto next_frame;
457 }
458}
459
460static void
461recv_tiger(struct tiger_hw *card, u8 irq_stat)
462{
463 u32 idx;
464 int cnt = card->recv.size / 2;
465
466 /* Note receive is via the WRITE DMA channel */
467 card->last_is0 &= ~NJ_IRQM0_WR_MASK;
468 card->last_is0 |= (irq_stat & NJ_IRQM0_WR_MASK);
469
470 if (irq_stat & NJ_IRQM0_WR_END)
471 idx = cnt - 1;
472 else
473 idx = card->recv.size - 1;
474
475 if (test_bit(FLG_ACTIVE, &card->bc[0].bch.Flags))
476 read_dma(&card->bc[0], idx, cnt);
477 if (test_bit(FLG_ACTIVE, &card->bc[1].bch.Flags))
478 read_dma(&card->bc[1], idx, cnt);
479}
480
481/* sync with current DMA address at start or after exception */
482static void
483resync(struct tiger_ch *bc, struct tiger_hw *card)
484{
485 card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
486 card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
487 if (bc->free > card->send.size / 2)
488 bc->free = card->send.size / 2;
489 /* currently we simple sync to the next complete free area
490 * this hast the advantage that we have always maximum time to
491 * handle TX irq
492 */
493 if (card->send.idx < ((card->send.size / 2) - 1))
494 bc->idx = (card->recv.size / 2) - 1;
495 else
496 bc->idx = card->recv.size - 1;
497 bc->txstate = TX_RUN;
498 pr_debug("%s: %s B%1d free %d idx %d/%d\n", card->name,
499 __func__, bc->bch.nr, bc->free, bc->idx, card->send.idx);
500}
501
502static int bc_next_frame(struct tiger_ch *);
503
504static void
505fill_hdlc_flag(struct tiger_ch *bc)
506{
507 struct tiger_hw *card = bc->bch.hw;
508 int count, i;
509 u32 m, v;
510 u8 *p;
511
512 if (bc->free == 0)
513 return;
514 pr_debug("%s: %s B%1d %d state %x idx %d/%d\n", card->name,
515 __func__, bc->bch.nr, bc->free, bc->txstate,
516 bc->idx, card->send.idx);
517 if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
518 resync(bc, card);
519 count = isdnhdlc_encode(&bc->hsend, NULL, 0, &i,
520 bc->hsbuf, bc->free);
521 pr_debug("%s: B%1d hdlc encoded %d flags\n", card->name,
522 bc->bch.nr, count);
523 bc->free -= count;
524 p = bc->hsbuf;
525 m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
526 for (i = 0; i < count; i++) {
527 if (bc->idx >= card->send.size)
528 bc->idx = 0;
529 v = card->send.start[bc->idx];
530 v &= m;
531 v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8;
532 card->send.start[bc->idx++] = v;
533 }
534 if (debug & DEBUG_HW_BFIFO) {
535 snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
536 bc->bch.nr, card->name, count);
537 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
538 }
539}
540
541static void
542fill_dma(struct tiger_ch *bc)
543{
544 struct tiger_hw *card = bc->bch.hw;
545 int count, i;
546 u32 m, v;
547 u8 *p;
548
549 if (bc->free == 0)
550 return;
551 count = bc->bch.tx_skb->len - bc->bch.tx_idx;
552 if (count <= 0)
553 return;
554 pr_debug("%s: %s B%1d %d/%d/%d/%d state %x idx %d/%d\n", card->name,
555 __func__, bc->bch.nr, count, bc->free, bc->bch.tx_idx,
556 bc->bch.tx_skb->len, bc->txstate, bc->idx, card->send.idx);
557 if (bc->txstate & (TX_IDLE | TX_INIT | TX_UNDERRUN))
558 resync(bc, card);
559 p = bc->bch.tx_skb->data + bc->bch.tx_idx;
560 if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
561 count = isdnhdlc_encode(&bc->hsend, p, count, &i,
562 bc->hsbuf, bc->free);
563 pr_debug("%s: B%1d hdlc encoded %d in %d\n", card->name,
564 bc->bch.nr, i, count);
565 bc->bch.tx_idx += i;
566 bc->free -= count;
567 p = bc->hsbuf;
568 } else {
569 if (count > bc->free)
570 count = bc->free;
571 bc->bch.tx_idx += count;
572 bc->free -= count;
573 }
574 m = (bc->bch.nr & 1) ? 0xffffff00 : 0xffff00ff;
575 for (i = 0; i < count; i++) {
576 if (bc->idx >= card->send.size)
577 bc->idx = 0;
578 v = card->send.start[bc->idx];
579 v &= m;
580 v |= (bc->bch.nr & 1) ? (u32)(p[i]) : ((u32)(p[i])) << 8;
581 card->send.start[bc->idx++] = v;
582 }
583 if (debug & DEBUG_HW_BFIFO) {
584 snprintf(card->log, LOG_SIZE, "B%1d-send %s %d ",
585 bc->bch.nr, card->name, count);
586 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, p, count);
587 }
588 if (bc->free)
589 bc_next_frame(bc);
590}
591
592
593static int
594bc_next_frame(struct tiger_ch *bc)
595{
596 if (bc->bch.tx_skb && bc->bch.tx_idx < bc->bch.tx_skb->len)
597 fill_dma(bc);
598 else {
599 if (bc->bch.tx_skb) {
600 /* send confirm, on trans, free on hdlc. */
601 if (test_bit(FLG_TRANSPARENT, &bc->bch.Flags))
602 confirm_Bsend(&bc->bch);
603 dev_kfree_skb(bc->bch.tx_skb);
604 }
605 if (get_next_bframe(&bc->bch))
606 fill_dma(bc);
607 else
608 return 0;
609 }
610 return 1;
611}
612
613static void
614send_tiger_bc(struct tiger_hw *card, struct tiger_ch *bc)
615{
616 int ret;
617
618 bc->free += card->send.size / 2;
619 if (bc->free >= card->send.size) {
620 if (!(bc->txstate & (TX_UNDERRUN | TX_INIT))) {
621 pr_info("%s: B%1d TX underrun state %x\n", card->name,
622 bc->bch.nr, bc->txstate);
623 bc->txstate |= TX_UNDERRUN;
624 }
625 bc->free = card->send.size;
626 }
627 ret = bc_next_frame(bc);
628 if (!ret) {
629 if (test_bit(FLG_HDLC, &bc->bch.Flags)) {
630 fill_hdlc_flag(bc);
631 return;
632 }
633 pr_debug("%s: B%1d TX no data free %d idx %d/%d\n", card->name,
634 bc->bch.nr, bc->free, bc->idx, card->send.idx);
635 if (!(bc->txstate & (TX_IDLE | TX_INIT))) {
636 fill_mem(bc, bc->idx, bc->free, 0xff);
637 if (bc->free == card->send.size)
638 bc->txstate |= TX_IDLE;
639 }
640 }
641}
642
643static void
644send_tiger(struct tiger_hw *card, u8 irq_stat)
645{
646 int i;
647
648 /* Note send is via the READ DMA channel */
649 if ((irq_stat & card->last_is0) & NJ_IRQM0_RD_MASK) {
650 pr_info("%s: tiger warn write double dma %x/%x\n",
651 card->name, irq_stat, card->last_is0);
652 return;
653 } else {
654 card->last_is0 &= ~NJ_IRQM0_RD_MASK;
655 card->last_is0 |= (irq_stat & NJ_IRQM0_RD_MASK);
656 }
657 for (i = 0; i < 2; i++) {
658 if (test_bit(FLG_ACTIVE, &card->bc[i].bch.Flags))
659 send_tiger_bc(card, &card->bc[i]);
660 }
661}
662
663static irqreturn_t
664nj_irq(int intno, void *dev_id)
665{
666 struct tiger_hw *card = dev_id;
667 u8 val, s1val, s0val;
668
669 spin_lock(&card->lock);
670 s0val = inb(card->base | NJ_IRQSTAT0);
671 s1val = inb(card->base | NJ_IRQSTAT1);
672 if ((s1val & NJ_ISACIRQ) && (s0val == 0)) {
673 /* shared IRQ */
674 spin_unlock(&card->lock);
675 return IRQ_NONE;
676 }
677 pr_debug("%s: IRQSTAT0 %02x IRQSTAT1 %02x\n", card->name, s0val, s1val);
678 card->irqcnt++;
679 if (!(s1val & NJ_ISACIRQ)) {
680 val = ReadISAC_nj(card, ISAC_ISTA);
681 if (val)
682 mISDNisac_irq(&card->isac, val);
683 }
684
685 if (s0val)
686 /* write to clear */
687 outb(s0val, card->base | NJ_IRQSTAT0);
688 else
689 goto end;
690 s1val = s0val;
691 /* set bits in sval to indicate which page is free */
692 card->recv.dmacur = inl(card->base | NJ_DMA_WRITE_ADR);
693 card->recv.idx = (card->recv.dmacur - card->recv.dmastart) >> 2;
694 if (card->recv.dmacur < card->recv.dmairq)
695 s0val = 0x08; /* the 2nd write area is free */
696 else
697 s0val = 0x04; /* the 1st write area is free */
698
699 card->send.dmacur = inl(card->base | NJ_DMA_READ_ADR);
700 card->send.idx = (card->send.dmacur - card->send.dmastart) >> 2;
701 if (card->send.dmacur < card->send.dmairq)
702 s0val |= 0x02; /* the 2nd read area is free */
703 else
704 s0val |= 0x01; /* the 1st read area is free */
705
706 pr_debug("%s: DMA Status %02x/%02x/%02x %d/%d\n", card->name,
707 s1val, s0val, card->last_is0,
708 card->recv.idx, card->send.idx);
709 /* test if we have a DMA interrupt */
710 if (s0val != card->last_is0) {
711 if ((s0val & NJ_IRQM0_RD_MASK) !=
712 (card->last_is0 & NJ_IRQM0_RD_MASK))
713 /* got a write dma int */
714 send_tiger(card, s0val);
715 if ((s0val & NJ_IRQM0_WR_MASK) !=
716 (card->last_is0 & NJ_IRQM0_WR_MASK))
717 /* got a read dma int */
718 recv_tiger(card, s0val);
719 }
720end:
721 spin_unlock(&card->lock);
722 return IRQ_HANDLED;
723}
724
725static int
726nj_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
727{
728 int ret = -EINVAL;
729 struct bchannel *bch = container_of(ch, struct bchannel, ch);
730 struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
731 struct tiger_hw *card = bch->hw;
732 struct mISDNhead *hh = mISDN_HEAD_P(skb);
733 u32 id;
734 u_long flags;
735
736 switch (hh->prim) {
737 case PH_DATA_REQ:
738 spin_lock_irqsave(&card->lock, flags);
739 ret = bchannel_senddata(bch, skb);
740 if (ret > 0) { /* direct TX */
741 id = hh->id; /* skb can be freed */
742 fill_dma(bc);
743 ret = 0;
744 spin_unlock_irqrestore(&card->lock, flags);
745 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
746 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
747 } else
748 spin_unlock_irqrestore(&card->lock, flags);
749 return ret;
750 case PH_ACTIVATE_REQ:
751 spin_lock_irqsave(&card->lock, flags);
752 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
753 ret = mode_tiger(bc, ch->protocol);
754 else
755 ret = 0;
756 spin_unlock_irqrestore(&card->lock, flags);
757 if (!ret)
758 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
759 NULL, GFP_KERNEL);
760 break;
761 case PH_DEACTIVATE_REQ:
762 spin_lock_irqsave(&card->lock, flags);
763 mISDN_clear_bchannel(bch);
764 mode_tiger(bc, ISDN_P_NONE);
765 spin_unlock_irqrestore(&card->lock, flags);
766 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
767 NULL, GFP_KERNEL);
768 ret = 0;
769 break;
770 }
771 if (!ret)
772 dev_kfree_skb(skb);
773 return ret;
774}
775
776static int
777channel_bctrl(struct tiger_ch *bc, struct mISDN_ctrl_req *cq)
778{
779 int ret = 0;
780 struct tiger_hw *card = bc->bch.hw;
781
782 switch (cq->op) {
783 case MISDN_CTRL_GETOP:
784 cq->op = 0;
785 break;
786 /* Nothing implemented yet */
787 case MISDN_CTRL_FILL_EMPTY:
788 default:
789 pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
790 ret = -EINVAL;
791 break;
792 }
793 return ret;
794}
795
796static int
797nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
798{
799 struct bchannel *bch = container_of(ch, struct bchannel, ch);
800 struct tiger_ch *bc = container_of(bch, struct tiger_ch, bch);
801 struct tiger_hw *card = bch->hw;
802 int ret = -EINVAL;
803 u_long flags;
804
805 pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
806 switch (cmd) {
807 case CLOSE_CHANNEL:
808 test_and_clear_bit(FLG_OPEN, &bch->Flags);
809 if (test_bit(FLG_ACTIVE, &bch->Flags)) {
810 spin_lock_irqsave(&card->lock, flags);
811 mISDN_freebchannel(bch);
812 test_and_clear_bit(FLG_TX_BUSY, &bch->Flags);
813 test_and_clear_bit(FLG_ACTIVE, &bch->Flags);
814 mode_tiger(bc, ISDN_P_NONE);
815 spin_unlock_irqrestore(&card->lock, flags);
816 }
817 ch->protocol = ISDN_P_NONE;
818 ch->peer = NULL;
819 module_put(THIS_MODULE);
820 ret = 0;
821 break;
822 case CONTROL_CHANNEL:
823 ret = channel_bctrl(bc, arg);
824 break;
825 default:
826 pr_info("%s: %s unknown prim(%x)\n", card->name, __func__, cmd);
827 }
828 return ret;
829}
830
831static int
832channel_ctrl(struct tiger_hw *card, struct mISDN_ctrl_req *cq)
833{
834 int ret = 0;
835
836 switch (cq->op) {
837 case MISDN_CTRL_GETOP:
838 cq->op = MISDN_CTRL_LOOP;
839 break;
840 case MISDN_CTRL_LOOP:
841 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
842 if (cq->channel < 0 || cq->channel > 3) {
843 ret = -EINVAL;
844 break;
845 }
846 ret = card->isac.ctrl(&card->isac, HW_TESTLOOP, cq->channel);
847 break;
848 default:
849 pr_info("%s: %s unknown Op %x\n", card->name, __func__, cq->op);
850 ret = -EINVAL;
851 break;
852 }
853 return ret;
854}
855
856static int
857open_bchannel(struct tiger_hw *card, struct channel_req *rq)
858{
859 struct bchannel *bch;
860
861 if (rq->adr.channel > 2)
862 return -EINVAL;
863 if (rq->protocol == ISDN_P_NONE)
864 return -EINVAL;
865 bch = &card->bc[rq->adr.channel - 1].bch;
866 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
867 return -EBUSY; /* b-channel can be only open once */
868 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
869 bch->ch.protocol = rq->protocol;
870 rq->ch = &bch->ch;
871 return 0;
872}
873
874/*
875 * device control function
876 */
877static int
878nj_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
879{
880 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
881 struct dchannel *dch = container_of(dev, struct dchannel, dev);
882 struct tiger_hw *card = dch->hw;
883 struct channel_req *rq;
884 int err = 0;
885
886 pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
887 switch (cmd) {
888 case OPEN_CHANNEL:
889 rq = arg;
890 if (rq->protocol == ISDN_P_TE_S0)
891 err = card->isac.open(&card->isac, rq);
892 else
893 err = open_bchannel(card, rq);
894 if (err)
895 break;
896 if (!try_module_get(THIS_MODULE))
897 pr_info("%s: cannot get module\n", card->name);
898 break;
899 case CLOSE_CHANNEL:
900 pr_debug("%s: dev(%d) close from %p\n", card->name, dch->dev.id,
901 __builtin_return_address(0));
902 module_put(THIS_MODULE);
903 break;
904 case CONTROL_CHANNEL:
905 err = channel_ctrl(card, arg);
906 break;
907 default:
908 pr_debug("%s: %s unknown command %x\n",
909 card->name, __func__, cmd);
910 return -EINVAL;
911 }
912 return err;
913}
914
915static int
916nj_init_card(struct tiger_hw *card)
917{
918 u_long flags;
919 int ret;
920
921 spin_lock_irqsave(&card->lock, flags);
922 nj_disable_hwirq(card);
923 spin_unlock_irqrestore(&card->lock, flags);
924
925 card->irq = card->pdev->irq;
926 if (request_irq(card->irq, nj_irq, IRQF_SHARED, card->name, card)) {
927 pr_info("%s: couldn't get interrupt %d\n",
928 card->name, card->irq);
929 card->irq = -1;
930 return -EIO;
931 }
932
933 spin_lock_irqsave(&card->lock, flags);
934 nj_reset(card);
935 ret = card->isac.init(&card->isac);
936 if (ret)
937 goto error;
938 ret = inittiger(card);
939 if (ret)
940 goto error;
941 mode_tiger(&card->bc[0], ISDN_P_NONE);
942 mode_tiger(&card->bc[1], ISDN_P_NONE);
943error:
944 spin_unlock_irqrestore(&card->lock, flags);
945 return ret;
946}
947
948
949static void
950nj_release(struct tiger_hw *card)
951{
952 u_long flags;
953 int i;
954
955 if (card->base_s) {
956 spin_lock_irqsave(&card->lock, flags);
957 nj_disable_hwirq(card);
958 mode_tiger(&card->bc[0], ISDN_P_NONE);
959 mode_tiger(&card->bc[1], ISDN_P_NONE);
960 card->isac.release(&card->isac);
961 spin_unlock_irqrestore(&card->lock, flags);
962 release_region(card->base, card->base_s);
963 card->base_s = 0;
964 }
965 if (card->irq > 0)
966 free_irq(card->irq, card);
967 if (card->isac.dch.dev.dev.class)
968 mISDN_unregister_device(&card->isac.dch.dev);
969
970 for (i = 0; i < 2; i++) {
971 mISDN_freebchannel(&card->bc[i].bch);
972 kfree(card->bc[i].hsbuf);
973 kfree(card->bc[i].hrbuf);
974 }
975 if (card->dma_p)
976 pci_free_consistent(card->pdev, NJ_DMA_SIZE,
977 card->dma_p, card->dma);
978 write_lock_irqsave(&card_lock, flags);
979 list_del(&card->list);
980 write_unlock_irqrestore(&card_lock, flags);
981 pci_clear_master(card->pdev);
982 pci_disable_device(card->pdev);
983 pci_set_drvdata(card->pdev, NULL);
984 kfree(card);
985}
986
987
988static int
989nj_setup(struct tiger_hw *card)
990{
991 card->base = pci_resource_start(card->pdev, 0);
992 card->base_s = pci_resource_len(card->pdev, 0);
993 if (!request_region(card->base, card->base_s, card->name)) {
994 pr_info("%s: NETjet config port %#x-%#x already in use\n",
995 card->name, card->base,
996 (u32)(card->base + card->base_s - 1));
997 card->base_s = 0;
998 return -EIO;
999 }
1000 ASSIGN_FUNC(nj, ISAC, card->isac);
1001 return 0;
1002}
1003
1004
1005static int __devinit
1006setup_instance(struct tiger_hw *card)
1007{
1008 int i, err;
1009 u_long flags;
1010
1011 snprintf(card->name, MISDN_MAX_IDLEN - 1, "netjet.%d", nj_cnt + 1);
1012 write_lock_irqsave(&card_lock, flags);
1013 list_add_tail(&card->list, &Cards);
1014 write_unlock_irqrestore(&card_lock, flags);
1015
1016 _set_debug(card);
1017 card->isac.name = card->name;
1018 spin_lock_init(&card->lock);
1019 card->isac.hwlock = &card->lock;
1020 mISDNisac_init(&card->isac, card);
1021
1022 card->isac.dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1023 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1024 card->isac.dch.dev.D.ctrl = nj_dctrl;
1025 for (i = 0; i < 2; i++) {
1026 card->bc[i].bch.nr = i + 1;
1027 set_channelmap(i + 1, card->isac.dch.dev.channelmap);
1028 mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM);
1029 card->bc[i].bch.hw = card;
1030 card->bc[i].bch.ch.send = nj_l2l1B;
1031 card->bc[i].bch.ch.ctrl = nj_bctrl;
1032 card->bc[i].bch.ch.nr = i + 1;
1033 list_add(&card->bc[i].bch.ch.list,
1034 &card->isac.dch.dev.bchannels);
1035 card->bc[i].bch.hw = card;
1036 }
1037 err = nj_setup(card);
1038 if (err)
1039 goto error;
1040 err = mISDN_register_device(&card->isac.dch.dev, &card->pdev->dev,
1041 card->name);
1042 if (err)
1043 goto error;
1044 err = nj_init_card(card);
1045 if (!err) {
1046 nj_cnt++;
1047 pr_notice("Netjet %d cards installed\n", nj_cnt);
1048 return 0;
1049 }
1050error:
1051 nj_release(card);
1052 return err;
1053}
1054
1055static int __devinit
1056nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1057{
1058 int err = -ENOMEM;
1059 int cfg;
1060 struct tiger_hw *card;
1061
1062 if (pdev->subsystem_vendor == 0x8086 &&
1063 pdev->subsystem_device == 0x0003) {
1064 pr_notice("Netjet: Digium X100P/X101P not handled\n");
1065 return -ENODEV;
1066 }
1067
1068 if (pdev->subsystem_vendor == 0x55 &&
1069 pdev->subsystem_device == 0x02) {
1070 pr_notice("Netjet: Enter!Now not handled yet\n");
1071 return -ENODEV;
1072 }
1073
1074 card = kzalloc(sizeof(struct tiger_hw), GFP_ATOMIC);
1075 if (!card) {
1076 pr_info("No kmem for Netjet\n");
1077 return err;
1078 }
1079
1080 card->pdev = pdev;
1081
1082 err = pci_enable_device(pdev);
1083 if (err) {
1084 kfree(card);
1085 return err;
1086 }
1087
1088 printk(KERN_INFO "nj_probe(mISDN): found adapter at %s\n",
1089 pci_name(pdev));
1090
1091 pci_set_master(pdev);
1092
1093 /* the TJ300 and TJ320 must be detected, the IRQ handling is different
1094 * unfortunately the chips use the same device ID, but the TJ320 has
1095 * the bit20 in status PCI cfg register set
1096 */
1097 pci_read_config_dword(pdev, 0x04, &cfg);
1098 if (cfg & 0x00100000)
1099 card->typ = NETJET_S_TJ320;
1100 else
1101 card->typ = NETJET_S_TJ300;
1102
1103 card->base = pci_resource_start(pdev, 0);
1104 card->irq = pdev->irq;
1105 pci_set_drvdata(pdev, card);
1106 err = setup_instance(card);
1107 if (err)
1108 pci_set_drvdata(pdev, NULL);
1109
1110 return err;
1111}
1112
1113
1114static void __devexit nj_remove(struct pci_dev *pdev)
1115{
1116 struct tiger_hw *card = pci_get_drvdata(pdev);
1117
1118 if (card)
1119 nj_release(card);
1120 else
1121 pr_info("%s drvdata already removed\n", __func__);
1122}
1123
1124/* We cannot select cards with PCI_SUB... IDs, since here are cards with
1125 * SUB IDs set to PCI_ANY_ID, so we need to match all and reject
1126 * known other cards which not work with this driver - see probe function */
1127static struct pci_device_id nj_pci_ids[] __devinitdata = {
1128 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_300,
1129 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1130 { }
1131};
1132MODULE_DEVICE_TABLE(pci, nj_pci_ids);
1133
1134static struct pci_driver nj_driver = {
1135 .name = "netjet",
1136 .probe = nj_probe,
1137 .remove = __devexit_p(nj_remove),
1138 .id_table = nj_pci_ids,
1139};
1140
1141static int __init nj_init(void)
1142{
1143 int err;
1144
1145 pr_notice("Netjet PCI driver Rev. %s\n", NETJET_REV);
1146 err = pci_register_driver(&nj_driver);
1147 return err;
1148}
1149
1150static void __exit nj_cleanup(void)
1151{
1152 pci_unregister_driver(&nj_driver);
1153}
1154
1155module_init(nj_init);
1156module_exit(nj_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/netjet.h b/drivers/isdn/hardware/mISDN/netjet.h
new file mode 100644
index 000000000000..d061ff995607
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/netjet.h
@@ -0,0 +1,58 @@
1/*
2 * NETjet common header file
3 *
4 * Author Karsten Keil
5 * based on work of Matt Henderson and Daniel Potts,
6 * Traverse Technologies P/L www.traverse.com.au
7 *
8 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#define NJ_CTRL 0x00
26#define NJ_DMACTRL 0x01
27#define NJ_AUXCTRL 0x02
28#define NJ_AUXDATA 0x03
29#define NJ_IRQMASK0 0x04
30#define NJ_IRQMASK1 0x05
31#define NJ_IRQSTAT0 0x06
32#define NJ_IRQSTAT1 0x07
33#define NJ_DMA_READ_START 0x08
34#define NJ_DMA_READ_IRQ 0x0c
35#define NJ_DMA_READ_END 0x10
36#define NJ_DMA_READ_ADR 0x14
37#define NJ_DMA_WRITE_START 0x18
38#define NJ_DMA_WRITE_IRQ 0x1c
39#define NJ_DMA_WRITE_END 0x20
40#define NJ_DMA_WRITE_ADR 0x24
41#define NJ_PULSE_CNT 0x28
42
43#define NJ_ISAC_OFF 0xc0
44#define NJ_ISACIRQ 0x10
45
46#define NJ_IRQM0_RD_MASK 0x03
47#define NJ_IRQM0_RD_IRQ 0x01
48#define NJ_IRQM0_RD_END 0x02
49#define NJ_IRQM0_WR_MASK 0x0c
50#define NJ_IRQM0_WR_IRQ 0x04
51#define NJ_IRQM0_WR_END 0x08
52
53/* one page here is no need to be smaller */
54#define NJ_DMA_SIZE 4096
55/* 2 * 64 byte is a compromise between IRQ count and latency */
56#define NJ_DMA_RXSIZE 128 /* 2 * 64 */
57#define NJ_DMA_TXSIZE 128 /* 2 * 64 */
58
diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c
new file mode 100644
index 000000000000..ff3a4e290da3
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/speedfax.c
@@ -0,0 +1,526 @@
1/*
2 * speedfax.c low level stuff for Sedlbauer Speedfax+ cards
3 * based on the ISAR DSP
4 * Thanks to Sedlbauer AG for informations and HW
5 *
6 * Author Karsten Keil <keil@isdn4linux.de>
7 *
8 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <linux/mISDNhw.h>
29#include <linux/firmware.h>
30#include "ipac.h"
31#include "isar.h"
32
33#define SPEEDFAX_REV "2.0"
34
35#define PCI_SUBVENDOR_SPEEDFAX_PYRAMID 0x51
36#define PCI_SUBVENDOR_SPEEDFAX_PCI 0x54
37#define PCI_SUB_ID_SEDLBAUER 0x01
38
39#define SFAX_PCI_ADDR 0xc8
40#define SFAX_PCI_ISAC 0xd0
41#define SFAX_PCI_ISAR 0xe0
42
43/* TIGER 100 Registers */
44
45#define TIGER_RESET_ADDR 0x00
46#define TIGER_EXTERN_RESET_ON 0x01
47#define TIGER_EXTERN_RESET_OFF 0x00
48#define TIGER_AUX_CTRL 0x02
49#define TIGER_AUX_DATA 0x03
50#define TIGER_AUX_IRQMASK 0x05
51#define TIGER_AUX_STATUS 0x07
52
53/* Tiger AUX BITs */
54#define SFAX_AUX_IOMASK 0xdd /* 1 and 5 are inputs */
55#define SFAX_ISAR_RESET_BIT_OFF 0x00
56#define SFAX_ISAR_RESET_BIT_ON 0x01
57#define SFAX_TIGER_IRQ_BIT 0x02
58#define SFAX_LED1_BIT 0x08
59#define SFAX_LED2_BIT 0x10
60
61#define SFAX_PCI_RESET_ON (SFAX_ISAR_RESET_BIT_ON)
62#define SFAX_PCI_RESET_OFF (SFAX_LED1_BIT | SFAX_LED2_BIT)
63
64static int sfax_cnt;
65static u32 debug;
66static u32 irqloops = 4;
67
68struct sfax_hw {
69 struct list_head list;
70 struct pci_dev *pdev;
71 char name[MISDN_MAX_IDLEN];
72 u32 irq;
73 u32 irqcnt;
74 u32 cfg;
75 struct _ioport p_isac;
76 struct _ioport p_isar;
77 u8 aux_data;
78 spinlock_t lock; /* HW access lock */
79 struct isac_hw isac;
80 struct isar_hw isar;
81};
82
83static LIST_HEAD(Cards);
84static DEFINE_RWLOCK(card_lock); /* protect Cards */
85
86static void
87_set_debug(struct sfax_hw *card)
88{
89 card->isac.dch.debug = debug;
90 card->isar.ch[0].bch.debug = debug;
91 card->isar.ch[1].bch.debug = debug;
92}
93
94static int
95set_debug(const char *val, struct kernel_param *kp)
96{
97 int ret;
98 struct sfax_hw *card;
99
100 ret = param_set_uint(val, kp);
101 if (!ret) {
102 read_lock(&card_lock);
103 list_for_each_entry(card, &Cards, list)
104 _set_debug(card);
105 read_unlock(&card_lock);
106 }
107 return ret;
108}
109
110MODULE_AUTHOR("Karsten Keil");
111MODULE_LICENSE("GPL v2");
112MODULE_VERSION(SPEEDFAX_REV);
113module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
114MODULE_PARM_DESC(debug, "Speedfax debug mask");
115module_param(irqloops, uint, S_IRUGO | S_IWUSR);
116MODULE_PARM_DESC(irqloops, "Speedfax maximal irqloops (default 4)");
117
118IOFUNC_IND(ISAC, sfax_hw, p_isac)
119IOFUNC_IND(ISAR, sfax_hw, p_isar)
120
121static irqreturn_t
122speedfax_irq(int intno, void *dev_id)
123{
124 struct sfax_hw *sf = dev_id;
125 u8 val;
126 int cnt = irqloops;
127
128 spin_lock(&sf->lock);
129 val = inb(sf->cfg + TIGER_AUX_STATUS);
130 if (val & SFAX_TIGER_IRQ_BIT) { /* for us or shared ? */
131 spin_unlock(&sf->lock);
132 return IRQ_NONE; /* shared */
133 }
134 sf->irqcnt++;
135 val = ReadISAR_IND(sf, ISAR_IRQBIT);
136Start_ISAR:
137 if (val & ISAR_IRQSTA)
138 mISDNisar_irq(&sf->isar);
139 val = ReadISAC_IND(sf, ISAC_ISTA);
140 if (val)
141 mISDNisac_irq(&sf->isac, val);
142 val = ReadISAR_IND(sf, ISAR_IRQBIT);
143 if ((val & ISAR_IRQSTA) && cnt--)
144 goto Start_ISAR;
145 if (cnt < irqloops)
146 pr_debug("%s: %d irqloops cpu%d\n", sf->name,
147 irqloops - cnt, smp_processor_id());
148 if (irqloops && !cnt)
149 pr_notice("%s: %d IRQ LOOP cpu%d\n", sf->name,
150 irqloops, smp_processor_id());
151 spin_unlock(&sf->lock);
152 return IRQ_HANDLED;
153}
154
155static void
156enable_hwirq(struct sfax_hw *sf)
157{
158 WriteISAC_IND(sf, ISAC_MASK, 0);
159 WriteISAR_IND(sf, ISAR_IRQBIT, ISAR_IRQMSK);
160 outb(SFAX_TIGER_IRQ_BIT, sf->cfg + TIGER_AUX_IRQMASK);
161}
162
163static void
164disable_hwirq(struct sfax_hw *sf)
165{
166 WriteISAC_IND(sf, ISAC_MASK, 0xFF);
167 WriteISAR_IND(sf, ISAR_IRQBIT, 0);
168 outb(0, sf->cfg + TIGER_AUX_IRQMASK);
169}
170
171static void
172reset_speedfax(struct sfax_hw *sf)
173{
174
175 pr_debug("%s: resetting card\n", sf->name);
176 outb(TIGER_EXTERN_RESET_ON, sf->cfg + TIGER_RESET_ADDR);
177 outb(SFAX_PCI_RESET_ON, sf->cfg + TIGER_AUX_DATA);
178 mdelay(1);
179 outb(TIGER_EXTERN_RESET_OFF, sf->cfg + TIGER_RESET_ADDR);
180 sf->aux_data = SFAX_PCI_RESET_OFF;
181 outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
182 mdelay(1);
183}
184
185static int
186sfax_ctrl(struct sfax_hw *sf, u32 cmd, u_long arg)
187{
188 int ret = 0;
189
190 switch (cmd) {
191 case HW_RESET_REQ:
192 reset_speedfax(sf);
193 break;
194 case HW_ACTIVATE_IND:
195 if (arg & 1)
196 sf->aux_data &= ~SFAX_LED1_BIT;
197 if (arg & 2)
198 sf->aux_data &= ~SFAX_LED2_BIT;
199 outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
200 break;
201 case HW_DEACT_IND:
202 if (arg & 1)
203 sf->aux_data |= SFAX_LED1_BIT;
204 if (arg & 2)
205 sf->aux_data |= SFAX_LED2_BIT;
206 outb(sf->aux_data, sf->cfg + TIGER_AUX_DATA);
207 break;
208 default:
209 pr_info("%s: %s unknown command %x %lx\n",
210 sf->name, __func__, cmd, arg);
211 ret = -EINVAL;
212 break;
213 }
214 return ret;
215}
216
217static int
218channel_ctrl(struct sfax_hw *sf, struct mISDN_ctrl_req *cq)
219{
220 int ret = 0;
221
222 switch (cq->op) {
223 case MISDN_CTRL_GETOP:
224 cq->op = MISDN_CTRL_LOOP;
225 break;
226 case MISDN_CTRL_LOOP:
227 /* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
228 if (cq->channel < 0 || cq->channel > 3) {
229 ret = -EINVAL;
230 break;
231 }
232 ret = sf->isac.ctrl(&sf->isac, HW_TESTLOOP, cq->channel);
233 break;
234 default:
235 pr_info("%s: unknown Op %x\n", sf->name, cq->op);
236 ret = -EINVAL;
237 break;
238 }
239 return ret;
240}
241
242static int
243sfax_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
244{
245 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
246 struct dchannel *dch = container_of(dev, struct dchannel, dev);
247 struct sfax_hw *sf = dch->hw;
248 struct channel_req *rq;
249 int err = 0;
250
251 pr_debug("%s: cmd:%x %p\n", sf->name, cmd, arg);
252 switch (cmd) {
253 case OPEN_CHANNEL:
254 rq = arg;
255 if (rq->protocol == ISDN_P_TE_S0)
256 err = sf->isac.open(&sf->isac, rq);
257 else
258 err = sf->isar.open(&sf->isar, rq);
259 if (err)
260 break;
261 if (!try_module_get(THIS_MODULE))
262 pr_info("%s: cannot get module\n", sf->name);
263 break;
264 case CLOSE_CHANNEL:
265 pr_debug("%s: dev(%d) close from %p\n", sf->name,
266 dch->dev.id, __builtin_return_address(0));
267 module_put(THIS_MODULE);
268 break;
269 case CONTROL_CHANNEL:
270 err = channel_ctrl(sf, arg);
271 break;
272 default:
273 pr_debug("%s: unknown command %x\n", sf->name, cmd);
274 return -EINVAL;
275 }
276 return err;
277}
278
279static int __devinit
280init_card(struct sfax_hw *sf)
281{
282 int ret, cnt = 3;
283 u_long flags;
284
285 ret = request_irq(sf->irq, speedfax_irq, IRQF_SHARED, sf->name, sf);
286 if (ret) {
287 pr_info("%s: couldn't get interrupt %d\n", sf->name, sf->irq);
288 return ret;
289 }
290 while (cnt--) {
291 spin_lock_irqsave(&sf->lock, flags);
292 ret = sf->isac.init(&sf->isac);
293 if (ret) {
294 spin_unlock_irqrestore(&sf->lock, flags);
295 pr_info("%s: ISAC init failed with %d\n",
296 sf->name, ret);
297 break;
298 }
299 enable_hwirq(sf);
300 /* RESET Receiver and Transmitter */
301 WriteISAC_IND(sf, ISAC_CMDR, 0x41);
302 spin_unlock_irqrestore(&sf->lock, flags);
303 msleep_interruptible(10);
304 if (debug & DEBUG_HW)
305 pr_notice("%s: IRQ %d count %d\n", sf->name,
306 sf->irq, sf->irqcnt);
307 if (!sf->irqcnt) {
308 pr_info("%s: IRQ(%d) got no requests during init %d\n",
309 sf->name, sf->irq, 3 - cnt);
310 } else
311 return 0;
312 }
313 free_irq(sf->irq, sf);
314 return -EIO;
315}
316
317
318static int __devinit
319setup_speedfax(struct sfax_hw *sf)
320{
321 u_long flags;
322
323 if (!request_region(sf->cfg, 256, sf->name)) {
324 pr_info("mISDN: %s config port %x-%x already in use\n",
325 sf->name, sf->cfg, sf->cfg + 255);
326 return -EIO;
327 }
328 outb(0xff, sf->cfg);
329 outb(0, sf->cfg);
330 outb(0xdd, sf->cfg + TIGER_AUX_CTRL);
331 outb(0, sf->cfg + TIGER_AUX_IRQMASK);
332
333 sf->isac.type = IPAC_TYPE_ISAC;
334 sf->p_isac.ale = sf->cfg + SFAX_PCI_ADDR;
335 sf->p_isac.port = sf->cfg + SFAX_PCI_ISAC;
336 sf->p_isar.ale = sf->cfg + SFAX_PCI_ADDR;
337 sf->p_isar.port = sf->cfg + SFAX_PCI_ISAR;
338 ASSIGN_FUNC(IND, ISAC, sf->isac);
339 ASSIGN_FUNC(IND, ISAR, sf->isar);
340 spin_lock_irqsave(&sf->lock, flags);
341 reset_speedfax(sf);
342 disable_hwirq(sf);
343 spin_unlock_irqrestore(&sf->lock, flags);
344 return 0;
345}
346
347static void
348release_card(struct sfax_hw *card) {
349 u_long flags;
350
351 spin_lock_irqsave(&card->lock, flags);
352 disable_hwirq(card);
353 spin_unlock_irqrestore(&card->lock, flags);
354 card->isac.release(&card->isac);
355 free_irq(card->irq, card);
356 card->isar.release(&card->isar);
357 mISDN_unregister_device(&card->isac.dch.dev);
358 release_region(card->cfg, 256);
359 pci_disable_device(card->pdev);
360 pci_set_drvdata(card->pdev, NULL);
361 write_lock_irqsave(&card_lock, flags);
362 list_del(&card->list);
363 write_unlock_irqrestore(&card_lock, flags);
364 kfree(card);
365 sfax_cnt--;
366}
367
368static int __devinit
369setup_instance(struct sfax_hw *card)
370{
371 const struct firmware *firmware;
372 int i, err;
373 u_long flags;
374
375 snprintf(card->name, MISDN_MAX_IDLEN - 1, "Speedfax.%d", sfax_cnt + 1);
376 write_lock_irqsave(&card_lock, flags);
377 list_add_tail(&card->list, &Cards);
378 write_unlock_irqrestore(&card_lock, flags);
379 _set_debug(card);
380 spin_lock_init(&card->lock);
381 card->isac.hwlock = &card->lock;
382 card->isar.hwlock = &card->lock;
383 card->isar.ctrl = (void *)&sfax_ctrl;
384 card->isac.name = card->name;
385 card->isar.name = card->name;
386 card->isar.owner = THIS_MODULE;
387
388 err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
389 if (err < 0) {
390 pr_info("%s: firmware request failed %d\n",
391 card->name, err);
392 goto error_fw;
393 }
394 if (debug & DEBUG_HW)
395 pr_notice("%s: got firmware %zu bytes\n",
396 card->name, firmware->size);
397
398 mISDNisac_init(&card->isac, card);
399
400 card->isac.dch.dev.D.ctrl = sfax_dctrl;
401 card->isac.dch.dev.Bprotocols =
402 mISDNisar_init(&card->isar, card);
403 for (i = 0; i < 2; i++) {
404 set_channelmap(i + 1, card->isac.dch.dev.channelmap);
405 list_add(&card->isar.ch[i].bch.ch.list,
406 &card->isac.dch.dev.bchannels);
407 }
408
409 err = setup_speedfax(card);
410 if (err)
411 goto error_setup;
412 err = card->isar.init(&card->isar);
413 if (err)
414 goto error;
415 err = mISDN_register_device(&card->isac.dch.dev,
416 &card->pdev->dev, card->name);
417 if (err)
418 goto error;
419 err = init_card(card);
420 if (err)
421 goto error_init;
422 err = card->isar.firmware(&card->isar, firmware->data, firmware->size);
423 if (!err) {
424 release_firmware(firmware);
425 sfax_cnt++;
426 pr_notice("SpeedFax %d cards installed\n", sfax_cnt);
427 return 0;
428 }
429 disable_hwirq(card);
430 free_irq(card->irq, card);
431error_init:
432 mISDN_unregister_device(&card->isac.dch.dev);
433error:
434 release_region(card->cfg, 256);
435error_setup:
436 card->isac.release(&card->isac);
437 card->isar.release(&card->isar);
438 release_firmware(firmware);
439error_fw:
440 pci_disable_device(card->pdev);
441 write_lock_irqsave(&card_lock, flags);
442 list_del(&card->list);
443 write_unlock_irqrestore(&card_lock, flags);
444 kfree(card);
445 return err;
446}
447
448static int __devinit
449sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
450{
451 int err = -ENOMEM;
452 struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL);
453
454 if (!card) {
455 pr_info("No memory for Speedfax+ PCI\n");
456 return err;
457 }
458 card->pdev = pdev;
459 err = pci_enable_device(pdev);
460 if (err) {
461 kfree(card);
462 return err;
463 }
464
465 pr_notice("mISDN: Speedfax found adapter %s at %s\n",
466 (char *)ent->driver_data, pci_name(pdev));
467
468 card->cfg = pci_resource_start(pdev, 0);
469 card->irq = pdev->irq;
470 pci_set_drvdata(pdev, card);
471 err = setup_instance(card);
472 if (err)
473 pci_set_drvdata(pdev, NULL);
474 return err;
475}
476
477static void __devexit
478sfax_remove_pci(struct pci_dev *pdev)
479{
480 struct sfax_hw *card = pci_get_drvdata(pdev);
481
482 if (card)
483 release_card(card);
484 else
485 pr_debug("%s: drvdata allready removed\n", __func__);
486}
487
488static struct pci_device_id sfaxpci_ids[] __devinitdata = {
489 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
490 PCI_SUBVENDOR_SPEEDFAX_PYRAMID, PCI_SUB_ID_SEDLBAUER,
491 0, 0, (unsigned long) "Pyramid Speedfax + PCI"
492 },
493 { PCI_VENDOR_ID_TIGERJET, PCI_DEVICE_ID_TIGERJET_100,
494 PCI_SUBVENDOR_SPEEDFAX_PCI, PCI_SUB_ID_SEDLBAUER,
495 0, 0, (unsigned long) "Sedlbauer Speedfax + PCI"
496 },
497 { }
498};
499MODULE_DEVICE_TABLE(pci, sfaxpci_ids);
500
501static struct pci_driver sfaxpci_driver = {
502 .name = "speedfax+ pci",
503 .probe = sfaxpci_probe,
504 .remove = __devexit_p(sfax_remove_pci),
505 .id_table = sfaxpci_ids,
506};
507
508static int __init
509Speedfax_init(void)
510{
511 int err;
512
513 pr_notice("Sedlbauer Speedfax+ Driver Rev. %s\n",
514 SPEEDFAX_REV);
515 err = pci_register_driver(&sfaxpci_driver);
516 return err;
517}
518
519static void __exit
520Speedfax_cleanup(void)
521{
522 pci_unregister_driver(&sfaxpci_driver);
523}
524
525module_init(Speedfax_init);
526module_exit(Speedfax_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c
new file mode 100644
index 000000000000..d3f1077b709b
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/w6692.c
@@ -0,0 +1,1440 @@
1/*
2 * w6692.c mISDN driver for Winbond w6692 based cards
3 *
4 * Author Karsten Keil <kkeil@suse.de>
5 * based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
6 *
7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include <linux/module.h>
25#include <linux/pci.h>
26#include <linux/delay.h>
27#include <linux/mISDNhw.h>
28#include "w6692.h"
29
30#define W6692_REV "2.0"
31
32#define DBUSY_TIMER_VALUE 80
33
34enum {
35 W6692_ASUS,
36 W6692_WINBOND,
37 W6692_USR
38};
39
40/* private data in the PCI devices list */
41struct w6692map {
42 u_int subtype;
43 char *name;
44};
45
46static const struct w6692map w6692_map[] =
47{
48 {W6692_ASUS, "Dynalink/AsusCom IS64PH"},
49 {W6692_WINBOND, "Winbond W6692"},
50 {W6692_USR, "USR W6692"}
51};
52
53#ifndef PCI_VENDOR_ID_USR
54#define PCI_VENDOR_ID_USR 0x16ec
55#define PCI_DEVICE_ID_USR_6692 0x3409
56#endif
57
58struct w6692_ch {
59 struct bchannel bch;
60 u32 addr;
61 struct timer_list timer;
62 u8 b_mode;
63};
64
65struct w6692_hw {
66 struct list_head list;
67 struct pci_dev *pdev;
68 char name[MISDN_MAX_IDLEN];
69 u32 irq;
70 u32 irqcnt;
71 u32 addr;
72 u32 fmask; /* feature mask - bit set per card nr */
73 int subtype;
74 spinlock_t lock; /* hw lock */
75 u8 imask;
76 u8 pctl;
77 u8 xaddr;
78 u8 xdata;
79 u8 state;
80 struct w6692_ch bc[2];
81 struct dchannel dch;
82 char log[64];
83};
84
85static LIST_HEAD(Cards);
86static DEFINE_RWLOCK(card_lock); /* protect Cards */
87
88static int w6692_cnt;
89static int debug;
90static u32 led;
91static u32 pots;
92
93static void
94_set_debug(struct w6692_hw *card)
95{
96 card->dch.debug = debug;
97 card->bc[0].bch.debug = debug;
98 card->bc[1].bch.debug = debug;
99}
100
101static int
102set_debug(const char *val, struct kernel_param *kp)
103{
104 int ret;
105 struct w6692_hw *card;
106
107 ret = param_set_uint(val, kp);
108 if (!ret) {
109 read_lock(&card_lock);
110 list_for_each_entry(card, &Cards, list)
111 _set_debug(card);
112 read_unlock(&card_lock);
113 }
114 return ret;
115}
116
117MODULE_AUTHOR("Karsten Keil");
118MODULE_LICENSE("GPL v2");
119MODULE_VERSION(W6692_REV);
120module_param_call(debug, set_debug, param_get_uint, &debug, S_IRUGO | S_IWUSR);
121MODULE_PARM_DESC(debug, "W6692 debug mask");
122module_param(led, uint, S_IRUGO | S_IWUSR);
123MODULE_PARM_DESC(led, "W6692 LED support bitmask (one bit per card)");
124module_param(pots, uint, S_IRUGO | S_IWUSR);
125MODULE_PARM_DESC(pots, "W6692 POTS support bitmask (one bit per card)");
126
127static inline u8
128ReadW6692(struct w6692_hw *card, u8 offset)
129{
130 return inb(card->addr + offset);
131}
132
133static inline void
134WriteW6692(struct w6692_hw *card, u8 offset, u8 value)
135{
136 outb(value, card->addr + offset);
137}
138
139static inline u8
140ReadW6692B(struct w6692_ch *bc, u8 offset)
141{
142 return inb(bc->addr + offset);
143}
144
145static inline void
146WriteW6692B(struct w6692_ch *bc, u8 offset, u8 value)
147{
148 outb(value, bc->addr + offset);
149}
150
151static void
152enable_hwirq(struct w6692_hw *card)
153{
154 WriteW6692(card, W_IMASK, card->imask);
155}
156
157static void
158disable_hwirq(struct w6692_hw *card)
159{
160 WriteW6692(card, W_IMASK, 0xff);
161}
162
163static const char *W6692Ver[] = {"V00", "V01", "V10", "V11"};
164
165static void
166W6692Version(struct w6692_hw *card)
167{
168 int val;
169
170 val = ReadW6692(card, W_D_RBCH);
171 pr_notice("%s: Winbond W6692 version: %s\n", card->name,
172 W6692Ver[(val >> 6) & 3]);
173}
174
175static void
176w6692_led_handler(struct w6692_hw *card, int on)
177{
178 if ((!(card->fmask & led)) || card->subtype == W6692_USR)
179 return;
180 if (on) {
181 card->xdata &= 0xfb; /* LED ON */
182 WriteW6692(card, W_XDATA, card->xdata);
183 } else {
184 card->xdata |= 0x04; /* LED OFF */
185 WriteW6692(card, W_XDATA, card->xdata);
186 }
187}
188
189static void
190ph_command(struct w6692_hw *card, u8 cmd)
191{
192 pr_debug("%s: ph_command %x\n", card->name, cmd);
193 WriteW6692(card, W_CIX, cmd);
194}
195
196static void
197W6692_new_ph(struct w6692_hw *card)
198{
199 if (card->state == W_L1CMD_RST)
200 ph_command(card, W_L1CMD_DRC);
201 schedule_event(&card->dch, FLG_PHCHANGE);
202}
203
204static void
205W6692_ph_bh(struct dchannel *dch)
206{
207 struct w6692_hw *card = dch->hw;
208
209 switch (card->state) {
210 case W_L1CMD_RST:
211 dch->state = 0;
212 l1_event(dch->l1, HW_RESET_IND);
213 break;
214 case W_L1IND_CD:
215 dch->state = 3;
216 l1_event(dch->l1, HW_DEACT_CNF);
217 break;
218 case W_L1IND_DRD:
219 dch->state = 3;
220 l1_event(dch->l1, HW_DEACT_IND);
221 break;
222 case W_L1IND_CE:
223 dch->state = 4;
224 l1_event(dch->l1, HW_POWERUP_IND);
225 break;
226 case W_L1IND_LD:
227 if (dch->state <= 5) {
228 dch->state = 5;
229 l1_event(dch->l1, ANYSIGNAL);
230 } else {
231 dch->state = 8;
232 l1_event(dch->l1, LOSTFRAMING);
233 }
234 break;
235 case W_L1IND_ARD:
236 dch->state = 6;
237 l1_event(dch->l1, INFO2);
238 break;
239 case W_L1IND_AI8:
240 dch->state = 7;
241 l1_event(dch->l1, INFO4_P8);
242 break;
243 case W_L1IND_AI10:
244 dch->state = 7;
245 l1_event(dch->l1, INFO4_P10);
246 break;
247 default:
248 pr_debug("%s: TE unknown state %02x dch state %02x\n",
249 card->name, card->state, dch->state);
250 break;
251 }
252 pr_debug("%s: TE newstate %02x\n", card->name, dch->state);
253}
254
255static void
256W6692_empty_Dfifo(struct w6692_hw *card, int count)
257{
258 struct dchannel *dch = &card->dch;
259 u8 *ptr;
260
261 pr_debug("%s: empty_Dfifo %d\n", card->name, count);
262 if (!dch->rx_skb) {
263 dch->rx_skb = mI_alloc_skb(card->dch.maxlen, GFP_ATOMIC);
264 if (!dch->rx_skb) {
265 pr_info("%s: D receive out of memory\n", card->name);
266 WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
267 return;
268 }
269 }
270 if ((dch->rx_skb->len + count) >= dch->maxlen) {
271 pr_debug("%s: empty_Dfifo overrun %d\n", card->name,
272 dch->rx_skb->len + count);
273 WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
274 return;
275 }
276 ptr = skb_put(dch->rx_skb, count);
277 insb(card->addr + W_D_RFIFO, ptr, count);
278 WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK);
279 if (debug & DEBUG_HW_DFIFO) {
280 snprintf(card->log, 63, "D-recv %s %d ",
281 card->name, count);
282 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
283 }
284}
285
286static void
287W6692_fill_Dfifo(struct w6692_hw *card)
288{
289 struct dchannel *dch = &card->dch;
290 int count;
291 u8 *ptr;
292 u8 cmd = W_D_CMDR_XMS;
293
294 pr_debug("%s: fill_Dfifo\n", card->name);
295 if (!dch->tx_skb)
296 return;
297 count = dch->tx_skb->len - dch->tx_idx;
298 if (count <= 0)
299 return;
300 if (count > W_D_FIFO_THRESH)
301 count = W_D_FIFO_THRESH;
302 else
303 cmd |= W_D_CMDR_XME;
304 ptr = dch->tx_skb->data + dch->tx_idx;
305 dch->tx_idx += count;
306 outsb(card->addr + W_D_XFIFO, ptr, count);
307 WriteW6692(card, W_D_CMDR, cmd);
308 if (test_and_set_bit(FLG_BUSY_TIMER, &dch->Flags)) {
309 pr_debug("%s: fill_Dfifo dbusytimer running\n", card->name);
310 del_timer(&dch->timer);
311 }
312 init_timer(&dch->timer);
313 dch->timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
314 add_timer(&dch->timer);
315 if (debug & DEBUG_HW_DFIFO) {
316 snprintf(card->log, 63, "D-send %s %d ",
317 card->name, count);
318 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
319 }
320}
321
322static void
323d_retransmit(struct w6692_hw *card)
324{
325 struct dchannel *dch = &card->dch;
326
327 if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
328 del_timer(&dch->timer);
329#ifdef FIXME
330 if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags))
331 dchannel_sched_event(dch, D_CLEARBUSY);
332#endif
333 if (test_bit(FLG_TX_BUSY, &dch->Flags)) {
334 /* Restart frame */
335 dch->tx_idx = 0;
336 W6692_fill_Dfifo(card);
337 } else if (dch->tx_skb) { /* should not happen */
338 pr_info("%s: %s without TX_BUSY\n", card->name, __func__);
339 test_and_set_bit(FLG_TX_BUSY, &dch->Flags);
340 dch->tx_idx = 0;
341 W6692_fill_Dfifo(card);
342 } else {
343 pr_info("%s: XDU no TX_BUSY\n", card->name);
344 if (get_next_dframe(dch))
345 W6692_fill_Dfifo(card);
346 }
347}
348
349static void
350handle_rxD(struct w6692_hw *card) {
351 u8 stat;
352 int count;
353
354 stat = ReadW6692(card, W_D_RSTA);
355 if (stat & (W_D_RSTA_RDOV | W_D_RSTA_CRCE | W_D_RSTA_RMB)) {
356 if (stat & W_D_RSTA_RDOV) {
357 pr_debug("%s: D-channel RDOV\n", card->name);
358#ifdef ERROR_STATISTIC
359 card->dch.err_rx++;
360#endif
361 }
362 if (stat & W_D_RSTA_CRCE) {
363 pr_debug("%s: D-channel CRC error\n", card->name);
364#ifdef ERROR_STATISTIC
365 card->dch.err_crc++;
366#endif
367 }
368 if (stat & W_D_RSTA_RMB) {
369 pr_debug("%s: D-channel ABORT\n", card->name);
370#ifdef ERROR_STATISTIC
371 card->dch.err_rx++;
372#endif
373 }
374 if (card->dch.rx_skb)
375 dev_kfree_skb(card->dch.rx_skb);
376 card->dch.rx_skb = NULL;
377 WriteW6692(card, W_D_CMDR, W_D_CMDR_RACK | W_D_CMDR_RRST);
378 } else {
379 count = ReadW6692(card, W_D_RBCL) & (W_D_FIFO_THRESH - 1);
380 if (count == 0)
381 count = W_D_FIFO_THRESH;
382 W6692_empty_Dfifo(card, count);
383 recv_Dchannel(&card->dch);
384 }
385}
386
387static void
388handle_txD(struct w6692_hw *card) {
389 if (test_and_clear_bit(FLG_BUSY_TIMER, &card->dch.Flags))
390 del_timer(&card->dch.timer);
391 if (card->dch.tx_skb && card->dch.tx_idx < card->dch.tx_skb->len) {
392 W6692_fill_Dfifo(card);
393 } else {
394 if (card->dch.tx_skb)
395 dev_kfree_skb(card->dch.tx_skb);
396 if (get_next_dframe(&card->dch))
397 W6692_fill_Dfifo(card);
398 }
399}
400
401static void
402handle_statusD(struct w6692_hw *card)
403{
404 struct dchannel *dch = &card->dch;
405 u8 exval, v1, cir;
406
407 exval = ReadW6692(card, W_D_EXIR);
408
409 pr_debug("%s: D_EXIR %02x\n", card->name, exval);
410 if (exval & (W_D_EXI_XDUN | W_D_EXI_XCOL)) {
411 /* Transmit underrun/collision */
412 pr_debug("%s: D-channel underrun/collision\n", card->name);
413#ifdef ERROR_STATISTIC
414 dch->err_tx++;
415#endif
416 d_retransmit(card);
417 }
418 if (exval & W_D_EXI_RDOV) { /* RDOV */
419 pr_debug("%s: D-channel RDOV\n", card->name);
420 WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST);
421 }
422 if (exval & W_D_EXI_TIN2) /* TIN2 - never */
423 pr_debug("%s: spurious TIN2 interrupt\n", card->name);
424 if (exval & W_D_EXI_MOC) { /* MOC - not supported */
425 v1 = ReadW6692(card, W_MOSR);
426 pr_debug("%s: spurious MOC interrupt MOSR %02x\n",
427 card->name, v1);
428 }
429 if (exval & W_D_EXI_ISC) { /* ISC - Level1 change */
430 cir = ReadW6692(card, W_CIR);
431 pr_debug("%s: ISC CIR %02X\n", card->name, cir);
432 if (cir & W_CIR_ICC) {
433 v1 = cir & W_CIR_COD_MASK;
434 pr_debug("%s: ph_state_change %x -> %x\n", card->name,
435 dch->state, v1);
436 card->state = v1;
437 if (card->fmask & led) {
438 switch (v1) {
439 case W_L1IND_AI8:
440 case W_L1IND_AI10:
441 w6692_led_handler(card, 1);
442 break;
443 default:
444 w6692_led_handler(card, 0);
445 break;
446 }
447 }
448 W6692_new_ph(card);
449 }
450 if (cir & W_CIR_SCC) {
451 v1 = ReadW6692(card, W_SQR);
452 pr_debug("%s: SCC SQR %02X\n", card->name, v1);
453 }
454 }
455 if (exval & W_D_EXI_WEXP)
456 pr_debug("%s: spurious WEXP interrupt!\n", card->name);
457 if (exval & W_D_EXI_TEXP)
458 pr_debug("%s: spurious TEXP interrupt!\n", card->name);
459}
460
461static void
462W6692_empty_Bfifo(struct w6692_ch *wch, int count)
463{
464 struct w6692_hw *card = wch->bch.hw;
465 u8 *ptr;
466
467 pr_debug("%s: empty_Bfifo %d\n", card->name, count);
468 if (unlikely(wch->bch.state == ISDN_P_NONE)) {
469 pr_debug("%s: empty_Bfifo ISDN_P_NONE\n", card->name);
470 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
471 if (wch->bch.rx_skb)
472 skb_trim(wch->bch.rx_skb, 0);
473 return;
474 }
475 if (!wch->bch.rx_skb) {
476 wch->bch.rx_skb = mI_alloc_skb(wch->bch.maxlen, GFP_ATOMIC);
477 if (unlikely(!wch->bch.rx_skb)) {
478 pr_info("%s: B receive out of memory\n", card->name);
479 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
480 W_B_CMDR_RACT);
481 return;
482 }
483 }
484 if (wch->bch.rx_skb->len + count > wch->bch.maxlen) {
485 pr_debug("%s: empty_Bfifo incoming packet too large\n",
486 card->name);
487 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
488 skb_trim(wch->bch.rx_skb, 0);
489 return;
490 }
491 ptr = skb_put(wch->bch.rx_skb, count);
492 insb(wch->addr + W_B_RFIFO, ptr, count);
493 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK | W_B_CMDR_RACT);
494 if (debug & DEBUG_HW_DFIFO) {
495 snprintf(card->log, 63, "B%1d-recv %s %d ",
496 wch->bch.nr, card->name, count);
497 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
498 }
499}
500
501static void
502W6692_fill_Bfifo(struct w6692_ch *wch)
503{
504 struct w6692_hw *card = wch->bch.hw;
505 int count;
506 u8 *ptr, cmd = W_B_CMDR_RACT | W_B_CMDR_XMS;
507
508 pr_debug("%s: fill Bfifo\n", card->name);
509 if (!wch->bch.tx_skb)
510 return;
511 count = wch->bch.tx_skb->len - wch->bch.tx_idx;
512 if (count <= 0)
513 return;
514 ptr = wch->bch.tx_skb->data + wch->bch.tx_idx;
515 if (count > W_B_FIFO_THRESH)
516 count = W_B_FIFO_THRESH;
517 else if (test_bit(FLG_HDLC, &wch->bch.Flags))
518 cmd |= W_B_CMDR_XME;
519
520 pr_debug("%s: fill Bfifo%d/%d\n", card->name,
521 count, wch->bch.tx_idx);
522 wch->bch.tx_idx += count;
523 outsb(wch->addr + W_B_XFIFO, ptr, count);
524 WriteW6692B(wch, W_B_CMDR, cmd);
525 if (debug & DEBUG_HW_DFIFO) {
526 snprintf(card->log, 63, "B%1d-send %s %d ",
527 wch->bch.nr, card->name, count);
528 print_hex_dump_bytes(card->log, DUMP_PREFIX_OFFSET, ptr, count);
529 }
530}
531
532static int
533setvolume(struct w6692_ch *wch, int mic, struct sk_buff *skb)
534{
535 struct w6692_hw *card = wch->bch.hw;
536 u16 *vol = (u16 *)skb->data;
537 u8 val;
538
539 if ((!(card->fmask & pots)) ||
540 !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
541 return -ENODEV;
542 if (skb->len < 2)
543 return -EINVAL;
544 if (*vol > 7)
545 return -EINVAL;
546 val = *vol & 7;
547 val = 7 - val;
548 if (mic) {
549 val <<= 3;
550 card->xaddr &= 0xc7;
551 } else {
552 card->xaddr &= 0xf8;
553 }
554 card->xaddr |= val;
555 WriteW6692(card, W_XADDR, card->xaddr);
556 return 0;
557}
558
559static int
560enable_pots(struct w6692_ch *wch)
561{
562 struct w6692_hw *card = wch->bch.hw;
563
564 if ((!(card->fmask & pots)) ||
565 !test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
566 return -ENODEV;
567 wch->b_mode |= W_B_MODE_EPCM | W_B_MODE_BSW0;
568 WriteW6692B(wch, W_B_MODE, wch->b_mode);
569 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
570 card->pctl |= ((wch->bch.nr & 2) ? W_PCTL_PCX : 0);
571 WriteW6692(card, W_PCTL, card->pctl);
572 return 0;
573}
574
575static int
576disable_pots(struct w6692_ch *wch)
577{
578 struct w6692_hw *card = wch->bch.hw;
579
580 if (!(card->fmask & pots))
581 return -ENODEV;
582 wch->b_mode &= ~(W_B_MODE_EPCM | W_B_MODE_BSW0);
583 WriteW6692B(wch, W_B_MODE, wch->b_mode);
584 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
585 W_B_CMDR_XRST);
586 return 0;
587}
588
589static int
590w6692_mode(struct w6692_ch *wch, u32 pr)
591{
592 struct w6692_hw *card;
593
594 card = wch->bch.hw;
595 pr_debug("%s: B%d protocol %x-->%x\n", card->name,
596 wch->bch.nr, wch->bch.state, pr);
597 switch (pr) {
598 case ISDN_P_NONE:
599 if ((card->fmask & pots) && (wch->b_mode & W_B_MODE_EPCM))
600 disable_pots(wch);
601 wch->b_mode = 0;
602 mISDN_clear_bchannel(&wch->bch);
603 WriteW6692B(wch, W_B_MODE, wch->b_mode);
604 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
605 test_and_clear_bit(FLG_HDLC, &wch->bch.Flags);
606 test_and_clear_bit(FLG_TRANSPARENT, &wch->bch.Flags);
607 break;
608 case ISDN_P_B_RAW:
609 wch->b_mode = W_B_MODE_MMS;
610 WriteW6692B(wch, W_B_MODE, wch->b_mode);
611 WriteW6692B(wch, W_B_EXIM, 0);
612 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
613 W_B_CMDR_XRST);
614 test_and_set_bit(FLG_TRANSPARENT, &wch->bch.Flags);
615 break;
616 case ISDN_P_B_HDLC:
617 wch->b_mode = W_B_MODE_ITF;
618 WriteW6692B(wch, W_B_MODE, wch->b_mode);
619 WriteW6692B(wch, W_B_ADM1, 0xff);
620 WriteW6692B(wch, W_B_ADM2, 0xff);
621 WriteW6692B(wch, W_B_EXIM, 0);
622 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_RACT |
623 W_B_CMDR_XRST);
624 test_and_set_bit(FLG_HDLC, &wch->bch.Flags);
625 break;
626 default:
627 pr_info("%s: protocol %x not known\n", card->name, pr);
628 return -ENOPROTOOPT;
629 }
630 wch->bch.state = pr;
631 return 0;
632}
633
634static void
635send_next(struct w6692_ch *wch)
636{
637 if (wch->bch.tx_skb && wch->bch.tx_idx < wch->bch.tx_skb->len)
638 W6692_fill_Bfifo(wch);
639 else {
640 if (wch->bch.tx_skb) {
641 /* send confirm, on trans, free on hdlc. */
642 if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
643 confirm_Bsend(&wch->bch);
644 dev_kfree_skb(wch->bch.tx_skb);
645 }
646 if (get_next_bframe(&wch->bch))
647 W6692_fill_Bfifo(wch);
648 }
649}
650
651static void
652W6692B_interrupt(struct w6692_hw *card, int ch)
653{
654 struct w6692_ch *wch = &card->bc[ch];
655 int count;
656 u8 stat, star = 0;
657
658 stat = ReadW6692B(wch, W_B_EXIR);
659 pr_debug("%s: B%d EXIR %02x\n", card->name, wch->bch.nr, stat);
660 if (stat & W_B_EXI_RME) {
661 star = ReadW6692B(wch, W_B_STAR);
662 if (star & (W_B_STAR_RDOV | W_B_STAR_CRCE | W_B_STAR_RMB)) {
663 if ((star & W_B_STAR_RDOV) &&
664 test_bit(FLG_ACTIVE, &wch->bch.Flags)) {
665 pr_debug("%s: B%d RDOV proto=%x\n", card->name,
666 wch->bch.nr, wch->bch.state);
667#ifdef ERROR_STATISTIC
668 wch->bch.err_rdo++;
669#endif
670 }
671 if (test_bit(FLG_HDLC, &wch->bch.Flags)) {
672 if (star & W_B_STAR_CRCE) {
673 pr_debug("%s: B%d CRC error\n",
674 card->name, wch->bch.nr);
675#ifdef ERROR_STATISTIC
676 wch->bch.err_crc++;
677#endif
678 }
679 if (star & W_B_STAR_RMB) {
680 pr_debug("%s: B%d message abort\n",
681 card->name, wch->bch.nr);
682#ifdef ERROR_STATISTIC
683 wch->bch.err_inv++;
684#endif
685 }
686 }
687 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
688 W_B_CMDR_RRST | W_B_CMDR_RACT);
689 if (wch->bch.rx_skb)
690 skb_trim(wch->bch.rx_skb, 0);
691 } else {
692 count = ReadW6692B(wch, W_B_RBCL) &
693 (W_B_FIFO_THRESH - 1);
694 if (count == 0)
695 count = W_B_FIFO_THRESH;
696 W6692_empty_Bfifo(wch, count);
697 recv_Bchannel(&wch->bch, 0);
698 }
699 }
700 if (stat & W_B_EXI_RMR) {
701 if (!(stat & W_B_EXI_RME))
702 star = ReadW6692B(wch, W_B_STAR);
703 if (star & W_B_STAR_RDOV) {
704 pr_debug("%s: B%d RDOV proto=%x\n", card->name,
705 wch->bch.nr, wch->bch.state);
706#ifdef ERROR_STATISTIC
707 wch->bch.err_rdo++;
708#endif
709 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
710 W_B_CMDR_RRST | W_B_CMDR_RACT);
711 } else {
712 W6692_empty_Bfifo(wch, W_B_FIFO_THRESH);
713 if (test_bit(FLG_TRANSPARENT, &wch->bch.Flags) &&
714 wch->bch.rx_skb && (wch->bch.rx_skb->len > 0))
715 recv_Bchannel(&wch->bch, 0);
716 }
717 }
718 if (stat & W_B_EXI_RDOV) {
719 /* only if it is not handled yet */
720 if (!(star & W_B_STAR_RDOV)) {
721 pr_debug("%s: B%d RDOV IRQ proto=%x\n", card->name,
722 wch->bch.nr, wch->bch.state);
723#ifdef ERROR_STATISTIC
724 wch->bch.err_rdo++;
725#endif
726 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_RACK |
727 W_B_CMDR_RRST | W_B_CMDR_RACT);
728 }
729 }
730 if (stat & W_B_EXI_XFR) {
731 if (!(stat & (W_B_EXI_RME | W_B_EXI_RMR))) {
732 star = ReadW6692B(wch, W_B_STAR);
733 pr_debug("%s: B%d star %02x\n", card->name,
734 wch->bch.nr, star);
735 }
736 if (star & W_B_STAR_XDOW) {
737 pr_debug("%s: B%d XDOW proto=%x\n", card->name,
738 wch->bch.nr, wch->bch.state);
739#ifdef ERROR_STATISTIC
740 wch->bch.err_xdu++;
741#endif
742 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST |
743 W_B_CMDR_RACT);
744 /* resend */
745 if (wch->bch.tx_skb) {
746 if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
747 wch->bch.tx_idx = 0;
748 }
749 }
750 send_next(wch);
751 if (stat & W_B_EXI_XDUN)
752 return; /* handle XDOW only once */
753 }
754 if (stat & W_B_EXI_XDUN) {
755 pr_debug("%s: B%d XDUN proto=%x\n", card->name,
756 wch->bch.nr, wch->bch.state);
757#ifdef ERROR_STATISTIC
758 wch->bch.err_xdu++;
759#endif
760 WriteW6692B(wch, W_B_CMDR, W_B_CMDR_XRST | W_B_CMDR_RACT);
761 /* resend */
762 if (wch->bch.tx_skb) {
763 if (!test_bit(FLG_TRANSPARENT, &wch->bch.Flags))
764 wch->bch.tx_idx = 0;
765 }
766 send_next(wch);
767 }
768}
769
770static irqreturn_t
771w6692_irq(int intno, void *dev_id)
772{
773 struct w6692_hw *card = dev_id;
774 u8 ista;
775
776 spin_lock(&card->lock);
777 ista = ReadW6692(card, W_ISTA);
778 if ((ista | card->imask) == card->imask) {
779 /* possible a shared IRQ reqest */
780 spin_unlock(&card->lock);
781 return IRQ_NONE;
782 }
783 card->irqcnt++;
784 pr_debug("%s: ista %02x\n", card->name, ista);
785 ista &= ~card->imask;
786 if (ista & W_INT_B1_EXI)
787 W6692B_interrupt(card, 0);
788 if (ista & W_INT_B2_EXI)
789 W6692B_interrupt(card, 1);
790 if (ista & W_INT_D_RME)
791 handle_rxD(card);
792 if (ista & W_INT_D_RMR)
793 W6692_empty_Dfifo(card, W_D_FIFO_THRESH);
794 if (ista & W_INT_D_XFR)
795 handle_txD(card);
796 if (ista & W_INT_D_EXI)
797 handle_statusD(card);
798 if (ista & (W_INT_XINT0 | W_INT_XINT1)) /* XINT0/1 - never */
799 pr_debug("%s: W6692 spurious XINT!\n", card->name);
800/* End IRQ Handler */
801 spin_unlock(&card->lock);
802 return IRQ_HANDLED;
803}
804
805static void
806dbusy_timer_handler(struct dchannel *dch)
807{
808 struct w6692_hw *card = dch->hw;
809 int rbch, star;
810 u_long flags;
811
812 if (test_bit(FLG_BUSY_TIMER, &dch->Flags)) {
813 spin_lock_irqsave(&card->lock, flags);
814 rbch = ReadW6692(card, W_D_RBCH);
815 star = ReadW6692(card, W_D_STAR);
816 pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
817 card->name, rbch, star);
818 if (star & W_D_STAR_XBZ) /* D-Channel Busy */
819 test_and_set_bit(FLG_L1_BUSY, &dch->Flags);
820 else {
821 /* discard frame; reset transceiver */
822 test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags);
823 if (dch->tx_idx)
824 dch->tx_idx = 0;
825 else
826 pr_info("%s: W6692 D-Channel Busy no tx_idx\n",
827 card->name);
828 /* Transmitter reset */
829 WriteW6692(card, W_D_CMDR, W_D_CMDR_XRST);
830 }
831 spin_unlock_irqrestore(&card->lock, flags);
832 }
833}
834
835void initW6692(struct w6692_hw *card)
836{
837 u8 val;
838
839 card->dch.timer.function = (void *)dbusy_timer_handler;
840 card->dch.timer.data = (u_long)&card->dch;
841 init_timer(&card->dch.timer);
842 w6692_mode(&card->bc[0], ISDN_P_NONE);
843 w6692_mode(&card->bc[1], ISDN_P_NONE);
844 WriteW6692(card, W_D_CTL, 0x00);
845 disable_hwirq(card);
846 WriteW6692(card, W_D_SAM, 0xff);
847 WriteW6692(card, W_D_TAM, 0xff);
848 WriteW6692(card, W_D_MODE, W_D_MODE_RACT);
849 card->state = W_L1CMD_RST;
850 ph_command(card, W_L1CMD_RST);
851 ph_command(card, W_L1CMD_ECK);
852 /* enable all IRQ but extern */
853 card->imask = 0x18;
854 WriteW6692(card, W_D_EXIM, 0x00);
855 WriteW6692B(&card->bc[0], W_B_EXIM, 0);
856 WriteW6692B(&card->bc[1], W_B_EXIM, 0);
857 /* Reset D-chan receiver and transmitter */
858 WriteW6692(card, W_D_CMDR, W_D_CMDR_RRST | W_D_CMDR_XRST);
859 /* Reset B-chan receiver and transmitter */
860 WriteW6692B(&card->bc[0], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
861 WriteW6692B(&card->bc[1], W_B_CMDR, W_B_CMDR_RRST | W_B_CMDR_XRST);
862 /* enable peripheral */
863 if (card->subtype == W6692_USR) {
864 /* seems that USR implemented some power control features
865 * Pin 79 is connected to the oscilator circuit so we
866 * have to handle it here
867 */
868 card->pctl = 0x80;
869 card->xdata = 0;
870 WriteW6692(card, W_PCTL, card->pctl);
871 WriteW6692(card, W_XDATA, card->xdata);
872 } else {
873 card->pctl = W_PCTL_OE5 | W_PCTL_OE4 | W_PCTL_OE2 |
874 W_PCTL_OE1 | W_PCTL_OE0;
875 card->xaddr = 0x00;/* all sw off */
876 if (card->fmask & pots)
877 card->xdata |= 0x06; /* POWER UP/ LED OFF / ALAW */
878 if (card->fmask & led)
879 card->xdata |= 0x04; /* LED OFF */
880 if ((card->fmask & pots) || (card->fmask & led)) {
881 WriteW6692(card, W_PCTL, card->pctl);
882 WriteW6692(card, W_XADDR, card->xaddr);
883 WriteW6692(card, W_XDATA, card->xdata);
884 val = ReadW6692(card, W_XADDR);
885 if (debug & DEBUG_HW)
886 pr_notice("%s: W_XADDR=%02x\n",
887 card->name, val);
888 }
889 }
890}
891
892static void
893reset_w6692(struct w6692_hw *card)
894{
895 WriteW6692(card, W_D_CTL, W_D_CTL_SRST);
896 mdelay(10);
897 WriteW6692(card, W_D_CTL, 0);
898}
899
900static int
901init_card(struct w6692_hw *card)
902{
903 int cnt = 3;
904 u_long flags;
905
906 spin_lock_irqsave(&card->lock, flags);
907 disable_hwirq(card);
908 spin_unlock_irqrestore(&card->lock, flags);
909 if (request_irq(card->irq, w6692_irq, IRQF_SHARED, card->name, card)) {
910 pr_info("%s: couldn't get interrupt %d\n", card->name,
911 card->irq);
912 return -EIO;
913 }
914 while (cnt--) {
915 spin_lock_irqsave(&card->lock, flags);
916 initW6692(card);
917 enable_hwirq(card);
918 spin_unlock_irqrestore(&card->lock, flags);
919 /* Timeout 10ms */
920 msleep_interruptible(10);
921 if (debug & DEBUG_HW)
922 pr_notice("%s: IRQ %d count %d\n", card->name,
923 card->irq, card->irqcnt);
924 if (!card->irqcnt) {
925 pr_info("%s: IRQ(%d) getting no IRQs during init %d\n",
926 card->name, card->irq, 3 - cnt);
927 reset_w6692(card);
928 } else
929 return 0;
930 }
931 free_irq(card->irq, card);
932 return -EIO;
933}
934
935static int
936w6692_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
937{
938 struct bchannel *bch = container_of(ch, struct bchannel, ch);
939 struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
940 struct w6692_hw *card = bch->hw;
941 int ret = -EINVAL;
942 struct mISDNhead *hh = mISDN_HEAD_P(skb);
943 u32 id;
944 u_long flags;
945
946 switch (hh->prim) {
947 case PH_DATA_REQ:
948 spin_lock_irqsave(&card->lock, flags);
949 ret = bchannel_senddata(bch, skb);
950 if (ret > 0) { /* direct TX */
951 id = hh->id; /* skb can be freed */
952 ret = 0;
953 W6692_fill_Bfifo(bc);
954 spin_unlock_irqrestore(&card->lock, flags);
955 if (!test_bit(FLG_TRANSPARENT, &bch->Flags))
956 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
957 } else
958 spin_unlock_irqrestore(&card->lock, flags);
959 return ret;
960 case PH_ACTIVATE_REQ:
961 spin_lock_irqsave(&card->lock, flags);
962 if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
963 ret = w6692_mode(bc, ch->protocol);
964 else
965 ret = 0;
966 spin_unlock_irqrestore(&card->lock, flags);
967 if (!ret)
968 _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
969 NULL, GFP_KERNEL);
970 break;
971 case PH_DEACTIVATE_REQ:
972 spin_lock_irqsave(&card->lock, flags);
973 mISDN_clear_bchannel(bch);
974 w6692_mode(bc, ISDN_P_NONE);
975 spin_unlock_irqrestore(&card->lock, flags);
976 _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
977 NULL, GFP_KERNEL);
978 ret = 0;
979 break;
980 default:
981 pr_info("%s: %s unknown prim(%x,%x)\n",
982 card->name, __func__, hh->prim, hh->id);
983 ret = -EINVAL;
984 }
985 if (!ret)
986 dev_kfree_skb(skb);
987 return ret;
988}
989
990static int
991channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
992{
993 int ret = 0;
994
995 switch (cq->op) {
996 case MISDN_CTRL_GETOP:
997 cq->op = 0;
998 break;
999 /* Nothing implemented yet */
1000 case MISDN_CTRL_FILL_EMPTY:
1001 default:
1002 pr_info("%s: unknown Op %x\n", __func__, cq->op);
1003 ret = -EINVAL;
1004 break;
1005 }
1006 return ret;
1007}
1008
1009static int
1010open_bchannel(struct w6692_hw *card, struct channel_req *rq)
1011{
1012 struct bchannel *bch;
1013
1014 if (rq->adr.channel > 2)
1015 return -EINVAL;
1016 if (rq->protocol == ISDN_P_NONE)
1017 return -EINVAL;
1018 bch = &card->bc[rq->adr.channel - 1].bch;
1019 if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1020 return -EBUSY; /* b-channel can be only open once */
1021 test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1022 bch->ch.protocol = rq->protocol;
1023 rq->ch = &bch->ch;
1024 return 0;
1025}
1026
1027static int
1028channel_ctrl(struct w6692_hw *card, struct mISDN_ctrl_req *cq)
1029{
1030 int ret = 0;
1031
1032 switch (cq->op) {
1033 case MISDN_CTRL_GETOP:
1034 cq->op = 0;
1035 break;
1036 default:
1037 pr_info("%s: unknown CTRL OP %x\n", card->name, cq->op);
1038 ret = -EINVAL;
1039 break;
1040 }
1041 return ret;
1042}
1043
1044static int
1045w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1046{
1047 struct bchannel *bch = container_of(ch, struct bchannel, ch);
1048 struct w6692_ch *bc = container_of(bch, struct w6692_ch, bch);
1049 struct w6692_hw *card = bch->hw;
1050 int ret = -EINVAL;
1051 u_long flags;
1052
1053 pr_debug("%s: %s cmd:%x %p\n", card->name, __func__, cmd, arg);
1054 switch (cmd) {
1055 case CLOSE_CHANNEL:
1056 test_and_clear_bit(FLG_OPEN, &bch->Flags);
1057 if (test_bit(FLG_ACTIVE, &bch->Flags)) {
1058 spin_lock_irqsave(&card->lock, flags);
1059 mISDN_freebchannel(bch);
1060 w6692_mode(bc, ISDN_P_NONE);
1061 spin_unlock_irqrestore(&card->lock, flags);
1062 } else {
1063 skb_queue_purge(&bch->rqueue);
1064 bch->rcount = 0;
1065 }
1066 ch->protocol = ISDN_P_NONE;
1067 ch->peer = NULL;
1068 module_put(THIS_MODULE);
1069 ret = 0;
1070 break;
1071 case CONTROL_CHANNEL:
1072 ret = channel_bctrl(bch, arg);
1073 break;
1074 default:
1075 pr_info("%s: %s unknown prim(%x)\n",
1076 card->name, __func__, cmd);
1077 }
1078 return ret;
1079}
1080
1081static int
1082w6692_l2l1D(struct mISDNchannel *ch, struct sk_buff *skb)
1083{
1084 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1085 struct dchannel *dch = container_of(dev, struct dchannel, dev);
1086 struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
1087 int ret = -EINVAL;
1088 struct mISDNhead *hh = mISDN_HEAD_P(skb);
1089 u32 id;
1090 u_long flags;
1091
1092 switch (hh->prim) {
1093 case PH_DATA_REQ:
1094 spin_lock_irqsave(&card->lock, flags);
1095 ret = dchannel_senddata(dch, skb);
1096 if (ret > 0) { /* direct TX */
1097 id = hh->id; /* skb can be freed */
1098 W6692_fill_Dfifo(card);
1099 ret = 0;
1100 spin_unlock_irqrestore(&card->lock, flags);
1101 queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
1102 } else
1103 spin_unlock_irqrestore(&card->lock, flags);
1104 return ret;
1105 case PH_ACTIVATE_REQ:
1106 ret = l1_event(dch->l1, hh->prim);
1107 break;
1108 case PH_DEACTIVATE_REQ:
1109 test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
1110 ret = l1_event(dch->l1, hh->prim);
1111 break;
1112 }
1113
1114 if (!ret)
1115 dev_kfree_skb(skb);
1116 return ret;
1117}
1118
1119static int
1120w6692_l1callback(struct dchannel *dch, u32 cmd)
1121{
1122 struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
1123 u_long flags;
1124
1125 pr_debug("%s: cmd(%x) state(%02x)\n", card->name, cmd, card->state);
1126 switch (cmd) {
1127 case INFO3_P8:
1128 spin_lock_irqsave(&card->lock, flags);
1129 ph_command(card, W_L1CMD_AR8);
1130 spin_unlock_irqrestore(&card->lock, flags);
1131 break;
1132 case INFO3_P10:
1133 spin_lock_irqsave(&card->lock, flags);
1134 ph_command(card, W_L1CMD_AR10);
1135 spin_unlock_irqrestore(&card->lock, flags);
1136 break;
1137 case HW_RESET_REQ:
1138 spin_lock_irqsave(&card->lock, flags);
1139 if (card->state != W_L1IND_DRD)
1140 ph_command(card, W_L1CMD_RST);
1141 ph_command(card, W_L1CMD_ECK);
1142 spin_unlock_irqrestore(&card->lock, flags);
1143 break;
1144 case HW_DEACT_REQ:
1145 skb_queue_purge(&dch->squeue);
1146 if (dch->tx_skb) {
1147 dev_kfree_skb(dch->tx_skb);
1148 dch->tx_skb = NULL;
1149 }
1150 dch->tx_idx = 0;
1151 if (dch->rx_skb) {
1152 dev_kfree_skb(dch->rx_skb);
1153 dch->rx_skb = NULL;
1154 }
1155 test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
1156 if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
1157 del_timer(&dch->timer);
1158 break;
1159 case HW_POWERUP_REQ:
1160 spin_lock_irqsave(&card->lock, flags);
1161 ph_command(card, W_L1CMD_ECK);
1162 spin_unlock_irqrestore(&card->lock, flags);
1163 break;
1164 case PH_ACTIVATE_IND:
1165 test_and_set_bit(FLG_ACTIVE, &dch->Flags);
1166 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
1167 GFP_ATOMIC);
1168 break;
1169 case PH_DEACTIVATE_IND:
1170 test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
1171 _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
1172 GFP_ATOMIC);
1173 break;
1174 default:
1175 pr_debug("%s: %s unknown command %x\n", card->name,
1176 __func__, cmd);
1177 return -1;
1178 }
1179 return 0;
1180}
1181
1182static int
1183open_dchannel(struct w6692_hw *card, struct channel_req *rq)
1184{
1185 pr_debug("%s: %s dev(%d) open from %p\n", card->name, __func__,
1186 card->dch.dev.id, __builtin_return_address(1));
1187 if (rq->protocol != ISDN_P_TE_S0)
1188 return -EINVAL;
1189 if (rq->adr.channel == 1)
1190 /* E-Channel not supported */
1191 return -EINVAL;
1192 rq->ch = &card->dch.dev.D;
1193 rq->ch->protocol = rq->protocol;
1194 if (card->dch.state == 7)
1195 _queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
1196 0, NULL, GFP_KERNEL);
1197 return 0;
1198}
1199
1200static int
1201w6692_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1202{
1203 struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1204 struct dchannel *dch = container_of(dev, struct dchannel, dev);
1205 struct w6692_hw *card = container_of(dch, struct w6692_hw, dch);
1206 struct channel_req *rq;
1207 int err = 0;
1208
1209 pr_debug("%s: DCTRL: %x %p\n", card->name, cmd, arg);
1210 switch (cmd) {
1211 case OPEN_CHANNEL:
1212 rq = arg;
1213 if (rq->protocol == ISDN_P_TE_S0)
1214 err = open_dchannel(card, rq);
1215 else
1216 err = open_bchannel(card, rq);
1217 if (err)
1218 break;
1219 if (!try_module_get(THIS_MODULE))
1220 pr_info("%s: cannot get module\n", card->name);
1221 break;
1222 case CLOSE_CHANNEL:
1223 pr_debug("%s: dev(%d) close from %p\n", card->name,
1224 dch->dev.id, __builtin_return_address(0));
1225 module_put(THIS_MODULE);
1226 break;
1227 case CONTROL_CHANNEL:
1228 err = channel_ctrl(card, arg);
1229 break;
1230 default:
1231 pr_debug("%s: unknown DCTRL command %x\n", card->name, cmd);
1232 return -EINVAL;
1233 }
1234 return err;
1235}
1236
1237static int
1238setup_w6692(struct w6692_hw *card)
1239{
1240 u32 val;
1241
1242 if (!request_region(card->addr, 256, card->name)) {
1243 pr_info("%s: config port %x-%x already in use\n", card->name,
1244 card->addr, card->addr + 255);
1245 return -EIO;
1246 }
1247 W6692Version(card);
1248 card->bc[0].addr = card->addr;
1249 card->bc[1].addr = card->addr + 0x40;
1250 val = ReadW6692(card, W_ISTA);
1251 if (debug & DEBUG_HW)
1252 pr_notice("%s ISTA=%02x\n", card->name, val);
1253 val = ReadW6692(card, W_IMASK);
1254 if (debug & DEBUG_HW)
1255 pr_notice("%s IMASK=%02x\n", card->name, val);
1256 val = ReadW6692(card, W_D_EXIR);
1257 if (debug & DEBUG_HW)
1258 pr_notice("%s D_EXIR=%02x\n", card->name, val);
1259 val = ReadW6692(card, W_D_EXIM);
1260 if (debug & DEBUG_HW)
1261 pr_notice("%s D_EXIM=%02x\n", card->name, val);
1262 val = ReadW6692(card, W_D_RSTA);
1263 if (debug & DEBUG_HW)
1264 pr_notice("%s D_RSTA=%02x\n", card->name, val);
1265 return 0;
1266}
1267
1268static void
1269release_card(struct w6692_hw *card)
1270{
1271 u_long flags;
1272
1273 spin_lock_irqsave(&card->lock, flags);
1274 disable_hwirq(card);
1275 w6692_mode(&card->bc[0], ISDN_P_NONE);
1276 w6692_mode(&card->bc[1], ISDN_P_NONE);
1277 if ((card->fmask & led) || card->subtype == W6692_USR) {
1278 card->xdata |= 0x04; /* LED OFF */
1279 WriteW6692(card, W_XDATA, card->xdata);
1280 }
1281 spin_unlock_irqrestore(&card->lock, flags);
1282 free_irq(card->irq, card);
1283 l1_event(card->dch.l1, CLOSE_CHANNEL);
1284 mISDN_unregister_device(&card->dch.dev);
1285 release_region(card->addr, 256);
1286 mISDN_freebchannel(&card->bc[1].bch);
1287 mISDN_freebchannel(&card->bc[0].bch);
1288 mISDN_freedchannel(&card->dch);
1289 write_lock_irqsave(&card_lock, flags);
1290 list_del(&card->list);
1291 write_unlock_irqrestore(&card_lock, flags);
1292 pci_disable_device(card->pdev);
1293 pci_set_drvdata(card->pdev, NULL);
1294 kfree(card);
1295}
1296
1297static int
1298setup_instance(struct w6692_hw *card)
1299{
1300 int i, err;
1301 u_long flags;
1302
1303 snprintf(card->name, MISDN_MAX_IDLEN - 1, "w6692.%d", w6692_cnt + 1);
1304 write_lock_irqsave(&card_lock, flags);
1305 list_add_tail(&card->list, &Cards);
1306 write_unlock_irqrestore(&card_lock, flags);
1307 card->fmask = (1 << w6692_cnt);
1308 _set_debug(card);
1309 spin_lock_init(&card->lock);
1310 mISDN_initdchannel(&card->dch, MAX_DFRAME_LEN_L1, W6692_ph_bh);
1311 card->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
1312 card->dch.dev.D.send = w6692_l2l1D;
1313 card->dch.dev.D.ctrl = w6692_dctrl;
1314 card->dch.dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1315 (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1316 card->dch.hw = card;
1317 card->dch.dev.nrbchan = 2;
1318 for (i = 0; i < 2; i++) {
1319 mISDN_initbchannel(&card->bc[i].bch, MAX_DATA_MEM);
1320 card->bc[i].bch.hw = card;
1321 card->bc[i].bch.nr = i + 1;
1322 card->bc[i].bch.ch.nr = i + 1;
1323 card->bc[i].bch.ch.send = w6692_l2l1B;
1324 card->bc[i].bch.ch.ctrl = w6692_bctrl;
1325 set_channelmap(i + 1, card->dch.dev.channelmap);
1326 list_add(&card->bc[i].bch.ch.list, &card->dch.dev.bchannels);
1327 }
1328 err = setup_w6692(card);
1329 if (err)
1330 goto error_setup;
1331 err = mISDN_register_device(&card->dch.dev, &card->pdev->dev,
1332 card->name);
1333 if (err)
1334 goto error_reg;
1335 err = init_card(card);
1336 if (err)
1337 goto error_init;
1338 err = create_l1(&card->dch, w6692_l1callback);
1339 if (!err) {
1340 w6692_cnt++;
1341 pr_notice("W6692 %d cards installed\n", w6692_cnt);
1342 return 0;
1343 }
1344
1345 free_irq(card->irq, card);
1346error_init:
1347 mISDN_unregister_device(&card->dch.dev);
1348error_reg:
1349 release_region(card->addr, 256);
1350error_setup:
1351 mISDN_freebchannel(&card->bc[1].bch);
1352 mISDN_freebchannel(&card->bc[0].bch);
1353 mISDN_freedchannel(&card->dch);
1354 write_lock_irqsave(&card_lock, flags);
1355 list_del(&card->list);
1356 write_unlock_irqrestore(&card_lock, flags);
1357 kfree(card);
1358 return err;
1359}
1360
1361static int __devinit
1362w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1363{
1364 int err = -ENOMEM;
1365 struct w6692_hw *card;
1366 struct w6692map *m = (struct w6692map *)ent->driver_data;
1367
1368 card = kzalloc(sizeof(struct w6692_hw), GFP_KERNEL);
1369 if (!card) {
1370 pr_info("No kmem for w6692 card\n");
1371 return err;
1372 }
1373 card->pdev = pdev;
1374 card->subtype = m->subtype;
1375 err = pci_enable_device(pdev);
1376 if (err) {
1377 kfree(card);
1378 return err;
1379 }
1380
1381 printk(KERN_INFO "mISDN_w6692: found adapter %s at %s\n",
1382 m->name, pci_name(pdev));
1383
1384 card->addr = pci_resource_start(pdev, 1);
1385 card->irq = pdev->irq;
1386 pci_set_drvdata(pdev, card);
1387 err = setup_instance(card);
1388 if (err)
1389 pci_set_drvdata(pdev, NULL);
1390 return err;
1391}
1392
1393static void __devexit
1394w6692_remove_pci(struct pci_dev *pdev)
1395{
1396 struct w6692_hw *card = pci_get_drvdata(pdev);
1397
1398 if (card)
1399 release_card(card);
1400 else
1401 if (debug)
1402 pr_notice("%s: drvdata allready removed\n", __func__);
1403}
1404
1405static struct pci_device_id w6692_ids[] = {
1406 { PCI_VENDOR_ID_DYNALINK, PCI_DEVICE_ID_DYNALINK_IS64PH,
1407 PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[0]},
1408 { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
1409 PCI_VENDOR_ID_USR, PCI_DEVICE_ID_USR_6692, 0, 0,
1410 (ulong)&w6692_map[2]},
1411 { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_6692,
1412 PCI_ANY_ID, PCI_ANY_ID, 0, 0, (ulong)&w6692_map[1]},
1413 { }
1414};
1415MODULE_DEVICE_TABLE(pci, w6692_ids);
1416
1417static struct pci_driver w6692_driver = {
1418 .name = "w6692",
1419 .probe = w6692_probe,
1420 .remove = __devexit_p(w6692_remove_pci),
1421 .id_table = w6692_ids,
1422};
1423
1424static int __init w6692_init(void)
1425{
1426 int err;
1427
1428 pr_notice("Winbond W6692 PCI driver Rev. %s\n", W6692_REV);
1429
1430 err = pci_register_driver(&w6692_driver);
1431 return err;
1432}
1433
1434static void __exit w6692_cleanup(void)
1435{
1436 pci_unregister_driver(&w6692_driver);
1437}
1438
1439module_init(w6692_init);
1440module_exit(w6692_cleanup);
diff --git a/drivers/isdn/hardware/mISDN/w6692.h b/drivers/isdn/hardware/mISDN/w6692.h
new file mode 100644
index 000000000000..f95697757fd0
--- /dev/null
+++ b/drivers/isdn/hardware/mISDN/w6692.h
@@ -0,0 +1,190 @@
1/*
2 * Winbond W6692 specific defines
3 *
4 * Author Karsten Keil <keil@isdn4linux.de>
5 * based on the w6692 I4L driver from Petr Novak <petr.novak@i.cz>
6 *
7 * Copyright 2009 by Karsten Keil <keil@isdn4linux.de>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24/* Specifications of W6692 registers */
25
26#define W_D_RFIFO 0x00 /* R */
27#define W_D_XFIFO 0x04 /* W */
28#define W_D_CMDR 0x08 /* W */
29#define W_D_MODE 0x0c /* R/W */
30#define W_D_TIMR 0x10 /* R/W */
31#define W_ISTA 0x14 /* R_clr */
32#define W_IMASK 0x18 /* R/W */
33#define W_D_EXIR 0x1c /* R_clr */
34#define W_D_EXIM 0x20 /* R/W */
35#define W_D_STAR 0x24 /* R */
36#define W_D_RSTA 0x28 /* R */
37#define W_D_SAM 0x2c /* R/W */
38#define W_D_SAP1 0x30 /* R/W */
39#define W_D_SAP2 0x34 /* R/W */
40#define W_D_TAM 0x38 /* R/W */
41#define W_D_TEI1 0x3c /* R/W */
42#define W_D_TEI2 0x40 /* R/W */
43#define W_D_RBCH 0x44 /* R */
44#define W_D_RBCL 0x48 /* R */
45#define W_TIMR2 0x4c /* W */
46#define W_L1_RC 0x50 /* R/W */
47#define W_D_CTL 0x54 /* R/W */
48#define W_CIR 0x58 /* R */
49#define W_CIX 0x5c /* W */
50#define W_SQR 0x60 /* R */
51#define W_SQX 0x64 /* W */
52#define W_PCTL 0x68 /* R/W */
53#define W_MOR 0x6c /* R */
54#define W_MOX 0x70 /* R/W */
55#define W_MOSR 0x74 /* R_clr */
56#define W_MOCR 0x78 /* R/W */
57#define W_GCR 0x7c /* R/W */
58
59#define W_B_RFIFO 0x80 /* R */
60#define W_B_XFIFO 0x84 /* W */
61#define W_B_CMDR 0x88 /* W */
62#define W_B_MODE 0x8c /* R/W */
63#define W_B_EXIR 0x90 /* R_clr */
64#define W_B_EXIM 0x94 /* R/W */
65#define W_B_STAR 0x98 /* R */
66#define W_B_ADM1 0x9c /* R/W */
67#define W_B_ADM2 0xa0 /* R/W */
68#define W_B_ADR1 0xa4 /* R/W */
69#define W_B_ADR2 0xa8 /* R/W */
70#define W_B_RBCL 0xac /* R */
71#define W_B_RBCH 0xb0 /* R */
72
73#define W_XADDR 0xf4 /* R/W */
74#define W_XDATA 0xf8 /* R/W */
75#define W_EPCTL 0xfc /* W */
76
77/* W6692 register bits */
78
79#define W_D_CMDR_XRST 0x01
80#define W_D_CMDR_XME 0x02
81#define W_D_CMDR_XMS 0x08
82#define W_D_CMDR_STT 0x10
83#define W_D_CMDR_RRST 0x40
84#define W_D_CMDR_RACK 0x80
85
86#define W_D_MODE_RLP 0x01
87#define W_D_MODE_DLP 0x02
88#define W_D_MODE_MFD 0x04
89#define W_D_MODE_TEE 0x08
90#define W_D_MODE_TMS 0x10
91#define W_D_MODE_RACT 0x40
92#define W_D_MODE_MMS 0x80
93
94#define W_INT_B2_EXI 0x01
95#define W_INT_B1_EXI 0x02
96#define W_INT_D_EXI 0x04
97#define W_INT_XINT0 0x08
98#define W_INT_XINT1 0x10
99#define W_INT_D_XFR 0x20
100#define W_INT_D_RME 0x40
101#define W_INT_D_RMR 0x80
102
103#define W_D_EXI_WEXP 0x01
104#define W_D_EXI_TEXP 0x02
105#define W_D_EXI_ISC 0x04
106#define W_D_EXI_MOC 0x08
107#define W_D_EXI_TIN2 0x10
108#define W_D_EXI_XCOL 0x20
109#define W_D_EXI_XDUN 0x40
110#define W_D_EXI_RDOV 0x80
111
112#define W_D_STAR_DRDY 0x10
113#define W_D_STAR_XBZ 0x20
114#define W_D_STAR_XDOW 0x80
115
116#define W_D_RSTA_RMB 0x10
117#define W_D_RSTA_CRCE 0x20
118#define W_D_RSTA_RDOV 0x40
119
120#define W_D_CTL_SRST 0x20
121
122#define W_CIR_SCC 0x80
123#define W_CIR_ICC 0x40
124#define W_CIR_COD_MASK 0x0f
125
126#define W_PCTL_PCX 0x01
127#define W_PCTL_XMODE 0x02
128#define W_PCTL_OE0 0x04
129#define W_PCTL_OE1 0x08
130#define W_PCTL_OE2 0x10
131#define W_PCTL_OE3 0x20
132#define W_PCTL_OE4 0x40
133#define W_PCTL_OE5 0x80
134
135#define W_B_CMDR_XRST 0x01
136#define W_B_CMDR_XME 0x02
137#define W_B_CMDR_XMS 0x04
138#define W_B_CMDR_RACT 0x20
139#define W_B_CMDR_RRST 0x40
140#define W_B_CMDR_RACK 0x80
141
142#define W_B_MODE_FTS0 0x01
143#define W_B_MODE_FTS1 0x02
144#define W_B_MODE_SW56 0x04
145#define W_B_MODE_BSW0 0x08
146#define W_B_MODE_BSW1 0x10
147#define W_B_MODE_EPCM 0x20
148#define W_B_MODE_ITF 0x40
149#define W_B_MODE_MMS 0x80
150
151#define W_B_EXI_XDUN 0x01
152#define W_B_EXI_XFR 0x02
153#define W_B_EXI_RDOV 0x10
154#define W_B_EXI_RME 0x20
155#define W_B_EXI_RMR 0x40
156
157#define W_B_STAR_XBZ 0x01
158#define W_B_STAR_XDOW 0x04
159#define W_B_STAR_RMB 0x10
160#define W_B_STAR_CRCE 0x20
161#define W_B_STAR_RDOV 0x40
162
163#define W_B_RBCH_LOV 0x20
164
165/* W6692 Layer1 commands */
166
167#define W_L1CMD_ECK 0x00
168#define W_L1CMD_RST 0x01
169#define W_L1CMD_SCP 0x04
170#define W_L1CMD_SSP 0x02
171#define W_L1CMD_AR8 0x08
172#define W_L1CMD_AR10 0x09
173#define W_L1CMD_EAL 0x0a
174#define W_L1CMD_DRC 0x0f
175
176/* W6692 Layer1 indications */
177
178#define W_L1IND_CE 0x07
179#define W_L1IND_DRD 0x00
180#define W_L1IND_LD 0x04
181#define W_L1IND_ARD 0x08
182#define W_L1IND_TI 0x0a
183#define W_L1IND_ATI 0x0b
184#define W_L1IND_AI8 0x0c
185#define W_L1IND_AI10 0x0d
186#define W_L1IND_CD 0x0f
187
188/* FIFO thresholds */
189#define W_D_FIFO_THRESH 64
190#define W_B_FIFO_THRESH 64
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig
index 7832d8ba8e44..3464ebc4cdbc 100644
--- a/drivers/isdn/hisax/Kconfig
+++ b/drivers/isdn/hisax/Kconfig
@@ -391,6 +391,7 @@ comment "HiSax sub driver modules"
391config HISAX_ST5481 391config HISAX_ST5481
392 tristate "ST5481 USB ISDN modem (EXPERIMENTAL)" 392 tristate "ST5481 USB ISDN modem (EXPERIMENTAL)"
393 depends on USB && EXPERIMENTAL 393 depends on USB && EXPERIMENTAL
394 select ISDN_HDLC
394 select CRC_CCITT 395 select CRC_CCITT
395 select BITREVERSE 396 select BITREVERSE
396 help 397 help
@@ -418,11 +419,6 @@ config HISAX_FRITZ_PCIPNP
418 (the latter also needs you to select "ISA Plug and Play support" 419 (the latter also needs you to select "ISA Plug and Play support"
419 from the menu "Plug and Play configuration") 420 from the menu "Plug and Play configuration")
420 421
421config HISAX_HDLC
422 bool
423 depends on HISAX_ST5481
424 default y
425
426config HISAX_AVM_A1_PCMCIA 422config HISAX_AVM_A1_PCMCIA
427 bool 423 bool
428 depends on HISAX_AVM_A1_CS 424 depends on HISAX_AVM_A1_CS
diff --git a/drivers/isdn/hisax/Makefile b/drivers/isdn/hisax/Makefile
index c7a3794bdae4..ab638b083df9 100644
--- a/drivers/isdn/hisax/Makefile
+++ b/drivers/isdn/hisax/Makefile
@@ -16,10 +16,6 @@ obj-$(CONFIG_HISAX_HFCUSB) += hfc_usb.o
16obj-$(CONFIG_HISAX_HFC4S8S) += hfc4s8s_l1.o 16obj-$(CONFIG_HISAX_HFC4S8S) += hfc4s8s_l1.o
17obj-$(CONFIG_HISAX_FRITZ_PCIPNP) += hisax_isac.o hisax_fcpcipnp.o 17obj-$(CONFIG_HISAX_FRITZ_PCIPNP) += hisax_isac.o hisax_fcpcipnp.o
18 18
19ifdef CONFIG_HISAX_HDLC
20obj-$(CONFIG_ISDN_DRV_HISAX) += isdnhdlc.o
21endif
22
23# Multipart objects. 19# Multipart objects.
24 20
25hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \ 21hisax_st5481-y := st5481_init.o st5481_usb.o st5481_d.o \
diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c
index 341faf58a65c..bf526a7a63af 100644
--- a/drivers/isdn/hisax/amd7930_fn.c
+++ b/drivers/isdn/hisax/amd7930_fn.c
@@ -238,8 +238,6 @@ Amd7930_bh(struct work_struct *work)
238 container_of(work, struct IsdnCardState, tqueue); 238 container_of(work, struct IsdnCardState, tqueue);
239 struct PStack *stptr; 239 struct PStack *stptr;
240 240
241 if (!cs)
242 return;
243 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { 241 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
244 if (cs->debug) 242 if (cs->debug)
245 debugl1(cs, "Amd7930: bh, D-Channel Busy cleared"); 243 debugl1(cs, "Amd7930: bh, D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index 025a20d487c5..475b1a020003 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -833,8 +833,6 @@ static struct FsmNode fnlist[] __initdata =
833}; 833};
834/* *INDENT-ON* */ 834/* *INDENT-ON* */
835 835
836#define FNCOUNT (sizeof(fnlist)/sizeof(struct FsmNode))
837
838int __init 836int __init
839CallcNew(void) 837CallcNew(void)
840{ 838{
@@ -842,7 +840,7 @@ CallcNew(void)
842 callcfsm.event_count = EVENT_COUNT; 840 callcfsm.event_count = EVENT_COUNT;
843 callcfsm.strEvent = strEvent; 841 callcfsm.strEvent = strEvent;
844 callcfsm.strState = strState; 842 callcfsm.strState = strState;
845 return FsmNew(&callcfsm, fnlist, FNCOUNT); 843 return FsmNew(&callcfsm, fnlist, ARRAY_SIZE(fnlist));
846} 844}
847 845
848void 846void
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c
index 3d337d924c23..d110a77940a4 100644
--- a/drivers/isdn/hisax/hfc_pci.c
+++ b/drivers/isdn/hisax/hfc_pci.c
@@ -1506,8 +1506,6 @@ hfcpci_bh(struct work_struct *work)
1506 u_long flags; 1506 u_long flags;
1507// struct PStack *stptr; 1507// struct PStack *stptr;
1508 1508
1509 if (!cs)
1510 return;
1511 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { 1509 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
1512 if (!cs->hw.hfcpci.nt_mode) 1510 if (!cs->hw.hfcpci.nt_mode)
1513 switch (cs->dc.hfcpci.ph_state) { 1511 switch (cs->dc.hfcpci.ph_state) {
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c
index d92e8d6c2ae2..419f87cad8cb 100644
--- a/drivers/isdn/hisax/hfc_sx.c
+++ b/drivers/isdn/hisax/hfc_sx.c
@@ -1255,8 +1255,6 @@ hfcsx_bh(struct work_struct *work)
1255 container_of(work, struct IsdnCardState, tqueue); 1255 container_of(work, struct IsdnCardState, tqueue);
1256 u_long flags; 1256 u_long flags;
1257 1257
1258 if (!cs)
1259 return;
1260 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) { 1258 if (test_and_clear_bit(D_L1STATECHANGE, &cs->event)) {
1261 if (!cs->hw.hfcsx.nt_mode) 1259 if (!cs->hw.hfcsx.nt_mode)
1262 switch (cs->dc.hfcsx.ph_state) { 1260 switch (cs->dc.hfcsx.ph_state) {
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 682cac32f259..9aba646ba221 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -83,8 +83,6 @@ icc_bh(struct work_struct *work)
83 container_of(work, struct IsdnCardState, tqueue); 83 container_of(work, struct IsdnCardState, tqueue);
84 struct PStack *stptr; 84 struct PStack *stptr;
85 85
86 if (!cs)
87 return;
88 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { 86 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
89 if (cs->debug) 87 if (cs->debug)
90 debugl1(cs, "D-Channel Busy cleared"); 88 debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c
index 07b1673122b8..a19354d94343 100644
--- a/drivers/isdn/hisax/isac.c
+++ b/drivers/isdn/hisax/isac.c
@@ -86,8 +86,6 @@ isac_bh(struct work_struct *work)
86 container_of(work, struct IsdnCardState, tqueue); 86 container_of(work, struct IsdnCardState, tqueue);
87 struct PStack *stptr; 87 struct PStack *stptr;
88 88
89 if (!cs)
90 return;
91 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { 89 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
92 if (cs->debug) 90 if (cs->debug)
93 debugl1(cs, "D-Channel Busy cleared"); 91 debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hisax/isdnhdlc.h b/drivers/isdn/hisax/isdnhdlc.h
deleted file mode 100644
index cf0a95a24015..000000000000
--- a/drivers/isdn/hisax/isdnhdlc.h
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * isdnhdlc.h -- General purpose ISDN HDLC decoder.
3 *
4 * Implementation of a HDLC decoder/encoder in software.
5 * Neccessary because some ISDN devices don't have HDLC
6 * controllers. Also included: a bit reversal table.
7 *
8 *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
9 * 2001 Frode Isaksen <fisaksen@bewan.com>
10 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef __ISDNHDLC_H__
28#define __ISDNHDLC_H__
29
30struct isdnhdlc_vars {
31 int bit_shift;
32 int hdlc_bits1;
33 int data_bits;
34 int ffbit_shift; // encoding only
35 int state;
36 int dstpos;
37
38 unsigned short crc;
39
40 unsigned char cbin;
41 unsigned char shift_reg;
42 unsigned char ffvalue;
43
44 unsigned int data_received:1; // set if transferring data
45 unsigned int dchannel:1; // set if D channel (send idle instead of flags)
46 unsigned int do_adapt56:1; // set if 56K adaptation
47 unsigned int do_closing:1; // set if in closing phase (need to send CRC + flag
48};
49
50
51/*
52 The return value from isdnhdlc_decode is
53 the frame length, 0 if no complete frame was decoded,
54 or a negative error number
55*/
56#define HDLC_FRAMING_ERROR 1
57#define HDLC_CRC_ERROR 2
58#define HDLC_LENGTH_ERROR 3
59
60extern void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56);
61
62extern int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, int slen,int *count,
63 unsigned char *dst, int dsize);
64
65extern void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc,int is_d_channel,int do_adapt56);
66
67extern int isdnhdlc_encode (struct isdnhdlc_vars *hdlc,const unsigned char *src,unsigned short slen,int *count,
68 unsigned char *dst,int dsize);
69
70#endif /* __ISDNHDLC_H__ */
diff --git a/drivers/isdn/hisax/isdnl1.c b/drivers/isdn/hisax/isdnl1.c
index 317f16f516f2..9ce6abe05b1a 100644
--- a/drivers/isdn/hisax/isdnl1.c
+++ b/drivers/isdn/hisax/isdnl1.c
@@ -647,8 +647,6 @@ static struct FsmNode L1SFnList[] __initdata =
647 {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact}, 647 {ST_L1_F8, EV_TIMER_DEACT, l1_timer_deact},
648}; 648};
649 649
650#define L1S_FN_COUNT (sizeof(L1SFnList)/sizeof(struct FsmNode))
651
652#ifdef HISAX_UINTERFACE 650#ifdef HISAX_UINTERFACE
653static void 651static void
654l1_deact_req_u(struct FsmInst *fi, int event, void *arg) 652l1_deact_req_u(struct FsmInst *fi, int event, void *arg)
@@ -706,8 +704,6 @@ static struct FsmNode L1UFnList[] __initdata =
706 {ST_L1_RESET, EV_TIMER_DEACT, l1_timer_deact}, 704 {ST_L1_RESET, EV_TIMER_DEACT, l1_timer_deact},
707}; 705};
708 706
709#define L1U_FN_COUNT (sizeof(L1UFnList)/sizeof(struct FsmNode))
710
711#endif 707#endif
712 708
713static void 709static void
@@ -754,8 +750,6 @@ static struct FsmNode L1BFnList[] __initdata =
754 {ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact}, 750 {ST_L1_WAIT_DEACT, EV_TIMER_DEACT, l1b_timer_deact},
755}; 751};
756 752
757#define L1B_FN_COUNT (sizeof(L1BFnList)/sizeof(struct FsmNode))
758
759int __init 753int __init
760Isdnl1New(void) 754Isdnl1New(void)
761{ 755{
@@ -765,7 +759,7 @@ Isdnl1New(void)
765 l1fsm_s.event_count = L1_EVENT_COUNT; 759 l1fsm_s.event_count = L1_EVENT_COUNT;
766 l1fsm_s.strEvent = strL1Event; 760 l1fsm_s.strEvent = strL1Event;
767 l1fsm_s.strState = strL1SState; 761 l1fsm_s.strState = strL1SState;
768 retval = FsmNew(&l1fsm_s, L1SFnList, L1S_FN_COUNT); 762 retval = FsmNew(&l1fsm_s, L1SFnList, ARRAY_SIZE(L1SFnList));
769 if (retval) 763 if (retval)
770 return retval; 764 return retval;
771 765
@@ -773,7 +767,7 @@ Isdnl1New(void)
773 l1fsm_b.event_count = L1_EVENT_COUNT; 767 l1fsm_b.event_count = L1_EVENT_COUNT;
774 l1fsm_b.strEvent = strL1Event; 768 l1fsm_b.strEvent = strL1Event;
775 l1fsm_b.strState = strL1BState; 769 l1fsm_b.strState = strL1BState;
776 retval = FsmNew(&l1fsm_b, L1BFnList, L1B_FN_COUNT); 770 retval = FsmNew(&l1fsm_b, L1BFnList, ARRAY_SIZE(L1BFnList));
777 if (retval) { 771 if (retval) {
778 FsmFree(&l1fsm_s); 772 FsmFree(&l1fsm_s);
779 return retval; 773 return retval;
@@ -783,7 +777,7 @@ Isdnl1New(void)
783 l1fsm_u.event_count = L1_EVENT_COUNT; 777 l1fsm_u.event_count = L1_EVENT_COUNT;
784 l1fsm_u.strEvent = strL1Event; 778 l1fsm_u.strEvent = strL1Event;
785 l1fsm_u.strState = strL1UState; 779 l1fsm_u.strState = strL1UState;
786 retval = FsmNew(&l1fsm_u, L1UFnList, L1U_FN_COUNT); 780 retval = FsmNew(&l1fsm_u, L1UFnList, ARRAY_SIZE(L1UFnList));
787 if (retval) { 781 if (retval) {
788 FsmFree(&l1fsm_s); 782 FsmFree(&l1fsm_s);
789 FsmFree(&l1fsm_b); 783 FsmFree(&l1fsm_b);
diff --git a/drivers/isdn/hisax/isdnl2.c b/drivers/isdn/hisax/isdnl2.c
index 3446f249d675..7b9496a63b5f 100644
--- a/drivers/isdn/hisax/isdnl2.c
+++ b/drivers/isdn/hisax/isdnl2.c
@@ -1623,8 +1623,6 @@ static struct FsmNode L2FnList[] __initdata =
1623 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da}, 1623 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
1624}; 1624};
1625 1625
1626#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
1627
1628static void 1626static void
1629isdnl2_l1l2(struct PStack *st, int pr, void *arg) 1627isdnl2_l1l2(struct PStack *st, int pr, void *arg)
1630{ 1628{
@@ -1836,7 +1834,7 @@ Isdnl2New(void)
1836 l2fsm.event_count = L2_EVENT_COUNT; 1834 l2fsm.event_count = L2_EVENT_COUNT;
1837 l2fsm.strEvent = strL2Event; 1835 l2fsm.strEvent = strL2Event;
1838 l2fsm.strState = strL2State; 1836 l2fsm.strState = strL2State;
1839 return FsmNew(&l2fsm, L2FnList, L2_FN_COUNT); 1837 return FsmNew(&l2fsm, L2FnList, ARRAY_SIZE(L2FnList));
1840} 1838}
1841 1839
1842void 1840void
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c
index 935f23356fae..06766022d3ae 100644
--- a/drivers/isdn/hisax/isdnl3.c
+++ b/drivers/isdn/hisax/isdnl3.c
@@ -543,8 +543,6 @@ static struct FsmNode L3FnList[] __initdata =
543}; 543};
544/* *INDENT-ON* */ 544/* *INDENT-ON* */
545 545
546#define L3_FN_COUNT (sizeof(L3FnList)/sizeof(struct FsmNode))
547
548void 546void
549l3_msg(struct PStack *st, int pr, void *arg) 547l3_msg(struct PStack *st, int pr, void *arg)
550{ 548{
@@ -587,7 +585,7 @@ Isdnl3New(void)
587 l3fsm.event_count = L3_EVENT_COUNT; 585 l3fsm.event_count = L3_EVENT_COUNT;
588 l3fsm.strEvent = strL3Event; 586 l3fsm.strEvent = strL3Event;
589 l3fsm.strState = strL3State; 587 l3fsm.strState = strL3State;
590 return FsmNew(&l3fsm, L3FnList, L3_FN_COUNT); 588 return FsmNew(&l3fsm, L3FnList, ARRAY_SIZE(L3FnList));
591} 589}
592 590
593void 591void
diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c
index c5c36eeff261..b0554f80bfb3 100644
--- a/drivers/isdn/hisax/l3_1tr6.c
+++ b/drivers/isdn/hisax/l3_1tr6.c
@@ -698,9 +698,6 @@ static struct stateentry downstl[] =
698 CC_T308_2, l3_1tr6_t308_2}, 698 CC_T308_2, l3_1tr6_t308_2},
699}; 699};
700 700
701#define DOWNSTL_LEN \
702 (sizeof(downstl) / sizeof(struct stateentry))
703
704static struct stateentry datastln1[] = 701static struct stateentry datastln1[] =
705{ 702{
706 {SBIT(0), 703 {SBIT(0),
@@ -735,9 +732,6 @@ static struct stateentry datastln1[] =
735 MT_N1_REL_ACK, l3_1tr6_rel_ack} 732 MT_N1_REL_ACK, l3_1tr6_rel_ack}
736}; 733};
737 734
738#define DATASTLN1_LEN \
739 (sizeof(datastln1) / sizeof(struct stateentry))
740
741static struct stateentry manstatelist[] = 735static struct stateentry manstatelist[] =
742{ 736{
743 {SBIT(2), 737 {SBIT(2),
@@ -746,8 +740,6 @@ static struct stateentry manstatelist[] =
746 DL_RELEASE | INDICATION, l3_1tr6_dl_release}, 740 DL_RELEASE | INDICATION, l3_1tr6_dl_release},
747}; 741};
748 742
749#define MANSLLEN \
750 (sizeof(manstatelist) / sizeof(struct stateentry))
751/* *INDENT-ON* */ 743/* *INDENT-ON* */
752 744
753static void 745static void
@@ -840,11 +832,11 @@ up1tr6(struct PStack *st, int pr, void *arg)
840 mt = MT_N1_INVALID; 832 mt = MT_N1_INVALID;
841 } 833 }
842 } 834 }
843 for (i = 0; i < DATASTLN1_LEN; i++) 835 for (i = 0; i < ARRAY_SIZE(datastln1); i++)
844 if ((mt == datastln1[i].primitive) && 836 if ((mt == datastln1[i].primitive) &&
845 ((1 << proc->state) & datastln1[i].state)) 837 ((1 << proc->state) & datastln1[i].state))
846 break; 838 break;
847 if (i == DATASTLN1_LEN) { 839 if (i == ARRAY_SIZE(datastln1)) {
848 dev_kfree_skb(skb); 840 dev_kfree_skb(skb);
849 if (st->l3.debug & L3_DEB_STATE) { 841 if (st->l3.debug & L3_DEB_STATE) {
850 sprintf(tmp, "up1tr6%sstate %d mt %x unhandled", 842 sprintf(tmp, "up1tr6%sstate %d mt %x unhandled",
@@ -892,11 +884,11 @@ down1tr6(struct PStack *st, int pr, void *arg)
892 proc = arg; 884 proc = arg;
893 } 885 }
894 886
895 for (i = 0; i < DOWNSTL_LEN; i++) 887 for (i = 0; i < ARRAY_SIZE(downstl); i++)
896 if ((pr == downstl[i].primitive) && 888 if ((pr == downstl[i].primitive) &&
897 ((1 << proc->state) & downstl[i].state)) 889 ((1 << proc->state) & downstl[i].state))
898 break; 890 break;
899 if (i == DOWNSTL_LEN) { 891 if (i == ARRAY_SIZE(downstl)) {
900 if (st->l3.debug & L3_DEB_STATE) { 892 if (st->l3.debug & L3_DEB_STATE) {
901 sprintf(tmp, "down1tr6 state %d prim %d unhandled", 893 sprintf(tmp, "down1tr6 state %d prim %d unhandled",
902 proc->state, pr); 894 proc->state, pr);
@@ -922,11 +914,11 @@ man1tr6(struct PStack *st, int pr, void *arg)
922 printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr); 914 printk(KERN_ERR "HiSax man1tr6 without proc pr=%04x\n", pr);
923 return; 915 return;
924 } 916 }
925 for (i = 0; i < MANSLLEN; i++) 917 for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
926 if ((pr == manstatelist[i].primitive) && 918 if ((pr == manstatelist[i].primitive) &&
927 ((1 << proc->state) & manstatelist[i].state)) 919 ((1 << proc->state) & manstatelist[i].state))
928 break; 920 break;
929 if (i == MANSLLEN) { 921 if (i == ARRAY_SIZE(manstatelist)) {
930 if (st->l3.debug & L3_DEB_STATE) { 922 if (st->l3.debug & L3_DEB_STATE) {
931 l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled", 923 l3_debug(st, "cr %d man1tr6 state %d prim %d unhandled",
932 proc->callref & 0x7f, proc->state, pr); 924 proc->callref & 0x7f, proc->state, pr);
diff --git a/drivers/isdn/hisax/l3dss1.c b/drivers/isdn/hisax/l3dss1.c
index 99feae8b9210..a12fa4d34903 100644
--- a/drivers/isdn/hisax/l3dss1.c
+++ b/drivers/isdn/hisax/l3dss1.c
@@ -2820,9 +2820,6 @@ static struct stateentry downstatelist[] =
2820 CC_T309, l3dss1_dl_release}, 2820 CC_T309, l3dss1_dl_release},
2821}; 2821};
2822 2822
2823#define DOWNSLLEN \
2824 (sizeof(downstatelist) / sizeof(struct stateentry))
2825
2826static struct stateentry datastatelist[] = 2823static struct stateentry datastatelist[] =
2827{ 2824{
2828 {ALL_STATES, 2825 {ALL_STATES,
@@ -2875,9 +2872,6 @@ static struct stateentry datastatelist[] =
2875 MT_RESUME_REJECT, l3dss1_resume_rej}, 2872 MT_RESUME_REJECT, l3dss1_resume_rej},
2876}; 2873};
2877 2874
2878#define DATASLLEN \
2879 (sizeof(datastatelist) / sizeof(struct stateentry))
2880
2881static struct stateentry globalmes_list[] = 2875static struct stateentry globalmes_list[] =
2882{ 2876{
2883 {ALL_STATES, 2877 {ALL_STATES,
@@ -2888,8 +2882,6 @@ static struct stateentry globalmes_list[] =
2888 MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack}, 2882 MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
2889*/ 2883*/
2890}; 2884};
2891#define GLOBALM_LEN \
2892 (sizeof(globalmes_list) / sizeof(struct stateentry))
2893 2885
2894static struct stateentry manstatelist[] = 2886static struct stateentry manstatelist[] =
2895{ 2887{
@@ -2903,8 +2895,6 @@ static struct stateentry manstatelist[] =
2903 DL_RELEASE | INDICATION, l3dss1_dl_release}, 2895 DL_RELEASE | INDICATION, l3dss1_dl_release},
2904}; 2896};
2905 2897
2906#define MANSLLEN \
2907 (sizeof(manstatelist) / sizeof(struct stateentry))
2908/* *INDENT-ON* */ 2898/* *INDENT-ON* */
2909 2899
2910 2900
@@ -2918,11 +2908,11 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
2918 struct l3_process *proc = st->l3.global; 2908 struct l3_process *proc = st->l3.global;
2919 2909
2920 proc->callref = skb->data[2]; /* cr flag */ 2910 proc->callref = skb->data[2]; /* cr flag */
2921 for (i = 0; i < GLOBALM_LEN; i++) 2911 for (i = 0; i < ARRAY_SIZE(globalmes_list); i++)
2922 if ((mt == globalmes_list[i].primitive) && 2912 if ((mt == globalmes_list[i].primitive) &&
2923 ((1 << proc->state) & globalmes_list[i].state)) 2913 ((1 << proc->state) & globalmes_list[i].state))
2924 break; 2914 break;
2925 if (i == GLOBALM_LEN) { 2915 if (i == ARRAY_SIZE(globalmes_list)) {
2926 if (st->l3.debug & L3_DEB_STATE) { 2916 if (st->l3.debug & L3_DEB_STATE) {
2927 l3_debug(st, "dss1 global state %d mt %x unhandled", 2917 l3_debug(st, "dss1 global state %d mt %x unhandled",
2928 proc->state, mt); 2918 proc->state, mt);
@@ -3097,11 +3087,11 @@ dss1up(struct PStack *st, int pr, void *arg)
3097 } 3087 }
3098 if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) 3088 if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
3099 l3dss1_deliver_display(proc, pr, p); /* Display IE included */ 3089 l3dss1_deliver_display(proc, pr, p); /* Display IE included */
3100 for (i = 0; i < DATASLLEN; i++) 3090 for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
3101 if ((mt == datastatelist[i].primitive) && 3091 if ((mt == datastatelist[i].primitive) &&
3102 ((1 << proc->state) & datastatelist[i].state)) 3092 ((1 << proc->state) & datastatelist[i].state))
3103 break; 3093 break;
3104 if (i == DATASLLEN) { 3094 if (i == ARRAY_SIZE(datastatelist)) {
3105 if (st->l3.debug & L3_DEB_STATE) { 3095 if (st->l3.debug & L3_DEB_STATE) {
3106 l3_debug(st, "dss1up%sstate %d mt %#x unhandled", 3096 l3_debug(st, "dss1up%sstate %d mt %#x unhandled",
3107 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", 3097 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
@@ -3156,11 +3146,11 @@ dss1down(struct PStack *st, int pr, void *arg)
3156 return; 3146 return;
3157 } 3147 }
3158 3148
3159 for (i = 0; i < DOWNSLLEN; i++) 3149 for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
3160 if ((pr == downstatelist[i].primitive) && 3150 if ((pr == downstatelist[i].primitive) &&
3161 ((1 << proc->state) & downstatelist[i].state)) 3151 ((1 << proc->state) & downstatelist[i].state))
3162 break; 3152 break;
3163 if (i == DOWNSLLEN) { 3153 if (i == ARRAY_SIZE(downstatelist)) {
3164 if (st->l3.debug & L3_DEB_STATE) { 3154 if (st->l3.debug & L3_DEB_STATE) {
3165 l3_debug(st, "dss1down state %d prim %#x unhandled", 3155 l3_debug(st, "dss1down state %d prim %#x unhandled",
3166 proc->state, pr); 3156 proc->state, pr);
@@ -3184,11 +3174,11 @@ dss1man(struct PStack *st, int pr, void *arg)
3184 printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr); 3174 printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
3185 return; 3175 return;
3186 } 3176 }
3187 for (i = 0; i < MANSLLEN; i++) 3177 for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
3188 if ((pr == manstatelist[i].primitive) && 3178 if ((pr == manstatelist[i].primitive) &&
3189 ((1 << proc->state) & manstatelist[i].state)) 3179 ((1 << proc->state) & manstatelist[i].state))
3190 break; 3180 break;
3191 if (i == MANSLLEN) { 3181 if (i == ARRAY_SIZE(manstatelist)) {
3192 if (st->l3.debug & L3_DEB_STATE) { 3182 if (st->l3.debug & L3_DEB_STATE) {
3193 l3_debug(st, "cr %d dss1man state %d prim %#x unhandled", 3183 l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
3194 proc->callref & 0x7f, proc->state, pr); 3184 proc->callref & 0x7f, proc->state, pr);
diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c
index f7041d5ba64e..4622d43c7e10 100644
--- a/drivers/isdn/hisax/l3ni1.c
+++ b/drivers/isdn/hisax/l3ni1.c
@@ -2755,9 +2755,6 @@ static struct stateentry downstatelist[] =
2755 CC_TSPID, l3ni1_spid_tout }, 2755 CC_TSPID, l3ni1_spid_tout },
2756}; 2756};
2757 2757
2758#define DOWNSLLEN \
2759 (sizeof(downstatelist) / sizeof(struct stateentry))
2760
2761static struct stateentry datastatelist[] = 2758static struct stateentry datastatelist[] =
2762{ 2759{
2763 {ALL_STATES, 2760 {ALL_STATES,
@@ -2810,9 +2807,6 @@ static struct stateentry datastatelist[] =
2810 MT_RESUME_REJECT, l3ni1_resume_rej}, 2807 MT_RESUME_REJECT, l3ni1_resume_rej},
2811}; 2808};
2812 2809
2813#define DATASLLEN \
2814 (sizeof(datastatelist) / sizeof(struct stateentry))
2815
2816static struct stateentry globalmes_list[] = 2810static struct stateentry globalmes_list[] =
2817{ 2811{
2818 {ALL_STATES, 2812 {ALL_STATES,
@@ -2825,8 +2819,6 @@ static struct stateentry globalmes_list[] =
2825 { SBIT( 0 ), MT_DL_ESTABLISHED, l3ni1_spid_send }, 2819 { SBIT( 0 ), MT_DL_ESTABLISHED, l3ni1_spid_send },
2826 { SBIT( 20 ) | SBIT( 21 ) | SBIT( 22 ), MT_INFORMATION, l3ni1_spid_epid }, 2820 { SBIT( 20 ) | SBIT( 21 ) | SBIT( 22 ), MT_INFORMATION, l3ni1_spid_epid },
2827}; 2821};
2828#define GLOBALM_LEN \
2829 (sizeof(globalmes_list) / sizeof(struct stateentry))
2830 2822
2831static struct stateentry manstatelist[] = 2823static struct stateentry manstatelist[] =
2832{ 2824{
@@ -2840,8 +2832,6 @@ static struct stateentry manstatelist[] =
2840 DL_RELEASE | INDICATION, l3ni1_dl_release}, 2832 DL_RELEASE | INDICATION, l3ni1_dl_release},
2841}; 2833};
2842 2834
2843#define MANSLLEN \
2844 (sizeof(manstatelist) / sizeof(struct stateentry))
2845/* *INDENT-ON* */ 2835/* *INDENT-ON* */
2846 2836
2847 2837
@@ -2858,11 +2848,11 @@ global_handler(struct PStack *st, int mt, struct sk_buff *skb)
2858 proc->callref = skb->data[2]; /* cr flag */ 2848 proc->callref = skb->data[2]; /* cr flag */
2859 else 2849 else
2860 proc->callref = 0; 2850 proc->callref = 0;
2861 for (i = 0; i < GLOBALM_LEN; i++) 2851 for (i = 0; i < ARRAY_SIZE(globalmes_list); i++)
2862 if ((mt == globalmes_list[i].primitive) && 2852 if ((mt == globalmes_list[i].primitive) &&
2863 ((1 << proc->state) & globalmes_list[i].state)) 2853 ((1 << proc->state) & globalmes_list[i].state))
2864 break; 2854 break;
2865 if (i == GLOBALM_LEN) { 2855 if (i == ARRAY_SIZE(globalmes_list)) {
2866 if (st->l3.debug & L3_DEB_STATE) { 2856 if (st->l3.debug & L3_DEB_STATE) {
2867 l3_debug(st, "ni1 global state %d mt %x unhandled", 2857 l3_debug(st, "ni1 global state %d mt %x unhandled",
2868 proc->state, mt); 2858 proc->state, mt);
@@ -3049,11 +3039,11 @@ ni1up(struct PStack *st, int pr, void *arg)
3049 } 3039 }
3050 if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL) 3040 if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
3051 l3ni1_deliver_display(proc, pr, p); /* Display IE included */ 3041 l3ni1_deliver_display(proc, pr, p); /* Display IE included */
3052 for (i = 0; i < DATASLLEN; i++) 3042 for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
3053 if ((mt == datastatelist[i].primitive) && 3043 if ((mt == datastatelist[i].primitive) &&
3054 ((1 << proc->state) & datastatelist[i].state)) 3044 ((1 << proc->state) & datastatelist[i].state))
3055 break; 3045 break;
3056 if (i == DATASLLEN) { 3046 if (i == ARRAY_SIZE(datastatelist)) {
3057 if (st->l3.debug & L3_DEB_STATE) { 3047 if (st->l3.debug & L3_DEB_STATE) {
3058 l3_debug(st, "ni1up%sstate %d mt %#x unhandled", 3048 l3_debug(st, "ni1up%sstate %d mt %#x unhandled",
3059 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", 3049 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
@@ -3108,11 +3098,11 @@ ni1down(struct PStack *st, int pr, void *arg)
3108 return; 3098 return;
3109 } 3099 }
3110 3100
3111 for (i = 0; i < DOWNSLLEN; i++) 3101 for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
3112 if ((pr == downstatelist[i].primitive) && 3102 if ((pr == downstatelist[i].primitive) &&
3113 ((1 << proc->state) & downstatelist[i].state)) 3103 ((1 << proc->state) & downstatelist[i].state))
3114 break; 3104 break;
3115 if (i == DOWNSLLEN) { 3105 if (i == ARRAY_SIZE(downstatelist)) {
3116 if (st->l3.debug & L3_DEB_STATE) { 3106 if (st->l3.debug & L3_DEB_STATE) {
3117 l3_debug(st, "ni1down state %d prim %#x unhandled", 3107 l3_debug(st, "ni1down state %d prim %#x unhandled",
3118 proc->state, pr); 3108 proc->state, pr);
@@ -3136,11 +3126,11 @@ ni1man(struct PStack *st, int pr, void *arg)
3136 printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr); 3126 printk(KERN_ERR "HiSax ni1man without proc pr=%04x\n", pr);
3137 return; 3127 return;
3138 } 3128 }
3139 for (i = 0; i < MANSLLEN; i++) 3129 for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
3140 if ((pr == manstatelist[i].primitive) && 3130 if ((pr == manstatelist[i].primitive) &&
3141 ((1 << proc->state) & manstatelist[i].state)) 3131 ((1 << proc->state) & manstatelist[i].state))
3142 break; 3132 break;
3143 if (i == MANSLLEN) { 3133 if (i == ARRAY_SIZE(manstatelist)) {
3144 if (st->l3.debug & L3_DEB_STATE) { 3134 if (st->l3.debug & L3_DEB_STATE) {
3145 l3_debug(st, "cr %d ni1man state %d prim %#x unhandled", 3135 l3_debug(st, "cr %d ni1man state %d prim %#x unhandled",
3146 proc->callref & 0x7f, proc->state, pr); 3136 proc->callref & 0x7f, proc->state, pr);
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c
index aacbf0d14b64..8b853d58e820 100644
--- a/drivers/isdn/hisax/q931.c
+++ b/drivers/isdn/hisax/q931.c
@@ -140,7 +140,7 @@ struct MessageType {
140 } 140 }
141}; 141};
142 142
143#define MTSIZE sizeof(mtlist)/sizeof(struct MessageType) 143#define MTSIZE ARRAY_SIZE(mtlist)
144 144
145static 145static
146struct MessageType mt_n0[] = 146struct MessageType mt_n0[] =
@@ -157,7 +157,7 @@ struct MessageType mt_n0[] =
157 {MT_N0_CLO_ACK, "CLOse ACKnowledge"} 157 {MT_N0_CLO_ACK, "CLOse ACKnowledge"}
158}; 158};
159 159
160#define MT_N0_LEN (sizeof(mt_n0) / sizeof(struct MessageType)) 160#define MT_N0_LEN ARRAY_SIZE(mt_n0)
161 161
162static 162static
163struct MessageType mt_n1[] = 163struct MessageType mt_n1[] =
@@ -194,7 +194,7 @@ struct MessageType mt_n1[] =
194 {MT_N1_STAT, "STATus"} 194 {MT_N1_STAT, "STATus"}
195}; 195};
196 196
197#define MT_N1_LEN (sizeof(mt_n1) / sizeof(struct MessageType)) 197#define MT_N1_LEN ARRAY_SIZE(mt_n1)
198 198
199 199
200static int 200static int
@@ -438,7 +438,7 @@ struct CauseValue {
438 }, 438 },
439}; 439};
440 440
441#define CVSIZE sizeof(cvlist)/sizeof(struct CauseValue) 441#define CVSIZE ARRAY_SIZE(cvlist)
442 442
443static 443static
444int 444int
@@ -516,7 +516,7 @@ struct MessageType cause_1tr6[] =
516 {CAUSE_UserInfoDiscarded, "User Info Discarded"} 516 {CAUSE_UserInfoDiscarded, "User Info Discarded"}
517}; 517};
518 518
519static int cause_1tr6_len = (sizeof(cause_1tr6) / sizeof(struct MessageType)); 519static int cause_1tr6_len = ARRAY_SIZE(cause_1tr6);
520 520
521static int 521static int
522prcause_1tr6(char *dest, u_char * p) 522prcause_1tr6(char *dest, u_char * p)
@@ -865,7 +865,7 @@ struct DTag { /* Display tags */
865 { 0x96, "Redirection name" }, 865 { 0x96, "Redirection name" },
866 { 0x9e, "Text" }, 866 { 0x9e, "Text" },
867}; 867};
868#define DTAGSIZE sizeof(dtaglist)/sizeof(struct DTag) 868#define DTAGSIZE ARRAY_SIZE(dtaglist)
869 869
870static int 870static int
871disptext_ni1(char *dest, u_char * p) 871disptext_ni1(char *dest, u_char * p)
@@ -1074,7 +1074,7 @@ struct InformationElement {
1074}; 1074};
1075 1075
1076 1076
1077#define IESIZE sizeof(ielist)/sizeof(struct InformationElement) 1077#define IESIZE ARRAY_SIZE(ielist)
1078 1078
1079static 1079static
1080struct InformationElement ielist_ni1[] = { 1080struct InformationElement ielist_ni1[] = {
@@ -1102,7 +1102,7 @@ struct InformationElement ielist_ni1[] = {
1102}; 1102};
1103 1103
1104 1104
1105#define IESIZE_NI1 sizeof(ielist_ni1)/sizeof(struct InformationElement) 1105#define IESIZE_NI1 ARRAY_SIZE(ielist_ni1)
1106 1106
1107static 1107static
1108struct InformationElement ielist_ni1_cs5[] = { 1108struct InformationElement ielist_ni1_cs5[] = {
@@ -1110,14 +1110,14 @@ struct InformationElement ielist_ni1_cs5[] = {
1110 { 0x2a, "Display text", disptext_ni1 }, 1110 { 0x2a, "Display text", disptext_ni1 },
1111}; 1111};
1112 1112
1113#define IESIZE_NI1_CS5 sizeof(ielist_ni1_cs5)/sizeof(struct InformationElement) 1113#define IESIZE_NI1_CS5 ARRAY_SIZE(ielist_ni1_cs5)
1114 1114
1115static 1115static
1116struct InformationElement ielist_ni1_cs6[] = { 1116struct InformationElement ielist_ni1_cs6[] = {
1117 { 0x7b, "Call appearance", general_ni1 }, 1117 { 0x7b, "Call appearance", general_ni1 },
1118}; 1118};
1119 1119
1120#define IESIZE_NI1_CS6 sizeof(ielist_ni1_cs6)/sizeof(struct InformationElement) 1120#define IESIZE_NI1_CS6 ARRAY_SIZE(ielist_ni1_cs6)
1121 1121
1122static struct InformationElement we_0[] = 1122static struct InformationElement we_0[] =
1123{ 1123{
@@ -1133,7 +1133,7 @@ static struct InformationElement we_0[] =
1133 {WE0_userInfo, "User Info", general} 1133 {WE0_userInfo, "User Info", general}
1134}; 1134};
1135 1135
1136#define WE_0_LEN (sizeof(we_0) / sizeof(struct InformationElement)) 1136#define WE_0_LEN ARRAY_SIZE(we_0)
1137 1137
1138static struct InformationElement we_6[] = 1138static struct InformationElement we_6[] =
1139{ 1139{
@@ -1145,7 +1145,7 @@ static struct InformationElement we_6[] =
1145 {WE6_statusCalled, "Status Called", general}, 1145 {WE6_statusCalled, "Status Called", general},
1146 {WE6_addTransAttr, "Additional Transmission Attributes", general} 1146 {WE6_addTransAttr, "Additional Transmission Attributes", general}
1147}; 1147};
1148#define WE_6_LEN (sizeof(we_6) / sizeof(struct InformationElement)) 1148#define WE_6_LEN ARRAY_SIZE(we_6)
1149 1149
1150int 1150int
1151QuickHex(char *txt, u_char * p, int cnt) 1151QuickHex(char *txt, u_char * p, int cnt)
diff --git a/drivers/isdn/hisax/st5481.h b/drivers/isdn/hisax/st5481.h
index cff7a6354334..64f78a8c28c5 100644
--- a/drivers/isdn/hisax/st5481.h
+++ b/drivers/isdn/hisax/st5481.h
@@ -226,7 +226,7 @@ printk(KERN_WARNING "%s:%s: " format "\n" , __FILE__, __func__ , ## arg)
226#define INFO(format, arg...) \ 226#define INFO(format, arg...) \
227printk(KERN_INFO "%s:%s: " format "\n" , __FILE__, __func__ , ## arg) 227printk(KERN_INFO "%s:%s: " format "\n" , __FILE__, __func__ , ## arg)
228 228
229#include "isdnhdlc.h" 229#include <linux/isdn/hdlc.h>
230#include "fsm.h" 230#include "fsm.h"
231#include "hisax_if.h" 231#include "hisax_if.h"
232#include <linux/skbuff.h> 232#include <linux/skbuff.h>
diff --git a/drivers/isdn/hisax/st5481_b.c b/drivers/isdn/hisax/st5481_b.c
index 0074b600a0ef..95b1cdd97958 100644
--- a/drivers/isdn/hisax/st5481_b.c
+++ b/drivers/isdn/hisax/st5481_b.c
@@ -218,7 +218,10 @@ static void st5481B_mode(struct st5481_bcs *bcs, int mode)
218 if (bcs->mode != L1_MODE_NULL) { 218 if (bcs->mode != L1_MODE_NULL) {
219 // Open the B channel 219 // Open the B channel
220 if (bcs->mode != L1_MODE_TRANS) { 220 if (bcs->mode != L1_MODE_TRANS) {
221 isdnhdlc_out_init(&b_out->hdlc_state, 0, bcs->mode == L1_MODE_HDLC_56K); 221 u32 features = HDLC_BITREVERSE;
222 if (bcs->mode == L1_MODE_HDLC_56K)
223 features |= HDLC_56KBIT;
224 isdnhdlc_out_init(&b_out->hdlc_state, features);
222 } 225 }
223 st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL); 226 st5481_usb_pipe_reset(adapter, (bcs->channel+1)*2, NULL, NULL);
224 227
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c
index 077991c1cd05..39e8e49cfd2d 100644
--- a/drivers/isdn/hisax/st5481_d.c
+++ b/drivers/isdn/hisax/st5481_d.c
@@ -417,7 +417,7 @@ static void dout_start_xmit(struct FsmInst *fsm, int event, void *arg)
417 417
418 DBG(2,"len=%d",skb->len); 418 DBG(2,"len=%d",skb->len);
419 419
420 isdnhdlc_out_init(&d_out->hdlc_state, 1, 0); 420 isdnhdlc_out_init(&d_out->hdlc_state, HDLC_DCHANNEL | HDLC_BITREVERSE);
421 421
422 if (test_and_set_bit(buf_nr, &d_out->busy)) { 422 if (test_and_set_bit(buf_nr, &d_out->busy)) {
423 WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy); 423 WARNING("ep %d urb %d busy %#lx", EP_D_OUT, buf_nr, d_out->busy);
diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c
index 2b3a055059ea..10d41c5d73ed 100644
--- a/drivers/isdn/hisax/st5481_usb.c
+++ b/drivers/isdn/hisax/st5481_usb.c
@@ -637,10 +637,13 @@ void st5481_in_mode(struct st5481_in *in, int mode)
637 usb_unlink_urb(in->urb[1]); 637 usb_unlink_urb(in->urb[1]);
638 638
639 if (in->mode != L1_MODE_NULL) { 639 if (in->mode != L1_MODE_NULL) {
640 if (in->mode != L1_MODE_TRANS) 640 if (in->mode != L1_MODE_TRANS) {
641 isdnhdlc_rcv_init(&in->hdlc_state, 641 u32 features = HDLC_BITREVERSE;
642 in->mode == L1_MODE_HDLC_56K); 642
643 643 if (in->mode == L1_MODE_HDLC_56K)
644 features |= HDLC_56KBIT;
645 isdnhdlc_rcv_init(&in->hdlc_state, features);
646 }
644 st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL); 647 st5481_usb_pipe_reset(in->adapter, in->ep, NULL, NULL);
645 st5481_usb_device_ctrl_msg(in->adapter, in->counter, 648 st5481_usb_device_ctrl_msg(in->adapter, in->counter,
646 in->packet_size, 649 in->packet_size,
diff --git a/drivers/isdn/hisax/tei.c b/drivers/isdn/hisax/tei.c
index ceb0df92fd3e..6e65424f1f04 100644
--- a/drivers/isdn/hisax/tei.c
+++ b/drivers/isdn/hisax/tei.c
@@ -447,8 +447,6 @@ static struct FsmNode TeiFnList[] __initdata =
447 {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req}, 447 {ST_TEI_IDVERIFY, EV_CHKREQ, tei_id_chk_req},
448}; 448};
449 449
450#define TEI_FN_COUNT (sizeof(TeiFnList)/sizeof(struct FsmNode))
451
452int __init 450int __init
453TeiNew(void) 451TeiNew(void)
454{ 452{
@@ -456,7 +454,7 @@ TeiNew(void)
456 teifsm.event_count = TEI_EVENT_COUNT; 454 teifsm.event_count = TEI_EVENT_COUNT;
457 teifsm.strEvent = strTeiEvent; 455 teifsm.strEvent = strTeiEvent;
458 teifsm.strState = strTeiState; 456 teifsm.strState = strTeiState;
459 return FsmNew(&teifsm, TeiFnList, TEI_FN_COUNT); 457 return FsmNew(&teifsm, TeiFnList, ARRAY_SIZE(TeiFnList));
460} 458}
461 459
462void 460void
diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c
index bb1c8dd1a230..c4d862c11a60 100644
--- a/drivers/isdn/hisax/w6692.c
+++ b/drivers/isdn/hisax/w6692.c
@@ -105,8 +105,6 @@ W6692_bh(struct work_struct *work)
105 container_of(work, struct IsdnCardState, tqueue); 105 container_of(work, struct IsdnCardState, tqueue);
106 struct PStack *stptr; 106 struct PStack *stptr;
107 107
108 if (!cs)
109 return;
110 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) { 108 if (test_and_clear_bit(D_CLEARBUSY, &cs->event)) {
111 if (cs->debug) 109 if (cs->debug)
112 debugl1(cs, "D-Channel Busy cleared"); 110 debugl1(cs, "D-Channel Busy cleared");
diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c
index 579974cf4c9a..c73004b3b2ac 100644
--- a/drivers/isdn/hysdn/hysdn_net.c
+++ b/drivers/isdn/hysdn/hysdn_net.c
@@ -148,7 +148,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
148 if (lp->sk_count <= 3) { 148 if (lp->sk_count <= 3) {
149 schedule_work(&((hysdn_card *) dev->ml_priv)->irq_queue); 149 schedule_work(&((hysdn_card *) dev->ml_priv)->irq_queue);
150 } 150 }
151 return (0); /* success */ 151 return NETDEV_TX_OK; /* success */
152} /* net_send_packet */ 152} /* net_send_packet */
153 153
154 154
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig
index ed3510f273d8..dd744ffd240b 100644
--- a/drivers/isdn/i4l/Kconfig
+++ b/drivers/isdn/i4l/Kconfig
@@ -2,6 +2,8 @@
2# Old ISDN4Linux config 2# Old ISDN4Linux config
3# 3#
4 4
5if ISDN_I4L
6
5config ISDN_PPP 7config ISDN_PPP
6 bool "Support synchronous PPP" 8 bool "Support synchronous PPP"
7 depends on INET 9 depends on INET
@@ -135,3 +137,12 @@ source "drivers/isdn/act2000/Kconfig"
135source "drivers/isdn/hysdn/Kconfig" 137source "drivers/isdn/hysdn/Kconfig"
136 138
137endmenu 139endmenu
140# end ISDN_I4L
141endif
142
143config ISDN_HDLC
144 tristate
145 depends on HISAX_ST5481
146 select CRC_CCITT
147 select BITREVERSE
148
diff --git a/drivers/isdn/i4l/Makefile b/drivers/isdn/i4l/Makefile
index 49a06c0005dd..cb9d3bb9fae0 100644
--- a/drivers/isdn/i4l/Makefile
+++ b/drivers/isdn/i4l/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_ISDN_I4L) += isdn.o 5obj-$(CONFIG_ISDN_I4L) += isdn.o
6obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o 6obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
7obj-$(CONFIG_ISDN_HDLC) += isdnhdlc.o
7 8
8# Multipart objects. 9# Multipart objects.
9 10
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index de4aad076ebc..57bf4bf50278 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -1051,12 +1051,12 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
1051 isdn_net_dev *nd; 1051 isdn_net_dev *nd;
1052 isdn_net_local *slp; 1052 isdn_net_local *slp;
1053 isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev); 1053 isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
1054 int retv = 0; 1054 int retv = NETDEV_TX_OK;
1055 1055
1056 if (((isdn_net_local *) netdev_priv(ndev))->master) { 1056 if (((isdn_net_local *) netdev_priv(ndev))->master) {
1057 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__); 1057 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1058 dev_kfree_skb(skb); 1058 dev_kfree_skb(skb);
1059 return 0; 1059 return NETDEV_TX_OK;
1060 } 1060 }
1061 1061
1062 /* For the other encaps the header has already been built */ 1062 /* For the other encaps the header has already been built */
@@ -1202,7 +1202,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1202 if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) { 1202 if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
1203 isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'"); 1203 isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
1204 dev_kfree_skb(skb); 1204 dev_kfree_skb(skb);
1205 return 0; 1205 return NETDEV_TX_OK;
1206 } 1206 }
1207 if (lp->phone[1]) { 1207 if (lp->phone[1]) {
1208 ulong flags; 1208 ulong flags;
@@ -1215,7 +1215,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1215 if(time_before(jiffies, lp->dialwait_timer)) { 1215 if(time_before(jiffies, lp->dialwait_timer)) {
1216 isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached"); 1216 isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
1217 dev_kfree_skb(skb); 1217 dev_kfree_skb(skb);
1218 return 0; 1218 return NETDEV_TX_OK;
1219 } else 1219 } else
1220 lp->dialwait_timer = 0; 1220 lp->dialwait_timer = 0;
1221 } 1221 }
@@ -1243,7 +1243,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1243 isdn_net_unreachable(ndev, skb, 1243 isdn_net_unreachable(ndev, skb,
1244 "No channel"); 1244 "No channel");
1245 dev_kfree_skb(skb); 1245 dev_kfree_skb(skb);
1246 return 0; 1246 return NETDEV_TX_OK;
1247 } 1247 }
1248 /* Log packet, which triggered dialing */ 1248 /* Log packet, which triggered dialing */
1249 if (dev->net_verbose) 1249 if (dev->net_verbose)
@@ -1258,7 +1258,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1258 dev_kfree_skb(skb); 1258 dev_kfree_skb(skb);
1259 isdn_net_unbind_channel(lp); 1259 isdn_net_unbind_channel(lp);
1260 spin_unlock_irqrestore(&dev->lock, flags); 1260 spin_unlock_irqrestore(&dev->lock, flags);
1261 return 0; /* STN (skb to nirvana) ;) */ 1261 return NETDEV_TX_OK; /* STN (skb to nirvana) ;) */
1262 } 1262 }
1263#ifdef CONFIG_IPPP_FILTER 1263#ifdef CONFIG_IPPP_FILTER
1264 if (isdn_ppp_autodial_filter(skb, lp)) { 1264 if (isdn_ppp_autodial_filter(skb, lp)) {
@@ -1267,7 +1267,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1267 spin_unlock_irqrestore(&dev->lock, flags); 1267 spin_unlock_irqrestore(&dev->lock, flags);
1268 isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered"); 1268 isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
1269 dev_kfree_skb(skb); 1269 dev_kfree_skb(skb);
1270 return 0; 1270 return NETDEV_TX_OK;
1271 } 1271 }
1272#endif 1272#endif
1273 spin_unlock_irqrestore(&dev->lock, flags); 1273 spin_unlock_irqrestore(&dev->lock, flags);
@@ -1285,7 +1285,7 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1285 isdn_net_unreachable(ndev, skb, 1285 isdn_net_unreachable(ndev, skb,
1286 "No phone number"); 1286 "No phone number");
1287 dev_kfree_skb(skb); 1287 dev_kfree_skb(skb);
1288 return 0; 1288 return NETDEV_TX_OK;
1289 } 1289 }
1290 } else { 1290 } else {
1291 /* Device is connected to an ISDN channel */ 1291 /* Device is connected to an ISDN channel */
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index aa30b5cb3513..2d14b64202a3 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -1223,7 +1223,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1223 isdn_net_dev *nd; 1223 isdn_net_dev *nd;
1224 unsigned int proto = PPP_IP; /* 0x21 */ 1224 unsigned int proto = PPP_IP; /* 0x21 */
1225 struct ippp_struct *ipt,*ipts; 1225 struct ippp_struct *ipt,*ipts;
1226 int slot, retval = 0; 1226 int slot, retval = NETDEV_TX_OK;
1227 1227
1228 mlp = (isdn_net_local *) netdev_priv(netdev); 1228 mlp = (isdn_net_local *) netdev_priv(netdev);
1229 nd = mlp->netdev; /* get master lp */ 1229 nd = mlp->netdev; /* get master lp */
@@ -1240,7 +1240,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1240 if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */ 1240 if (!(ipts->pppcfg & SC_ENABLE_IP)) { /* PPP connected ? */
1241 if (ipts->debug & 0x1) 1241 if (ipts->debug & 0x1)
1242 printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name); 1242 printk(KERN_INFO "%s: IP frame delayed.\n", netdev->name);
1243 retval = 1; 1243 retval = NETDEV_TX_BUSY;
1244 goto out; 1244 goto out;
1245 } 1245 }
1246 1246
@@ -1261,7 +1261,7 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev)
1261 lp = isdn_net_get_locked_lp(nd); 1261 lp = isdn_net_get_locked_lp(nd);
1262 if (!lp) { 1262 if (!lp) {
1263 printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name); 1263 printk(KERN_WARNING "%s: all channels busy - requeuing!\n", netdev->name);
1264 retval = 1; 1264 retval = NETDEV_TX_BUSY;
1265 goto out; 1265 goto out;
1266 } 1266 }
1267 /* we have our lp locked from now on */ 1267 /* we have our lp locked from now on */
diff --git a/drivers/isdn/hisax/isdnhdlc.c b/drivers/isdn/i4l/isdnhdlc.c
index c69a77a80062..c989aa35dc2f 100644
--- a/drivers/isdn/hisax/isdnhdlc.c
+++ b/drivers/isdn/i4l/isdnhdlc.c
@@ -1,29 +1,32 @@
1/* 1/*
2 * isdnhdlc.c -- General purpose ISDN HDLC decoder. 2 * isdnhdlc.c -- General purpose ISDN HDLC decoder.
3 * 3 *
4 *Copyright (C) 2002 Wolfgang Mües <wolfgang@iksw-muees.de> 4 * Copyright (C)
5 * 2001 Frode Isaksen <fisaksen@bewan.com> 5 * 2009 Karsten Keil <keil@b1-systems.de>
6 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de> 6 * 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
7 * 2001 Frode Isaksen <fisaksen@bewan.com>
8 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
7 * 9 *
8 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 13 * (at your option) any later version.
12 * 14 *
13 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 18 * GNU General Public License for more details.
17 * 19 *
18 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 23 */
22 24
23#include <linux/module.h> 25#include <linux/module.h>
24#include <linux/init.h> 26#include <linux/init.h>
25#include <linux/crc-ccitt.h> 27#include <linux/crc-ccitt.h>
26#include "isdnhdlc.h" 28#include <linux/isdn/hdlc.h>
29#include <linux/bitrev.h>
27 30
28/*-------------------------------------------------------------------*/ 31/*-------------------------------------------------------------------*/
29 32
@@ -36,44 +39,32 @@ MODULE_LICENSE("GPL");
36/*-------------------------------------------------------------------*/ 39/*-------------------------------------------------------------------*/
37 40
38enum { 41enum {
39 HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7, 42 HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
40 HDLC_GET_DATA,HDLC_FAST_FLAG 43 HDLC_GET_DATA, HDLC_FAST_FLAG
41}; 44};
42 45
43enum { 46enum {
44 HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG, 47 HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
45 HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG, 48 HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
46 HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0, 49 HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
47 HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED 50 HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
48}; 51};
49 52
50void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56) 53void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
51{ 54{
52 hdlc->bit_shift = 0; 55 memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
53 hdlc->hdlc_bits1 = 0;
54 hdlc->data_bits = 0;
55 hdlc->ffbit_shift = 0;
56 hdlc->data_received = 0;
57 hdlc->state = HDLC_GET_DATA; 56 hdlc->state = HDLC_GET_DATA;
58 hdlc->do_adapt56 = do_adapt56; 57 if (features & HDLC_56KBIT)
59 hdlc->dchannel = 0; 58 hdlc->do_adapt56 = 1;
60 hdlc->crc = 0; 59 if (features & HDLC_BITREVERSE)
61 hdlc->cbin = 0; 60 hdlc->do_bitreverse = 1;
62 hdlc->shift_reg = 0;
63 hdlc->ffvalue = 0;
64 hdlc->dstpos = 0;
65} 61}
62EXPORT_SYMBOL(isdnhdlc_out_init);
66 63
67void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56) 64void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
68{ 65{
69 hdlc->bit_shift = 0; 66 memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
70 hdlc->hdlc_bits1 = 0; 67 if (features & HDLC_DCHANNEL) {
71 hdlc->data_bits = 0;
72 hdlc->ffbit_shift = 0;
73 hdlc->data_received = 0;
74 hdlc->do_closing = 0;
75 hdlc->ffvalue = 0;
76 if (is_d_channel) {
77 hdlc->dchannel = 1; 68 hdlc->dchannel = 1;
78 hdlc->state = HDLC_SEND_FIRST_FLAG; 69 hdlc->state = HDLC_SEND_FIRST_FLAG;
79 } else { 70 } else {
@@ -82,16 +73,32 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
82 hdlc->ffvalue = 0x7e; 73 hdlc->ffvalue = 0x7e;
83 } 74 }
84 hdlc->cbin = 0x7e; 75 hdlc->cbin = 0x7e;
85 hdlc->bit_shift = 0; 76 if (features & HDLC_56KBIT) {
86 if(do_adapt56){
87 hdlc->do_adapt56 = 1; 77 hdlc->do_adapt56 = 1;
88 hdlc->data_bits = 0;
89 hdlc->state = HDLC_SENDFLAG_B0; 78 hdlc->state = HDLC_SENDFLAG_B0;
90 } else { 79 } else
91 hdlc->do_adapt56 = 0;
92 hdlc->data_bits = 8; 80 hdlc->data_bits = 8;
81 if (features & HDLC_BITREVERSE)
82 hdlc->do_bitreverse = 1;
83}
84EXPORT_SYMBOL(isdnhdlc_rcv_init);
85
86static int
87check_frame(struct isdnhdlc_vars *hdlc)
88{
89 int status;
90
91 if (hdlc->dstpos < 2) /* too small - framing error */
92 status = -HDLC_FRAMING_ERROR;
93 else if (hdlc->crc != 0xf0b8) /* crc error */
94 status = -HDLC_CRC_ERROR;
95 else {
96 /* remove CRC */
97 hdlc->dstpos -= 2;
98 /* good frame */
99 status = hdlc->dstpos;
93 } 100 }
94 hdlc->shift_reg = 0; 101 return status;
95} 102}
96 103
97/* 104/*
@@ -121,40 +128,67 @@ void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_ada
121 returns - number of decoded bytes in the destination buffer and status 128 returns - number of decoded bytes in the destination buffer and status
122 flag. 129 flag.
123 */ 130 */
124int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src, 131int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
125 int slen, int *count, unsigned char *dst, int dsize) 132 int *count, u8 *dst, int dsize)
126{ 133{
127 int status=0; 134 int status = 0;
128 135
129 static const unsigned char fast_flag[]={ 136 static const unsigned char fast_flag[] = {
130 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f 137 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
131 }; 138 };
132 139
133 static const unsigned char fast_flag_value[]={ 140 static const unsigned char fast_flag_value[] = {
134 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f 141 0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
135 }; 142 };
136 143
137 static const unsigned char fast_abort[]={ 144 static const unsigned char fast_abort[] = {
138 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff 145 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
139 }; 146 };
140 147
148#define handle_fast_flag(h) \
149 do {\
150 if (h->cbin == fast_flag[h->bit_shift]) {\
151 h->ffvalue = fast_flag_value[h->bit_shift];\
152 h->state = HDLC_FAST_FLAG;\
153 h->ffbit_shift = h->bit_shift;\
154 h->bit_shift = 1;\
155 } else {\
156 h->state = HDLC_GET_DATA;\
157 h->data_received = 0;\
158 } \
159 } while (0)
160
161#define handle_abort(h) \
162 do {\
163 h->shift_reg = fast_abort[h->ffbit_shift - 1];\
164 h->hdlc_bits1 = h->ffbit_shift - 2;\
165 if (h->hdlc_bits1 < 0)\
166 h->hdlc_bits1 = 0;\
167 h->data_bits = h->ffbit_shift - 1;\
168 h->state = HDLC_GET_DATA;\
169 h->data_received = 0;\
170 } while (0)
171
141 *count = slen; 172 *count = slen;
142 173
143 while(slen > 0){ 174 while (slen > 0) {
144 if(hdlc->bit_shift==0){ 175 if (hdlc->bit_shift == 0) {
145 hdlc->cbin = *src++; 176 /* the code is for bitreverse streams */
177 if (hdlc->do_bitreverse == 0)
178 hdlc->cbin = bitrev8(*src++);
179 else
180 hdlc->cbin = *src++;
146 slen--; 181 slen--;
147 hdlc->bit_shift = 8; 182 hdlc->bit_shift = 8;
148 if(hdlc->do_adapt56){ 183 if (hdlc->do_adapt56)
149 hdlc->bit_shift --; 184 hdlc->bit_shift--;
150 }
151 } 185 }
152 186
153 switch(hdlc->state){ 187 switch (hdlc->state) {
154 case STOPPED: 188 case STOPPED:
155 return 0; 189 return 0;
156 case HDLC_FAST_IDLE: 190 case HDLC_FAST_IDLE:
157 if(hdlc->cbin == 0xff){ 191 if (hdlc->cbin == 0xff) {
158 hdlc->bit_shift = 0; 192 hdlc->bit_shift = 0;
159 break; 193 break;
160 } 194 }
@@ -163,32 +197,30 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
163 hdlc->bit_shift = 8; 197 hdlc->bit_shift = 8;
164 break; 198 break;
165 case HDLC_GET_FLAG_B0: 199 case HDLC_GET_FLAG_B0:
166 if(!(hdlc->cbin & 0x80)) { 200 if (!(hdlc->cbin & 0x80)) {
167 hdlc->state = HDLC_GETFLAG_B1A6; 201 hdlc->state = HDLC_GETFLAG_B1A6;
168 hdlc->hdlc_bits1 = 0; 202 hdlc->hdlc_bits1 = 0;
169 } else { 203 } else {
170 if(!hdlc->do_adapt56){ 204 if ((!hdlc->do_adapt56) &&
171 if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1) 205 (++hdlc->hdlc_bits1 >= 8) &&
206 (hdlc->bit_shift == 1))
172 hdlc->state = HDLC_FAST_IDLE; 207 hdlc->state = HDLC_FAST_IDLE;
173 }
174 } 208 }
175 hdlc->cbin<<=1; 209 hdlc->cbin <<= 1;
176 hdlc->bit_shift --; 210 hdlc->bit_shift--;
177 break; 211 break;
178 case HDLC_GETFLAG_B1A6: 212 case HDLC_GETFLAG_B1A6:
179 if(hdlc->cbin & 0x80){ 213 if (hdlc->cbin & 0x80) {
180 hdlc->hdlc_bits1++; 214 hdlc->hdlc_bits1++;
181 if(hdlc->hdlc_bits1==6){ 215 if (hdlc->hdlc_bits1 == 6)
182 hdlc->state = HDLC_GETFLAG_B7; 216 hdlc->state = HDLC_GETFLAG_B7;
183 } 217 } else
184 } else {
185 hdlc->hdlc_bits1 = 0; 218 hdlc->hdlc_bits1 = 0;
186 } 219 hdlc->cbin <<= 1;
187 hdlc->cbin<<=1; 220 hdlc->bit_shift--;
188 hdlc->bit_shift --;
189 break; 221 break;
190 case HDLC_GETFLAG_B7: 222 case HDLC_GETFLAG_B7:
191 if(hdlc->cbin & 0x80) { 223 if (hdlc->cbin & 0x80) {
192 hdlc->state = HDLC_GET_FLAG_B0; 224 hdlc->state = HDLC_GET_FLAG_B0;
193 } else { 225 } else {
194 hdlc->state = HDLC_GET_DATA; 226 hdlc->state = HDLC_GET_DATA;
@@ -198,74 +230,55 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
198 hdlc->data_bits = 0; 230 hdlc->data_bits = 0;
199 hdlc->data_received = 0; 231 hdlc->data_received = 0;
200 } 232 }
201 hdlc->cbin<<=1; 233 hdlc->cbin <<= 1;
202 hdlc->bit_shift --; 234 hdlc->bit_shift--;
203 break; 235 break;
204 case HDLC_GET_DATA: 236 case HDLC_GET_DATA:
205 if(hdlc->cbin & 0x80){ 237 if (hdlc->cbin & 0x80) {
206 hdlc->hdlc_bits1++; 238 hdlc->hdlc_bits1++;
207 switch(hdlc->hdlc_bits1){ 239 switch (hdlc->hdlc_bits1) {
208 case 6: 240 case 6:
209 break; 241 break;
210 case 7: 242 case 7:
211 if(hdlc->data_received) { 243 if (hdlc->data_received)
212 // bad frame 244 /* bad frame */
213 status = -HDLC_FRAMING_ERROR; 245 status = -HDLC_FRAMING_ERROR;
214 } 246 if (!hdlc->do_adapt56) {
215 if(!hdlc->do_adapt56){ 247 if (hdlc->cbin == fast_abort
216 if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){ 248 [hdlc->bit_shift + 1]) {
217 hdlc->state = HDLC_FAST_IDLE; 249 hdlc->state =
218 hdlc->bit_shift=1; 250 HDLC_FAST_IDLE;
251 hdlc->bit_shift = 1;
219 break; 252 break;
220 } 253 }
221 } else { 254 } else
222 hdlc->state = HDLC_GET_FLAG_B0; 255 hdlc->state = HDLC_GET_FLAG_B0;
223 }
224 break; 256 break;
225 default: 257 default:
226 hdlc->shift_reg>>=1; 258 hdlc->shift_reg >>= 1;
227 hdlc->shift_reg |= 0x80; 259 hdlc->shift_reg |= 0x80;
228 hdlc->data_bits++; 260 hdlc->data_bits++;
229 break; 261 break;
230 } 262 }
231 } else { 263 } else {
232 switch(hdlc->hdlc_bits1){ 264 switch (hdlc->hdlc_bits1) {
233 case 5: 265 case 5:
234 break; 266 break;
235 case 6: 267 case 6:
236 if(hdlc->data_received){ 268 if (hdlc->data_received)
237 if (hdlc->dstpos < 2) { 269 status = check_frame(hdlc);
238 status = -HDLC_FRAMING_ERROR;
239 } else if (hdlc->crc != 0xf0b8){
240 // crc error
241 status = -HDLC_CRC_ERROR;
242 } else {
243 // remove CRC
244 hdlc->dstpos -= 2;
245 // good frame
246 status = hdlc->dstpos;
247 }
248 }
249 hdlc->crc = 0xffff; 270 hdlc->crc = 0xffff;
250 hdlc->shift_reg = 0; 271 hdlc->shift_reg = 0;
251 hdlc->data_bits = 0; 272 hdlc->data_bits = 0;
252 if(!hdlc->do_adapt56){ 273 if (!hdlc->do_adapt56)
253 if(hdlc->cbin==fast_flag[hdlc->bit_shift]){ 274 handle_fast_flag(hdlc);
254 hdlc->ffvalue = fast_flag_value[hdlc->bit_shift]; 275 else {
255 hdlc->state = HDLC_FAST_FLAG;
256 hdlc->ffbit_shift = hdlc->bit_shift;
257 hdlc->bit_shift = 1;
258 } else {
259 hdlc->state = HDLC_GET_DATA;
260 hdlc->data_received = 0;
261 }
262 } else {
263 hdlc->state = HDLC_GET_DATA; 276 hdlc->state = HDLC_GET_DATA;
264 hdlc->data_received = 0; 277 hdlc->data_received = 0;
265 } 278 }
266 break; 279 break;
267 default: 280 default:
268 hdlc->shift_reg>>=1; 281 hdlc->shift_reg >>= 1;
269 hdlc->data_bits++; 282 hdlc->data_bits++;
270 break; 283 break;
271 } 284 }
@@ -278,16 +291,17 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
278 hdlc->bit_shift--; 291 hdlc->bit_shift--;
279 return status; 292 return status;
280 } 293 }
281 if(hdlc->data_bits==8){ 294 if (hdlc->data_bits == 8) {
282 hdlc->data_bits = 0; 295 hdlc->data_bits = 0;
283 hdlc->data_received = 1; 296 hdlc->data_received = 1;
284 hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); 297 hdlc->crc = crc_ccitt_byte(hdlc->crc,
298 hdlc->shift_reg);
285 299
286 // good byte received 300 /* good byte received */
287 if (hdlc->dstpos < dsize) { 301 if (hdlc->dstpos < dsize)
288 dst[hdlc->dstpos++] = hdlc->shift_reg; 302 dst[hdlc->dstpos++] = hdlc->shift_reg;
289 } else { 303 else {
290 // frame too long 304 /* frame too long */
291 status = -HDLC_LENGTH_ERROR; 305 status = -HDLC_LENGTH_ERROR;
292 hdlc->dstpos = 0; 306 hdlc->dstpos = 0;
293 } 307 }
@@ -296,24 +310,18 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
296 hdlc->bit_shift--; 310 hdlc->bit_shift--;
297 break; 311 break;
298 case HDLC_FAST_FLAG: 312 case HDLC_FAST_FLAG:
299 if(hdlc->cbin==hdlc->ffvalue){ 313 if (hdlc->cbin == hdlc->ffvalue) {
300 hdlc->bit_shift = 0; 314 hdlc->bit_shift = 0;
301 break; 315 break;
302 } else { 316 } else {
303 if(hdlc->cbin == 0xff){ 317 if (hdlc->cbin == 0xff) {
304 hdlc->state = HDLC_FAST_IDLE; 318 hdlc->state = HDLC_FAST_IDLE;
305 hdlc->bit_shift=0; 319 hdlc->bit_shift = 0;
306 } else if(hdlc->ffbit_shift==8){ 320 } else if (hdlc->ffbit_shift == 8) {
307 hdlc->state = HDLC_GETFLAG_B7; 321 hdlc->state = HDLC_GETFLAG_B7;
308 break; 322 break;
309 } else { 323 } else
310 hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1]; 324 handle_abort(hdlc);
311 hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
312 if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
313 hdlc->data_bits = hdlc->ffbit_shift-1;
314 hdlc->state = HDLC_GET_DATA;
315 hdlc->data_received = 0;
316 }
317 } 325 }
318 break; 326 break;
319 default: 327 default:
@@ -323,7 +331,7 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
323 *count -= slen; 331 *count -= slen;
324 return 0; 332 return 0;
325} 333}
326 334EXPORT_SYMBOL(isdnhdlc_decode);
327/* 335/*
328 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream. 336 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
329 337
@@ -343,59 +351,70 @@ int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
343 dsize - destination buffer size 351 dsize - destination buffer size
344 returns - number of encoded bytes in the destination buffer 352 returns - number of encoded bytes in the destination buffer
345*/ 353*/
346int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src, 354int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
347 unsigned short slen, int *count, 355 int *count, u8 *dst, int dsize)
348 unsigned char *dst, int dsize)
349{ 356{
350 static const unsigned char xfast_flag_value[] = { 357 static const unsigned char xfast_flag_value[] = {
351 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e 358 0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
352 }; 359 };
353 360
354 int len = 0; 361 int len = 0;
355 362
356 *count = slen; 363 *count = slen;
357 364
365 /* special handling for one byte frames */
366 if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
367 hdlc->state = HDLC_SENDFLAG_ONE;
358 while (dsize > 0) { 368 while (dsize > 0) {
359 if(hdlc->bit_shift==0){ 369 if (hdlc->bit_shift == 0) {
360 if(slen && !hdlc->do_closing){ 370 if (slen && !hdlc->do_closing) {
361 hdlc->shift_reg = *src++; 371 hdlc->shift_reg = *src++;
362 slen--; 372 slen--;
363 if (slen == 0) 373 if (slen == 0)
364 hdlc->do_closing = 1; /* closing sequence, CRC + flag(s) */ 374 /* closing sequence, CRC + flag(s) */
375 hdlc->do_closing = 1;
365 hdlc->bit_shift = 8; 376 hdlc->bit_shift = 8;
366 } else { 377 } else {
367 if(hdlc->state == HDLC_SEND_DATA){ 378 if (hdlc->state == HDLC_SEND_DATA) {
368 if(hdlc->data_received){ 379 if (hdlc->data_received) {
369 hdlc->state = HDLC_SEND_CRC1; 380 hdlc->state = HDLC_SEND_CRC1;
370 hdlc->crc ^= 0xffff; 381 hdlc->crc ^= 0xffff;
371 hdlc->bit_shift = 8; 382 hdlc->bit_shift = 8;
372 hdlc->shift_reg = hdlc->crc & 0xff; 383 hdlc->shift_reg =
373 } else if(!hdlc->do_adapt56){ 384 hdlc->crc & 0xff;
374 hdlc->state = HDLC_SEND_FAST_FLAG; 385 } else if (!hdlc->do_adapt56)
375 } else { 386 hdlc->state =
376 hdlc->state = HDLC_SENDFLAG_B0; 387 HDLC_SEND_FAST_FLAG;
377 } 388 else
389 hdlc->state =
390 HDLC_SENDFLAG_B0;
378 } 391 }
379 392
380 } 393 }
381 } 394 }
382 395
383 switch(hdlc->state){ 396 switch (hdlc->state) {
384 case STOPPED: 397 case STOPPED:
385 while (dsize--) 398 while (dsize--)
386 *dst++ = 0xff; 399 *dst++ = 0xff;
387
388 return dsize; 400 return dsize;
389 case HDLC_SEND_FAST_FLAG: 401 case HDLC_SEND_FAST_FLAG:
390 hdlc->do_closing = 0; 402 hdlc->do_closing = 0;
391 if(slen == 0){ 403 if (slen == 0) {
392 *dst++ = hdlc->ffvalue; 404 /* the code is for bitreverse streams */
405 if (hdlc->do_bitreverse == 0)
406 *dst++ = bitrev8(hdlc->ffvalue);
407 else
408 *dst++ = hdlc->ffvalue;
393 len++; 409 len++;
394 dsize--; 410 dsize--;
395 break; 411 break;
396 } 412 }
397 if(hdlc->bit_shift==8){ 413 /* fall through */
398 hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits); 414 case HDLC_SENDFLAG_ONE:
415 if (hdlc->bit_shift == 8) {
416 hdlc->cbin = hdlc->ffvalue >>
417 (8 - hdlc->data_bits);
399 hdlc->state = HDLC_SEND_DATA; 418 hdlc->state = HDLC_SEND_DATA;
400 hdlc->crc = 0xffff; 419 hdlc->crc = 0xffff;
401 hdlc->hdlc_bits1 = 0; 420 hdlc->hdlc_bits1 = 0;
@@ -413,17 +432,17 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
413 hdlc->cbin <<= 1; 432 hdlc->cbin <<= 1;
414 hdlc->data_bits++; 433 hdlc->data_bits++;
415 hdlc->cbin++; 434 hdlc->cbin++;
416 if(++hdlc->hdlc_bits1 == 6) 435 if (++hdlc->hdlc_bits1 == 6)
417 hdlc->state = HDLC_SENDFLAG_B7; 436 hdlc->state = HDLC_SENDFLAG_B7;
418 break; 437 break;
419 case HDLC_SENDFLAG_B7: 438 case HDLC_SENDFLAG_B7:
420 hdlc->cbin <<= 1; 439 hdlc->cbin <<= 1;
421 hdlc->data_bits++; 440 hdlc->data_bits++;
422 if(slen == 0){ 441 if (slen == 0) {
423 hdlc->state = HDLC_SENDFLAG_B0; 442 hdlc->state = HDLC_SENDFLAG_B0;
424 break; 443 break;
425 } 444 }
426 if(hdlc->bit_shift==8){ 445 if (hdlc->bit_shift == 8) {
427 hdlc->state = HDLC_SEND_DATA; 446 hdlc->state = HDLC_SEND_DATA;
428 hdlc->crc = 0xffff; 447 hdlc->crc = 0xffff;
429 hdlc->hdlc_bits1 = 0; 448 hdlc->hdlc_bits1 = 0;
@@ -432,7 +451,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
432 break; 451 break;
433 case HDLC_SEND_FIRST_FLAG: 452 case HDLC_SEND_FIRST_FLAG:
434 hdlc->data_received = 1; 453 hdlc->data_received = 1;
435 if(hdlc->data_bits==8){ 454 if (hdlc->data_bits == 8) {
436 hdlc->state = HDLC_SEND_DATA; 455 hdlc->state = HDLC_SEND_DATA;
437 hdlc->crc = 0xffff; 456 hdlc->crc = 0xffff;
438 hdlc->hdlc_bits1 = 0; 457 hdlc->hdlc_bits1 = 0;
@@ -440,11 +459,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
440 } 459 }
441 hdlc->cbin <<= 1; 460 hdlc->cbin <<= 1;
442 hdlc->data_bits++; 461 hdlc->data_bits++;
443 if(hdlc->shift_reg & 0x01) 462 if (hdlc->shift_reg & 0x01)
444 hdlc->cbin++; 463 hdlc->cbin++;
445 hdlc->shift_reg >>= 1; 464 hdlc->shift_reg >>= 1;
446 hdlc->bit_shift--; 465 hdlc->bit_shift--;
447 if(hdlc->bit_shift==0){ 466 if (hdlc->bit_shift == 0) {
448 hdlc->state = HDLC_SEND_DATA; 467 hdlc->state = HDLC_SEND_DATA;
449 hdlc->crc = 0xffff; 468 hdlc->crc = 0xffff;
450 hdlc->hdlc_bits1 = 0; 469 hdlc->hdlc_bits1 = 0;
@@ -453,14 +472,14 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
453 case HDLC_SEND_DATA: 472 case HDLC_SEND_DATA:
454 hdlc->cbin <<= 1; 473 hdlc->cbin <<= 1;
455 hdlc->data_bits++; 474 hdlc->data_bits++;
456 if(hdlc->hdlc_bits1 == 5){ 475 if (hdlc->hdlc_bits1 == 5) {
457 hdlc->hdlc_bits1 = 0; 476 hdlc->hdlc_bits1 = 0;
458 break; 477 break;
459 } 478 }
460 if(hdlc->bit_shift==8){ 479 if (hdlc->bit_shift == 8)
461 hdlc->crc = crc_ccitt_byte(hdlc->crc, hdlc->shift_reg); 480 hdlc->crc = crc_ccitt_byte(hdlc->crc,
462 } 481 hdlc->shift_reg);
463 if(hdlc->shift_reg & 0x01){ 482 if (hdlc->shift_reg & 0x01) {
464 hdlc->hdlc_bits1++; 483 hdlc->hdlc_bits1++;
465 hdlc->cbin++; 484 hdlc->cbin++;
466 hdlc->shift_reg >>= 1; 485 hdlc->shift_reg >>= 1;
@@ -474,11 +493,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
474 case HDLC_SEND_CRC1: 493 case HDLC_SEND_CRC1:
475 hdlc->cbin <<= 1; 494 hdlc->cbin <<= 1;
476 hdlc->data_bits++; 495 hdlc->data_bits++;
477 if(hdlc->hdlc_bits1 == 5){ 496 if (hdlc->hdlc_bits1 == 5) {
478 hdlc->hdlc_bits1 = 0; 497 hdlc->hdlc_bits1 = 0;
479 break; 498 break;
480 } 499 }
481 if(hdlc->shift_reg & 0x01){ 500 if (hdlc->shift_reg & 0x01) {
482 hdlc->hdlc_bits1++; 501 hdlc->hdlc_bits1++;
483 hdlc->cbin++; 502 hdlc->cbin++;
484 hdlc->shift_reg >>= 1; 503 hdlc->shift_reg >>= 1;
@@ -488,7 +507,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
488 hdlc->shift_reg >>= 1; 507 hdlc->shift_reg >>= 1;
489 hdlc->bit_shift--; 508 hdlc->bit_shift--;
490 } 509 }
491 if(hdlc->bit_shift==0){ 510 if (hdlc->bit_shift == 0) {
492 hdlc->shift_reg = (hdlc->crc >> 8); 511 hdlc->shift_reg = (hdlc->crc >> 8);
493 hdlc->state = HDLC_SEND_CRC2; 512 hdlc->state = HDLC_SEND_CRC2;
494 hdlc->bit_shift = 8; 513 hdlc->bit_shift = 8;
@@ -497,11 +516,11 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
497 case HDLC_SEND_CRC2: 516 case HDLC_SEND_CRC2:
498 hdlc->cbin <<= 1; 517 hdlc->cbin <<= 1;
499 hdlc->data_bits++; 518 hdlc->data_bits++;
500 if(hdlc->hdlc_bits1 == 5){ 519 if (hdlc->hdlc_bits1 == 5) {
501 hdlc->hdlc_bits1 = 0; 520 hdlc->hdlc_bits1 = 0;
502 break; 521 break;
503 } 522 }
504 if(hdlc->shift_reg & 0x01){ 523 if (hdlc->shift_reg & 0x01) {
505 hdlc->hdlc_bits1++; 524 hdlc->hdlc_bits1++;
506 hdlc->cbin++; 525 hdlc->cbin++;
507 hdlc->shift_reg >>= 1; 526 hdlc->shift_reg >>= 1;
@@ -511,7 +530,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
511 hdlc->shift_reg >>= 1; 530 hdlc->shift_reg >>= 1;
512 hdlc->bit_shift--; 531 hdlc->bit_shift--;
513 } 532 }
514 if(hdlc->bit_shift==0){ 533 if (hdlc->bit_shift == 0) {
515 hdlc->shift_reg = 0x7e; 534 hdlc->shift_reg = 0x7e;
516 hdlc->state = HDLC_SEND_CLOSING_FLAG; 535 hdlc->state = HDLC_SEND_CLOSING_FLAG;
517 hdlc->bit_shift = 8; 536 hdlc->bit_shift = 8;
@@ -520,33 +539,36 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
520 case HDLC_SEND_CLOSING_FLAG: 539 case HDLC_SEND_CLOSING_FLAG:
521 hdlc->cbin <<= 1; 540 hdlc->cbin <<= 1;
522 hdlc->data_bits++; 541 hdlc->data_bits++;
523 if(hdlc->hdlc_bits1 == 5){ 542 if (hdlc->hdlc_bits1 == 5) {
524 hdlc->hdlc_bits1 = 0; 543 hdlc->hdlc_bits1 = 0;
525 break; 544 break;
526 } 545 }
527 if(hdlc->shift_reg & 0x01){ 546 if (hdlc->shift_reg & 0x01)
528 hdlc->cbin++; 547 hdlc->cbin++;
529 }
530 hdlc->shift_reg >>= 1; 548 hdlc->shift_reg >>= 1;
531 hdlc->bit_shift--; 549 hdlc->bit_shift--;
532 if(hdlc->bit_shift==0){ 550 if (hdlc->bit_shift == 0) {
533 hdlc->ffvalue = xfast_flag_value[hdlc->data_bits]; 551 hdlc->ffvalue =
534 if(hdlc->dchannel){ 552 xfast_flag_value[hdlc->data_bits];
553 if (hdlc->dchannel) {
535 hdlc->ffvalue = 0x7e; 554 hdlc->ffvalue = 0x7e;
536 hdlc->state = HDLC_SEND_IDLE1; 555 hdlc->state = HDLC_SEND_IDLE1;
537 hdlc->bit_shift = 8-hdlc->data_bits; 556 hdlc->bit_shift = 8-hdlc->data_bits;
538 if(hdlc->bit_shift==0) 557 if (hdlc->bit_shift == 0)
539 hdlc->state = HDLC_SEND_FAST_IDLE; 558 hdlc->state =
559 HDLC_SEND_FAST_IDLE;
540 } else { 560 } else {
541 if(!hdlc->do_adapt56){ 561 if (!hdlc->do_adapt56) {
542 hdlc->state = HDLC_SEND_FAST_FLAG; 562 hdlc->state =
563 HDLC_SEND_FAST_FLAG;
543 hdlc->data_received = 0; 564 hdlc->data_received = 0;
544 } else { 565 } else {
545 hdlc->state = HDLC_SENDFLAG_B0; 566 hdlc->state = HDLC_SENDFLAG_B0;
546 hdlc->data_received = 0; 567 hdlc->data_received = 0;
547 } 568 }
548 // Finished with this frame, send flags 569 /* Finished this frame, send flags */
549 if (dsize > 1) dsize = 1; 570 if (dsize > 1)
571 dsize = 1;
550 } 572 }
551 } 573 }
552 break; 574 break;
@@ -556,7 +578,7 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
556 hdlc->cbin++; 578 hdlc->cbin++;
557 hdlc->data_bits++; 579 hdlc->data_bits++;
558 hdlc->bit_shift--; 580 hdlc->bit_shift--;
559 if(hdlc->bit_shift==0){ 581 if (hdlc->bit_shift == 0) {
560 hdlc->state = HDLC_SEND_FAST_IDLE; 582 hdlc->state = HDLC_SEND_FAST_IDLE;
561 hdlc->bit_shift = 0; 583 hdlc->bit_shift = 0;
562 } 584 }
@@ -565,12 +587,17 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
565 hdlc->do_closing = 0; 587 hdlc->do_closing = 0;
566 hdlc->cbin = 0xff; 588 hdlc->cbin = 0xff;
567 hdlc->data_bits = 8; 589 hdlc->data_bits = 8;
568 if(hdlc->bit_shift == 8){ 590 if (hdlc->bit_shift == 8) {
569 hdlc->cbin = 0x7e; 591 hdlc->cbin = 0x7e;
570 hdlc->state = HDLC_SEND_FIRST_FLAG; 592 hdlc->state = HDLC_SEND_FIRST_FLAG;
571 } else { 593 } else {
572 *dst++ = hdlc->cbin; 594 /* the code is for bitreverse streams */
573 hdlc->bit_shift = hdlc->data_bits = 0; 595 if (hdlc->do_bitreverse == 0)
596 *dst++ = bitrev8(hdlc->cbin);
597 else
598 *dst++ = hdlc->cbin;
599 hdlc->bit_shift = 0;
600 hdlc->data_bits = 0;
574 len++; 601 len++;
575 dsize = 0; 602 dsize = 0;
576 } 603 }
@@ -578,15 +605,19 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
578 default: 605 default:
579 break; 606 break;
580 } 607 }
581 if(hdlc->do_adapt56){ 608 if (hdlc->do_adapt56) {
582 if(hdlc->data_bits==7){ 609 if (hdlc->data_bits == 7) {
583 hdlc->cbin <<= 1; 610 hdlc->cbin <<= 1;
584 hdlc->cbin++; 611 hdlc->cbin++;
585 hdlc->data_bits++; 612 hdlc->data_bits++;
586 } 613 }
587 } 614 }
588 if(hdlc->data_bits==8){ 615 if (hdlc->data_bits == 8) {
589 *dst++ = hdlc->cbin; 616 /* the code is for bitreverse streams */
617 if (hdlc->do_bitreverse == 0)
618 *dst++ = bitrev8(hdlc->cbin);
619 else
620 *dst++ = hdlc->cbin;
590 hdlc->data_bits = 0; 621 hdlc->data_bits = 0;
591 len++; 622 len++;
592 dsize--; 623 dsize--;
@@ -596,8 +627,4 @@ int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
596 627
597 return len; 628 return len;
598} 629}
599
600EXPORT_SYMBOL(isdnhdlc_rcv_init);
601EXPORT_SYMBOL(isdnhdlc_decode);
602EXPORT_SYMBOL(isdnhdlc_out_init);
603EXPORT_SYMBOL(isdnhdlc_encode); 630EXPORT_SYMBOL(isdnhdlc_encode);
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c
index 0481a0cdf6db..e8049be552aa 100644
--- a/drivers/isdn/mISDN/hwchannel.c
+++ b/drivers/isdn/mISDN/hwchannel.c
@@ -114,13 +114,14 @@ mISDN_freedchannel(struct dchannel *ch)
114} 114}
115EXPORT_SYMBOL(mISDN_freedchannel); 115EXPORT_SYMBOL(mISDN_freedchannel);
116 116
117int 117void
118mISDN_freebchannel(struct bchannel *ch) 118mISDN_clear_bchannel(struct bchannel *ch)
119{ 119{
120 if (ch->tx_skb) { 120 if (ch->tx_skb) {
121 dev_kfree_skb(ch->tx_skb); 121 dev_kfree_skb(ch->tx_skb);
122 ch->tx_skb = NULL; 122 ch->tx_skb = NULL;
123 } 123 }
124 ch->tx_idx = 0;
124 if (ch->rx_skb) { 125 if (ch->rx_skb) {
125 dev_kfree_skb(ch->rx_skb); 126 dev_kfree_skb(ch->rx_skb);
126 ch->rx_skb = NULL; 127 ch->rx_skb = NULL;
@@ -129,6 +130,16 @@ mISDN_freebchannel(struct bchannel *ch)
129 dev_kfree_skb(ch->next_skb); 130 dev_kfree_skb(ch->next_skb);
130 ch->next_skb = NULL; 131 ch->next_skb = NULL;
131 } 132 }
133 test_and_clear_bit(FLG_TX_BUSY, &ch->Flags);
134 test_and_clear_bit(FLG_TX_NEXT, &ch->Flags);
135 test_and_clear_bit(FLG_ACTIVE, &ch->Flags);
136}
137EXPORT_SYMBOL(mISDN_clear_bchannel);
138
139int
140mISDN_freebchannel(struct bchannel *ch)
141{
142 mISDN_clear_bchannel(ch);
132 skb_queue_purge(&ch->rqueue); 143 skb_queue_purge(&ch->rqueue);
133 ch->rcount = 0; 144 ch->rcount = 0;
134 flush_scheduled_work(); 145 flush_scheduled_work();
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c
index 9c2589e986d6..e17f0044e0b6 100644
--- a/drivers/isdn/mISDN/layer2.c
+++ b/drivers/isdn/mISDN/layer2.c
@@ -1832,8 +1832,6 @@ static struct FsmNode L2FnList[] =
1832 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da}, 1832 {ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
1833}; 1833};
1834 1834
1835#define L2_FN_COUNT (sizeof(L2FnList)/sizeof(struct FsmNode))
1836
1837static int 1835static int
1838ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) 1836ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
1839{ 1837{