diff options
Diffstat (limited to 'drivers/isdn')
47 files changed, 1153 insertions, 585 deletions
diff --git a/drivers/isdn/Kconfig b/drivers/isdn/Kconfig index 3d113c6e4a70..02bdca6f95c3 100644 --- a/drivers/isdn/Kconfig +++ b/drivers/isdn/Kconfig | |||
@@ -61,4 +61,6 @@ source "drivers/isdn/hardware/Kconfig" | |||
61 | 61 | ||
62 | endif # ISDN_CAPI | 62 | endif # ISDN_CAPI |
63 | 63 | ||
64 | source "drivers/isdn/gigaset/Kconfig" | ||
65 | |||
64 | endif # ISDN | 66 | endif # ISDN |
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index 29419a8d31dc..16f2e465e5f9 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c | |||
@@ -490,7 +490,14 @@ static void pars_2_message(_cmsg * cmsg) | |||
490 | } | 490 | } |
491 | } | 491 | } |
492 | 492 | ||
493 | /*-------------------------------------------------------*/ | 493 | /** |
494 | * capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure | ||
495 | * @cmsg: _cmsg structure | ||
496 | * @msg: buffer for assembled message | ||
497 | * | ||
498 | * Return value: 0 for success | ||
499 | */ | ||
500 | |||
494 | unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg) | 501 | unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg) |
495 | { | 502 | { |
496 | cmsg->m = msg; | 503 | cmsg->m = msg; |
@@ -553,7 +560,14 @@ static void message_2_pars(_cmsg * cmsg) | |||
553 | } | 560 | } |
554 | } | 561 | } |
555 | 562 | ||
556 | /*-------------------------------------------------------*/ | 563 | /** |
564 | * capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure | ||
565 | * @cmsg: _cmsg structure | ||
566 | * @msg: buffer for assembled message | ||
567 | * | ||
568 | * Return value: 0 for success | ||
569 | */ | ||
570 | |||
557 | unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) | 571 | unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) |
558 | { | 572 | { |
559 | memset(cmsg, 0, sizeof(_cmsg)); | 573 | memset(cmsg, 0, sizeof(_cmsg)); |
@@ -573,7 +587,18 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg) | |||
573 | return 0; | 587 | return 0; |
574 | } | 588 | } |
575 | 589 | ||
576 | /*-------------------------------------------------------*/ | 590 | /** |
591 | * capi_cmsg_header() - initialize header part of _cmsg structure | ||
592 | * @cmsg: _cmsg structure | ||
593 | * @_ApplId: ApplID field value | ||
594 | * @_Command: Command field value | ||
595 | * @_Subcommand: Subcommand field value | ||
596 | * @_Messagenumber: Message Number field value | ||
597 | * @_Controller: Controller/PLCI/NCCI field value | ||
598 | * | ||
599 | * Return value: 0 for success | ||
600 | */ | ||
601 | |||
577 | unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId, | 602 | unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId, |
578 | u8 _Command, u8 _Subcommand, | 603 | u8 _Command, u8 _Subcommand, |
579 | u16 _Messagenumber, u32 _Controller) | 604 | u16 _Messagenumber, u32 _Controller) |
@@ -641,6 +666,14 @@ static char *mnames[] = | |||
641 | [0x4e] = "MANUFACTURER_RESP" | 666 | [0x4e] = "MANUFACTURER_RESP" |
642 | }; | 667 | }; |
643 | 668 | ||
669 | /** | ||
670 | * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name | ||
671 | * @cmd: command number | ||
672 | * @subcmd: subcommand number | ||
673 | * | ||
674 | * Return value: static string, NULL if command/subcommand unknown | ||
675 | */ | ||
676 | |||
644 | char *capi_cmd2str(u8 cmd, u8 subcmd) | 677 | char *capi_cmd2str(u8 cmd, u8 subcmd) |
645 | { | 678 | { |
646 | return mnames[command_2_index(cmd, subcmd)]; | 679 | return mnames[command_2_index(cmd, subcmd)]; |
@@ -879,6 +912,11 @@ init: | |||
879 | return cdb; | 912 | return cdb; |
880 | } | 913 | } |
881 | 914 | ||
915 | /** | ||
916 | * cdebbuf_free() - free CAPI debug buffer | ||
917 | * @cdb: buffer to free | ||
918 | */ | ||
919 | |||
882 | void cdebbuf_free(_cdebbuf *cdb) | 920 | void cdebbuf_free(_cdebbuf *cdb) |
883 | { | 921 | { |
884 | if (likely(cdb == g_debbuf)) { | 922 | if (likely(cdb == g_debbuf)) { |
@@ -891,6 +929,16 @@ void cdebbuf_free(_cdebbuf *cdb) | |||
891 | } | 929 | } |
892 | 930 | ||
893 | 931 | ||
932 | /** | ||
933 | * capi_message2str() - format CAPI 2.0 message for printing | ||
934 | * @msg: CAPI 2.0 message | ||
935 | * | ||
936 | * Allocates a CAPI debug buffer and fills it with a printable representation | ||
937 | * of the CAPI 2.0 message in @msg. | ||
938 | * Return value: allocated debug buffer, NULL on error | ||
939 | * The returned buffer should be freed by a call to cdebbuf_free() after use. | ||
940 | */ | ||
941 | |||
894 | _cdebbuf *capi_message2str(u8 * msg) | 942 | _cdebbuf *capi_message2str(u8 * msg) |
895 | { | 943 | { |
896 | _cdebbuf *cdb; | 944 | _cdebbuf *cdb; |
@@ -926,10 +974,23 @@ _cdebbuf *capi_message2str(u8 * msg) | |||
926 | return cdb; | 974 | return cdb; |
927 | } | 975 | } |
928 | 976 | ||
977 | /** | ||
978 | * capi_cmsg2str() - format _cmsg structure for printing | ||
979 | * @cmsg: _cmsg structure | ||
980 | * | ||
981 | * Allocates a CAPI debug buffer and fills it with a printable representation | ||
982 | * of the CAPI 2.0 message stored in @cmsg by a previous call to | ||
983 | * capi_cmsg2message() or capi_message2cmsg(). | ||
984 | * Return value: allocated debug buffer, NULL on error | ||
985 | * The returned buffer should be freed by a call to cdebbuf_free() after use. | ||
986 | */ | ||
987 | |||
929 | _cdebbuf *capi_cmsg2str(_cmsg * cmsg) | 988 | _cdebbuf *capi_cmsg2str(_cmsg * cmsg) |
930 | { | 989 | { |
931 | _cdebbuf *cdb; | 990 | _cdebbuf *cdb; |
932 | 991 | ||
992 | if (!cmsg->m) | ||
993 | return NULL; /* no message */ | ||
933 | cdb = cdebbuf_alloc(); | 994 | cdb = cdebbuf_alloc(); |
934 | if (!cdb) | 995 | if (!cdb) |
935 | return NULL; | 996 | return NULL; |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index f33170368cd1..57d26360f64e 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -377,14 +377,14 @@ void capi_ctr_ready(struct capi_ctr * card) | |||
377 | EXPORT_SYMBOL(capi_ctr_ready); | 377 | EXPORT_SYMBOL(capi_ctr_ready); |
378 | 378 | ||
379 | /** | 379 | /** |
380 | * capi_ctr_reseted() - signal CAPI controller reset | 380 | * capi_ctr_down() - signal CAPI controller not ready |
381 | * @card: controller descriptor structure. | 381 | * @card: controller descriptor structure. |
382 | * | 382 | * |
383 | * Called by hardware driver to signal that the controller is down and | 383 | * Called by hardware driver to signal that the controller is down and |
384 | * unavailable for use. | 384 | * unavailable for use. |
385 | */ | 385 | */ |
386 | 386 | ||
387 | void capi_ctr_reseted(struct capi_ctr * card) | 387 | void capi_ctr_down(struct capi_ctr * card) |
388 | { | 388 | { |
389 | u16 appl; | 389 | u16 appl; |
390 | 390 | ||
@@ -413,7 +413,7 @@ void capi_ctr_reseted(struct capi_ctr * card) | |||
413 | notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); | 413 | notify_push(KCI_CONTRDOWN, card->cnr, 0, 0); |
414 | } | 414 | } |
415 | 415 | ||
416 | EXPORT_SYMBOL(capi_ctr_reseted); | 416 | EXPORT_SYMBOL(capi_ctr_down); |
417 | 417 | ||
418 | /** | 418 | /** |
419 | * capi_ctr_suspend_output() - suspend controller | 419 | * capi_ctr_suspend_output() - suspend controller |
@@ -517,7 +517,7 @@ EXPORT_SYMBOL(attach_capi_ctr); | |||
517 | int detach_capi_ctr(struct capi_ctr *card) | 517 | int detach_capi_ctr(struct capi_ctr *card) |
518 | { | 518 | { |
519 | if (card->cardstate != CARD_DETECTED) | 519 | if (card->cardstate != CARD_DETECTED) |
520 | capi_ctr_reseted(card); | 520 | capi_ctr_down(card); |
521 | 521 | ||
522 | ncards--; | 522 | ncards--; |
523 | 523 | ||
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig index 9ca889adf120..18ab8652aa57 100644 --- a/drivers/isdn/gigaset/Kconfig +++ b/drivers/isdn/gigaset/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | menuconfig ISDN_DRV_GIGASET | 1 | menuconfig ISDN_DRV_GIGASET |
2 | tristate "Siemens Gigaset support" | 2 | tristate "Siemens Gigaset support" |
3 | depends on ISDN_I4L | ||
3 | select CRC_CCITT | 4 | select CRC_CCITT |
4 | select BITREVERSE | 5 | select BITREVERSE |
5 | help | 6 | help |
@@ -42,11 +43,4 @@ config GIGASET_DEBUG | |||
42 | This enables debugging code in the Gigaset drivers. | 43 | This enables debugging code in the Gigaset drivers. |
43 | If in doubt, say yes. | 44 | If in doubt, say yes. |
44 | 45 | ||
45 | config GIGASET_UNDOCREQ | ||
46 | bool "Support for undocumented USB requests" | ||
47 | help | ||
48 | This enables support for USB requests we only know from | ||
49 | reverse engineering (currently M105 only). If you need | ||
50 | features like configuration mode of M105, say yes. | ||
51 | |||
52 | endif # ISDN_DRV_GIGASET | 46 | endif # ISDN_DRV_GIGASET |
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c index 2a4ce96f04bd..234cc5d53312 100644 --- a/drivers/isdn/gigaset/asyncdata.c +++ b/drivers/isdn/gigaset/asyncdata.c | |||
@@ -174,9 +174,8 @@ byte_stuff: | |||
174 | 174 | ||
175 | if (unlikely(fcs != PPP_GOODFCS)) { | 175 | if (unlikely(fcs != PPP_GOODFCS)) { |
176 | dev_err(cs->dev, | 176 | dev_err(cs->dev, |
177 | "Packet checksum at %lu failed, " | 177 | "Checksum failed, %u bytes corrupted!\n", |
178 | "packet is corrupted (%u bytes)!\n", | 178 | skb->len); |
179 | bcs->rcvbytes, skb->len); | ||
180 | compskb = NULL; | 179 | compskb = NULL; |
181 | gigaset_rcv_error(compskb, cs, bcs); | 180 | gigaset_rcv_error(compskb, cs, bcs); |
182 | error = 1; | 181 | error = 1; |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 0048ce98bfa8..e4141bf8b2f3 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -565,8 +565,6 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, | |||
565 | gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); | 565 | gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel); |
566 | gigaset_at_init(&bcs->at_state, bcs, cs, -1); | 566 | gigaset_at_init(&bcs->at_state, bcs, cs, -1); |
567 | 567 | ||
568 | bcs->rcvbytes = 0; | ||
569 | |||
570 | #ifdef CONFIG_GIGASET_DEBUG | 568 | #ifdef CONFIG_GIGASET_DEBUG |
571 | bcs->emptycount = 0; | 569 | bcs->emptycount = 0; |
572 | #endif | 570 | #endif |
@@ -672,14 +670,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
672 | cs->tty = NULL; | 670 | cs->tty = NULL; |
673 | cs->tty_dev = NULL; | 671 | cs->tty_dev = NULL; |
674 | cs->cidmode = cidmode != 0; | 672 | cs->cidmode = cidmode != 0; |
675 | 673 | cs->tabnocid = gigaset_tab_nocid; | |
676 | //if(onechannel) { //FIXME | 674 | cs->tabcid = gigaset_tab_cid; |
677 | cs->tabnocid = gigaset_tab_nocid_m10x; | ||
678 | cs->tabcid = gigaset_tab_cid_m10x; | ||
679 | //} else { | ||
680 | // cs->tabnocid = gigaset_tab_nocid; | ||
681 | // cs->tabcid = gigaset_tab_cid; | ||
682 | //} | ||
683 | 675 | ||
684 | init_waitqueue_head(&cs->waitqueue); | 676 | init_waitqueue_head(&cs->waitqueue); |
685 | cs->waiting = 0; | 677 | cs->waiting = 0; |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index e582a4887bc1..ec5169604a6a 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -160,7 +160,7 @@ | |||
160 | 160 | ||
161 | 161 | ||
162 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring | 162 | // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring |
163 | struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | 163 | struct reply_t gigaset_tab_nocid[] = |
164 | { | 164 | { |
165 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 165 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
166 | 166 | ||
@@ -280,7 +280,7 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */ | |||
280 | }; | 280 | }; |
281 | 281 | ||
282 | // 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall | 282 | // 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall |
283 | struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | 283 | struct reply_t gigaset_tab_cid[] = |
284 | { | 284 | { |
285 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ | 285 | /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */ |
286 | 286 | ||
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 747178f03d2c..a2f6125739eb 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -282,8 +282,8 @@ struct reply_t { | |||
282 | char *command; /* NULL==none */ | 282 | char *command; /* NULL==none */ |
283 | }; | 283 | }; |
284 | 284 | ||
285 | extern struct reply_t gigaset_tab_cid_m10x[]; | 285 | extern struct reply_t gigaset_tab_cid[]; |
286 | extern struct reply_t gigaset_tab_nocid_m10x[]; | 286 | extern struct reply_t gigaset_tab_nocid[]; |
287 | 287 | ||
288 | struct inbuf_t { | 288 | struct inbuf_t { |
289 | unsigned char *rcvbuf; /* usb-gigaset receive buffer */ | 289 | unsigned char *rcvbuf; /* usb-gigaset receive buffer */ |
@@ -384,7 +384,6 @@ struct bc_state { | |||
384 | int trans_up; /* Counter of packages (upstream) */ | 384 | int trans_up; /* Counter of packages (upstream) */ |
385 | 385 | ||
386 | struct at_state_t at_state; | 386 | struct at_state_t at_state; |
387 | unsigned long rcvbytes; | ||
388 | 387 | ||
389 | __u16 fcs; | 388 | __u16 fcs; |
390 | struct sk_buff *skb; | 389 | struct sk_buff *skb; |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 69a702f0db93..9b22f9cf2f33 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -544,11 +544,11 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
544 | 544 | ||
545 | gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); | 545 | gig_dbg(DEBUG_ANY, "Register driver capabilities to LL"); |
546 | 546 | ||
547 | //iif->id[sizeof(iif->id) - 1]=0; | ||
548 | //strncpy(iif->id, isdnid, sizeof(iif->id) - 1); | ||
549 | if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index) | 547 | if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index) |
550 | >= sizeof iif->id) | 548 | >= sizeof iif->id) { |
551 | return -ENOMEM; //FIXME EINVAL/...?? | 549 | pr_err("ID too long: %s\n", isdnid); |
550 | return 0; | ||
551 | } | ||
552 | 552 | ||
553 | iif->owner = THIS_MODULE; | 553 | iif->owner = THIS_MODULE; |
554 | iif->channels = cs->channels; | 554 | iif->channels = cs->channels; |
@@ -568,8 +568,10 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid) | |||
568 | iif->rcvcallb_skb = NULL; /* Will be set by LL */ | 568 | iif->rcvcallb_skb = NULL; /* Will be set by LL */ |
569 | iif->statcallb = NULL; /* Will be set by LL */ | 569 | iif->statcallb = NULL; /* Will be set by LL */ |
570 | 570 | ||
571 | if (!register_isdn(iif)) | 571 | if (!register_isdn(iif)) { |
572 | pr_err("register_isdn failed\n"); | ||
572 | return 0; | 573 | return 0; |
574 | } | ||
573 | 575 | ||
574 | cs->myid = iif->channels; /* Set my device id */ | 576 | cs->myid = iif->channels; /* Set my device id */ |
575 | return 1; | 577 | return 1; |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 820a30923fee..1ebfcab74662 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -599,8 +599,7 @@ void gigaset_if_init(struct cardstate *cs) | |||
599 | if (!IS_ERR(cs->tty_dev)) | 599 | if (!IS_ERR(cs->tty_dev)) |
600 | dev_set_drvdata(cs->tty_dev, cs); | 600 | dev_set_drvdata(cs->tty_dev, cs); |
601 | else { | 601 | else { |
602 | dev_warn(cs->dev, | 602 | pr_warning("could not register device to the tty subsystem\n"); |
603 | "could not register device to the tty subsystem\n"); | ||
604 | cs->tty_dev = NULL; | 603 | cs->tty_dev = NULL; |
605 | } | 604 | } |
606 | mutex_unlock(&cs->mutex); | 605 | mutex_unlock(&cs->mutex); |
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 29808c4fb1cb..db3a1e4cd489 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -246,6 +246,10 @@ static inline void dump_bytes(enum debuglevel level, const char *tag, | |||
246 | unsigned char c; | 246 | unsigned char c; |
247 | static char dbgline[3 * 32 + 1]; | 247 | static char dbgline[3 * 32 + 1]; |
248 | int i = 0; | 248 | int i = 0; |
249 | |||
250 | if (!(gigaset_debuglevel & level)) | ||
251 | return; | ||
252 | |||
249 | while (count-- > 0) { | 253 | while (count-- > 0) { |
250 | if (i > sizeof(dbgline) - 4) { | 254 | if (i > sizeof(dbgline) - 4) { |
251 | dbgline[i] = '\0'; | 255 | dbgline[i] = '\0'; |
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c index da6f3acf9fd0..9715aad9c3f0 100644 --- a/drivers/isdn/gigaset/proc.c +++ b/drivers/isdn/gigaset/proc.c | |||
@@ -79,5 +79,5 @@ void gigaset_init_dev_sysfs(struct cardstate *cs) | |||
79 | 79 | ||
80 | gig_dbg(DEBUG_INIT, "setting up sysfs"); | 80 | gig_dbg(DEBUG_INIT, "setting up sysfs"); |
81 | if (device_create_file(cs->tty_dev, &dev_attr_cidmode)) | 81 | if (device_create_file(cs->tty_dev, &dev_attr_cidmode)) |
82 | dev_err(cs->dev, "could not create sysfs attribute\n"); | 82 | pr_err("could not create sysfs attribute\n"); |
83 | } | 83 | } |
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index d78385166099..4deb1ab0dbf8 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -153,8 +153,6 @@ static inline unsigned tiocm_to_gigaset(unsigned state) | |||
153 | return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0); | 153 | return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0); |
154 | } | 154 | } |
155 | 155 | ||
156 | #ifdef CONFIG_GIGASET_UNDOCREQ | ||
157 | /* WARNING: EXPERIMENTAL! */ | ||
158 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | 156 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, |
159 | unsigned new_state) | 157 | unsigned new_state) |
160 | { | 158 | { |
@@ -176,6 +174,11 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | |||
176 | return 0; | 174 | return 0; |
177 | } | 175 | } |
178 | 176 | ||
177 | /* | ||
178 | * Set M105 configuration value | ||
179 | * using undocumented device commands reverse engineered from USB traces | ||
180 | * of the Siemens Windows driver | ||
181 | */ | ||
179 | static int set_value(struct cardstate *cs, u8 req, u16 val) | 182 | static int set_value(struct cardstate *cs, u8 req, u16 val) |
180 | { | 183 | { |
181 | struct usb_device *udev = cs->hw.usb->udev; | 184 | struct usb_device *udev = cs->hw.usb->udev; |
@@ -205,8 +208,10 @@ static int set_value(struct cardstate *cs, u8 req, u16 val) | |||
205 | return r < 0 ? r : (r2 < 0 ? r2 : 0); | 208 | return r < 0 ? r : (r2 < 0 ? r2 : 0); |
206 | } | 209 | } |
207 | 210 | ||
208 | /* WARNING: HIGHLY EXPERIMENTAL! */ | 211 | /* |
209 | // don't use this in an interrupt/BH | 212 | * set the baud rate on the internal serial adapter |
213 | * using the undocumented parameter setting command | ||
214 | */ | ||
210 | static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) | 215 | static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) |
211 | { | 216 | { |
212 | u16 val; | 217 | u16 val; |
@@ -237,8 +242,10 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) | |||
237 | return set_value(cs, 1, val); | 242 | return set_value(cs, 1, val); |
238 | } | 243 | } |
239 | 244 | ||
240 | /* WARNING: HIGHLY EXPERIMENTAL! */ | 245 | /* |
241 | // don't use this in an interrupt/BH | 246 | * set the line format on the internal serial adapter |
247 | * using the undocumented parameter setting command | ||
248 | */ | ||
242 | static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | 249 | static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) |
243 | { | 250 | { |
244 | u16 val = 0; | 251 | u16 val = 0; |
@@ -274,24 +281,6 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
274 | return set_value(cs, 3, val); | 281 | return set_value(cs, 3, val); |
275 | } | 282 | } |
276 | 283 | ||
277 | #else | ||
278 | static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state, | ||
279 | unsigned new_state) | ||
280 | { | ||
281 | return -ENOTTY; | ||
282 | } | ||
283 | |||
284 | static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | ||
285 | { | ||
286 | return -ENOTTY; | ||
287 | } | ||
288 | |||
289 | static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag) | ||
290 | { | ||
291 | return -ENOTTY; | ||
292 | } | ||
293 | #endif | ||
294 | |||
295 | 284 | ||
296 | /*================================================================================================================*/ | 285 | /*================================================================================================================*/ |
297 | static int gigaset_init_bchannel(struct bc_state *bcs) | 286 | static int gigaset_init_bchannel(struct bc_state *bcs) |
@@ -362,10 +351,8 @@ static void gigaset_modem_fill(unsigned long data) | |||
362 | } while (again); | 351 | } while (again); |
363 | } | 352 | } |
364 | 353 | ||
365 | /** | 354 | /* |
366 | * gigaset_read_int_callback | 355 | * Interrupt Input URB completion routine |
367 | * | ||
368 | * It is called if the data was received from the device. | ||
369 | */ | 356 | */ |
370 | static void gigaset_read_int_callback(struct urb *urb) | 357 | static void gigaset_read_int_callback(struct urb *urb) |
371 | { | 358 | { |
@@ -567,18 +554,19 @@ static int gigaset_chars_in_buffer(struct cardstate *cs) | |||
567 | return cs->cmdbytes; | 554 | return cs->cmdbytes; |
568 | } | 555 | } |
569 | 556 | ||
557 | /* | ||
558 | * set the break characters on the internal serial adapter | ||
559 | * using undocumented device commands reverse engineered from USB traces | ||
560 | * of the Siemens Windows driver | ||
561 | */ | ||
570 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) | 562 | static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) |
571 | { | 563 | { |
572 | #ifdef CONFIG_GIGASET_UNDOCREQ | ||
573 | struct usb_device *udev = cs->hw.usb->udev; | 564 | struct usb_device *udev = cs->hw.usb->udev; |
574 | 565 | ||
575 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); | 566 | gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf); |
576 | memcpy(cs->hw.usb->bchars, buf, 6); | 567 | memcpy(cs->hw.usb->bchars, buf, 6); |
577 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, | 568 | return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41, |
578 | 0, 0, &buf, 6, 2000); | 569 | 0, 0, &buf, 6, 2000); |
579 | #else | ||
580 | return -ENOTTY; | ||
581 | #endif | ||
582 | } | 570 | } |
583 | 571 | ||
584 | static int gigaset_freebcshw(struct bc_state *bcs) | 572 | static int gigaset_freebcshw(struct bc_state *bcs) |
@@ -625,7 +613,6 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
625 | ucs->bchars[5] = 0x13; | 613 | ucs->bchars[5] = 0x13; |
626 | ucs->bulk_out_buffer = NULL; | 614 | ucs->bulk_out_buffer = NULL; |
627 | ucs->bulk_out_urb = NULL; | 615 | ucs->bulk_out_urb = NULL; |
628 | //ucs->urb_cmd_out = NULL; | ||
629 | ucs->read_urb = NULL; | 616 | ucs->read_urb = NULL; |
630 | tasklet_init(&cs->write_tasklet, | 617 | tasklet_init(&cs->write_tasklet, |
631 | &gigaset_modem_fill, (unsigned long) cs); | 618 | &gigaset_modem_fill, (unsigned long) cs); |
@@ -742,7 +729,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
742 | cs->dev = &interface->dev; | 729 | cs->dev = &interface->dev; |
743 | 730 | ||
744 | /* save address of controller structure */ | 731 | /* save address of controller structure */ |
745 | usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs); | 732 | usb_set_intfdata(interface, cs); |
746 | 733 | ||
747 | endpoint = &hostif->endpoint[0].desc; | 734 | endpoint = &hostif->endpoint[0].desc; |
748 | 735 | ||
@@ -921,8 +908,7 @@ static const struct gigaset_ops ops = { | |||
921 | gigaset_m10x_input, | 908 | gigaset_m10x_input, |
922 | }; | 909 | }; |
923 | 910 | ||
924 | /** | 911 | /* |
925 | * usb_gigaset_init | ||
926 | * This function is called while kernel-module is loaded | 912 | * This function is called while kernel-module is loaded |
927 | */ | 913 | */ |
928 | static int __init usb_gigaset_init(void) | 914 | static int __init usb_gigaset_init(void) |
@@ -952,9 +938,7 @@ error: | |||
952 | return -1; | 938 | return -1; |
953 | } | 939 | } |
954 | 940 | ||
955 | 941 | /* | |
956 | /** | ||
957 | * usb_gigaset_exit | ||
958 | * This function is called while unloading the kernel-module | 942 | * This function is called while unloading the kernel-module |
959 | */ | 943 | */ |
960 | static void __exit usb_gigaset_exit(void) | 944 | static void __exit usb_gigaset_exit(void) |
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c index abf05ec31760..a7c0083e78a7 100644 --- a/drivers/isdn/hardware/avm/b1.c +++ b/drivers/isdn/hardware/avm/b1.c | |||
@@ -330,7 +330,7 @@ void b1_reset_ctr(struct capi_ctr *ctrl) | |||
330 | spin_lock_irqsave(&card->lock, flags); | 330 | spin_lock_irqsave(&card->lock, flags); |
331 | capilib_release(&cinfo->ncci_head); | 331 | capilib_release(&cinfo->ncci_head); |
332 | spin_unlock_irqrestore(&card->lock, flags); | 332 | spin_unlock_irqrestore(&card->lock, flags); |
333 | capi_ctr_reseted(ctrl); | 333 | capi_ctr_down(ctrl); |
334 | } | 334 | } |
335 | 335 | ||
336 | void b1_register_appl(struct capi_ctr *ctrl, | 336 | void b1_register_appl(struct capi_ctr *ctrl, |
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c index da34b98e3de7..0e84aaae43fd 100644 --- a/drivers/isdn/hardware/avm/b1dma.c +++ b/drivers/isdn/hardware/avm/b1dma.c | |||
@@ -759,7 +759,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl) | |||
759 | memset(cinfo->version, 0, sizeof(cinfo->version)); | 759 | memset(cinfo->version, 0, sizeof(cinfo->version)); |
760 | capilib_release(&cinfo->ncci_head); | 760 | capilib_release(&cinfo->ncci_head); |
761 | spin_unlock_irqrestore(&card->lock, flags); | 761 | spin_unlock_irqrestore(&card->lock, flags); |
762 | capi_ctr_reseted(ctrl); | 762 | capi_ctr_down(ctrl); |
763 | } | 763 | } |
764 | 764 | ||
765 | /* ------------------------------------------------------------- */ | 765 | /* ------------------------------------------------------------- */ |
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index 9df1d3f66c87..6833301a45fc 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c | |||
@@ -681,7 +681,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) | |||
681 | spin_lock_irqsave(&card->lock, flags); | 681 | spin_lock_irqsave(&card->lock, flags); |
682 | capilib_release(&cinfo->ncci_head); | 682 | capilib_release(&cinfo->ncci_head); |
683 | spin_unlock_irqrestore(&card->lock, flags); | 683 | spin_unlock_irqrestore(&card->lock, flags); |
684 | capi_ctr_reseted(&cinfo->capi_ctrl); | 684 | capi_ctr_down(&cinfo->capi_ctrl); |
685 | } | 685 | } |
686 | card->nlogcontr = 0; | 686 | card->nlogcontr = 0; |
687 | return IRQ_HANDLED; | 687 | return IRQ_HANDLED; |
@@ -909,7 +909,7 @@ static void c4_reset_ctr(struct capi_ctr *ctrl) | |||
909 | for (i=0; i < card->nr_controllers; i++) { | 909 | for (i=0; i < card->nr_controllers; i++) { |
910 | cinfo = &card->ctrlinfo[i]; | 910 | cinfo = &card->ctrlinfo[i]; |
911 | memset(cinfo->version, 0, sizeof(cinfo->version)); | 911 | memset(cinfo->version, 0, sizeof(cinfo->version)); |
912 | capi_ctr_reseted(&cinfo->capi_ctrl); | 912 | capi_ctr_down(&cinfo->capi_ctrl); |
913 | } | 913 | } |
914 | card->nlogcontr = 0; | 914 | card->nlogcontr = 0; |
915 | } | 915 | } |
diff --git a/drivers/isdn/hardware/avm/t1isa.c b/drivers/isdn/hardware/avm/t1isa.c index e7724493738c..1c53fd49adb6 100644 --- a/drivers/isdn/hardware/avm/t1isa.c +++ b/drivers/isdn/hardware/avm/t1isa.c | |||
@@ -339,7 +339,7 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl) | |||
339 | spin_lock_irqsave(&card->lock, flags); | 339 | spin_lock_irqsave(&card->lock, flags); |
340 | capilib_release(&cinfo->ncci_head); | 340 | capilib_release(&cinfo->ncci_head); |
341 | spin_unlock_irqrestore(&card->lock, flags); | 341 | spin_unlock_irqrestore(&card->lock, flags); |
342 | capi_ctr_reseted(ctrl); | 342 | capi_ctr_down(ctrl); |
343 | } | 343 | } |
344 | 344 | ||
345 | static void t1isa_remove(struct pci_dev *pdev) | 345 | static void t1isa_remove(struct pci_dev *pdev) |
diff --git a/drivers/isdn/hardware/mISDN/Kconfig b/drivers/isdn/hardware/mISDN/Kconfig index fd112ae252cf..3024566dd099 100644 --- a/drivers/isdn/hardware/mISDN/Kconfig +++ b/drivers/isdn/hardware/mISDN/Kconfig | |||
@@ -13,7 +13,7 @@ config MISDN_HFCPCI | |||
13 | 13 | ||
14 | config MISDN_HFCMULTI | 14 | config MISDN_HFCMULTI |
15 | tristate "Support for HFC multiport cards (HFC-4S/8S/E1)" | 15 | tristate "Support for HFC multiport cards (HFC-4S/8S/E1)" |
16 | depends on PCI | 16 | depends on PCI || 8xx |
17 | depends on MISDN | 17 | depends on MISDN |
18 | help | 18 | help |
19 | Enable support for cards with Cologne Chip AG's HFC multiport | 19 | Enable support for cards with Cologne Chip AG's HFC multiport |
@@ -23,6 +23,15 @@ config MISDN_HFCMULTI | |||
23 | * HFC-8S (8 S/T interfaces on one chip) | 23 | * HFC-8S (8 S/T interfaces on one chip) |
24 | * HFC-E1 (E1 interface for 2Mbit ISDN) | 24 | * HFC-E1 (E1 interface for 2Mbit ISDN) |
25 | 25 | ||
26 | config MISDN_HFCMULTI_8xx | ||
27 | boolean "Support for XHFC embedded board in HFC multiport driver" | ||
28 | depends on MISDN | ||
29 | depends on MISDN_HFCMULTI | ||
30 | depends on 8xx | ||
31 | default 8xx | ||
32 | help | ||
33 | Enable support for the XHFC embedded solution from Speech Design. | ||
34 | |||
26 | config MISDN_HFCUSB | 35 | config MISDN_HFCUSB |
27 | tristate "Support for HFC-S USB based TAs" | 36 | tristate "Support for HFC-S USB based TAs" |
28 | depends on USB | 37 | depends on USB |
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h index 663b77f578be..0c773866efc7 100644 --- a/drivers/isdn/hardware/mISDN/hfc_multi.h +++ b/drivers/isdn/hardware/mISDN/hfc_multi.h | |||
@@ -17,6 +17,16 @@ | |||
17 | #define PCI_ENA_REGIO 0x01 | 17 | #define PCI_ENA_REGIO 0x01 |
18 | #define PCI_ENA_MEMIO 0x02 | 18 | #define PCI_ENA_MEMIO 0x02 |
19 | 19 | ||
20 | #define XHFC_IRQ 4 /* SIU_IRQ2 */ | ||
21 | #define XHFC_MEMBASE 0xFE000000 | ||
22 | #define XHFC_MEMSIZE 0x00001000 | ||
23 | #define XHFC_OFFSET 0x00001000 | ||
24 | #define PA_XHFC_A0 0x0020 /* PA10 */ | ||
25 | #define PB_XHFC_IRQ1 0x00000100 /* PB23 */ | ||
26 | #define PB_XHFC_IRQ2 0x00000200 /* PB22 */ | ||
27 | #define PB_XHFC_IRQ3 0x00000400 /* PB21 */ | ||
28 | #define PB_XHFC_IRQ4 0x00000800 /* PB20 */ | ||
29 | |||
20 | /* | 30 | /* |
21 | * NOTE: some registers are assigned multiple times due to different modes | 31 | * NOTE: some registers are assigned multiple times due to different modes |
22 | * also registers are assigned differen for HFC-4s/8s and HFC-E1 | 32 | * also registers are assigned differen for HFC-4s/8s and HFC-E1 |
@@ -44,6 +54,7 @@ struct hfc_chan { | |||
44 | int conf; /* conference setting of TX slot */ | 54 | int conf; /* conference setting of TX slot */ |
45 | int txpending; /* if there is currently data in */ | 55 | int txpending; /* if there is currently data in */ |
46 | /* the FIFO 0=no, 1=yes, 2=splloop */ | 56 | /* the FIFO 0=no, 1=yes, 2=splloop */ |
57 | int Zfill; /* rx-fifo level on last hfcmulti_tx */ | ||
47 | int rx_off; /* set to turn fifo receive off */ | 58 | int rx_off; /* set to turn fifo receive off */ |
48 | int coeff_count; /* curren coeff block */ | 59 | int coeff_count; /* curren coeff block */ |
49 | s32 *coeff; /* memory pointer to 8 coeff blocks */ | 60 | s32 *coeff; /* memory pointer to 8 coeff blocks */ |
@@ -62,6 +73,7 @@ struct hfcm_hw { | |||
62 | u_char r_sci_msk; | 73 | u_char r_sci_msk; |
63 | u_char r_tx0, r_tx1; | 74 | u_char r_tx0, r_tx1; |
64 | u_char a_st_ctrl0[8]; | 75 | u_char a_st_ctrl0[8]; |
76 | u_char r_bert_wd_md; | ||
65 | timer_t timer; | 77 | timer_t timer; |
66 | }; | 78 | }; |
67 | 79 | ||
@@ -79,6 +91,11 @@ struct hfcm_hw { | |||
79 | #define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */ | 91 | #define HFC_CFG_CRC4 10 /* disable CRC-4 Multiframe mode, */ |
80 | /* use double frame instead. */ | 92 | /* use double frame instead. */ |
81 | 93 | ||
94 | #define HFC_TYPE_E1 1 /* controller is HFC-E1 */ | ||
95 | #define HFC_TYPE_4S 4 /* controller is HFC-4S */ | ||
96 | #define HFC_TYPE_8S 8 /* controller is HFC-8S */ | ||
97 | #define HFC_TYPE_XHFC 5 /* controller is XHFC */ | ||
98 | |||
82 | #define HFC_CHIP_EXRAM_128 0 /* external ram 128k */ | 99 | #define HFC_CHIP_EXRAM_128 0 /* external ram 128k */ |
83 | #define HFC_CHIP_EXRAM_512 1 /* external ram 256k */ | 100 | #define HFC_CHIP_EXRAM_512 1 /* external ram 256k */ |
84 | #define HFC_CHIP_REVISION0 2 /* old fifo handling */ | 101 | #define HFC_CHIP_REVISION0 2 /* old fifo handling */ |
@@ -86,19 +103,22 @@ struct hfcm_hw { | |||
86 | #define HFC_CHIP_PCM_MASTER 4 /* PCM is master */ | 103 | #define HFC_CHIP_PCM_MASTER 4 /* PCM is master */ |
87 | #define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */ | 104 | #define HFC_CHIP_RX_SYNC 5 /* disable pll sync for pcm */ |
88 | #define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */ | 105 | #define HFC_CHIP_DTMF 6 /* DTMF decoding is enabled */ |
89 | #define HFC_CHIP_ULAW 7 /* ULAW mode */ | 106 | #define HFC_CHIP_CONF 7 /* conference handling is enabled */ |
90 | #define HFC_CHIP_CLOCK2 8 /* double clock mode */ | 107 | #define HFC_CHIP_ULAW 8 /* ULAW mode */ |
91 | #define HFC_CHIP_E1CLOCK_GET 9 /* always get clock from E1 interface */ | 108 | #define HFC_CHIP_CLOCK2 9 /* double clock mode */ |
92 | #define HFC_CHIP_E1CLOCK_PUT 10 /* always put clock from E1 interface */ | 109 | #define HFC_CHIP_E1CLOCK_GET 10 /* always get clock from E1 interface */ |
93 | #define HFC_CHIP_WATCHDOG 11 /* whether we should send signals */ | 110 | #define HFC_CHIP_E1CLOCK_PUT 11 /* always put clock from E1 interface */ |
111 | #define HFC_CHIP_WATCHDOG 12 /* whether we should send signals */ | ||
94 | /* to the watchdog */ | 112 | /* to the watchdog */ |
95 | #define HFC_CHIP_B410P 12 /* whether we have a b410p with echocan in */ | 113 | #define HFC_CHIP_B410P 13 /* whether we have a b410p with echocan in */ |
96 | /* hw */ | 114 | /* hw */ |
97 | #define HFC_CHIP_PLXSD 13 /* whether we have a Speech-Design PLX */ | 115 | #define HFC_CHIP_PLXSD 14 /* whether we have a Speech-Design PLX */ |
116 | #define HFC_CHIP_EMBSD 15 /* whether we have a SD Embedded board */ | ||
98 | 117 | ||
99 | #define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */ | 118 | #define HFC_IO_MODE_PCIMEM 0x00 /* normal memory mapped IO */ |
100 | #define HFC_IO_MODE_REGIO 0x01 /* PCI io access */ | 119 | #define HFC_IO_MODE_REGIO 0x01 /* PCI io access */ |
101 | #define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */ | 120 | #define HFC_IO_MODE_PLXSD 0x02 /* access HFC via PLX9030 */ |
121 | #define HFC_IO_MODE_EMBSD 0x03 /* direct access */ | ||
102 | 122 | ||
103 | /* table entry in the PCI devices list */ | 123 | /* table entry in the PCI devices list */ |
104 | struct hm_map { | 124 | struct hm_map { |
@@ -111,6 +131,7 @@ struct hm_map { | |||
111 | int opticalsupport; | 131 | int opticalsupport; |
112 | int dip_type; | 132 | int dip_type; |
113 | int io_mode; | 133 | int io_mode; |
134 | int irq; | ||
114 | }; | 135 | }; |
115 | 136 | ||
116 | struct hfc_multi { | 137 | struct hfc_multi { |
@@ -118,7 +139,7 @@ struct hfc_multi { | |||
118 | struct hm_map *mtyp; | 139 | struct hm_map *mtyp; |
119 | int id; | 140 | int id; |
120 | int pcm; /* id of pcm bus */ | 141 | int pcm; /* id of pcm bus */ |
121 | int type; | 142 | int ctype; /* controller type */ |
122 | int ports; | 143 | int ports; |
123 | 144 | ||
124 | u_int irq; /* irq used by card */ | 145 | u_int irq; /* irq used by card */ |
@@ -158,10 +179,16 @@ struct hfc_multi { | |||
158 | int len); | 179 | int len); |
159 | void (*write_fifo)(struct hfc_multi *hc, u_char *data, | 180 | void (*write_fifo)(struct hfc_multi *hc, u_char *data, |
160 | int len); | 181 | int len); |
161 | u_long pci_origmembase, plx_origmembase, dsp_origmembase; | 182 | u_long pci_origmembase, plx_origmembase; |
162 | void __iomem *pci_membase; /* PCI memory */ | 183 | void __iomem *pci_membase; /* PCI memory */ |
163 | void __iomem *plx_membase; /* PLX memory */ | 184 | void __iomem *plx_membase; /* PLX memory */ |
164 | u_char *dsp_membase; /* DSP on PLX */ | 185 | u_long xhfc_origmembase; |
186 | u_char *xhfc_membase; | ||
187 | u_long *xhfc_memaddr, *xhfc_memdata; | ||
188 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | ||
189 | struct immap *immap; | ||
190 | #endif | ||
191 | u_long pb_irqmsk; /* Portbit mask to check the IRQ line */ | ||
165 | u_long pci_iobase; /* PCI IO */ | 192 | u_long pci_iobase; /* PCI IO */ |
166 | struct hfcm_hw hw; /* remember data of write-only-registers */ | 193 | struct hfcm_hw hw; /* remember data of write-only-registers */ |
167 | 194 | ||
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h new file mode 100644 index 000000000000..45ddced956d5 --- /dev/null +++ b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h | |||
@@ -0,0 +1,167 @@ | |||
1 | /* | ||
2 | * For License see notice in hfc_multi.c | ||
3 | * | ||
4 | * special IO and init functions for the embedded XHFC board | ||
5 | * from Speech Design | ||
6 | * | ||
7 | */ | ||
8 | |||
9 | #include <asm/8xx_immap.h> | ||
10 | |||
11 | /* Change this to the value used by your board */ | ||
12 | #ifndef IMAP_ADDR | ||
13 | #define IMAP_ADDR 0xFFF00000 | ||
14 | #endif | ||
15 | |||
16 | static void | ||
17 | #ifdef HFC_REGISTER_DEBUG | ||
18 | HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val, | ||
19 | const char *function, int line) | ||
20 | #else | ||
21 | HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val) | ||
22 | #endif | ||
23 | { | ||
24 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
25 | writeb(reg, hc->xhfc_memaddr); | ||
26 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
27 | writeb(val, hc->xhfc_memdata); | ||
28 | } | ||
29 | static u_char | ||
30 | #ifdef HFC_REGISTER_DEBUG | ||
31 | HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line) | ||
32 | #else | ||
33 | HFC_inb_embsd(struct hfc_multi *hc, u_char reg) | ||
34 | #endif | ||
35 | { | ||
36 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
37 | writeb(reg, hc->xhfc_memaddr); | ||
38 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
39 | return readb(hc->xhfc_memdata); | ||
40 | } | ||
41 | static u_short | ||
42 | #ifdef HFC_REGISTER_DEBUG | ||
43 | HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line) | ||
44 | #else | ||
45 | HFC_inw_embsd(struct hfc_multi *hc, u_char reg) | ||
46 | #endif | ||
47 | { | ||
48 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
49 | writeb(reg, hc->xhfc_memaddr); | ||
50 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
51 | return readb(hc->xhfc_memdata); | ||
52 | } | ||
53 | static void | ||
54 | #ifdef HFC_REGISTER_DEBUG | ||
55 | HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line) | ||
56 | #else | ||
57 | HFC_wait_embsd(struct hfc_multi *hc) | ||
58 | #endif | ||
59 | { | ||
60 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
61 | writeb(R_STATUS, hc->xhfc_memaddr); | ||
62 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
63 | while (readb(hc->xhfc_memdata) & V_BUSY) | ||
64 | cpu_relax(); | ||
65 | } | ||
66 | |||
67 | /* write fifo data (EMBSD) */ | ||
68 | void | ||
69 | write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len) | ||
70 | { | ||
71 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
72 | *hc->xhfc_memaddr = A_FIFO_DATA0; | ||
73 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
74 | while (len) { | ||
75 | *hc->xhfc_memdata = *data; | ||
76 | data++; | ||
77 | len--; | ||
78 | } | ||
79 | } | ||
80 | |||
81 | /* read fifo data (EMBSD) */ | ||
82 | void | ||
83 | read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len) | ||
84 | { | ||
85 | hc->immap->im_ioport.iop_padat |= PA_XHFC_A0; | ||
86 | *hc->xhfc_memaddr = A_FIFO_DATA0; | ||
87 | hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0); | ||
88 | while (len) { | ||
89 | *data = (u_char)(*hc->xhfc_memdata); | ||
90 | data++; | ||
91 | len--; | ||
92 | } | ||
93 | } | ||
94 | |||
95 | static int | ||
96 | setup_embedded(struct hfc_multi *hc, struct hm_map *m) | ||
97 | { | ||
98 | printk(KERN_INFO | ||
99 | "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n", | ||
100 | m->vendor_name, m->card_name, m->clock2 ? "double" : "normal"); | ||
101 | |||
102 | hc->pci_dev = NULL; | ||
103 | if (m->clock2) | ||
104 | test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip); | ||
105 | |||
106 | hc->leds = m->leds; | ||
107 | hc->ledstate = 0xAFFEAFFE; | ||
108 | hc->opticalsupport = m->opticalsupport; | ||
109 | |||
110 | hc->pci_iobase = 0; | ||
111 | hc->pci_membase = 0; | ||
112 | hc->xhfc_membase = NULL; | ||
113 | hc->xhfc_memaddr = NULL; | ||
114 | hc->xhfc_memdata = NULL; | ||
115 | |||
116 | /* set memory access methods */ | ||
117 | if (m->io_mode) /* use mode from card config */ | ||
118 | hc->io_mode = m->io_mode; | ||
119 | switch (hc->io_mode) { | ||
120 | case HFC_IO_MODE_EMBSD: | ||
121 | test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip); | ||
122 | hc->slots = 128; /* required */ | ||
123 | /* fall through */ | ||
124 | hc->HFC_outb = HFC_outb_embsd; | ||
125 | hc->HFC_inb = HFC_inb_embsd; | ||
126 | hc->HFC_inw = HFC_inw_embsd; | ||
127 | hc->HFC_wait = HFC_wait_embsd; | ||
128 | hc->read_fifo = read_fifo_embsd; | ||
129 | hc->write_fifo = write_fifo_embsd; | ||
130 | hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id; | ||
131 | hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase, | ||
132 | XHFC_MEMSIZE); | ||
133 | if (!hc->xhfc_membase) { | ||
134 | printk(KERN_WARNING | ||
135 | "HFC-multi: failed to remap xhfc address space. " | ||
136 | "(internal error)\n"); | ||
137 | return -EIO; | ||
138 | } | ||
139 | hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4); | ||
140 | hc->xhfc_memdata = (u_long *)(hc->xhfc_membase); | ||
141 | printk(KERN_INFO | ||
142 | "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx " | ||
143 | "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n", | ||
144 | (u_long)hc->xhfc_membase, hc->xhfc_origmembase, | ||
145 | (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata); | ||
146 | break; | ||
147 | default: | ||
148 | printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); | ||
149 | return -EIO; | ||
150 | } | ||
151 | |||
152 | /* Prepare the MPC8XX PortA 10 as output (address/data selector) */ | ||
153 | hc->immap = (struct immap *)(IMAP_ADDR); | ||
154 | hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0); | ||
155 | hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0); | ||
156 | hc->immap->im_ioport.iop_padir |= PA_XHFC_A0; | ||
157 | |||
158 | /* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */ | ||
159 | hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id); | ||
160 | hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk); | ||
161 | hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk); | ||
162 | hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk); | ||
163 | |||
164 | /* At this point the needed config is done */ | ||
165 | /* fifos are still not enabled */ | ||
166 | return 0; | ||
167 | } | ||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 0b28141e43bf..e1dab30aed30 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -104,7 +104,7 @@ | |||
104 | * If unsure, don't give this parameter. | 104 | * If unsure, don't give this parameter. |
105 | * | 105 | * |
106 | * dslot: | 106 | * dslot: |
107 | * NOTE: only one poll value must be given for every card. | 107 | * NOTE: only one dslot value must be given for every card. |
108 | * Also this value must be given for non-E1 cards. If omitted, the E1 | 108 | * Also this value must be given for non-E1 cards. If omitted, the E1 |
109 | * card has D-channel on time slot 16, which is default. | 109 | * card has D-channel on time slot 16, which is default. |
110 | * If 1..15 or 17..31, an alternate time slot is used for D-channel. | 110 | * If 1..15 or 17..31, an alternate time slot is used for D-channel. |
@@ -139,6 +139,10 @@ | |||
139 | * Selects interface with clock source for mISDN and applications. | 139 | * Selects interface with clock source for mISDN and applications. |
140 | * Set to card number starting with 1. Set to -1 to disable. | 140 | * Set to card number starting with 1. Set to -1 to disable. |
141 | * By default, the first card is used as clock source. | 141 | * By default, the first card is used as clock source. |
142 | * | ||
143 | * hwid: | ||
144 | * NOTE: only one hwid value must be given once | ||
145 | * Enable special embedded devices with XHFC controllers. | ||
142 | */ | 146 | */ |
143 | 147 | ||
144 | /* | 148 | /* |
@@ -206,6 +210,11 @@ static int clock; | |||
206 | static uint timer; | 210 | static uint timer; |
207 | static uint clockdelay_te = CLKDEL_TE; | 211 | static uint clockdelay_te = CLKDEL_TE; |
208 | static uint clockdelay_nt = CLKDEL_NT; | 212 | static uint clockdelay_nt = CLKDEL_NT; |
213 | #define HWID_NONE 0 | ||
214 | #define HWID_MINIP4 1 | ||
215 | #define HWID_MINIP8 2 | ||
216 | #define HWID_MINIP16 3 | ||
217 | static uint hwid = HWID_NONE; | ||
209 | 218 | ||
210 | static int HFC_cnt, Port_cnt, PCM_cnt = 99; | 219 | static int HFC_cnt, Port_cnt, PCM_cnt = 99; |
211 | 220 | ||
@@ -223,6 +232,7 @@ module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR); | |||
223 | module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR); | 232 | module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR); |
224 | module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); | 233 | module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR); |
225 | module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); | 234 | module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); |
235 | module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */ | ||
226 | 236 | ||
227 | #ifdef HFC_REGISTER_DEBUG | 237 | #ifdef HFC_REGISTER_DEBUG |
228 | #define HFC_outb(hc, reg, val) \ | 238 | #define HFC_outb(hc, reg, val) \ |
@@ -252,6 +262,10 @@ module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR); | |||
252 | #define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc)) | 262 | #define HFC_wait_nodebug(hc) (hc->HFC_wait_nodebug(hc)) |
253 | #endif | 263 | #endif |
254 | 264 | ||
265 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | ||
266 | #include "hfc_multi_8xx.h" | ||
267 | #endif | ||
268 | |||
255 | /* HFC_IO_MODE_PCIMEM */ | 269 | /* HFC_IO_MODE_PCIMEM */ |
256 | static void | 270 | static void |
257 | #ifdef HFC_REGISTER_DEBUG | 271 | #ifdef HFC_REGISTER_DEBUG |
@@ -261,7 +275,7 @@ HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val, | |||
261 | HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val) | 275 | HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val) |
262 | #endif | 276 | #endif |
263 | { | 277 | { |
264 | writeb(val, (hc->pci_membase)+reg); | 278 | writeb(val, hc->pci_membase + reg); |
265 | } | 279 | } |
266 | static u_char | 280 | static u_char |
267 | #ifdef HFC_REGISTER_DEBUG | 281 | #ifdef HFC_REGISTER_DEBUG |
@@ -270,7 +284,7 @@ HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line) | |||
270 | HFC_inb_pcimem(struct hfc_multi *hc, u_char reg) | 284 | HFC_inb_pcimem(struct hfc_multi *hc, u_char reg) |
271 | #endif | 285 | #endif |
272 | { | 286 | { |
273 | return readb((hc->pci_membase)+reg); | 287 | return readb(hc->pci_membase + reg); |
274 | } | 288 | } |
275 | static u_short | 289 | static u_short |
276 | #ifdef HFC_REGISTER_DEBUG | 290 | #ifdef HFC_REGISTER_DEBUG |
@@ -279,7 +293,7 @@ HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line) | |||
279 | HFC_inw_pcimem(struct hfc_multi *hc, u_char reg) | 293 | HFC_inw_pcimem(struct hfc_multi *hc, u_char reg) |
280 | #endif | 294 | #endif |
281 | { | 295 | { |
282 | return readw((hc->pci_membase)+reg); | 296 | return readw(hc->pci_membase + reg); |
283 | } | 297 | } |
284 | static void | 298 | static void |
285 | #ifdef HFC_REGISTER_DEBUG | 299 | #ifdef HFC_REGISTER_DEBUG |
@@ -288,7 +302,8 @@ HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line) | |||
288 | HFC_wait_pcimem(struct hfc_multi *hc) | 302 | HFC_wait_pcimem(struct hfc_multi *hc) |
289 | #endif | 303 | #endif |
290 | { | 304 | { |
291 | while (readb((hc->pci_membase)+R_STATUS) & V_BUSY); | 305 | while (readb(hc->pci_membase + R_STATUS) & V_BUSY) |
306 | cpu_relax(); | ||
292 | } | 307 | } |
293 | 308 | ||
294 | /* HFC_IO_MODE_REGIO */ | 309 | /* HFC_IO_MODE_REGIO */ |
@@ -300,7 +315,7 @@ HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val, | |||
300 | HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val) | 315 | HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val) |
301 | #endif | 316 | #endif |
302 | { | 317 | { |
303 | outb(reg, (hc->pci_iobase)+4); | 318 | outb(reg, hc->pci_iobase + 4); |
304 | outb(val, hc->pci_iobase); | 319 | outb(val, hc->pci_iobase); |
305 | } | 320 | } |
306 | static u_char | 321 | static u_char |
@@ -310,7 +325,7 @@ HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line) | |||
310 | HFC_inb_regio(struct hfc_multi *hc, u_char reg) | 325 | HFC_inb_regio(struct hfc_multi *hc, u_char reg) |
311 | #endif | 326 | #endif |
312 | { | 327 | { |
313 | outb(reg, (hc->pci_iobase)+4); | 328 | outb(reg, hc->pci_iobase + 4); |
314 | return inb(hc->pci_iobase); | 329 | return inb(hc->pci_iobase); |
315 | } | 330 | } |
316 | static u_short | 331 | static u_short |
@@ -320,7 +335,7 @@ HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line) | |||
320 | HFC_inw_regio(struct hfc_multi *hc, u_char reg) | 335 | HFC_inw_regio(struct hfc_multi *hc, u_char reg) |
321 | #endif | 336 | #endif |
322 | { | 337 | { |
323 | outb(reg, (hc->pci_iobase)+4); | 338 | outb(reg, hc->pci_iobase + 4); |
324 | return inw(hc->pci_iobase); | 339 | return inw(hc->pci_iobase); |
325 | } | 340 | } |
326 | static void | 341 | static void |
@@ -330,8 +345,9 @@ HFC_wait_regio(struct hfc_multi *hc, const char *function, int line) | |||
330 | HFC_wait_regio(struct hfc_multi *hc) | 345 | HFC_wait_regio(struct hfc_multi *hc) |
331 | #endif | 346 | #endif |
332 | { | 347 | { |
333 | outb(R_STATUS, (hc->pci_iobase)+4); | 348 | outb(R_STATUS, hc->pci_iobase + 4); |
334 | while (inb(hc->pci_iobase) & V_BUSY); | 349 | while (inb(hc->pci_iobase) & V_BUSY) |
350 | cpu_relax(); | ||
335 | } | 351 | } |
336 | 352 | ||
337 | #ifdef HFC_REGISTER_DEBUG | 353 | #ifdef HFC_REGISTER_DEBUG |
@@ -350,14 +366,14 @@ HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val, | |||
350 | if (regname[0] == '\0') | 366 | if (regname[0] == '\0') |
351 | strcpy(regname, "register"); | 367 | strcpy(regname, "register"); |
352 | 368 | ||
353 | bits[7] = '0'+(!!(val&1)); | 369 | bits[7] = '0' + (!!(val & 1)); |
354 | bits[6] = '0'+(!!(val&2)); | 370 | bits[6] = '0' + (!!(val & 2)); |
355 | bits[5] = '0'+(!!(val&4)); | 371 | bits[5] = '0' + (!!(val & 4)); |
356 | bits[4] = '0'+(!!(val&8)); | 372 | bits[4] = '0' + (!!(val & 8)); |
357 | bits[3] = '0'+(!!(val&16)); | 373 | bits[3] = '0' + (!!(val & 16)); |
358 | bits[2] = '0'+(!!(val&32)); | 374 | bits[2] = '0' + (!!(val & 32)); |
359 | bits[1] = '0'+(!!(val&64)); | 375 | bits[1] = '0' + (!!(val & 64)); |
360 | bits[0] = '0'+(!!(val&128)); | 376 | bits[0] = '0' + (!!(val & 128)); |
361 | printk(KERN_DEBUG | 377 | printk(KERN_DEBUG |
362 | "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n", | 378 | "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n", |
363 | hc->id, reg, regname, val, bits, function, line); | 379 | hc->id, reg, regname, val, bits, function, line); |
@@ -380,14 +396,14 @@ HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line) | |||
380 | if (regname[0] == '\0') | 396 | if (regname[0] == '\0') |
381 | strcpy(regname, "register"); | 397 | strcpy(regname, "register"); |
382 | 398 | ||
383 | bits[7] = '0'+(!!(val&1)); | 399 | bits[7] = '0' + (!!(val & 1)); |
384 | bits[6] = '0'+(!!(val&2)); | 400 | bits[6] = '0' + (!!(val & 2)); |
385 | bits[5] = '0'+(!!(val&4)); | 401 | bits[5] = '0' + (!!(val & 4)); |
386 | bits[4] = '0'+(!!(val&8)); | 402 | bits[4] = '0' + (!!(val & 8)); |
387 | bits[3] = '0'+(!!(val&16)); | 403 | bits[3] = '0' + (!!(val & 16)); |
388 | bits[2] = '0'+(!!(val&32)); | 404 | bits[2] = '0' + (!!(val & 32)); |
389 | bits[1] = '0'+(!!(val&64)); | 405 | bits[1] = '0' + (!!(val & 64)); |
390 | bits[0] = '0'+(!!(val&128)); | 406 | bits[0] = '0' + (!!(val & 128)); |
391 | printk(KERN_DEBUG | 407 | printk(KERN_DEBUG |
392 | "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n", | 408 | "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n", |
393 | hc->id, reg, regname, val, bits, function, line); | 409 | hc->id, reg, regname, val, bits, function, line); |
@@ -467,6 +483,7 @@ write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) | |||
467 | len--; | 483 | len--; |
468 | } | 484 | } |
469 | } | 485 | } |
486 | |||
470 | /* read fifo data (REGIO) */ | 487 | /* read fifo data (REGIO) */ |
471 | static void | 488 | static void |
472 | read_fifo_regio(struct hfc_multi *hc, u_char *data, int len) | 489 | read_fifo_regio(struct hfc_multi *hc, u_char *data, int len) |
@@ -512,7 +529,6 @@ read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) | |||
512 | } | 529 | } |
513 | } | 530 | } |
514 | 531 | ||
515 | |||
516 | static void | 532 | static void |
517 | enable_hwirq(struct hfc_multi *hc) | 533 | enable_hwirq(struct hfc_multi *hc) |
518 | { | 534 | { |
@@ -928,7 +944,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
928 | writel(pv, plx_acc_32); | 944 | writel(pv, plx_acc_32); |
929 | if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { | 945 | if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { |
930 | pcmmaster = hc; | 946 | pcmmaster = hc; |
931 | if (hc->type == 1) { | 947 | if (hc->ctype == HFC_TYPE_E1) { |
932 | if (debug & DEBUG_HFCMULTI_PLXSD) | 948 | if (debug & DEBUG_HFCMULTI_PLXSD) |
933 | printk(KERN_DEBUG | 949 | printk(KERN_DEBUG |
934 | "Schedule SYNC_I\n"); | 950 | "Schedule SYNC_I\n"); |
@@ -949,7 +965,8 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
949 | pv |= PLX_SYNC_O_EN; | 965 | pv |= PLX_SYNC_O_EN; |
950 | writel(pv, plx_acc_32); | 966 | writel(pv, plx_acc_32); |
951 | /* switch to jatt PLL, if not disabled by RX_SYNC */ | 967 | /* switch to jatt PLL, if not disabled by RX_SYNC */ |
952 | if (hc->type == 1 && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { | 968 | if (hc->ctype == HFC_TYPE_E1 |
969 | && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { | ||
953 | if (debug & DEBUG_HFCMULTI_PLXSD) | 970 | if (debug & DEBUG_HFCMULTI_PLXSD) |
954 | printk(KERN_DEBUG "Schedule jatt PLL\n"); | 971 | printk(KERN_DEBUG "Schedule jatt PLL\n"); |
955 | hc->e1_resync |= 2; /* switch to jatt */ | 972 | hc->e1_resync |= 2; /* switch to jatt */ |
@@ -961,7 +978,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
961 | printk(KERN_DEBUG | 978 | printk(KERN_DEBUG |
962 | "id=%d (0x%p) = PCM master syncronized " | 979 | "id=%d (0x%p) = PCM master syncronized " |
963 | "with QUARTZ\n", hc->id, hc); | 980 | "with QUARTZ\n", hc->id, hc); |
964 | if (hc->type == 1) { | 981 | if (hc->ctype == HFC_TYPE_E1) { |
965 | /* Use the crystal clock for the PCM | 982 | /* Use the crystal clock for the PCM |
966 | master card */ | 983 | master card */ |
967 | if (debug & DEBUG_HFCMULTI_PLXSD) | 984 | if (debug & DEBUG_HFCMULTI_PLXSD) |
@@ -972,7 +989,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) | |||
972 | if (debug & DEBUG_HFCMULTI_PLXSD) | 989 | if (debug & DEBUG_HFCMULTI_PLXSD) |
973 | printk(KERN_DEBUG | 990 | printk(KERN_DEBUG |
974 | "QUARTZ is automatically " | 991 | "QUARTZ is automatically " |
975 | "enabled by HFC-%dS\n", hc->type); | 992 | "enabled by HFC-%dS\n", hc->ctype); |
976 | } | 993 | } |
977 | plx_acc_32 = hc->plx_membase + PLX_GPIOC; | 994 | plx_acc_32 = hc->plx_membase + PLX_GPIOC; |
978 | pv = readl(plx_acc_32); | 995 | pv = readl(plx_acc_32); |
@@ -996,7 +1013,7 @@ plxsd_checksync(struct hfc_multi *hc, int rm) | |||
996 | if (hc->syncronized) { | 1013 | if (hc->syncronized) { |
997 | if (syncmaster == NULL) { | 1014 | if (syncmaster == NULL) { |
998 | if (debug & DEBUG_HFCMULTI_PLXSD) | 1015 | if (debug & DEBUG_HFCMULTI_PLXSD) |
999 | printk(KERN_WARNING "%s: GOT sync on card %d" | 1016 | printk(KERN_DEBUG "%s: GOT sync on card %d" |
1000 | " (id=%d)\n", __func__, hc->id + 1, | 1017 | " (id=%d)\n", __func__, hc->id + 1, |
1001 | hc->id); | 1018 | hc->id); |
1002 | hfcmulti_resync(hc, hc, rm); | 1019 | hfcmulti_resync(hc, hc, rm); |
@@ -1004,7 +1021,7 @@ plxsd_checksync(struct hfc_multi *hc, int rm) | |||
1004 | } else { | 1021 | } else { |
1005 | if (syncmaster == hc) { | 1022 | if (syncmaster == hc) { |
1006 | if (debug & DEBUG_HFCMULTI_PLXSD) | 1023 | if (debug & DEBUG_HFCMULTI_PLXSD) |
1007 | printk(KERN_WARNING "%s: LOST sync on card %d" | 1024 | printk(KERN_DEBUG "%s: LOST sync on card %d" |
1008 | " (id=%d)\n", __func__, hc->id + 1, | 1025 | " (id=%d)\n", __func__, hc->id + 1, |
1009 | hc->id); | 1026 | hc->id); |
1010 | hfcmulti_resync(hc, NULL, rm); | 1027 | hfcmulti_resync(hc, NULL, rm); |
@@ -1053,20 +1070,23 @@ release_io_hfcmulti(struct hfc_multi *hc) | |||
1053 | pv &= ~PLX_DSP_RES_N; | 1070 | pv &= ~PLX_DSP_RES_N; |
1054 | writel(pv, plx_acc_32); | 1071 | writel(pv, plx_acc_32); |
1055 | if (debug & DEBUG_HFCMULTI_INIT) | 1072 | if (debug & DEBUG_HFCMULTI_INIT) |
1056 | printk(KERN_WARNING "%s: PCM off: PLX_GPIO=%x\n", | 1073 | printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n", |
1057 | __func__, pv); | 1074 | __func__, pv); |
1058 | spin_unlock_irqrestore(&plx_lock, plx_flags); | 1075 | spin_unlock_irqrestore(&plx_lock, plx_flags); |
1059 | } | 1076 | } |
1060 | 1077 | ||
1061 | /* disable memory mapped ports / io ports */ | 1078 | /* disable memory mapped ports / io ports */ |
1062 | test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ | 1079 | test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ |
1063 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); | 1080 | if (hc->pci_dev) |
1081 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); | ||
1064 | if (hc->pci_membase) | 1082 | if (hc->pci_membase) |
1065 | iounmap(hc->pci_membase); | 1083 | iounmap(hc->pci_membase); |
1066 | if (hc->plx_membase) | 1084 | if (hc->plx_membase) |
1067 | iounmap(hc->plx_membase); | 1085 | iounmap(hc->plx_membase); |
1068 | if (hc->pci_iobase) | 1086 | if (hc->pci_iobase) |
1069 | release_region(hc->pci_iobase, 8); | 1087 | release_region(hc->pci_iobase, 8); |
1088 | if (hc->xhfc_membase) | ||
1089 | iounmap((void *)hc->xhfc_membase); | ||
1070 | 1090 | ||
1071 | if (hc->pci_dev) { | 1091 | if (hc->pci_dev) { |
1072 | pci_disable_device(hc->pci_dev); | 1092 | pci_disable_device(hc->pci_dev); |
@@ -1100,8 +1120,9 @@ init_chip(struct hfc_multi *hc) | |||
1100 | /* revision check */ | 1120 | /* revision check */ |
1101 | if (debug & DEBUG_HFCMULTI_INIT) | 1121 | if (debug & DEBUG_HFCMULTI_INIT) |
1102 | printk(KERN_DEBUG "%s: entered\n", __func__); | 1122 | printk(KERN_DEBUG "%s: entered\n", __func__); |
1103 | val = HFC_inb(hc, R_CHIP_ID)>>4; | 1123 | val = HFC_inb(hc, R_CHIP_ID); |
1104 | if (val != 0x8 && val != 0xc && val != 0xe) { | 1124 | if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe && |
1125 | (val >> 1) != 0x31) { | ||
1105 | printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); | 1126 | printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); |
1106 | err = -EIO; | 1127 | err = -EIO; |
1107 | goto out; | 1128 | goto out; |
@@ -1109,8 +1130,9 @@ init_chip(struct hfc_multi *hc) | |||
1109 | rev = HFC_inb(hc, R_CHIP_RV); | 1130 | rev = HFC_inb(hc, R_CHIP_RV); |
1110 | printk(KERN_INFO | 1131 | printk(KERN_INFO |
1111 | "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", | 1132 | "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", |
1112 | val, rev, (rev == 0) ? " (old FIFO handling)" : ""); | 1133 | val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ? |
1113 | if (rev == 0) { | 1134 | " (old FIFO handling)" : ""); |
1135 | if (hc->ctype != HFC_TYPE_XHFC && rev == 0) { | ||
1114 | test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); | 1136 | test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); |
1115 | printk(KERN_WARNING | 1137 | printk(KERN_WARNING |
1116 | "HFC_multi: NOTE: Your chip is revision 0, " | 1138 | "HFC_multi: NOTE: Your chip is revision 0, " |
@@ -1152,6 +1174,12 @@ init_chip(struct hfc_multi *hc) | |||
1152 | hc->Zlen = 8000; | 1174 | hc->Zlen = 8000; |
1153 | hc->DTMFbase = 0x2000; | 1175 | hc->DTMFbase = 0x2000; |
1154 | } | 1176 | } |
1177 | if (hc->ctype == HFC_TYPE_XHFC) { | ||
1178 | hc->Flen = 0x8; | ||
1179 | hc->Zmin = 0x0; | ||
1180 | hc->Zlen = 64; | ||
1181 | hc->DTMFbase = 0x0; | ||
1182 | } | ||
1155 | hc->max_trans = poll << 1; | 1183 | hc->max_trans = poll << 1; |
1156 | if (hc->max_trans > hc->Zlen) | 1184 | if (hc->max_trans > hc->Zlen) |
1157 | hc->max_trans = hc->Zlen; | 1185 | hc->max_trans = hc->Zlen; |
@@ -1176,7 +1204,7 @@ init_chip(struct hfc_multi *hc) | |||
1176 | writel(pv, plx_acc_32); | 1204 | writel(pv, plx_acc_32); |
1177 | spin_unlock_irqrestore(&plx_lock, plx_flags); | 1205 | spin_unlock_irqrestore(&plx_lock, plx_flags); |
1178 | if (debug & DEBUG_HFCMULTI_INIT) | 1206 | if (debug & DEBUG_HFCMULTI_INIT) |
1179 | printk(KERN_WARNING "%s: slave/term: PLX_GPIO=%x\n", | 1207 | printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n", |
1180 | __func__, pv); | 1208 | __func__, pv); |
1181 | /* | 1209 | /* |
1182 | * If we are the 3rd PLXSD card or higher, we must turn | 1210 | * If we are the 3rd PLXSD card or higher, we must turn |
@@ -1204,13 +1232,17 @@ init_chip(struct hfc_multi *hc) | |||
1204 | writel(pv, plx_acc_32); | 1232 | writel(pv, plx_acc_32); |
1205 | spin_unlock_irqrestore(&plx_lock, plx_flags); | 1233 | spin_unlock_irqrestore(&plx_lock, plx_flags); |
1206 | if (debug & DEBUG_HFCMULTI_INIT) | 1234 | if (debug & DEBUG_HFCMULTI_INIT) |
1207 | printk(KERN_WARNING "%s: term off: PLX_GPIO=%x\n", | 1235 | printk(KERN_DEBUG |
1208 | __func__, pv); | 1236 | "%s: term off: PLX_GPIO=%x\n", |
1237 | __func__, pv); | ||
1209 | } | 1238 | } |
1210 | spin_unlock_irqrestore(&HFClock, hfc_flags); | 1239 | spin_unlock_irqrestore(&HFClock, hfc_flags); |
1211 | hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ | 1240 | hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ |
1212 | } | 1241 | } |
1213 | 1242 | ||
1243 | if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) | ||
1244 | hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ | ||
1245 | |||
1214 | /* we only want the real Z2 read-pointer for revision > 0 */ | 1246 | /* we only want the real Z2 read-pointer for revision > 0 */ |
1215 | if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) | 1247 | if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) |
1216 | hc->hw.r_ram_sz |= V_FZ_MD; | 1248 | hc->hw.r_ram_sz |= V_FZ_MD; |
@@ -1234,15 +1266,24 @@ init_chip(struct hfc_multi *hc) | |||
1234 | 1266 | ||
1235 | /* soft reset */ | 1267 | /* soft reset */ |
1236 | HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); | 1268 | HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); |
1237 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | 1269 | if (hc->ctype == HFC_TYPE_XHFC) |
1270 | HFC_outb(hc, 0x0C /* R_FIFO_THRES */, | ||
1271 | 0x11 /* 16 Bytes TX/RX */); | ||
1272 | else | ||
1273 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | ||
1238 | HFC_outb(hc, R_FIFO_MD, 0); | 1274 | HFC_outb(hc, R_FIFO_MD, 0); |
1239 | hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | V_RLD_EPR; | 1275 | if (hc->ctype == HFC_TYPE_XHFC) |
1276 | hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES; | ||
1277 | else | ||
1278 | hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | ||
1279 | | V_RLD_EPR; | ||
1240 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); | 1280 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); |
1241 | udelay(100); | 1281 | udelay(100); |
1242 | hc->hw.r_cirm = 0; | 1282 | hc->hw.r_cirm = 0; |
1243 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); | 1283 | HFC_outb(hc, R_CIRM, hc->hw.r_cirm); |
1244 | udelay(100); | 1284 | udelay(100); |
1245 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | 1285 | if (hc->ctype != HFC_TYPE_XHFC) |
1286 | HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); | ||
1246 | 1287 | ||
1247 | /* Speech Design PLX bridge pcm and sync mode */ | 1288 | /* Speech Design PLX bridge pcm and sync mode */ |
1248 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 1289 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
@@ -1254,13 +1295,13 @@ init_chip(struct hfc_multi *hc) | |||
1254 | pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; | 1295 | pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; |
1255 | pv |= PLX_SYNC_O_EN; | 1296 | pv |= PLX_SYNC_O_EN; |
1256 | if (debug & DEBUG_HFCMULTI_INIT) | 1297 | if (debug & DEBUG_HFCMULTI_INIT) |
1257 | printk(KERN_WARNING "%s: master: PLX_GPIO=%x\n", | 1298 | printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n", |
1258 | __func__, pv); | 1299 | __func__, pv); |
1259 | } else { | 1300 | } else { |
1260 | pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N); | 1301 | pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N); |
1261 | pv &= ~PLX_SYNC_O_EN; | 1302 | pv &= ~PLX_SYNC_O_EN; |
1262 | if (debug & DEBUG_HFCMULTI_INIT) | 1303 | if (debug & DEBUG_HFCMULTI_INIT) |
1263 | printk(KERN_WARNING "%s: slave: PLX_GPIO=%x\n", | 1304 | printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n", |
1264 | __func__, pv); | 1305 | __func__, pv); |
1265 | } | 1306 | } |
1266 | writel(pv, plx_acc_32); | 1307 | writel(pv, plx_acc_32); |
@@ -1278,13 +1319,16 @@ init_chip(struct hfc_multi *hc) | |||
1278 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); | 1319 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); |
1279 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) | 1320 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) |
1280 | HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ | 1321 | HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ |
1322 | else if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) | ||
1323 | HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */ | ||
1281 | else | 1324 | else |
1282 | HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ | 1325 | HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ |
1283 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); | 1326 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); |
1284 | for (i = 0; i < 256; i++) { | 1327 | for (i = 0; i < 256; i++) { |
1285 | HFC_outb_nodebug(hc, R_SLOT, i); | 1328 | HFC_outb_nodebug(hc, R_SLOT, i); |
1286 | HFC_outb_nodebug(hc, A_SL_CFG, 0); | 1329 | HFC_outb_nodebug(hc, A_SL_CFG, 0); |
1287 | HFC_outb_nodebug(hc, A_CONF, 0); | 1330 | if (hc->ctype != HFC_TYPE_XHFC) |
1331 | HFC_outb_nodebug(hc, A_CONF, 0); | ||
1288 | hc->slot_owner[i] = -1; | 1332 | hc->slot_owner[i] = -1; |
1289 | } | 1333 | } |
1290 | 1334 | ||
@@ -1296,6 +1340,9 @@ init_chip(struct hfc_multi *hc) | |||
1296 | HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); | 1340 | HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); |
1297 | } | 1341 | } |
1298 | 1342 | ||
1343 | if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) | ||
1344 | HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */); | ||
1345 | |||
1299 | /* B410P GPIO */ | 1346 | /* B410P GPIO */ |
1300 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { | 1347 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { |
1301 | printk(KERN_NOTICE "Setting GPIOs\n"); | 1348 | printk(KERN_NOTICE "Setting GPIOs\n"); |
@@ -1366,8 +1413,8 @@ controller_fail: | |||
1366 | writel(pv, plx_acc_32); | 1413 | writel(pv, plx_acc_32); |
1367 | spin_unlock_irqrestore(&plx_lock, plx_flags); | 1414 | spin_unlock_irqrestore(&plx_lock, plx_flags); |
1368 | if (debug & DEBUG_HFCMULTI_INIT) | 1415 | if (debug & DEBUG_HFCMULTI_INIT) |
1369 | printk(KERN_WARNING "%s: master: PLX_GPIO" | 1416 | printk(KERN_DEBUG "%s: master: " |
1370 | "=%x\n", __func__, pv); | 1417 | "PLX_GPIO=%x\n", __func__, pv); |
1371 | } | 1418 | } |
1372 | hc->hw.r_pcm_md0 |= V_PCM_MD; | 1419 | hc->hw.r_pcm_md0 |= V_PCM_MD; |
1373 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); | 1420 | HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); |
@@ -1401,7 +1448,7 @@ controller_fail: | |||
1401 | writel(pv, plx_acc_32); | 1448 | writel(pv, plx_acc_32); |
1402 | spin_unlock_irqrestore(&plx_lock, plx_flags); | 1449 | spin_unlock_irqrestore(&plx_lock, plx_flags); |
1403 | if (debug & DEBUG_HFCMULTI_INIT) | 1450 | if (debug & DEBUG_HFCMULTI_INIT) |
1404 | printk(KERN_WARNING "%s: reset off: PLX_GPIO=%x\n", | 1451 | printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n", |
1405 | __func__, pv); | 1452 | __func__, pv); |
1406 | } | 1453 | } |
1407 | 1454 | ||
@@ -1424,7 +1471,7 @@ controller_fail: | |||
1424 | hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; | 1471 | hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; |
1425 | 1472 | ||
1426 | /* set E1 state machine IRQ */ | 1473 | /* set E1 state machine IRQ */ |
1427 | if (hc->type == 1) | 1474 | if (hc->ctype == HFC_TYPE_E1) |
1428 | hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; | 1475 | hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; |
1429 | 1476 | ||
1430 | /* set DTMF detection */ | 1477 | /* set DTMF detection */ |
@@ -1444,7 +1491,8 @@ controller_fail: | |||
1444 | r_conf_en = V_CONF_EN | V_ULAW; | 1491 | r_conf_en = V_CONF_EN | V_ULAW; |
1445 | else | 1492 | else |
1446 | r_conf_en = V_CONF_EN; | 1493 | r_conf_en = V_CONF_EN; |
1447 | HFC_outb(hc, R_CONF_EN, r_conf_en); | 1494 | if (hc->ctype != HFC_TYPE_XHFC) |
1495 | HFC_outb(hc, R_CONF_EN, r_conf_en); | ||
1448 | 1496 | ||
1449 | /* setting leds */ | 1497 | /* setting leds */ |
1450 | switch (hc->leds) { | 1498 | switch (hc->leds) { |
@@ -1468,16 +1516,23 @@ controller_fail: | |||
1468 | break; | 1516 | break; |
1469 | } | 1517 | } |
1470 | 1518 | ||
1519 | if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) { | ||
1520 | hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */ | ||
1521 | HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); | ||
1522 | } | ||
1523 | |||
1471 | /* set master clock */ | 1524 | /* set master clock */ |
1472 | if (hc->masterclk >= 0) { | 1525 | if (hc->masterclk >= 0) { |
1473 | if (debug & DEBUG_HFCMULTI_INIT) | 1526 | if (debug & DEBUG_HFCMULTI_INIT) |
1474 | printk(KERN_DEBUG "%s: setting ST master clock " | 1527 | printk(KERN_DEBUG "%s: setting ST master clock " |
1475 | "to port %d (0..%d)\n", | 1528 | "to port %d (0..%d)\n", |
1476 | __func__, hc->masterclk, hc->ports-1); | 1529 | __func__, hc->masterclk, hc->ports-1); |
1477 | hc->hw.r_st_sync = hc->masterclk | V_AUTO_SYNC; | 1530 | hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC); |
1478 | HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); | 1531 | HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); |
1479 | } | 1532 | } |
1480 | 1533 | ||
1534 | |||
1535 | |||
1481 | /* setting misc irq */ | 1536 | /* setting misc irq */ |
1482 | HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); | 1537 | HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); |
1483 | if (debug & DEBUG_HFCMULTI_INIT) | 1538 | if (debug & DEBUG_HFCMULTI_INIT) |
@@ -1817,8 +1872,8 @@ hfcmulti_dtmf(struct hfc_multi *hc) | |||
1817 | coeff[(co<<1)|1] = mantissa; | 1872 | coeff[(co<<1)|1] = mantissa; |
1818 | } | 1873 | } |
1819 | if (debug & DEBUG_HFCMULTI_DTMF) | 1874 | if (debug & DEBUG_HFCMULTI_DTMF) |
1820 | printk("%s: DTMF ready %08x %08x %08x %08x " | 1875 | printk(" DTMF ready %08x %08x %08x %08x " |
1821 | "%08x %08x %08x %08x\n", __func__, | 1876 | "%08x %08x %08x %08x\n", |
1822 | coeff[0], coeff[1], coeff[2], coeff[3], | 1877 | coeff[0], coeff[1], coeff[2], coeff[3], |
1823 | coeff[4], coeff[5], coeff[6], coeff[7]); | 1878 | coeff[4], coeff[5], coeff[6], coeff[7]); |
1824 | hc->chan[ch].coeff_count++; | 1879 | hc->chan[ch].coeff_count++; |
@@ -1826,7 +1881,7 @@ hfcmulti_dtmf(struct hfc_multi *hc) | |||
1826 | hc->chan[ch].coeff_count = 0; | 1881 | hc->chan[ch].coeff_count = 0; |
1827 | skb = mI_alloc_skb(512, GFP_ATOMIC); | 1882 | skb = mI_alloc_skb(512, GFP_ATOMIC); |
1828 | if (!skb) { | 1883 | if (!skb) { |
1829 | printk(KERN_WARNING "%s: No memory for skb\n", | 1884 | printk(KERN_DEBUG "%s: No memory for skb\n", |
1830 | __func__); | 1885 | __func__); |
1831 | continue; | 1886 | continue; |
1832 | } | 1887 | } |
@@ -1929,7 +1984,7 @@ next_frame: | |||
1929 | Fspace = 1; | 1984 | Fspace = 1; |
1930 | } | 1985 | } |
1931 | /* one frame only for ST D-channels, to allow resending */ | 1986 | /* one frame only for ST D-channels, to allow resending */ |
1932 | if (hc->type != 1 && dch) { | 1987 | if (hc->ctype != HFC_TYPE_E1 && dch) { |
1933 | if (f1 != f2) | 1988 | if (f1 != f2) |
1934 | Fspace = 0; | 1989 | Fspace = 0; |
1935 | } | 1990 | } |
@@ -1945,6 +2000,9 @@ next_frame: | |||
1945 | "%d!=%d\n", __func__, hc->id + 1, temp, z2); | 2000 | "%d!=%d\n", __func__, hc->id + 1, temp, z2); |
1946 | z2 = temp; /* repeat unti Z2 is equal */ | 2001 | z2 = temp; /* repeat unti Z2 is equal */ |
1947 | } | 2002 | } |
2003 | hc->chan[ch].Zfill = z1 - z2; | ||
2004 | if (hc->chan[ch].Zfill < 0) | ||
2005 | hc->chan[ch].Zfill += hc->Zlen; | ||
1948 | Zspace = z2 - z1; | 2006 | Zspace = z2 - z1; |
1949 | if (Zspace <= 0) | 2007 | if (Zspace <= 0) |
1950 | Zspace += hc->Zlen; | 2008 | Zspace += hc->Zlen; |
@@ -1968,12 +2026,22 @@ next_frame: | |||
1968 | "slot_tx %d\n", | 2026 | "slot_tx %d\n", |
1969 | __func__, ch, slot_tx); | 2027 | __func__, ch, slot_tx); |
1970 | /* connect slot */ | 2028 | /* connect slot */ |
1971 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | 2029 | if (hc->ctype == HFC_TYPE_XHFC) |
1972 | V_HDLC_TRP | V_IFF); | 2030 | HFC_outb(hc, A_CON_HDLC, 0xc0 |
2031 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2032 | /* Enable FIFO, no interrupt */ | ||
2033 | else | ||
2034 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | ||
2035 | V_HDLC_TRP | V_IFF); | ||
1973 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); | 2036 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); |
1974 | HFC_wait_nodebug(hc); | 2037 | HFC_wait_nodebug(hc); |
1975 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | 2038 | if (hc->ctype == HFC_TYPE_XHFC) |
1976 | V_HDLC_TRP | V_IFF); | 2039 | HFC_outb(hc, A_CON_HDLC, 0xc0 |
2040 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2041 | /* Enable FIFO, no interrupt */ | ||
2042 | else | ||
2043 | HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | | ||
2044 | V_HDLC_TRP | V_IFF); | ||
1977 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); | 2045 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); |
1978 | HFC_wait_nodebug(hc); | 2046 | HFC_wait_nodebug(hc); |
1979 | } | 2047 | } |
@@ -2001,10 +2069,22 @@ next_frame: | |||
2001 | "FIFO data: channel %d slot_tx %d\n", | 2069 | "FIFO data: channel %d slot_tx %d\n", |
2002 | __func__, ch, slot_tx); | 2070 | __func__, ch, slot_tx); |
2003 | /* disconnect slot */ | 2071 | /* disconnect slot */ |
2004 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); | 2072 | if (hc->ctype == HFC_TYPE_XHFC) |
2073 | HFC_outb(hc, A_CON_HDLC, 0x80 | ||
2074 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2075 | /* Enable FIFO, no interrupt */ | ||
2076 | else | ||
2077 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | | ||
2078 | V_HDLC_TRP | V_IFF); | ||
2005 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); | 2079 | HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); |
2006 | HFC_wait_nodebug(hc); | 2080 | HFC_wait_nodebug(hc); |
2007 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); | 2081 | if (hc->ctype == HFC_TYPE_XHFC) |
2082 | HFC_outb(hc, A_CON_HDLC, 0x80 | ||
2083 | | 0x07 << 2 | V_HDLC_TRP | V_IFF); | ||
2084 | /* Enable FIFO, no interrupt */ | ||
2085 | else | ||
2086 | HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | | ||
2087 | V_HDLC_TRP | V_IFF); | ||
2008 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); | 2088 | HFC_outb_nodebug(hc, R_FIFO, ch<<1); |
2009 | HFC_wait_nodebug(hc); | 2089 | HFC_wait_nodebug(hc); |
2010 | } | 2090 | } |
@@ -2027,10 +2107,11 @@ next_frame: | |||
2027 | printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space " | 2107 | printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space " |
2028 | "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n", | 2108 | "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n", |
2029 | __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, | 2109 | __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, |
2030 | temp ? "HDLC":"TRANS"); | 2110 | temp ? "HDLC" : "TRANS"); |
2031 | 2111 | ||
2032 | /* Have to prep the audio data */ | 2112 | /* Have to prep the audio data */ |
2033 | hc->write_fifo(hc, d, ii - i); | 2113 | hc->write_fifo(hc, d, ii - i); |
2114 | hc->chan[ch].Zfill += ii - i; | ||
2034 | *idxp = ii; | 2115 | *idxp = ii; |
2035 | 2116 | ||
2036 | /* if not all data has been written */ | 2117 | /* if not all data has been written */ |
@@ -2226,7 +2307,7 @@ next_frame: | |||
2226 | if (dch) | 2307 | if (dch) |
2227 | recv_Dchannel(dch); | 2308 | recv_Dchannel(dch); |
2228 | else | 2309 | else |
2229 | recv_Bchannel(bch); | 2310 | recv_Bchannel(bch, MISDN_ID_ANY); |
2230 | *sp = skb; | 2311 | *sp = skb; |
2231 | again++; | 2312 | again++; |
2232 | goto next_frame; | 2313 | goto next_frame; |
@@ -2258,7 +2339,7 @@ next_frame: | |||
2258 | "(z1=%04x, z2=%04x) TRANS\n", | 2339 | "(z1=%04x, z2=%04x) TRANS\n", |
2259 | __func__, hc->id + 1, ch, Zsize, z1, z2); | 2340 | __func__, hc->id + 1, ch, Zsize, z1, z2); |
2260 | /* only bch is transparent */ | 2341 | /* only bch is transparent */ |
2261 | recv_Bchannel(bch); | 2342 | recv_Bchannel(bch, hc->chan[ch].Zfill); |
2262 | *sp = skb; | 2343 | *sp = skb; |
2263 | } | 2344 | } |
2264 | } | 2345 | } |
@@ -2323,7 +2404,7 @@ handle_timer_irq(struct hfc_multi *hc) | |||
2323 | spin_unlock_irqrestore(&HFClock, flags); | 2404 | spin_unlock_irqrestore(&HFClock, flags); |
2324 | } | 2405 | } |
2325 | 2406 | ||
2326 | if (hc->type != 1 || hc->e1_state == 1) | 2407 | if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1) |
2327 | for (ch = 0; ch <= 31; ch++) { | 2408 | for (ch = 0; ch <= 31; ch++) { |
2328 | if (hc->created[hc->chan[ch].port]) { | 2409 | if (hc->created[hc->chan[ch].port]) { |
2329 | hfcmulti_tx(hc, ch); | 2410 | hfcmulti_tx(hc, ch); |
@@ -2346,7 +2427,7 @@ handle_timer_irq(struct hfc_multi *hc) | |||
2346 | } | 2427 | } |
2347 | } | 2428 | } |
2348 | } | 2429 | } |
2349 | if (hc->type == 1 && hc->created[0]) { | 2430 | if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) { |
2350 | dch = hc->chan[hc->dslot].dch; | 2431 | dch = hc->chan[hc->dslot].dch; |
2351 | if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { | 2432 | if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { |
2352 | /* LOS */ | 2433 | /* LOS */ |
@@ -2606,7 +2687,10 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2606 | "card %d, this is no bug.\n", hc->id + 1, irqsem); | 2687 | "card %d, this is no bug.\n", hc->id + 1, irqsem); |
2607 | irqsem = hc->id + 1; | 2688 | irqsem = hc->id + 1; |
2608 | #endif | 2689 | #endif |
2609 | 2690 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | |
2691 | if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk) | ||
2692 | goto irq_notforus; | ||
2693 | #endif | ||
2610 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 2694 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
2611 | spin_lock_irqsave(&plx_lock, flags); | 2695 | spin_lock_irqsave(&plx_lock, flags); |
2612 | plx_acc = hc->plx_membase + PLX_INTCSR; | 2696 | plx_acc = hc->plx_membase + PLX_INTCSR; |
@@ -2646,7 +2730,7 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2646 | } | 2730 | } |
2647 | hc->irqcnt++; | 2731 | hc->irqcnt++; |
2648 | if (r_irq_statech) { | 2732 | if (r_irq_statech) { |
2649 | if (hc->type != 1) | 2733 | if (hc->ctype != HFC_TYPE_E1) |
2650 | ph_state_irq(hc, r_irq_statech); | 2734 | ph_state_irq(hc, r_irq_statech); |
2651 | } | 2735 | } |
2652 | if (status & V_EXT_IRQSTA) | 2736 | if (status & V_EXT_IRQSTA) |
@@ -2660,7 +2744,7 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2660 | r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); | 2744 | r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); |
2661 | r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */ | 2745 | r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */ |
2662 | if (r_irq_misc & V_STA_IRQ) { | 2746 | if (r_irq_misc & V_STA_IRQ) { |
2663 | if (hc->type == 1) { | 2747 | if (hc->ctype == HFC_TYPE_E1) { |
2664 | /* state machine */ | 2748 | /* state machine */ |
2665 | dch = hc->chan[hc->dslot].dch; | 2749 | dch = hc->chan[hc->dslot].dch; |
2666 | e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); | 2750 | e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); |
@@ -2699,13 +2783,13 @@ hfcmulti_interrupt(int intno, void *dev_id) | |||
2699 | handle_timer_irq(hc); | 2783 | handle_timer_irq(hc); |
2700 | } | 2784 | } |
2701 | 2785 | ||
2702 | if (r_irq_misc & V_DTMF_IRQ) { | 2786 | if (r_irq_misc & V_DTMF_IRQ) |
2703 | hfcmulti_dtmf(hc); | 2787 | hfcmulti_dtmf(hc); |
2704 | } | 2788 | |
2705 | if (r_irq_misc & V_IRQ_PROC) { | 2789 | if (r_irq_misc & V_IRQ_PROC) { |
2706 | static int irq_proc_cnt; | 2790 | static int irq_proc_cnt; |
2707 | if (!irq_proc_cnt++) | 2791 | if (!irq_proc_cnt++) |
2708 | printk(KERN_WARNING "%s: got V_IRQ_PROC -" | 2792 | printk(KERN_DEBUG "%s: got V_IRQ_PROC -" |
2709 | " this should not happen\n", __func__); | 2793 | " this should not happen\n", __func__); |
2710 | } | 2794 | } |
2711 | 2795 | ||
@@ -2782,7 +2866,8 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2782 | if (hc->slot_owner[oslot_tx<<1] == ch) { | 2866 | if (hc->slot_owner[oslot_tx<<1] == ch) { |
2783 | HFC_outb(hc, R_SLOT, oslot_tx << 1); | 2867 | HFC_outb(hc, R_SLOT, oslot_tx << 1); |
2784 | HFC_outb(hc, A_SL_CFG, 0); | 2868 | HFC_outb(hc, A_SL_CFG, 0); |
2785 | HFC_outb(hc, A_CONF, 0); | 2869 | if (hc->ctype != HFC_TYPE_XHFC) |
2870 | HFC_outb(hc, A_CONF, 0); | ||
2786 | hc->slot_owner[oslot_tx<<1] = -1; | 2871 | hc->slot_owner[oslot_tx<<1] = -1; |
2787 | } else { | 2872 | } else { |
2788 | if (debug & DEBUG_HFCMULTI_MODE) | 2873 | if (debug & DEBUG_HFCMULTI_MODE) |
@@ -2835,7 +2920,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2835 | flow_tx, routing, conf); | 2920 | flow_tx, routing, conf); |
2836 | HFC_outb(hc, R_SLOT, slot_tx << 1); | 2921 | HFC_outb(hc, R_SLOT, slot_tx << 1); |
2837 | HFC_outb(hc, A_SL_CFG, (ch<<1) | routing); | 2922 | HFC_outb(hc, A_SL_CFG, (ch<<1) | routing); |
2838 | HFC_outb(hc, A_CONF, (conf < 0) ? 0 : (conf | V_CONF_SL)); | 2923 | if (hc->ctype != HFC_TYPE_XHFC) |
2924 | HFC_outb(hc, A_CONF, | ||
2925 | (conf < 0) ? 0 : (conf | V_CONF_SL)); | ||
2839 | hc->slot_owner[slot_tx << 1] = ch; | 2926 | hc->slot_owner[slot_tx << 1] = ch; |
2840 | hc->chan[ch].slot_tx = slot_tx; | 2927 | hc->chan[ch].slot_tx = slot_tx; |
2841 | hc->chan[ch].bank_tx = bank_tx; | 2928 | hc->chan[ch].bank_tx = bank_tx; |
@@ -2852,7 +2939,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2852 | else | 2939 | else |
2853 | flow_rx = 0xc0; /* ST->(FIFO,PCM) */ | 2940 | flow_rx = 0xc0; /* ST->(FIFO,PCM) */ |
2854 | /* put on slot */ | 2941 | /* put on slot */ |
2855 | routing = bank_rx?0x80:0xc0; /* reversed */ | 2942 | routing = bank_rx ? 0x80 : 0xc0; /* reversed */ |
2856 | if (conf >= 0 || bank_rx > 1) | 2943 | if (conf >= 0 || bank_rx > 1) |
2857 | routing = 0x40; /* loop */ | 2944 | routing = 0x40; /* loop */ |
2858 | if (debug & DEBUG_HFCMULTI_MODE) | 2945 | if (debug & DEBUG_HFCMULTI_MODE) |
@@ -2885,9 +2972,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2885 | HFC_outb(hc, A_IRQ_MSK, 0); | 2972 | HFC_outb(hc, A_IRQ_MSK, 0); |
2886 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); | 2973 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); |
2887 | HFC_wait(hc); | 2974 | HFC_wait(hc); |
2888 | if (hc->chan[ch].bch && hc->type != 1) { | 2975 | if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) { |
2889 | hc->hw.a_st_ctrl0[hc->chan[ch].port] &= | 2976 | hc->hw.a_st_ctrl0[hc->chan[ch].port] &= |
2890 | ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN; | 2977 | ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN; |
2891 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); | 2978 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); |
2892 | /* undocumented: delay after R_ST_SEL */ | 2979 | /* undocumented: delay after R_ST_SEL */ |
2893 | udelay(1); | 2980 | udelay(1); |
@@ -2961,8 +3048,13 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2961 | /* enable TX fifo */ | 3048 | /* enable TX fifo */ |
2962 | HFC_outb(hc, R_FIFO, ch << 1); | 3049 | HFC_outb(hc, R_FIFO, ch << 1); |
2963 | HFC_wait(hc); | 3050 | HFC_wait(hc); |
2964 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | | 3051 | if (hc->ctype == HFC_TYPE_XHFC) |
2965 | V_HDLC_TRP | V_IFF); | 3052 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 | |
3053 | V_HDLC_TRP | V_IFF); | ||
3054 | /* Enable FIFO, no interrupt */ | ||
3055 | else | ||
3056 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | | ||
3057 | V_HDLC_TRP | V_IFF); | ||
2966 | HFC_outb(hc, A_SUBCH_CFG, 0); | 3058 | HFC_outb(hc, A_SUBCH_CFG, 0); |
2967 | HFC_outb(hc, A_IRQ_MSK, 0); | 3059 | HFC_outb(hc, A_IRQ_MSK, 0); |
2968 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); | 3060 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); |
@@ -2972,13 +3064,19 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2972 | /* enable RX fifo */ | 3064 | /* enable RX fifo */ |
2973 | HFC_outb(hc, R_FIFO, (ch<<1)|1); | 3065 | HFC_outb(hc, R_FIFO, (ch<<1)|1); |
2974 | HFC_wait(hc); | 3066 | HFC_wait(hc); |
2975 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | V_HDLC_TRP); | 3067 | if (hc->ctype == HFC_TYPE_XHFC) |
3068 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 | | ||
3069 | V_HDLC_TRP); | ||
3070 | /* Enable FIFO, no interrupt*/ | ||
3071 | else | ||
3072 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | | ||
3073 | V_HDLC_TRP); | ||
2976 | HFC_outb(hc, A_SUBCH_CFG, 0); | 3074 | HFC_outb(hc, A_SUBCH_CFG, 0); |
2977 | HFC_outb(hc, A_IRQ_MSK, 0); | 3075 | HFC_outb(hc, A_IRQ_MSK, 0); |
2978 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); | 3076 | HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); |
2979 | HFC_wait(hc); | 3077 | HFC_wait(hc); |
2980 | } | 3078 | } |
2981 | if (hc->type != 1) { | 3079 | if (hc->ctype != HFC_TYPE_E1) { |
2982 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= | 3080 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= |
2983 | ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; | 3081 | ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; |
2984 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); | 3082 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); |
@@ -2999,7 +3097,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
2999 | /* enable TX fifo */ | 3097 | /* enable TX fifo */ |
3000 | HFC_outb(hc, R_FIFO, ch<<1); | 3098 | HFC_outb(hc, R_FIFO, ch<<1); |
3001 | HFC_wait(hc); | 3099 | HFC_wait(hc); |
3002 | if (hc->type == 1 || hc->chan[ch].bch) { | 3100 | if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) { |
3003 | /* E1 or B-channel */ | 3101 | /* E1 or B-channel */ |
3004 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); | 3102 | HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); |
3005 | HFC_outb(hc, A_SUBCH_CFG, 0); | 3103 | HFC_outb(hc, A_SUBCH_CFG, 0); |
@@ -3015,7 +3113,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
3015 | HFC_outb(hc, R_FIFO, (ch<<1)|1); | 3113 | HFC_outb(hc, R_FIFO, (ch<<1)|1); |
3016 | HFC_wait(hc); | 3114 | HFC_wait(hc); |
3017 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); | 3115 | HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); |
3018 | if (hc->type == 1 || hc->chan[ch].bch) | 3116 | if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) |
3019 | HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ | 3117 | HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ |
3020 | else | 3118 | else |
3021 | HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ | 3119 | HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ |
@@ -3024,7 +3122,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, | |||
3024 | HFC_wait(hc); | 3122 | HFC_wait(hc); |
3025 | if (hc->chan[ch].bch) { | 3123 | if (hc->chan[ch].bch) { |
3026 | test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); | 3124 | test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); |
3027 | if (hc->type != 1) { | 3125 | if (hc->ctype != HFC_TYPE_E1) { |
3028 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= | 3126 | hc->hw.a_st_ctrl0[hc->chan[ch].port] |= |
3029 | ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN; | 3127 | ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN; |
3030 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); | 3128 | HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); |
@@ -3104,7 +3202,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) | |||
3104 | case HW_RESET_REQ: | 3202 | case HW_RESET_REQ: |
3105 | /* start activation */ | 3203 | /* start activation */ |
3106 | spin_lock_irqsave(&hc->lock, flags); | 3204 | spin_lock_irqsave(&hc->lock, flags); |
3107 | if (hc->type == 1) { | 3205 | if (hc->ctype == HFC_TYPE_E1) { |
3108 | if (debug & DEBUG_HFCMULTI_MSG) | 3206 | if (debug & DEBUG_HFCMULTI_MSG) |
3109 | printk(KERN_DEBUG | 3207 | printk(KERN_DEBUG |
3110 | "%s: HW_RESET_REQ no BRI\n", | 3208 | "%s: HW_RESET_REQ no BRI\n", |
@@ -3125,7 +3223,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) | |||
3125 | case HW_DEACT_REQ: | 3223 | case HW_DEACT_REQ: |
3126 | /* start deactivation */ | 3224 | /* start deactivation */ |
3127 | spin_lock_irqsave(&hc->lock, flags); | 3225 | spin_lock_irqsave(&hc->lock, flags); |
3128 | if (hc->type == 1) { | 3226 | if (hc->ctype == HFC_TYPE_E1) { |
3129 | if (debug & DEBUG_HFCMULTI_MSG) | 3227 | if (debug & DEBUG_HFCMULTI_MSG) |
3130 | printk(KERN_DEBUG | 3228 | printk(KERN_DEBUG |
3131 | "%s: HW_DEACT_REQ no BRI\n", | 3229 | "%s: HW_DEACT_REQ no BRI\n", |
@@ -3159,7 +3257,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd) | |||
3159 | break; | 3257 | break; |
3160 | case HW_POWERUP_REQ: | 3258 | case HW_POWERUP_REQ: |
3161 | spin_lock_irqsave(&hc->lock, flags); | 3259 | spin_lock_irqsave(&hc->lock, flags); |
3162 | if (hc->type == 1) { | 3260 | if (hc->ctype == HFC_TYPE_E1) { |
3163 | if (debug & DEBUG_HFCMULTI_MSG) | 3261 | if (debug & DEBUG_HFCMULTI_MSG) |
3164 | printk(KERN_DEBUG | 3262 | printk(KERN_DEBUG |
3165 | "%s: HW_POWERUP_REQ no BRI\n", | 3263 | "%s: HW_POWERUP_REQ no BRI\n", |
@@ -3236,7 +3334,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
3236 | __func__, hc->chan[dch->slot].port, | 3334 | __func__, hc->chan[dch->slot].port, |
3237 | hc->ports-1); | 3335 | hc->ports-1); |
3238 | /* start activation */ | 3336 | /* start activation */ |
3239 | if (hc->type == 1) { | 3337 | if (hc->ctype == HFC_TYPE_E1) { |
3240 | ph_state_change(dch); | 3338 | ph_state_change(dch); |
3241 | if (debug & DEBUG_HFCMULTI_STATE) | 3339 | if (debug & DEBUG_HFCMULTI_STATE) |
3242 | printk(KERN_DEBUG | 3340 | printk(KERN_DEBUG |
@@ -3269,7 +3367,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
3269 | __func__, hc->chan[dch->slot].port, | 3367 | __func__, hc->chan[dch->slot].port, |
3270 | hc->ports-1); | 3368 | hc->ports-1); |
3271 | /* start deactivation */ | 3369 | /* start deactivation */ |
3272 | if (hc->type == 1) { | 3370 | if (hc->ctype == HFC_TYPE_E1) { |
3273 | if (debug & DEBUG_HFCMULTI_MSG) | 3371 | if (debug & DEBUG_HFCMULTI_MSG) |
3274 | printk(KERN_DEBUG | 3372 | printk(KERN_DEBUG |
3275 | "%s: PH_DEACTIVATE no BRI\n", | 3373 | "%s: PH_DEACTIVATE no BRI\n", |
@@ -3410,9 +3508,9 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
3410 | switch (hh->id) { | 3508 | switch (hh->id) { |
3411 | case HFC_SPL_LOOP_ON: /* set sample loop */ | 3509 | case HFC_SPL_LOOP_ON: /* set sample loop */ |
3412 | if (debug & DEBUG_HFCMULTI_MSG) | 3510 | if (debug & DEBUG_HFCMULTI_MSG) |
3413 | printk(KERN_DEBUG | 3511 | printk(KERN_DEBUG |
3414 | "%s: HFC_SPL_LOOP_ON (len = %d)\n", | 3512 | "%s: HFC_SPL_LOOP_ON (len = %d)\n", |
3415 | __func__, skb->len); | 3513 | __func__, skb->len); |
3416 | ret = 0; | 3514 | ret = 0; |
3417 | break; | 3515 | break; |
3418 | case HFC_SPL_LOOP_OFF: /* set silence */ | 3516 | case HFC_SPL_LOOP_OFF: /* set silence */ |
@@ -3489,6 +3587,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) | |||
3489 | features->hfc_id = hc->id; | 3587 | features->hfc_id = hc->id; |
3490 | if (test_bit(HFC_CHIP_DTMF, &hc->chip)) | 3588 | if (test_bit(HFC_CHIP_DTMF, &hc->chip)) |
3491 | features->hfc_dtmf = 1; | 3589 | features->hfc_dtmf = 1; |
3590 | if (test_bit(HFC_CHIP_CONF, &hc->chip)) | ||
3591 | features->hfc_conf = 1; | ||
3492 | features->hfc_loops = 0; | 3592 | features->hfc_loops = 0; |
3493 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { | 3593 | if (test_bit(HFC_CHIP_B410P, &hc->chip)) { |
3494 | features->hfc_echocanhw = 1; | 3594 | features->hfc_echocanhw = 1; |
@@ -3619,14 +3719,13 @@ ph_state_change(struct dchannel *dch) | |||
3619 | int ch, i; | 3719 | int ch, i; |
3620 | 3720 | ||
3621 | if (!dch) { | 3721 | if (!dch) { |
3622 | printk(KERN_WARNING "%s: ERROR given dch is NULL\n", | 3722 | printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__); |
3623 | __func__); | ||
3624 | return; | 3723 | return; |
3625 | } | 3724 | } |
3626 | hc = dch->hw; | 3725 | hc = dch->hw; |
3627 | ch = dch->slot; | 3726 | ch = dch->slot; |
3628 | 3727 | ||
3629 | if (hc->type == 1) { | 3728 | if (hc->ctype == HFC_TYPE_E1) { |
3630 | if (dch->dev.D.protocol == ISDN_P_TE_E1) { | 3729 | if (dch->dev.D.protocol == ISDN_P_TE_E1) { |
3631 | if (debug & DEBUG_HFCMULTI_STATE) | 3730 | if (debug & DEBUG_HFCMULTI_STATE) |
3632 | printk(KERN_DEBUG | 3731 | printk(KERN_DEBUG |
@@ -3641,14 +3740,15 @@ ph_state_change(struct dchannel *dch) | |||
3641 | switch (dch->state) { | 3740 | switch (dch->state) { |
3642 | case (1): | 3741 | case (1): |
3643 | if (hc->e1_state != 1) { | 3742 | if (hc->e1_state != 1) { |
3644 | for (i = 1; i <= 31; i++) { | 3743 | for (i = 1; i <= 31; i++) { |
3645 | /* reset fifos on e1 activation */ | 3744 | /* reset fifos on e1 activation */ |
3646 | HFC_outb_nodebug(hc, R_FIFO, (i << 1) | 1); | 3745 | HFC_outb_nodebug(hc, R_FIFO, |
3647 | HFC_wait_nodebug(hc); | 3746 | (i << 1) | 1); |
3648 | HFC_outb_nodebug(hc, | 3747 | HFC_wait_nodebug(hc); |
3649 | R_INC_RES_FIFO, V_RES_F); | 3748 | HFC_outb_nodebug(hc, R_INC_RES_FIFO, |
3650 | HFC_wait_nodebug(hc); | 3749 | V_RES_F); |
3651 | } | 3750 | HFC_wait_nodebug(hc); |
3751 | } | ||
3652 | } | 3752 | } |
3653 | test_and_set_bit(FLG_ACTIVE, &dch->Flags); | 3753 | test_and_set_bit(FLG_ACTIVE, &dch->Flags); |
3654 | _queue_data(&dch->dev.D, PH_ACTIVATE_IND, | 3754 | _queue_data(&dch->dev.D, PH_ACTIVATE_IND, |
@@ -3751,7 +3851,7 @@ hfcmulti_initmode(struct dchannel *dch) | |||
3751 | if (debug & DEBUG_HFCMULTI_INIT) | 3851 | if (debug & DEBUG_HFCMULTI_INIT) |
3752 | printk(KERN_DEBUG "%s: entered\n", __func__); | 3852 | printk(KERN_DEBUG "%s: entered\n", __func__); |
3753 | 3853 | ||
3754 | if (hc->type == 1) { | 3854 | if (hc->ctype == HFC_TYPE_E1) { |
3755 | hc->chan[hc->dslot].slot_tx = -1; | 3855 | hc->chan[hc->dslot].slot_tx = -1; |
3756 | hc->chan[hc->dslot].slot_rx = -1; | 3856 | hc->chan[hc->dslot].slot_rx = -1; |
3757 | hc->chan[hc->dslot].conf = -1; | 3857 | hc->chan[hc->dslot].conf = -1; |
@@ -3900,6 +4000,11 @@ hfcmulti_initmode(struct dchannel *dch) | |||
3900 | } | 4000 | } |
3901 | if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) | 4001 | if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) |
3902 | hc->hw.a_st_ctrl0[pt] |= V_TX_LI; | 4002 | hc->hw.a_st_ctrl0[pt] |= V_TX_LI; |
4003 | if (hc->ctype == HFC_TYPE_XHFC) { | ||
4004 | hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */; | ||
4005 | HFC_outb(hc, 0x35 /* A_ST_CTRL3 */, | ||
4006 | 0x7c << 1 /* V_ST_PULSE */); | ||
4007 | } | ||
3903 | /* line setup */ | 4008 | /* line setup */ |
3904 | HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); | 4009 | HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); |
3905 | /* disable E-channel */ | 4010 | /* disable E-channel */ |
@@ -3943,12 +4048,12 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch, | |||
3943 | return -EINVAL; | 4048 | return -EINVAL; |
3944 | if ((dch->dev.D.protocol != ISDN_P_NONE) && | 4049 | if ((dch->dev.D.protocol != ISDN_P_NONE) && |
3945 | (dch->dev.D.protocol != rq->protocol)) { | 4050 | (dch->dev.D.protocol != rq->protocol)) { |
3946 | if (debug & DEBUG_HFCMULTI_MODE) | 4051 | if (debug & DEBUG_HFCMULTI_MODE) |
3947 | printk(KERN_WARNING "%s: change protocol %x to %x\n", | 4052 | printk(KERN_DEBUG "%s: change protocol %x to %x\n", |
3948 | __func__, dch->dev.D.protocol, rq->protocol); | 4053 | __func__, dch->dev.D.protocol, rq->protocol); |
3949 | } | 4054 | } |
3950 | if ((dch->dev.D.protocol == ISDN_P_TE_S0) | 4055 | if ((dch->dev.D.protocol == ISDN_P_TE_S0) && |
3951 | && (rq->protocol != ISDN_P_TE_S0)) | 4056 | (rq->protocol != ISDN_P_TE_S0)) |
3952 | l1_event(dch->l1, CLOSE_CHANNEL); | 4057 | l1_event(dch->l1, CLOSE_CHANNEL); |
3953 | if (dch->dev.D.protocol != rq->protocol) { | 4058 | if (dch->dev.D.protocol != rq->protocol) { |
3954 | if (rq->protocol == ISDN_P_TE_S0) { | 4059 | if (rq->protocol == ISDN_P_TE_S0) { |
@@ -3986,7 +4091,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch, | |||
3986 | return -EINVAL; | 4091 | return -EINVAL; |
3987 | if (rq->protocol == ISDN_P_NONE) | 4092 | if (rq->protocol == ISDN_P_NONE) |
3988 | return -EINVAL; | 4093 | return -EINVAL; |
3989 | if (hc->type == 1) | 4094 | if (hc->ctype == HFC_TYPE_E1) |
3990 | ch = rq->adr.channel; | 4095 | ch = rq->adr.channel; |
3991 | else | 4096 | else |
3992 | ch = (rq->adr.channel - 1) + (dch->slot - 2); | 4097 | ch = (rq->adr.channel - 1) + (dch->slot - 2); |
@@ -4013,11 +4118,41 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch, | |||
4013 | static int | 4118 | static int |
4014 | channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) | 4119 | channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) |
4015 | { | 4120 | { |
4121 | struct hfc_multi *hc = dch->hw; | ||
4016 | int ret = 0; | 4122 | int ret = 0; |
4123 | int wd_mode, wd_cnt; | ||
4017 | 4124 | ||
4018 | switch (cq->op) { | 4125 | switch (cq->op) { |
4019 | case MISDN_CTRL_GETOP: | 4126 | case MISDN_CTRL_GETOP: |
4020 | cq->op = 0; | 4127 | cq->op = MISDN_CTRL_HFC_OP; |
4128 | break; | ||
4129 | case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */ | ||
4130 | wd_cnt = cq->p1 & 0xf; | ||
4131 | wd_mode = !!(cq->p1 >> 4); | ||
4132 | if (debug & DEBUG_HFCMULTI_MSG) | ||
4133 | printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s" | ||
4134 | ", counter 0x%x\n", __func__, | ||
4135 | wd_mode ? "AUTO" : "MANUAL", wd_cnt); | ||
4136 | /* set the watchdog timer */ | ||
4137 | HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4)); | ||
4138 | hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0); | ||
4139 | if (hc->ctype == HFC_TYPE_XHFC) | ||
4140 | hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */; | ||
4141 | /* init the watchdog register and reset the counter */ | ||
4142 | HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES); | ||
4143 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | ||
4144 | /* enable the watchdog output for Speech-Design */ | ||
4145 | HFC_outb(hc, R_GPIO_SEL, V_GPIO_SEL7); | ||
4146 | HFC_outb(hc, R_GPIO_EN1, V_GPIO_EN15); | ||
4147 | HFC_outb(hc, R_GPIO_OUT1, 0); | ||
4148 | HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15); | ||
4149 | } | ||
4150 | break; | ||
4151 | case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */ | ||
4152 | if (debug & DEBUG_HFCMULTI_MSG) | ||
4153 | printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n", | ||
4154 | __func__); | ||
4155 | HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES); | ||
4021 | break; | 4156 | break; |
4022 | default: | 4157 | default: |
4023 | printk(KERN_WARNING "%s: unknown Op %x\n", | 4158 | printk(KERN_WARNING "%s: unknown Op %x\n", |
@@ -4047,7 +4182,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
4047 | switch (rq->protocol) { | 4182 | switch (rq->protocol) { |
4048 | case ISDN_P_TE_S0: | 4183 | case ISDN_P_TE_S0: |
4049 | case ISDN_P_NT_S0: | 4184 | case ISDN_P_NT_S0: |
4050 | if (hc->type == 1) { | 4185 | if (hc->ctype == HFC_TYPE_E1) { |
4051 | err = -EINVAL; | 4186 | err = -EINVAL; |
4052 | break; | 4187 | break; |
4053 | } | 4188 | } |
@@ -4055,7 +4190,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
4055 | break; | 4190 | break; |
4056 | case ISDN_P_TE_E1: | 4191 | case ISDN_P_TE_E1: |
4057 | case ISDN_P_NT_E1: | 4192 | case ISDN_P_NT_E1: |
4058 | if (hc->type != 1) { | 4193 | if (hc->ctype != HFC_TYPE_E1) { |
4059 | err = -EINVAL; | 4194 | err = -EINVAL; |
4060 | break; | 4195 | break; |
4061 | } | 4196 | } |
@@ -4122,13 +4257,13 @@ init_card(struct hfc_multi *hc) | |||
4122 | disable_hwirq(hc); | 4257 | disable_hwirq(hc); |
4123 | spin_unlock_irqrestore(&hc->lock, flags); | 4258 | spin_unlock_irqrestore(&hc->lock, flags); |
4124 | 4259 | ||
4125 | if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, IRQF_SHARED, | 4260 | if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED, |
4126 | "HFC-multi", hc)) { | 4261 | "HFC-multi", hc)) { |
4127 | printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", | 4262 | printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", |
4128 | hc->pci_dev->irq); | 4263 | hc->irq); |
4264 | hc->irq = 0; | ||
4129 | return -EIO; | 4265 | return -EIO; |
4130 | } | 4266 | } |
4131 | hc->irq = hc->pci_dev->irq; | ||
4132 | 4267 | ||
4133 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 4268 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
4134 | spin_lock_irqsave(&plx_lock, plx_flags); | 4269 | spin_lock_irqsave(&plx_lock, plx_flags); |
@@ -4187,7 +4322,7 @@ error: | |||
4187 | } | 4322 | } |
4188 | 4323 | ||
4189 | if (debug & DEBUG_HFCMULTI_INIT) | 4324 | if (debug & DEBUG_HFCMULTI_INIT) |
4190 | printk(KERN_WARNING "%s: free irq %d\n", __func__, hc->irq); | 4325 | printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq); |
4191 | if (hc->irq) { | 4326 | if (hc->irq) { |
4192 | free_irq(hc->irq, hc); | 4327 | free_irq(hc->irq, hc); |
4193 | hc->irq = 0; | 4328 | hc->irq = 0; |
@@ -4235,6 +4370,10 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4235 | hc->ledstate = 0xAFFEAFFE; | 4370 | hc->ledstate = 0xAFFEAFFE; |
4236 | hc->opticalsupport = m->opticalsupport; | 4371 | hc->opticalsupport = m->opticalsupport; |
4237 | 4372 | ||
4373 | hc->pci_iobase = 0; | ||
4374 | hc->pci_membase = NULL; | ||
4375 | hc->plx_membase = NULL; | ||
4376 | |||
4238 | /* set memory access methods */ | 4377 | /* set memory access methods */ |
4239 | if (m->io_mode) /* use mode from card config */ | 4378 | if (m->io_mode) /* use mode from card config */ |
4240 | hc->io_mode = m->io_mode; | 4379 | hc->io_mode = m->io_mode; |
@@ -4242,44 +4381,12 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4242 | case HFC_IO_MODE_PLXSD: | 4381 | case HFC_IO_MODE_PLXSD: |
4243 | test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); | 4382 | test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); |
4244 | hc->slots = 128; /* required */ | 4383 | hc->slots = 128; /* required */ |
4245 | /* fall through */ | ||
4246 | case HFC_IO_MODE_PCIMEM: | ||
4247 | hc->HFC_outb = HFC_outb_pcimem; | 4384 | hc->HFC_outb = HFC_outb_pcimem; |
4248 | hc->HFC_inb = HFC_inb_pcimem; | 4385 | hc->HFC_inb = HFC_inb_pcimem; |
4249 | hc->HFC_inw = HFC_inw_pcimem; | 4386 | hc->HFC_inw = HFC_inw_pcimem; |
4250 | hc->HFC_wait = HFC_wait_pcimem; | 4387 | hc->HFC_wait = HFC_wait_pcimem; |
4251 | hc->read_fifo = read_fifo_pcimem; | 4388 | hc->read_fifo = read_fifo_pcimem; |
4252 | hc->write_fifo = write_fifo_pcimem; | 4389 | hc->write_fifo = write_fifo_pcimem; |
4253 | break; | ||
4254 | case HFC_IO_MODE_REGIO: | ||
4255 | hc->HFC_outb = HFC_outb_regio; | ||
4256 | hc->HFC_inb = HFC_inb_regio; | ||
4257 | hc->HFC_inw = HFC_inw_regio; | ||
4258 | hc->HFC_wait = HFC_wait_regio; | ||
4259 | hc->read_fifo = read_fifo_regio; | ||
4260 | hc->write_fifo = write_fifo_regio; | ||
4261 | break; | ||
4262 | default: | ||
4263 | printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); | ||
4264 | pci_disable_device(hc->pci_dev); | ||
4265 | return -EIO; | ||
4266 | } | ||
4267 | hc->HFC_outb_nodebug = hc->HFC_outb; | ||
4268 | hc->HFC_inb_nodebug = hc->HFC_inb; | ||
4269 | hc->HFC_inw_nodebug = hc->HFC_inw; | ||
4270 | hc->HFC_wait_nodebug = hc->HFC_wait; | ||
4271 | #ifdef HFC_REGISTER_DEBUG | ||
4272 | hc->HFC_outb = HFC_outb_debug; | ||
4273 | hc->HFC_inb = HFC_inb_debug; | ||
4274 | hc->HFC_inw = HFC_inw_debug; | ||
4275 | hc->HFC_wait = HFC_wait_debug; | ||
4276 | #endif | ||
4277 | hc->pci_iobase = 0; | ||
4278 | hc->pci_membase = NULL; | ||
4279 | hc->plx_membase = NULL; | ||
4280 | |||
4281 | switch (hc->io_mode) { | ||
4282 | case HFC_IO_MODE_PLXSD: | ||
4283 | hc->plx_origmembase = hc->pci_dev->resource[0].start; | 4390 | hc->plx_origmembase = hc->pci_dev->resource[0].start; |
4284 | /* MEMBASE 1 is PLX PCI Bridge */ | 4391 | /* MEMBASE 1 is PLX PCI Bridge */ |
4285 | 4392 | ||
@@ -4327,6 +4434,12 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4327 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); | 4434 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); |
4328 | break; | 4435 | break; |
4329 | case HFC_IO_MODE_PCIMEM: | 4436 | case HFC_IO_MODE_PCIMEM: |
4437 | hc->HFC_outb = HFC_outb_pcimem; | ||
4438 | hc->HFC_inb = HFC_inb_pcimem; | ||
4439 | hc->HFC_inw = HFC_inw_pcimem; | ||
4440 | hc->HFC_wait = HFC_wait_pcimem; | ||
4441 | hc->read_fifo = read_fifo_pcimem; | ||
4442 | hc->write_fifo = write_fifo_pcimem; | ||
4330 | hc->pci_origmembase = hc->pci_dev->resource[1].start; | 4443 | hc->pci_origmembase = hc->pci_dev->resource[1].start; |
4331 | if (!hc->pci_origmembase) { | 4444 | if (!hc->pci_origmembase) { |
4332 | printk(KERN_WARNING | 4445 | printk(KERN_WARNING |
@@ -4343,12 +4456,18 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, | |||
4343 | pci_disable_device(hc->pci_dev); | 4456 | pci_disable_device(hc->pci_dev); |
4344 | return -EIO; | 4457 | return -EIO; |
4345 | } | 4458 | } |
4346 | printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d " | 4459 | printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ " |
4347 | "HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, | 4460 | "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, |
4348 | hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); | 4461 | hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); |
4349 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); | 4462 | pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); |
4350 | break; | 4463 | break; |
4351 | case HFC_IO_MODE_REGIO: | 4464 | case HFC_IO_MODE_REGIO: |
4465 | hc->HFC_outb = HFC_outb_regio; | ||
4466 | hc->HFC_inb = HFC_inb_regio; | ||
4467 | hc->HFC_inw = HFC_inw_regio; | ||
4468 | hc->HFC_wait = HFC_wait_regio; | ||
4469 | hc->read_fifo = read_fifo_regio; | ||
4470 | hc->write_fifo = write_fifo_regio; | ||
4352 | hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; | 4471 | hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; |
4353 | if (!hc->pci_iobase) { | 4472 | if (!hc->pci_iobase) { |
4354 | printk(KERN_WARNING | 4473 | printk(KERN_WARNING |
@@ -4430,7 +4549,7 @@ release_port(struct hfc_multi *hc, struct dchannel *dch) | |||
4430 | dch->timer.function = NULL; | 4549 | dch->timer.function = NULL; |
4431 | } | 4550 | } |
4432 | 4551 | ||
4433 | if (hc->type == 1) { /* E1 */ | 4552 | if (hc->ctype == HFC_TYPE_E1) { /* E1 */ |
4434 | /* remove sync */ | 4553 | /* remove sync */ |
4435 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { | 4554 | if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { |
4436 | hc->syncronized = 0; | 4555 | hc->syncronized = 0; |
@@ -4508,7 +4627,7 @@ release_card(struct hfc_multi *hc) | |||
4508 | int ch; | 4627 | int ch; |
4509 | 4628 | ||
4510 | if (debug & DEBUG_HFCMULTI_INIT) | 4629 | if (debug & DEBUG_HFCMULTI_INIT) |
4511 | printk(KERN_WARNING "%s: release card (%d) entered\n", | 4630 | printk(KERN_DEBUG "%s: release card (%d) entered\n", |
4512 | __func__, hc->id); | 4631 | __func__, hc->id); |
4513 | 4632 | ||
4514 | /* unregister clock source */ | 4633 | /* unregister clock source */ |
@@ -4537,7 +4656,7 @@ release_card(struct hfc_multi *hc) | |||
4537 | /* release hardware & irq */ | 4656 | /* release hardware & irq */ |
4538 | if (hc->irq) { | 4657 | if (hc->irq) { |
4539 | if (debug & DEBUG_HFCMULTI_INIT) | 4658 | if (debug & DEBUG_HFCMULTI_INIT) |
4540 | printk(KERN_WARNING "%s: free irq %d\n", | 4659 | printk(KERN_DEBUG "%s: free irq %d\n", |
4541 | __func__, hc->irq); | 4660 | __func__, hc->irq); |
4542 | free_irq(hc->irq, hc); | 4661 | free_irq(hc->irq, hc); |
4543 | hc->irq = 0; | 4662 | hc->irq = 0; |
@@ -4546,17 +4665,17 @@ release_card(struct hfc_multi *hc) | |||
4546 | release_io_hfcmulti(hc); | 4665 | release_io_hfcmulti(hc); |
4547 | 4666 | ||
4548 | if (debug & DEBUG_HFCMULTI_INIT) | 4667 | if (debug & DEBUG_HFCMULTI_INIT) |
4549 | printk(KERN_WARNING "%s: remove instance from list\n", | 4668 | printk(KERN_DEBUG "%s: remove instance from list\n", |
4550 | __func__); | 4669 | __func__); |
4551 | list_del(&hc->list); | 4670 | list_del(&hc->list); |
4552 | 4671 | ||
4553 | if (debug & DEBUG_HFCMULTI_INIT) | 4672 | if (debug & DEBUG_HFCMULTI_INIT) |
4554 | printk(KERN_WARNING "%s: delete instance\n", __func__); | 4673 | printk(KERN_DEBUG "%s: delete instance\n", __func__); |
4555 | if (hc == syncmaster) | 4674 | if (hc == syncmaster) |
4556 | syncmaster = NULL; | 4675 | syncmaster = NULL; |
4557 | kfree(hc); | 4676 | kfree(hc); |
4558 | if (debug & DEBUG_HFCMULTI_INIT) | 4677 | if (debug & DEBUG_HFCMULTI_INIT) |
4559 | printk(KERN_WARNING "%s: card successfully removed\n", | 4678 | printk(KERN_DEBUG "%s: card successfully removed\n", |
4560 | __func__); | 4679 | __func__); |
4561 | } | 4680 | } |
4562 | 4681 | ||
@@ -4579,7 +4698,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m) | |||
4579 | (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); | 4698 | (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); |
4580 | dch->dev.D.send = handle_dmsg; | 4699 | dch->dev.D.send = handle_dmsg; |
4581 | dch->dev.D.ctrl = hfcm_dctrl; | 4700 | dch->dev.D.ctrl = hfcm_dctrl; |
4582 | dch->dev.nrbchan = (hc->dslot)?30:31; | 4701 | dch->dev.nrbchan = (hc->dslot) ? 30 : 31; |
4583 | dch->slot = hc->dslot; | 4702 | dch->slot = hc->dslot; |
4584 | hc->chan[hc->dslot].dch = dch; | 4703 | hc->chan[hc->dslot].dch = dch; |
4585 | hc->chan[hc->dslot].port = 0; | 4704 | hc->chan[hc->dslot].port = 0; |
@@ -4821,7 +4940,7 @@ init_multi_port(struct hfc_multi *hc, int pt) | |||
4821 | } | 4940 | } |
4822 | /* disable E-channel */ | 4941 | /* disable E-channel */ |
4823 | if (port[Port_cnt] & 0x004) { | 4942 | if (port[Port_cnt] & 0x004) { |
4824 | if (debug & DEBUG_HFCMULTI_INIT) | 4943 | if (debug & DEBUG_HFCMULTI_INIT) |
4825 | printk(KERN_DEBUG | 4944 | printk(KERN_DEBUG |
4826 | "%s: PROTOCOL disable E-channel: " | 4945 | "%s: PROTOCOL disable E-channel: " |
4827 | "card(%d) port(%d)\n", | 4946 | "card(%d) port(%d)\n", |
@@ -4829,9 +4948,15 @@ init_multi_port(struct hfc_multi *hc, int pt) | |||
4829 | test_and_set_bit(HFC_CFG_DIS_ECHANNEL, | 4948 | test_and_set_bit(HFC_CFG_DIS_ECHANNEL, |
4830 | &hc->chan[i + 2].cfg); | 4949 | &hc->chan[i + 2].cfg); |
4831 | } | 4950 | } |
4832 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d", | 4951 | if (hc->ctype == HFC_TYPE_XHFC) { |
4833 | hc->type, HFC_cnt + 1, pt + 1); | 4952 | snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d", |
4834 | ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); | 4953 | HFC_cnt + 1, pt + 1); |
4954 | ret = mISDN_register_device(&dch->dev, NULL, name); | ||
4955 | } else { | ||
4956 | snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d", | ||
4957 | hc->ctype, HFC_cnt + 1, pt + 1); | ||
4958 | ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); | ||
4959 | } | ||
4835 | if (ret) | 4960 | if (ret) |
4836 | goto free_chan; | 4961 | goto free_chan; |
4837 | hc->created[pt] = 1; | 4962 | hc->created[pt] = 1; |
@@ -4842,9 +4967,9 @@ free_chan: | |||
4842 | } | 4967 | } |
4843 | 4968 | ||
4844 | static int | 4969 | static int |
4845 | hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | 4970 | hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, |
4971 | const struct pci_device_id *ent) | ||
4846 | { | 4972 | { |
4847 | struct hm_map *m = (struct hm_map *)ent->driver_data; | ||
4848 | int ret_err = 0; | 4973 | int ret_err = 0; |
4849 | int pt; | 4974 | int pt; |
4850 | struct hfc_multi *hc; | 4975 | struct hfc_multi *hc; |
@@ -4879,16 +5004,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4879 | } | 5004 | } |
4880 | spin_lock_init(&hc->lock); | 5005 | spin_lock_init(&hc->lock); |
4881 | hc->mtyp = m; | 5006 | hc->mtyp = m; |
4882 | hc->type = m->type; | 5007 | hc->ctype = m->type; |
4883 | hc->ports = m->ports; | 5008 | hc->ports = m->ports; |
4884 | hc->id = HFC_cnt; | 5009 | hc->id = HFC_cnt; |
4885 | hc->pcm = pcm[HFC_cnt]; | 5010 | hc->pcm = pcm[HFC_cnt]; |
4886 | hc->io_mode = iomode[HFC_cnt]; | 5011 | hc->io_mode = iomode[HFC_cnt]; |
4887 | if (dslot[HFC_cnt] < 0 && hc->type == 1) { | 5012 | if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) { |
4888 | hc->dslot = 0; | 5013 | hc->dslot = 0; |
4889 | printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " | 5014 | printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " |
4890 | "31 B-channels\n"); | 5015 | "31 B-channels\n"); |
4891 | } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) { | 5016 | } |
5017 | if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 | ||
5018 | && hc->ctype == HFC_TYPE_E1) { | ||
4892 | hc->dslot = dslot[HFC_cnt]; | 5019 | hc->dslot = dslot[HFC_cnt]; |
4893 | printk(KERN_INFO "HFC-E1 card has alternating D-channel on " | 5020 | printk(KERN_INFO "HFC-E1 card has alternating D-channel on " |
4894 | "time slot %d\n", dslot[HFC_cnt]); | 5021 | "time slot %d\n", dslot[HFC_cnt]); |
@@ -4910,8 +5037,11 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4910 | for (i = 0; i < (poll >> 1); i++) | 5037 | for (i = 0; i < (poll >> 1); i++) |
4911 | hc->silence_data[i] = hc->silence; | 5038 | hc->silence_data[i] = hc->silence; |
4912 | 5039 | ||
4913 | if (!(type[HFC_cnt] & 0x200)) | 5040 | if (hc->ctype != HFC_TYPE_XHFC) { |
4914 | test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); | 5041 | if (!(type[HFC_cnt] & 0x200)) |
5042 | test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); | ||
5043 | test_and_set_bit(HFC_CHIP_CONF, &hc->chip); | ||
5044 | } | ||
4915 | 5045 | ||
4916 | if (type[HFC_cnt] & 0x800) | 5046 | if (type[HFC_cnt] & 0x800) |
4917 | test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); | 5047 | test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); |
@@ -4935,8 +5065,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4935 | printk(KERN_NOTICE "Watchdog enabled\n"); | 5065 | printk(KERN_NOTICE "Watchdog enabled\n"); |
4936 | } | 5066 | } |
4937 | 5067 | ||
4938 | /* setup pci, hc->slots may change due to PLXSD */ | 5068 | if (pdev && ent) |
4939 | ret_err = setup_pci(hc, pdev, ent); | 5069 | /* setup pci, hc->slots may change due to PLXSD */ |
5070 | ret_err = setup_pci(hc, pdev, ent); | ||
5071 | else | ||
5072 | #ifdef CONFIG_MISDN_HFCMULTI_8xx | ||
5073 | ret_err = setup_embedded(hc, m); | ||
5074 | #else | ||
5075 | { | ||
5076 | printk(KERN_WARNING "Embedded IO Mode not selected\n"); | ||
5077 | ret_err = -EIO; | ||
5078 | } | ||
5079 | #endif | ||
4940 | if (ret_err) { | 5080 | if (ret_err) { |
4941 | if (hc == syncmaster) | 5081 | if (hc == syncmaster) |
4942 | syncmaster = NULL; | 5082 | syncmaster = NULL; |
@@ -4944,7 +5084,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4944 | return ret_err; | 5084 | return ret_err; |
4945 | } | 5085 | } |
4946 | 5086 | ||
4947 | /* crate channels */ | 5087 | hc->HFC_outb_nodebug = hc->HFC_outb; |
5088 | hc->HFC_inb_nodebug = hc->HFC_inb; | ||
5089 | hc->HFC_inw_nodebug = hc->HFC_inw; | ||
5090 | hc->HFC_wait_nodebug = hc->HFC_wait; | ||
5091 | #ifdef HFC_REGISTER_DEBUG | ||
5092 | hc->HFC_outb = HFC_outb_debug; | ||
5093 | hc->HFC_inb = HFC_inb_debug; | ||
5094 | hc->HFC_inw = HFC_inw_debug; | ||
5095 | hc->HFC_wait = HFC_wait_debug; | ||
5096 | #endif | ||
5097 | /* create channels */ | ||
4948 | for (pt = 0; pt < hc->ports; pt++) { | 5098 | for (pt = 0; pt < hc->ports; pt++) { |
4949 | if (Port_cnt >= MAX_PORTS) { | 5099 | if (Port_cnt >= MAX_PORTS) { |
4950 | printk(KERN_ERR "too many ports (max=%d).\n", | 5100 | printk(KERN_ERR "too many ports (max=%d).\n", |
@@ -4952,7 +5102,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4952 | ret_err = -EINVAL; | 5102 | ret_err = -EINVAL; |
4953 | goto free_card; | 5103 | goto free_card; |
4954 | } | 5104 | } |
4955 | if (hc->type == 1) | 5105 | if (hc->ctype == HFC_TYPE_E1) |
4956 | ret_err = init_e1_port(hc, m); | 5106 | ret_err = init_e1_port(hc, m); |
4957 | else | 5107 | else |
4958 | ret_err = init_multi_port(hc, pt); | 5108 | ret_err = init_multi_port(hc, pt); |
@@ -5036,6 +5186,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5036 | hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); | 5186 | hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); |
5037 | 5187 | ||
5038 | /* initialize hardware */ | 5188 | /* initialize hardware */ |
5189 | hc->irq = (m->irq) ? : hc->pci_dev->irq; | ||
5039 | ret_err = init_card(hc); | 5190 | ret_err = init_card(hc); |
5040 | if (ret_err) { | 5191 | if (ret_err) { |
5041 | printk(KERN_ERR "init card returns %d\n", ret_err); | 5192 | printk(KERN_ERR "init card returns %d\n", ret_err); |
@@ -5074,7 +5225,7 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev) | |||
5074 | spin_unlock_irqrestore(&HFClock, flags); | 5225 | spin_unlock_irqrestore(&HFClock, flags); |
5075 | } else { | 5226 | } else { |
5076 | if (debug) | 5227 | if (debug) |
5077 | printk(KERN_WARNING "%s: drvdata allready removed\n", | 5228 | printk(KERN_DEBUG "%s: drvdata allready removed\n", |
5078 | __func__); | 5229 | __func__); |
5079 | } | 5230 | } |
5080 | } | 5231 | } |
@@ -5086,45 +5237,48 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev) | |||
5086 | #define VENDOR_PRIM "PrimuX" | 5237 | #define VENDOR_PRIM "PrimuX" |
5087 | 5238 | ||
5088 | static const struct hm_map hfcm_map[] = { | 5239 | static const struct hm_map hfcm_map[] = { |
5089 | /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0}, | 5240 | /*0*/ {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0}, |
5090 | /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0}, | 5241 | /*1*/ {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, |
5091 | /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0}, | 5242 | /*2*/ {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0}, |
5092 | /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0}, | 5243 | /*3*/ {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, |
5093 | /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0}, | 5244 | /*4*/ {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0}, |
5094 | /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0}, | 5245 | /*5*/ {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0}, |
5095 | /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0}, | 5246 | /*6*/ {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0}, |
5096 | /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0}, | 5247 | /*7*/ {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0}, |
5097 | /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO}, | 5248 | /*8*/ {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0}, |
5098 | /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0}, | 5249 | /*9*/ {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0}, |
5099 | /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0}, | 5250 | /*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0}, |
5100 | /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0}, | 5251 | /*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0}, |
5101 | 5252 | ||
5102 | /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0}, | 5253 | /*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0}, |
5103 | /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S, | 5254 | /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S, |
5104 | HFC_IO_MODE_REGIO}, | 5255 | HFC_IO_MODE_REGIO, 0}, |
5105 | /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0}, | 5256 | /*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0}, |
5106 | /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0}, | 5257 | /*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0}, |
5107 | 5258 | ||
5108 | /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0}, | 5259 | /*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0}, |
5109 | /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0}, | 5260 | /*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0}, |
5110 | /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0}, | 5261 | /*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0}, |
5111 | 5262 | ||
5112 | /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0}, | 5263 | /*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, |
5113 | /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0}, | 5264 | /*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0}, |
5114 | /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0}, | 5265 | /*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, |
5115 | /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0}, | 5266 | /*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0}, |
5116 | 5267 | ||
5117 | /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0}, | 5268 | /*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0}, |
5118 | /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0}, | 5269 | /*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0}, |
5119 | /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0}, | 5270 | /*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0}, |
5120 | 5271 | ||
5121 | /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0, | 5272 | /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0, |
5122 | HFC_IO_MODE_PLXSD}, | 5273 | HFC_IO_MODE_PLXSD, 0}, |
5123 | /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0, | 5274 | /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0, |
5124 | HFC_IO_MODE_PLXSD}, | 5275 | HFC_IO_MODE_PLXSD, 0}, |
5125 | /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0}, | 5276 | /*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0}, |
5126 | /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0}, | 5277 | /*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0}, |
5127 | /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0}, | 5278 | /*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0}, |
5279 | /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0, | ||
5280 | HFC_IO_MODE_EMBSD, XHFC_IRQ}, | ||
5281 | /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0}, | ||
5128 | }; | 5282 | }; |
5129 | 5283 | ||
5130 | #undef H | 5284 | #undef H |
@@ -5178,6 +5332,8 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = { | |||
5178 | PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */ | 5332 | PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */ |
5179 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, | 5333 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, |
5180 | PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */ | 5334 | PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */ |
5335 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD, | ||
5336 | PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S */ | ||
5181 | 5337 | ||
5182 | 5338 | ||
5183 | /* Cards with HFC-E1 Chip */ | 5339 | /* Cards with HFC-E1 Chip */ |
@@ -5201,6 +5357,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = { | |||
5201 | PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */ | 5357 | PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */ |
5202 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD, | 5358 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD, |
5203 | PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */ | 5359 | PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */ |
5360 | |||
5361 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD, | ||
5362 | PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */ | ||
5363 | |||
5204 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_ANY_ID, PCI_ANY_ID, | 5364 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_ANY_ID, PCI_ANY_ID, |
5205 | 0, 0, 0}, | 5365 | 0, 0, 0}, |
5206 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_ANY_ID, PCI_ANY_ID, | 5366 | { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_ANY_ID, PCI_ANY_ID, |
@@ -5231,7 +5391,7 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
5231 | "Please contact the driver maintainer for support.\n"); | 5391 | "Please contact the driver maintainer for support.\n"); |
5232 | return -ENODEV; | 5392 | return -ENODEV; |
5233 | } | 5393 | } |
5234 | ret = hfcmulti_init(pdev, ent); | 5394 | ret = hfcmulti_init(m, pdev, ent); |
5235 | if (ret) | 5395 | if (ret) |
5236 | return ret; | 5396 | return ret; |
5237 | HFC_cnt++; | 5397 | HFC_cnt++; |
@@ -5261,6 +5421,8 @@ static int __init | |||
5261 | HFCmulti_init(void) | 5421 | HFCmulti_init(void) |
5262 | { | 5422 | { |
5263 | int err; | 5423 | int err; |
5424 | int i, xhfc = 0; | ||
5425 | struct hm_map m; | ||
5264 | 5426 | ||
5265 | printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION); | 5427 | printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION); |
5266 | 5428 | ||
@@ -5308,11 +5470,43 @@ HFCmulti_init(void) | |||
5308 | if (!clock) | 5470 | if (!clock) |
5309 | clock = 1; | 5471 | clock = 1; |
5310 | 5472 | ||
5473 | /* Register the embedded devices. | ||
5474 | * This should be done before the PCI cards registration */ | ||
5475 | switch (hwid) { | ||
5476 | case HWID_MINIP4: | ||
5477 | xhfc = 1; | ||
5478 | m = hfcm_map[31]; | ||
5479 | break; | ||
5480 | case HWID_MINIP8: | ||
5481 | xhfc = 2; | ||
5482 | m = hfcm_map[31]; | ||
5483 | break; | ||
5484 | case HWID_MINIP16: | ||
5485 | xhfc = 4; | ||
5486 | m = hfcm_map[31]; | ||
5487 | break; | ||
5488 | default: | ||
5489 | xhfc = 0; | ||
5490 | } | ||
5491 | |||
5492 | for (i = 0; i < xhfc; ++i) { | ||
5493 | err = hfcmulti_init(&m, NULL, NULL); | ||
5494 | if (err) { | ||
5495 | printk(KERN_ERR "error registering embedded driver: " | ||
5496 | "%x\n", err); | ||
5497 | return -err; | ||
5498 | } | ||
5499 | HFC_cnt++; | ||
5500 | printk(KERN_INFO "%d devices registered\n", HFC_cnt); | ||
5501 | } | ||
5502 | |||
5503 | /* Register the PCI cards */ | ||
5311 | err = pci_register_driver(&hfcmultipci_driver); | 5504 | err = pci_register_driver(&hfcmultipci_driver); |
5312 | if (err < 0) { | 5505 | if (err < 0) { |
5313 | printk(KERN_ERR "error registering pci driver: %x\n", err); | 5506 | printk(KERN_ERR "error registering pci driver: %x\n", err); |
5314 | return err; | 5507 | return err; |
5315 | } | 5508 | } |
5509 | |||
5316 | return 0; | 5510 | return 0; |
5317 | } | 5511 | } |
5318 | 5512 | ||
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 641a9cd1a532..228ffbed1286 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c | |||
@@ -257,7 +257,7 @@ reset_hfcpci(struct hfc_pci *hc) | |||
257 | Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); | 257 | Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); |
258 | 258 | ||
259 | /* Clear already pending ints */ | 259 | /* Clear already pending ints */ |
260 | if (Read_hfc(hc, HFCPCI_INT_S1)); | 260 | val = Read_hfc(hc, HFCPCI_INT_S1); |
261 | 261 | ||
262 | /* set NT/TE mode */ | 262 | /* set NT/TE mode */ |
263 | hfcpci_setmode(hc); | 263 | hfcpci_setmode(hc); |
@@ -452,7 +452,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz, | |||
452 | } | 452 | } |
453 | bz->za[new_f2].z2 = cpu_to_le16(new_z2); | 453 | bz->za[new_f2].z2 = cpu_to_le16(new_z2); |
454 | bz->f2 = new_f2; /* next buffer */ | 454 | bz->f2 = new_f2; /* next buffer */ |
455 | recv_Bchannel(bch); | 455 | recv_Bchannel(bch, MISDN_ID_ANY); |
456 | } | 456 | } |
457 | } | 457 | } |
458 | 458 | ||
@@ -499,7 +499,8 @@ receive_dmsg(struct hfc_pci *hc) | |||
499 | df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | | 499 | df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | |
500 | (MAX_D_FRAMES + 1); /* next buffer */ | 500 | (MAX_D_FRAMES + 1); /* next buffer */ |
501 | df->za[df->f2 & D_FREG_MASK].z2 = | 501 | df->za[df->f2 & D_FREG_MASK].z2 = |
502 | cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & (D_FIFO_SIZE - 1)); | 502 | cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & |
503 | (D_FIFO_SIZE - 1)); | ||
503 | } else { | 504 | } else { |
504 | dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC); | 505 | dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC); |
505 | if (!dch->rx_skb) { | 506 | if (!dch->rx_skb) { |
@@ -541,35 +542,45 @@ receive_dmsg(struct hfc_pci *hc) | |||
541 | * check for transparent receive data and read max one 'poll' size if avail | 542 | * check for transparent receive data and read max one 'poll' size if avail |
542 | */ | 543 | */ |
543 | static void | 544 | static void |
544 | hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) | 545 | hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz, |
546 | struct bzfifo *txbz, u_char *bdata) | ||
545 | { | 547 | { |
546 | __le16 *z1r, *z2r; | 548 | __le16 *z1r, *z2r, *z1t, *z2t; |
547 | int new_z2, fcnt, maxlen; | 549 | int new_z2, fcnt_rx, fcnt_tx, maxlen; |
548 | u_char *ptr, *ptr1; | 550 | u_char *ptr, *ptr1; |
549 | 551 | ||
550 | z1r = &bz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ | 552 | z1r = &rxbz->za[MAX_B_FRAMES].z1; /* pointer to z reg */ |
551 | z2r = z1r + 1; | 553 | z2r = z1r + 1; |
554 | z1t = &txbz->za[MAX_B_FRAMES].z1; | ||
555 | z2t = z1t + 1; | ||
552 | 556 | ||
553 | fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); | 557 | fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r); |
554 | if (!fcnt) | 558 | if (!fcnt_rx) |
555 | return; /* no data avail */ | 559 | return; /* no data avail */ |
556 | 560 | ||
557 | if (fcnt <= 0) | 561 | if (fcnt_rx <= 0) |
558 | fcnt += B_FIFO_SIZE; /* bytes actually buffered */ | 562 | fcnt_rx += B_FIFO_SIZE; /* bytes actually buffered */ |
559 | new_z2 = le16_to_cpu(*z2r) + fcnt; /* new position in fifo */ | 563 | new_z2 = le16_to_cpu(*z2r) + fcnt_rx; /* new position in fifo */ |
560 | if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) | 564 | if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL)) |
561 | new_z2 -= B_FIFO_SIZE; /* buffer wrap */ | 565 | new_z2 -= B_FIFO_SIZE; /* buffer wrap */ |
562 | 566 | ||
563 | if (fcnt > MAX_DATA_SIZE) { /* flush, if oversized */ | 567 | if (fcnt_rx > MAX_DATA_SIZE) { /* flush, if oversized */ |
564 | *z2r = cpu_to_le16(new_z2); /* new position */ | 568 | *z2r = cpu_to_le16(new_z2); /* new position */ |
565 | return; | 569 | return; |
566 | } | 570 | } |
567 | 571 | ||
568 | bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC); | 572 | fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t); |
573 | if (fcnt_tx <= 0) | ||
574 | fcnt_tx += B_FIFO_SIZE; | ||
575 | /* fcnt_tx contains available bytes in tx-fifo */ | ||
576 | fcnt_tx = B_FIFO_SIZE - fcnt_tx; | ||
577 | /* remaining bytes to send (bytes in tx-fifo) */ | ||
578 | |||
579 | bch->rx_skb = mI_alloc_skb(fcnt_rx, GFP_ATOMIC); | ||
569 | if (bch->rx_skb) { | 580 | if (bch->rx_skb) { |
570 | ptr = skb_put(bch->rx_skb, fcnt); | 581 | ptr = skb_put(bch->rx_skb, fcnt_rx); |
571 | if (le16_to_cpu(*z2r) + fcnt <= B_FIFO_SIZE + B_SUB_VAL) | 582 | if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL) |
572 | maxlen = fcnt; /* complete transfer */ | 583 | maxlen = fcnt_rx; /* complete transfer */ |
573 | else | 584 | else |
574 | maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r); | 585 | maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r); |
575 | /* maximum */ | 586 | /* maximum */ |
@@ -577,14 +588,14 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) | |||
577 | ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL); | 588 | ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL); |
578 | /* start of data */ | 589 | /* start of data */ |
579 | memcpy(ptr, ptr1, maxlen); /* copy data */ | 590 | memcpy(ptr, ptr1, maxlen); /* copy data */ |
580 | fcnt -= maxlen; | 591 | fcnt_rx -= maxlen; |
581 | 592 | ||
582 | if (fcnt) { /* rest remaining */ | 593 | if (fcnt_rx) { /* rest remaining */ |
583 | ptr += maxlen; | 594 | ptr += maxlen; |
584 | ptr1 = bdata; /* start of buffer */ | 595 | ptr1 = bdata; /* start of buffer */ |
585 | memcpy(ptr, ptr1, fcnt); /* rest */ | 596 | memcpy(ptr, ptr1, fcnt_rx); /* rest */ |
586 | } | 597 | } |
587 | recv_Bchannel(bch); | 598 | recv_Bchannel(bch, fcnt_tx); /* bch, id */ |
588 | } else | 599 | } else |
589 | printk(KERN_WARNING "HFCPCI: receive out of memory\n"); | 600 | printk(KERN_WARNING "HFCPCI: receive out of memory\n"); |
590 | 601 | ||
@@ -600,26 +611,28 @@ main_rec_hfcpci(struct bchannel *bch) | |||
600 | struct hfc_pci *hc = bch->hw; | 611 | struct hfc_pci *hc = bch->hw; |
601 | int rcnt, real_fifo; | 612 | int rcnt, real_fifo; |
602 | int receive = 0, count = 5; | 613 | int receive = 0, count = 5; |
603 | struct bzfifo *bz; | 614 | struct bzfifo *txbz, *rxbz; |
604 | u_char *bdata; | 615 | u_char *bdata; |
605 | struct zt *zp; | 616 | struct zt *zp; |
606 | 617 | ||
607 | if ((bch->nr & 2) && (!hc->hw.bswapped)) { | 618 | if ((bch->nr & 2) && (!hc->hw.bswapped)) { |
608 | bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; | 619 | rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2; |
620 | txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2; | ||
609 | bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; | 621 | bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2; |
610 | real_fifo = 1; | 622 | real_fifo = 1; |
611 | } else { | 623 | } else { |
612 | bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1; | 624 | rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1; |
625 | txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1; | ||
613 | bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1; | 626 | bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1; |
614 | real_fifo = 0; | 627 | real_fifo = 0; |
615 | } | 628 | } |
616 | Begin: | 629 | Begin: |
617 | count--; | 630 | count--; |
618 | if (bz->f1 != bz->f2) { | 631 | if (rxbz->f1 != rxbz->f2) { |
619 | if (bch->debug & DEBUG_HW_BCHANNEL) | 632 | if (bch->debug & DEBUG_HW_BCHANNEL) |
620 | printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n", | 633 | printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n", |
621 | bch->nr, bz->f1, bz->f2); | 634 | bch->nr, rxbz->f1, rxbz->f2); |
622 | zp = &bz->za[bz->f2]; | 635 | zp = &rxbz->za[rxbz->f2]; |
623 | 636 | ||
624 | rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2); | 637 | rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2); |
625 | if (rcnt < 0) | 638 | if (rcnt < 0) |
@@ -630,8 +643,8 @@ Begin: | |||
630 | "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n", | 643 | "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n", |
631 | bch->nr, le16_to_cpu(zp->z1), | 644 | bch->nr, le16_to_cpu(zp->z1), |
632 | le16_to_cpu(zp->z2), rcnt); | 645 | le16_to_cpu(zp->z2), rcnt); |
633 | hfcpci_empty_bfifo(bch, bz, bdata, rcnt); | 646 | hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt); |
634 | rcnt = bz->f1 - bz->f2; | 647 | rcnt = rxbz->f1 - rxbz->f2; |
635 | if (rcnt < 0) | 648 | if (rcnt < 0) |
636 | rcnt += MAX_B_FRAMES + 1; | 649 | rcnt += MAX_B_FRAMES + 1; |
637 | if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) { | 650 | if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) { |
@@ -644,7 +657,7 @@ Begin: | |||
644 | else | 657 | else |
645 | receive = 0; | 658 | receive = 0; |
646 | } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { | 659 | } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) { |
647 | hfcpci_empty_fifo_trans(bch, bz, bdata); | 660 | hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata); |
648 | return; | 661 | return; |
649 | } else | 662 | } else |
650 | receive = 0; | 663 | receive = 0; |
@@ -954,6 +967,7 @@ static void | |||
954 | ph_state_nt(struct dchannel *dch) | 967 | ph_state_nt(struct dchannel *dch) |
955 | { | 968 | { |
956 | struct hfc_pci *hc = dch->hw; | 969 | struct hfc_pci *hc = dch->hw; |
970 | u_char val; | ||
957 | 971 | ||
958 | if (dch->debug) | 972 | if (dch->debug) |
959 | printk(KERN_DEBUG "%s: NT newstate %x\n", | 973 | printk(KERN_DEBUG "%s: NT newstate %x\n", |
@@ -967,7 +981,7 @@ ph_state_nt(struct dchannel *dch) | |||
967 | hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; | 981 | hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER; |
968 | Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); | 982 | Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1); |
969 | /* Clear already pending ints */ | 983 | /* Clear already pending ints */ |
970 | if (Read_hfc(hc, HFCPCI_INT_S1)); | 984 | val = Read_hfc(hc, HFCPCI_INT_S1); |
971 | Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); | 985 | Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE); |
972 | udelay(10); | 986 | udelay(10); |
973 | Write_hfc(hc, HFCPCI_STATES, 4); | 987 | Write_hfc(hc, HFCPCI_STATES, 4); |
@@ -1256,8 +1270,7 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) | |||
1256 | rx_slot = (bc>>8) & 0xff; | 1270 | rx_slot = (bc>>8) & 0xff; |
1257 | tx_slot = (bc>>16) & 0xff; | 1271 | tx_slot = (bc>>16) & 0xff; |
1258 | bc = bc & 0xff; | 1272 | bc = bc & 0xff; |
1259 | } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && | 1273 | } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE)) |
1260 | (protocol > ISDN_P_NONE)) | ||
1261 | printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n", | 1274 | printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n", |
1262 | __func__); | 1275 | __func__); |
1263 | if (hc->chanlimit > 1) { | 1276 | if (hc->chanlimit > 1) { |
@@ -1315,8 +1328,8 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) | |||
1315 | case (ISDN_P_B_RAW): | 1328 | case (ISDN_P_B_RAW): |
1316 | bch->state = protocol; | 1329 | bch->state = protocol; |
1317 | bch->nr = bc; | 1330 | bch->nr = bc; |
1318 | hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0); | 1331 | hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0); |
1319 | hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0); | 1332 | hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0); |
1320 | if (bc & 2) { | 1333 | if (bc & 2) { |
1321 | hc->hw.sctrl |= SCTRL_B2_ENA; | 1334 | hc->hw.sctrl |= SCTRL_B2_ENA; |
1322 | hc->hw.sctrl_r |= SCTRL_B2_ENA; | 1335 | hc->hw.sctrl_r |= SCTRL_B2_ENA; |
@@ -1350,8 +1363,8 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) | |||
1350 | case (ISDN_P_B_HDLC): | 1363 | case (ISDN_P_B_HDLC): |
1351 | bch->state = protocol; | 1364 | bch->state = protocol; |
1352 | bch->nr = bc; | 1365 | bch->nr = bc; |
1353 | hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0); | 1366 | hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0); |
1354 | hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0); | 1367 | hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0); |
1355 | if (bc & 2) { | 1368 | if (bc & 2) { |
1356 | hc->hw.sctrl |= SCTRL_B2_ENA; | 1369 | hc->hw.sctrl |= SCTRL_B2_ENA; |
1357 | hc->hw.sctrl_r |= SCTRL_B2_ENA; | 1370 | hc->hw.sctrl_r |= SCTRL_B2_ENA; |
@@ -1445,7 +1458,7 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan) | |||
1445 | switch (protocol) { | 1458 | switch (protocol) { |
1446 | case (ISDN_P_B_RAW): | 1459 | case (ISDN_P_B_RAW): |
1447 | bch->state = protocol; | 1460 | bch->state = protocol; |
1448 | hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0); | 1461 | hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0); |
1449 | if (chan & 2) { | 1462 | if (chan & 2) { |
1450 | hc->hw.sctrl_r |= SCTRL_B2_ENA; | 1463 | hc->hw.sctrl_r |= SCTRL_B2_ENA; |
1451 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; | 1464 | hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX; |
@@ -1470,7 +1483,7 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan) | |||
1470 | break; | 1483 | break; |
1471 | case (ISDN_P_B_HDLC): | 1484 | case (ISDN_P_B_HDLC): |
1472 | bch->state = protocol; | 1485 | bch->state = protocol; |
1473 | hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0); | 1486 | hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0); |
1474 | if (chan & 2) { | 1487 | if (chan & 2) { |
1475 | hc->hw.sctrl_r |= SCTRL_B2_ENA; | 1488 | hc->hw.sctrl_r |= SCTRL_B2_ENA; |
1476 | hc->hw.last_bfifo_cnt[1] = 0; | 1489 | hc->hw.last_bfifo_cnt[1] = 0; |
@@ -1793,10 +1806,9 @@ init_card(struct hfc_pci *hc) | |||
1793 | printk(KERN_WARNING | 1806 | printk(KERN_WARNING |
1794 | "HFC PCI: IRQ(%d) getting no interrupts " | 1807 | "HFC PCI: IRQ(%d) getting no interrupts " |
1795 | "during init %d\n", hc->irq, 4 - cnt); | 1808 | "during init %d\n", hc->irq, 4 - cnt); |
1796 | if (cnt == 1) { | 1809 | if (cnt == 1) |
1797 | spin_unlock_irqrestore(&hc->lock, flags); | 1810 | break; |
1798 | return -EIO; | 1811 | else { |
1799 | } else { | ||
1800 | reset_hfcpci(hc); | 1812 | reset_hfcpci(hc); |
1801 | cnt--; | 1813 | cnt--; |
1802 | } | 1814 | } |
@@ -2035,7 +2047,8 @@ setup_hw(struct hfc_pci *hc) | |||
2035 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); | 2047 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); |
2036 | return 1; | 2048 | return 1; |
2037 | } | 2049 | } |
2038 | hc->hw.pci_io = (char __iomem *)(unsigned long)hc->pdev->resource[1].start; | 2050 | hc->hw.pci_io = |
2051 | (char __iomem *)(unsigned long)hc->pdev->resource[1].start; | ||
2039 | 2052 | ||
2040 | if (!hc->hw.pci_io) { | 2053 | if (!hc->hw.pci_io) { |
2041 | printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); | 2054 | printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); |
@@ -2277,7 +2290,7 @@ hfc_remove_pci(struct pci_dev *pdev) | |||
2277 | release_card(card); | 2290 | release_card(card); |
2278 | else | 2291 | else |
2279 | if (debug) | 2292 | if (debug) |
2280 | printk(KERN_WARNING "%s: drvdata already removed\n", | 2293 | printk(KERN_DEBUG "%s: drvdata already removed\n", |
2281 | __func__); | 2294 | __func__); |
2282 | } | 2295 | } |
2283 | 2296 | ||
diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index 9c427fb204ee..6b7704c41b94 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c | |||
@@ -947,7 +947,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, | |||
947 | if (fifo->dch) | 947 | if (fifo->dch) |
948 | recv_Dchannel(fifo->dch); | 948 | recv_Dchannel(fifo->dch); |
949 | if (fifo->bch) | 949 | if (fifo->bch) |
950 | recv_Bchannel(fifo->bch); | 950 | recv_Bchannel(fifo->bch, MISDN_ID_ANY); |
951 | if (fifo->ech) | 951 | if (fifo->ech) |
952 | recv_Echannel(fifo->ech, | 952 | recv_Echannel(fifo->ech, |
953 | &hw->dch); | 953 | &hw->dch); |
@@ -969,7 +969,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len, | |||
969 | } else { | 969 | } else { |
970 | /* deliver transparent data to layer2 */ | 970 | /* deliver transparent data to layer2 */ |
971 | if (rx_skb->len >= poll) | 971 | if (rx_skb->len >= poll) |
972 | recv_Bchannel(fifo->bch); | 972 | recv_Bchannel(fifo->bch, MISDN_ID_ANY); |
973 | } | 973 | } |
974 | spin_unlock(&hw->lock); | 974 | spin_unlock(&hw->lock); |
975 | } | 975 | } |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index f1265667b062..3d337d924c23 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -82,8 +82,9 @@ release_io_hfcpci(struct IsdnCardState *cs) | |||
82 | Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); | 82 | Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2); |
83 | pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */ | 83 | pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0); /* disable memory mapped ports + busmaster */ |
84 | del_timer(&cs->hw.hfcpci.timer); | 84 | del_timer(&cs->hw.hfcpci.timer); |
85 | kfree(cs->hw.hfcpci.share_start); | 85 | pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, |
86 | cs->hw.hfcpci.share_start = NULL; | 86 | cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); |
87 | cs->hw.hfcpci.fifos = NULL; | ||
87 | iounmap((void *)cs->hw.hfcpci.pci_io); | 88 | iounmap((void *)cs->hw.hfcpci.pci_io); |
88 | } | 89 | } |
89 | 90 | ||
@@ -1663,8 +1664,19 @@ setup_hfcpci(struct IsdnCard *card) | |||
1663 | dev_hfcpci); | 1664 | dev_hfcpci); |
1664 | i++; | 1665 | i++; |
1665 | if (tmp_hfcpci) { | 1666 | if (tmp_hfcpci) { |
1667 | dma_addr_t dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL; | ||
1666 | if (pci_enable_device(tmp_hfcpci)) | 1668 | if (pci_enable_device(tmp_hfcpci)) |
1667 | continue; | 1669 | continue; |
1670 | if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) { | ||
1671 | printk(KERN_WARNING | ||
1672 | "HiSax hfc_pci: No suitable DMA available.\n"); | ||
1673 | continue; | ||
1674 | } | ||
1675 | if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) { | ||
1676 | printk(KERN_WARNING | ||
1677 | "HiSax hfc_pci: No suitable consistent DMA available.\n"); | ||
1678 | continue; | ||
1679 | } | ||
1668 | pci_set_master(tmp_hfcpci); | 1680 | pci_set_master(tmp_hfcpci); |
1669 | if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) | 1681 | if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK))) |
1670 | continue; | 1682 | continue; |
@@ -1693,22 +1705,29 @@ setup_hfcpci(struct IsdnCard *card) | |||
1693 | printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); | 1705 | printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); |
1694 | return (0); | 1706 | return (0); |
1695 | } | 1707 | } |
1708 | |||
1696 | /* Allocate memory for FIFOS */ | 1709 | /* Allocate memory for FIFOS */ |
1697 | /* Because the HFC-PCI needs a 32K physical alignment, we */ | 1710 | cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev, |
1698 | /* need to allocate the double mem and align the address */ | 1711 | 0x8000, &cs->hw.hfcpci.dma); |
1699 | if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) { | 1712 | if (!cs->hw.hfcpci.fifos) { |
1700 | printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n"); | 1713 | printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n"); |
1714 | return 0; | ||
1715 | } | ||
1716 | if (cs->hw.hfcpci.dma & 0x7fff) { | ||
1717 | printk(KERN_WARNING | ||
1718 | "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n", | ||
1719 | (u_long)cs->hw.hfcpci.dma); | ||
1720 | pci_free_consistent(cs->hw.hfcpci.dev, 0x8000, | ||
1721 | cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma); | ||
1701 | return 0; | 1722 | return 0; |
1702 | } | 1723 | } |
1703 | cs->hw.hfcpci.fifos = (void *) | 1724 | pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma); |
1704 | (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000; | ||
1705 | pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos)); | ||
1706 | cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); | 1725 | cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256); |
1707 | printk(KERN_INFO | 1726 | printk(KERN_INFO |
1708 | "HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n", | 1727 | "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n", |
1709 | cs->hw.hfcpci.pci_io, | 1728 | cs->hw.hfcpci.pci_io, |
1710 | cs->hw.hfcpci.fifos, | 1729 | cs->hw.hfcpci.fifos, |
1711 | (u_int) virt_to_bus(cs->hw.hfcpci.fifos), | 1730 | (u_long)cs->hw.hfcpci.dma, |
1712 | cs->irq, HZ); | 1731 | cs->irq, HZ); |
1713 | 1732 | ||
1714 | spin_lock_irqsave(&cs->lock, flags); | 1733 | spin_lock_irqsave(&cs->lock, flags); |
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index f8527046f197..0685c1946969 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h | |||
@@ -703,7 +703,7 @@ struct hfcPCI_hw { | |||
703 | int nt_timer; | 703 | int nt_timer; |
704 | struct pci_dev *dev; | 704 | struct pci_dev *dev; |
705 | unsigned char *pci_io; /* start of PCI IO memory */ | 705 | unsigned char *pci_io; /* start of PCI IO memory */ |
706 | void *share_start; /* shared memory for Fifos start */ | 706 | dma_addr_t dma; /* dma handle for Fifos */ |
707 | void *fifos; /* FIFO memory */ | 707 | void *fifos; /* FIFO memory */ |
708 | int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */ | 708 | int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */ |
709 | struct timer_list timer; | 709 | struct timer_list timer; |
diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 53f6ad1235db..4ffaa14b9fc4 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c | |||
@@ -67,7 +67,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) | |||
67 | printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n"); | 67 | printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n"); |
68 | #endif | 68 | #endif |
69 | capilib_release(&cinfo->ncci_head); | 69 | capilib_release(&cinfo->ncci_head); |
70 | capi_ctr_reseted(ctrl); | 70 | capi_ctr_down(ctrl); |
71 | } | 71 | } |
72 | 72 | ||
73 | /****************************** | 73 | /****************************** |
@@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card) | |||
347 | if(cinfo) { | 347 | if(cinfo) { |
348 | ctrl = &cinfo->capi_ctrl; | 348 | ctrl = &cinfo->capi_ctrl; |
349 | /* ctrl->suspend_output(ctrl); */ | 349 | /* ctrl->suspend_output(ctrl); */ |
350 | capi_ctr_reseted(ctrl); | 350 | capi_ctr_down(ctrl); |
351 | } | 351 | } |
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index 36778b270c30..ed3510f273d8 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig | |||
@@ -135,5 +135,3 @@ source "drivers/isdn/act2000/Kconfig" | |||
135 | source "drivers/isdn/hysdn/Kconfig" | 135 | source "drivers/isdn/hysdn/Kconfig" |
136 | 136 | ||
137 | endmenu | 137 | endmenu |
138 | |||
139 | source "drivers/isdn/gigaset/Kconfig" | ||
diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index cb8943da4f12..34d54e7281fd 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c | |||
@@ -1069,7 +1069,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb) | |||
1069 | lp = isdn_net_get_locked_lp(nd); | 1069 | lp = isdn_net_get_locked_lp(nd); |
1070 | if (!lp) { | 1070 | if (!lp) { |
1071 | printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name); | 1071 | printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name); |
1072 | return 1; | 1072 | return NETDEV_TX_BUSY; |
1073 | } | 1073 | } |
1074 | /* we have our lp locked from now on */ | 1074 | /* we have our lp locked from now on */ |
1075 | 1075 | ||
@@ -1273,14 +1273,14 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
1273 | spin_unlock_irqrestore(&dev->lock, flags); | 1273 | spin_unlock_irqrestore(&dev->lock, flags); |
1274 | isdn_net_dial(); /* Initiate dialing */ | 1274 | isdn_net_dial(); /* Initiate dialing */ |
1275 | netif_stop_queue(ndev); | 1275 | netif_stop_queue(ndev); |
1276 | return 1; /* let upper layer requeue skb packet */ | 1276 | return NETDEV_TX_BUSY; /* let upper layer requeue skb packet */ |
1277 | } | 1277 | } |
1278 | #endif | 1278 | #endif |
1279 | /* Initiate dialing */ | 1279 | /* Initiate dialing */ |
1280 | spin_unlock_irqrestore(&dev->lock, flags); | 1280 | spin_unlock_irqrestore(&dev->lock, flags); |
1281 | isdn_net_dial(); | 1281 | isdn_net_dial(); |
1282 | isdn_net_device_stop_queue(lp); | 1282 | isdn_net_device_stop_queue(lp); |
1283 | return 1; | 1283 | return NETDEV_TX_BUSY; |
1284 | } else { | 1284 | } else { |
1285 | isdn_net_unreachable(ndev, skb, | 1285 | isdn_net_unreachable(ndev, skb, |
1286 | "No phone number"); | 1286 | "No phone number"); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 1a2222cbb805..b4d4522e5071 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1592,7 +1592,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp) | |||
1592 | int retval, line; | 1592 | int retval, line; |
1593 | 1593 | ||
1594 | line = tty->index; | 1594 | line = tty->index; |
1595 | if (line < 0 || line > ISDN_MAX_CHANNELS) | 1595 | if (line < 0 || line >= ISDN_MAX_CHANNELS) |
1596 | return -ENODEV; | 1596 | return -ENODEV; |
1597 | info = &dev->mdm.info[line]; | 1597 | info = &dev->mdm.info[line]; |
1598 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) | 1598 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) |
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index 9426c9827e47..21d34be5af6a 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c | |||
@@ -214,7 +214,7 @@ get_free_devid(void) | |||
214 | if (!test_and_set_bit(i, (u_long *)&device_ids)) | 214 | if (!test_and_set_bit(i, (u_long *)&device_ids)) |
215 | break; | 215 | break; |
216 | if (i > MAX_DEVICE_ID) | 216 | if (i > MAX_DEVICE_ID) |
217 | return -1; | 217 | return -EBUSY; |
218 | return i; | 218 | return i; |
219 | } | 219 | } |
220 | 220 | ||
@@ -224,10 +224,10 @@ mISDN_register_device(struct mISDNdevice *dev, | |||
224 | { | 224 | { |
225 | int err; | 225 | int err; |
226 | 226 | ||
227 | dev->id = get_free_devid(); | 227 | err = get_free_devid(); |
228 | err = -EBUSY; | 228 | if (err < 0) |
229 | if (dev->id < 0) | ||
230 | goto error1; | 229 | goto error1; |
230 | dev->id = err; | ||
231 | 231 | ||
232 | device_initialize(&dev->dev); | 232 | device_initialize(&dev->dev); |
233 | if (name && name[0]) | 233 | if (name && name[0]) |
diff --git a/drivers/isdn/mISDN/dsp.h b/drivers/isdn/mISDN/dsp.h index 98a33c58f091..18af86879c05 100644 --- a/drivers/isdn/mISDN/dsp.h +++ b/drivers/isdn/mISDN/dsp.h | |||
@@ -112,9 +112,11 @@ struct dsp_conf { | |||
112 | 112 | ||
113 | #define DSP_DTMF_NPOINTS 102 | 113 | #define DSP_DTMF_NPOINTS 102 |
114 | 114 | ||
115 | #define ECHOCAN_BUFLEN (4*128) | 115 | #define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */ |
116 | #define ECHOCAN_BUFF_MASK 0x3ff /* -1 */ | ||
116 | 117 | ||
117 | struct dsp_dtmf { | 118 | struct dsp_dtmf { |
119 | int enable; /* dtmf is enabled */ | ||
118 | int treshold; /* above this is dtmf (square of) */ | 120 | int treshold; /* above this is dtmf (square of) */ |
119 | int software; /* dtmf uses software decoding */ | 121 | int software; /* dtmf uses software decoding */ |
120 | int hardware; /* dtmf uses hardware decoding */ | 122 | int hardware; /* dtmf uses hardware decoding */ |
@@ -123,7 +125,7 @@ struct dsp_dtmf { | |||
123 | /* buffers one full dtmf frame */ | 125 | /* buffers one full dtmf frame */ |
124 | u8 lastwhat, lastdigit; | 126 | u8 lastwhat, lastdigit; |
125 | int count; | 127 | int count; |
126 | u8 digits[16]; /* just the dtmf result */ | 128 | u8 digits[16]; /* dtmf result */ |
127 | }; | 129 | }; |
128 | 130 | ||
129 | 131 | ||
@@ -150,6 +152,15 @@ struct dsp_tone { | |||
150 | struct timer_list tl; | 152 | struct timer_list tl; |
151 | }; | 153 | }; |
152 | 154 | ||
155 | /*************** | ||
156 | * echo stuff * | ||
157 | ***************/ | ||
158 | |||
159 | struct dsp_echo { | ||
160 | int software; /* echo is generated by software */ | ||
161 | int hardware; /* echo is generated by hardware */ | ||
162 | }; | ||
163 | |||
153 | /***************** | 164 | /***************** |
154 | * general stuff * | 165 | * general stuff * |
155 | *****************/ | 166 | *****************/ |
@@ -160,7 +171,7 @@ struct dsp { | |||
160 | struct mISDNchannel *up; | 171 | struct mISDNchannel *up; |
161 | unsigned char name[64]; | 172 | unsigned char name[64]; |
162 | int b_active; | 173 | int b_active; |
163 | int echo; /* echo is enabled */ | 174 | struct dsp_echo echo; |
164 | int rx_disabled; /* what the user wants */ | 175 | int rx_disabled; /* what the user wants */ |
165 | int rx_is_off; /* what the card is */ | 176 | int rx_is_off; /* what the card is */ |
166 | int tx_mix; | 177 | int tx_mix; |
@@ -261,5 +272,5 @@ extern int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg); | |||
261 | extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, | 272 | extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, |
262 | int len); | 273 | int len); |
263 | extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, | 274 | extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, |
264 | int len); | 275 | int len, unsigned int txlen); |
265 | 276 | ||
diff --git a/drivers/isdn/mISDN/dsp_audio.c b/drivers/isdn/mISDN/dsp_audio.c index de3795e3f432..9c7c6451bf3d 100644 --- a/drivers/isdn/mISDN/dsp_audio.c +++ b/drivers/isdn/mISDN/dsp_audio.c | |||
@@ -210,9 +210,8 @@ dsp_audio_generate_seven(void) | |||
210 | j = 0; | 210 | j = 0; |
211 | for (k = 0; k < 256; k++) { | 211 | for (k = 0; k < 256; k++) { |
212 | if (dsp_audio_alaw_to_s32[k] | 212 | if (dsp_audio_alaw_to_s32[k] |
213 | < dsp_audio_alaw_to_s32[i]) { | 213 | < dsp_audio_alaw_to_s32[i]) |
214 | j++; | 214 | j++; |
215 | } | ||
216 | } | 215 | } |
217 | sorted_alaw[j] = i; | 216 | sorted_alaw[j] = i; |
218 | } | 217 | } |
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 58c43e429f73..9c7c0d1ba55f 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c | |||
@@ -163,8 +163,9 @@ dsp_cmx_debug(struct dsp *dsp) | |||
163 | 163 | ||
164 | printk(KERN_DEBUG "-----Current DSP\n"); | 164 | printk(KERN_DEBUG "-----Current DSP\n"); |
165 | list_for_each_entry(odsp, &dsp_ilist, list) { | 165 | list_for_each_entry(odsp, &dsp_ilist, list) { |
166 | printk(KERN_DEBUG "* %s echo=%d txmix=%d", | 166 | printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d", |
167 | odsp->name, odsp->echo, odsp->tx_mix); | 167 | odsp->name, odsp->echo.hardware, odsp->echo.software, |
168 | odsp->tx_mix); | ||
168 | if (odsp->conf) | 169 | if (odsp->conf) |
169 | printk(" (Conf %d)", odsp->conf->id); | 170 | printk(" (Conf %d)", odsp->conf->id); |
170 | if (dsp == odsp) | 171 | if (dsp == odsp) |
@@ -177,10 +178,12 @@ dsp_cmx_debug(struct dsp *dsp) | |||
177 | list_for_each_entry(member, &conf->mlist, list) { | 178 | list_for_each_entry(member, &conf->mlist, list) { |
178 | printk(KERN_DEBUG | 179 | printk(KERN_DEBUG |
179 | " - member = %s (slot_tx %d, bank_tx %d, " | 180 | " - member = %s (slot_tx %d, bank_tx %d, " |
180 | "slot_rx %d, bank_rx %d hfc_conf %d)%s\n", | 181 | "slot_rx %d, bank_rx %d hfc_conf %d " |
182 | "tx_data %d rx_is_off %d)%s\n", | ||
181 | member->dsp->name, member->dsp->pcm_slot_tx, | 183 | member->dsp->name, member->dsp->pcm_slot_tx, |
182 | member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, | 184 | member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx, |
183 | member->dsp->pcm_bank_rx, member->dsp->hfc_conf, | 185 | member->dsp->pcm_bank_rx, member->dsp->hfc_conf, |
186 | member->dsp->tx_data, member->dsp->rx_is_off, | ||
184 | (member->dsp == dsp) ? " *this*" : ""); | 187 | (member->dsp == dsp) ? " *this*" : ""); |
185 | } | 188 | } |
186 | } | 189 | } |
@@ -235,7 +238,7 @@ dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf) | |||
235 | 238 | ||
236 | member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC); | 239 | member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC); |
237 | if (!member) { | 240 | if (!member) { |
238 | printk(KERN_ERR "kmalloc struct dsp_conf_member failed\n"); | 241 | printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n"); |
239 | return -ENOMEM; | 242 | return -ENOMEM; |
240 | } | 243 | } |
241 | member->dsp = dsp; | 244 | member->dsp = dsp; |
@@ -314,7 +317,7 @@ static struct dsp_conf | |||
314 | 317 | ||
315 | conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC); | 318 | conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC); |
316 | if (!conf) { | 319 | if (!conf) { |
317 | printk(KERN_ERR "kmalloc struct dsp_conf failed\n"); | 320 | printk(KERN_ERR "kzalloc struct dsp_conf failed\n"); |
318 | return NULL; | 321 | return NULL; |
319 | } | 322 | } |
320 | INIT_LIST_HEAD(&conf->mlist); | 323 | INIT_LIST_HEAD(&conf->mlist); |
@@ -385,7 +388,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp) | |||
385 | int freeunits[8]; | 388 | int freeunits[8]; |
386 | u_char freeslots[256]; | 389 | u_char freeslots[256]; |
387 | int same_hfc = -1, same_pcm = -1, current_conf = -1, | 390 | int same_hfc = -1, same_pcm = -1, current_conf = -1, |
388 | all_conf = 1; | 391 | all_conf = 1, tx_data = 0; |
389 | 392 | ||
390 | /* dsp gets updated (no conf) */ | 393 | /* dsp gets updated (no conf) */ |
391 | if (!conf) { | 394 | if (!conf) { |
@@ -409,7 +412,7 @@ one_member: | |||
409 | /* process hw echo */ | 412 | /* process hw echo */ |
410 | if (dsp->features.pcm_banks < 1) | 413 | if (dsp->features.pcm_banks < 1) |
411 | return; | 414 | return; |
412 | if (!dsp->echo) { | 415 | if (!dsp->echo.software && !dsp->echo.hardware) { |
413 | /* NO ECHO: remove PCM slot if assigned */ | 416 | /* NO ECHO: remove PCM slot if assigned */ |
414 | if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) { | 417 | if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) { |
415 | if (dsp_debug & DEBUG_DSP_CMX) | 418 | if (dsp_debug & DEBUG_DSP_CMX) |
@@ -427,10 +430,15 @@ one_member: | |||
427 | } | 430 | } |
428 | return; | 431 | return; |
429 | } | 432 | } |
433 | /* echo is enabled, find out if we use soft or hardware */ | ||
434 | dsp->echo.software = dsp->tx_data; | ||
435 | dsp->echo.hardware = 0; | ||
430 | /* ECHO: already echo */ | 436 | /* ECHO: already echo */ |
431 | if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 && | 437 | if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 && |
432 | dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) | 438 | dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) { |
439 | dsp->echo.hardware = 1; | ||
433 | return; | 440 | return; |
441 | } | ||
434 | /* ECHO: if slot already assigned */ | 442 | /* ECHO: if slot already assigned */ |
435 | if (dsp->pcm_slot_tx >= 0) { | 443 | if (dsp->pcm_slot_tx >= 0) { |
436 | dsp->pcm_slot_rx = dsp->pcm_slot_tx; | 444 | dsp->pcm_slot_rx = dsp->pcm_slot_tx; |
@@ -443,6 +451,7 @@ one_member: | |||
443 | dsp->pcm_slot_tx); | 451 | dsp->pcm_slot_tx); |
444 | dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, | 452 | dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, |
445 | dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); | 453 | dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); |
454 | dsp->echo.hardware = 1; | ||
446 | return; | 455 | return; |
447 | } | 456 | } |
448 | /* ECHO: find slot */ | 457 | /* ECHO: find slot */ |
@@ -472,6 +481,7 @@ one_member: | |||
472 | "%s no slot available for echo\n", | 481 | "%s no slot available for echo\n", |
473 | __func__); | 482 | __func__); |
474 | /* no more slots available */ | 483 | /* no more slots available */ |
484 | dsp->echo.software = 1; | ||
475 | return; | 485 | return; |
476 | } | 486 | } |
477 | /* assign free slot */ | 487 | /* assign free slot */ |
@@ -485,6 +495,7 @@ one_member: | |||
485 | __func__, dsp->name, dsp->pcm_slot_tx); | 495 | __func__, dsp->name, dsp->pcm_slot_tx); |
486 | dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, | 496 | dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN, |
487 | dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); | 497 | dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2); |
498 | dsp->echo.hardware = 1; | ||
488 | return; | 499 | return; |
489 | } | 500 | } |
490 | 501 | ||
@@ -554,7 +565,7 @@ conf_software: | |||
554 | return; | 565 | return; |
555 | } | 566 | } |
556 | /* check if member has echo turned on */ | 567 | /* check if member has echo turned on */ |
557 | if (member->dsp->echo) { | 568 | if (member->dsp->echo.hardware || member->dsp->echo.software) { |
558 | if (dsp_debug & DEBUG_DSP_CMX) | 569 | if (dsp_debug & DEBUG_DSP_CMX) |
559 | printk(KERN_DEBUG | 570 | printk(KERN_DEBUG |
560 | "%s dsp %s cannot form a conf, because " | 571 | "%s dsp %s cannot form a conf, because " |
@@ -592,10 +603,9 @@ conf_software: | |||
592 | if (member->dsp->tx_data) { | 603 | if (member->dsp->tx_data) { |
593 | if (dsp_debug & DEBUG_DSP_CMX) | 604 | if (dsp_debug & DEBUG_DSP_CMX) |
594 | printk(KERN_DEBUG | 605 | printk(KERN_DEBUG |
595 | "%s dsp %s cannot form a conf, because " | 606 | "%s dsp %s tx_data is turned on\n", |
596 | "tx_data is turned on\n", | ||
597 | __func__, member->dsp->name); | 607 | __func__, member->dsp->name); |
598 | goto conf_software; | 608 | tx_data = 1; |
599 | } | 609 | } |
600 | /* check if pipeline exists */ | 610 | /* check if pipeline exists */ |
601 | if (member->dsp->pipeline.inuse) { | 611 | if (member->dsp->pipeline.inuse) { |
@@ -794,7 +804,7 @@ conf_software: | |||
794 | nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, | 804 | nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, |
795 | nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); | 805 | nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); |
796 | conf->hardware = 1; | 806 | conf->hardware = 1; |
797 | conf->software = 0; | 807 | conf->software = tx_data; |
798 | return; | 808 | return; |
799 | /* if members have one bank (or on the same chip) */ | 809 | /* if members have one bank (or on the same chip) */ |
800 | } else { | 810 | } else { |
@@ -904,7 +914,7 @@ conf_software: | |||
904 | nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, | 914 | nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx, |
905 | nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); | 915 | nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx); |
906 | conf->hardware = 1; | 916 | conf->hardware = 1; |
907 | conf->software = 0; | 917 | conf->software = tx_data; |
908 | return; | 918 | return; |
909 | } | 919 | } |
910 | } | 920 | } |
@@ -937,6 +947,10 @@ conf_software: | |||
937 | if (current_conf >= 0) { | 947 | if (current_conf >= 0) { |
938 | join_members: | 948 | join_members: |
939 | list_for_each_entry(member, &conf->mlist, list) { | 949 | list_for_each_entry(member, &conf->mlist, list) { |
950 | /* if no conference engine on our chip, change to | ||
951 | * software */ | ||
952 | if (!member->dsp->features.hfc_conf) | ||
953 | goto conf_software; | ||
940 | /* in case of hdlc, change to software */ | 954 | /* in case of hdlc, change to software */ |
941 | if (member->dsp->hdlc) | 955 | if (member->dsp->hdlc) |
942 | goto conf_software; | 956 | goto conf_software; |
@@ -1295,17 +1309,25 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) | |||
1295 | int r, rr, t, tt, o_r, o_rr; | 1309 | int r, rr, t, tt, o_r, o_rr; |
1296 | int preload = 0; | 1310 | int preload = 0; |
1297 | struct mISDNhead *hh, *thh; | 1311 | struct mISDNhead *hh, *thh; |
1312 | int tx_data_only = 0; | ||
1298 | 1313 | ||
1299 | /* don't process if: */ | 1314 | /* don't process if: */ |
1300 | if (!dsp->b_active) { /* if not active */ | 1315 | if (!dsp->b_active) { /* if not active */ |
1301 | dsp->last_tx = 0; | 1316 | dsp->last_tx = 0; |
1302 | return; | 1317 | return; |
1303 | } | 1318 | } |
1304 | if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */ | 1319 | if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */ |
1320 | dsp->echo.hardware) && /* OR hardware echo */ | ||
1305 | dsp->tx_R == dsp->tx_W && /* AND no tx-data */ | 1321 | dsp->tx_R == dsp->tx_W && /* AND no tx-data */ |
1306 | !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */ | 1322 | !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */ |
1307 | dsp->last_tx = 0; | 1323 | if (!dsp->tx_data) { /* no tx_data for user space required */ |
1308 | return; | 1324 | dsp->last_tx = 0; |
1325 | return; | ||
1326 | } | ||
1327 | if (dsp->conf && dsp->conf->software && dsp->conf->hardware) | ||
1328 | tx_data_only = 1; | ||
1329 | if (dsp->conf->software && dsp->echo.hardware) | ||
1330 | tx_data_only = 1; | ||
1309 | } | 1331 | } |
1310 | 1332 | ||
1311 | #ifdef CMX_DEBUG | 1333 | #ifdef CMX_DEBUG |
@@ -1367,7 +1389,8 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) | |||
1367 | while (r != rr && t != tt) { | 1389 | while (r != rr && t != tt) { |
1368 | #ifdef CMX_TX_DEBUG | 1390 | #ifdef CMX_TX_DEBUG |
1369 | if (strlen(debugbuf) < 48) | 1391 | if (strlen(debugbuf) < 48) |
1370 | sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]); | 1392 | sprintf(debugbuf+strlen(debugbuf), " %02x", |
1393 | p[t]); | ||
1371 | #endif | 1394 | #endif |
1372 | *d++ = p[t]; /* write tx_buff */ | 1395 | *d++ = p[t]; /* write tx_buff */ |
1373 | t = (t+1) & CMX_BUFF_MASK; | 1396 | t = (t+1) & CMX_BUFF_MASK; |
@@ -1388,7 +1411,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) | |||
1388 | /* PROCESS DATA (one member / no conf) */ | 1411 | /* PROCESS DATA (one member / no conf) */ |
1389 | if (!conf || members <= 1) { | 1412 | if (!conf || members <= 1) { |
1390 | /* -> if echo is NOT enabled */ | 1413 | /* -> if echo is NOT enabled */ |
1391 | if (!dsp->echo) { | 1414 | if (!dsp->echo.software) { |
1392 | /* -> send tx-data if available or use 0-volume */ | 1415 | /* -> send tx-data if available or use 0-volume */ |
1393 | while (r != rr && t != tt) { | 1416 | while (r != rr && t != tt) { |
1394 | *d++ = p[t]; /* write tx_buff */ | 1417 | *d++ = p[t]; /* write tx_buff */ |
@@ -1438,7 +1461,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) | |||
1438 | o_r = (o_rr - rr + r) & CMX_BUFF_MASK; | 1461 | o_r = (o_rr - rr + r) & CMX_BUFF_MASK; |
1439 | /* start rx-pointer at current read position*/ | 1462 | /* start rx-pointer at current read position*/ |
1440 | /* -> if echo is NOT enabled */ | 1463 | /* -> if echo is NOT enabled */ |
1441 | if (!dsp->echo) { | 1464 | if (!dsp->echo.software) { |
1442 | /* | 1465 | /* |
1443 | * -> copy other member's rx-data, | 1466 | * -> copy other member's rx-data, |
1444 | * if tx-data is available, mix | 1467 | * if tx-data is available, mix |
@@ -1486,7 +1509,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members) | |||
1486 | #endif | 1509 | #endif |
1487 | /* PROCESS DATA (three or more members) */ | 1510 | /* PROCESS DATA (three or more members) */ |
1488 | /* -> if echo is NOT enabled */ | 1511 | /* -> if echo is NOT enabled */ |
1489 | if (!dsp->echo) { | 1512 | if (!dsp->echo.software) { |
1490 | /* | 1513 | /* |
1491 | * -> substract rx-data from conf-data, | 1514 | * -> substract rx-data from conf-data, |
1492 | * if tx-data is available, mix | 1515 | * if tx-data is available, mix |
@@ -1550,27 +1573,40 @@ send_packet: | |||
1550 | * becuase we want what we send, not what we filtered | 1573 | * becuase we want what we send, not what we filtered |
1551 | */ | 1574 | */ |
1552 | if (dsp->tx_data) { | 1575 | if (dsp->tx_data) { |
1553 | /* PREPARE RESULT */ | 1576 | if (tx_data_only) { |
1554 | txskb = mI_alloc_skb(len, GFP_ATOMIC); | 1577 | hh->prim = DL_DATA_REQ; |
1555 | if (!txskb) { | 1578 | hh->id = 0; |
1556 | printk(KERN_ERR | 1579 | /* queue and trigger */ |
1557 | "FATAL ERROR in mISDN_dsp.o: " | 1580 | skb_queue_tail(&dsp->sendq, nskb); |
1558 | "cannot alloc %d bytes\n", len); | 1581 | schedule_work(&dsp->workq); |
1582 | /* exit because only tx_data is used */ | ||
1583 | return; | ||
1559 | } else { | 1584 | } else { |
1560 | thh = mISDN_HEAD_P(txskb); | 1585 | txskb = mI_alloc_skb(len, GFP_ATOMIC); |
1561 | thh->prim = DL_DATA_REQ; | 1586 | if (!txskb) { |
1562 | thh->id = 0; | 1587 | printk(KERN_ERR |
1563 | memcpy(skb_put(txskb, len), nskb->data+preload, len); | 1588 | "FATAL ERROR in mISDN_dsp.o: " |
1564 | /* queue (trigger later) */ | 1589 | "cannot alloc %d bytes\n", len); |
1565 | skb_queue_tail(&dsp->sendq, txskb); | 1590 | } else { |
1591 | thh = mISDN_HEAD_P(txskb); | ||
1592 | thh->prim = DL_DATA_REQ; | ||
1593 | thh->id = 0; | ||
1594 | memcpy(skb_put(txskb, len), nskb->data+preload, | ||
1595 | len); | ||
1596 | /* queue (trigger later) */ | ||
1597 | skb_queue_tail(&dsp->sendq, txskb); | ||
1598 | } | ||
1566 | } | 1599 | } |
1567 | } | 1600 | } |
1601 | |||
1602 | /* send data only to card, if we don't just calculated tx_data */ | ||
1568 | /* adjust volume */ | 1603 | /* adjust volume */ |
1569 | if (dsp->tx_volume) | 1604 | if (dsp->tx_volume) |
1570 | dsp_change_volume(nskb, dsp->tx_volume); | 1605 | dsp_change_volume(nskb, dsp->tx_volume); |
1571 | /* pipeline */ | 1606 | /* pipeline */ |
1572 | if (dsp->pipeline.inuse) | 1607 | if (dsp->pipeline.inuse) |
1573 | dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len); | 1608 | dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, |
1609 | nskb->len); | ||
1574 | /* crypt */ | 1610 | /* crypt */ |
1575 | if (dsp->bf_enable) | 1611 | if (dsp->bf_enable) |
1576 | dsp_bf_encrypt(dsp, nskb->data, nskb->len); | 1612 | dsp_bf_encrypt(dsp, nskb->data, nskb->len); |
@@ -1592,7 +1628,8 @@ dsp_cmx_send(void *arg) | |||
1592 | struct dsp_conf_member *member; | 1628 | struct dsp_conf_member *member; |
1593 | struct dsp *dsp; | 1629 | struct dsp *dsp; |
1594 | int mustmix, members; | 1630 | int mustmix, members; |
1595 | s32 mixbuffer[MAX_POLL+100], *c; | 1631 | static s32 mixbuffer[MAX_POLL+100]; |
1632 | s32 *c; | ||
1596 | u8 *p, *q; | 1633 | u8 *p, *q; |
1597 | int r, rr; | 1634 | int r, rr; |
1598 | int jittercheck = 0, delay, i; | 1635 | int jittercheck = 0, delay, i; |
@@ -1890,10 +1927,8 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb) | |||
1890 | 1927 | ||
1891 | /* no conf */ | 1928 | /* no conf */ |
1892 | if (!dsp->conf) { | 1929 | if (!dsp->conf) { |
1893 | /* in case of hardware (echo) */ | 1930 | /* in case of software echo */ |
1894 | if (dsp->pcm_slot_tx >= 0) | 1931 | if (dsp->echo.software) { |
1895 | return; | ||
1896 | if (dsp->echo) { | ||
1897 | nskb = skb_clone(skb, GFP_ATOMIC); | 1932 | nskb = skb_clone(skb, GFP_ATOMIC); |
1898 | if (nskb) { | 1933 | if (nskb) { |
1899 | hh = mISDN_HEAD_P(nskb); | 1934 | hh = mISDN_HEAD_P(nskb); |
@@ -1909,7 +1944,7 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb) | |||
1909 | if (dsp->conf->hardware) | 1944 | if (dsp->conf->hardware) |
1910 | return; | 1945 | return; |
1911 | list_for_each_entry(member, &dsp->conf->mlist, list) { | 1946 | list_for_each_entry(member, &dsp->conf->mlist, list) { |
1912 | if (dsp->echo || member->dsp != dsp) { | 1947 | if (dsp->echo.software || member->dsp != dsp) { |
1913 | nskb = skb_clone(skb, GFP_ATOMIC); | 1948 | nskb = skb_clone(skb, GFP_ATOMIC); |
1914 | if (nskb) { | 1949 | if (nskb) { |
1915 | hh = mISDN_HEAD_P(nskb); | 1950 | hh = mISDN_HEAD_P(nskb); |
diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 47dbfe298b43..77ee2867c8b4 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c | |||
@@ -203,13 +203,13 @@ dsp_rx_off_member(struct dsp *dsp) | |||
203 | else if (dsp->dtmf.software) | 203 | else if (dsp->dtmf.software) |
204 | rx_off = 0; | 204 | rx_off = 0; |
205 | /* echo in software */ | 205 | /* echo in software */ |
206 | else if (dsp->echo && dsp->pcm_slot_tx < 0) | 206 | else if (dsp->echo.software) |
207 | rx_off = 0; | 207 | rx_off = 0; |
208 | /* bridge in software */ | 208 | /* bridge in software */ |
209 | else if (dsp->conf) { | 209 | else if (dsp->conf && dsp->conf->software) |
210 | if (dsp->conf->software) | 210 | rx_off = 0; |
211 | rx_off = 0; | 211 | /* data is not required by user space and not required |
212 | } | 212 | * for echo dtmf detection, soft-echo, soft-bridging */ |
213 | 213 | ||
214 | if (rx_off == dsp->rx_is_off) | 214 | if (rx_off == dsp->rx_is_off) |
215 | return; | 215 | return; |
@@ -280,7 +280,7 @@ dsp_fill_empty(struct dsp *dsp) | |||
280 | static int | 280 | static int |
281 | dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) | 281 | dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) |
282 | { | 282 | { |
283 | struct sk_buff *nskb; | 283 | struct sk_buff *nskb; |
284 | int ret = 0; | 284 | int ret = 0; |
285 | int cont; | 285 | int cont; |
286 | u8 *data; | 286 | u8 *data; |
@@ -306,15 +306,18 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) | |||
306 | "to %d\n", *((int *)data)); | 306 | "to %d\n", *((int *)data)); |
307 | dsp->dtmf.treshold = (*(int *)data) * 10000; | 307 | dsp->dtmf.treshold = (*(int *)data) * 10000; |
308 | } | 308 | } |
309 | dsp->dtmf.enable = 1; | ||
309 | /* init goertzel */ | 310 | /* init goertzel */ |
310 | dsp_dtmf_goertzel_init(dsp); | 311 | dsp_dtmf_goertzel_init(dsp); |
311 | 312 | ||
312 | /* check dtmf hardware */ | 313 | /* check dtmf hardware */ |
313 | dsp_dtmf_hardware(dsp); | 314 | dsp_dtmf_hardware(dsp); |
315 | dsp_rx_off(dsp); | ||
314 | break; | 316 | break; |
315 | case DTMF_TONE_STOP: /* turn off DTMF */ | 317 | case DTMF_TONE_STOP: /* turn off DTMF */ |
316 | if (dsp_debug & DEBUG_DSP_CORE) | 318 | if (dsp_debug & DEBUG_DSP_CORE) |
317 | printk(KERN_DEBUG "%s: stop dtmf\n", __func__); | 319 | printk(KERN_DEBUG "%s: stop dtmf\n", __func__); |
320 | dsp->dtmf.enable = 0; | ||
318 | dsp->dtmf.hardware = 0; | 321 | dsp->dtmf.hardware = 0; |
319 | dsp->dtmf.software = 0; | 322 | dsp->dtmf.software = 0; |
320 | break; | 323 | break; |
@@ -414,7 +417,7 @@ tone_off: | |||
414 | dsp_rx_off(dsp); | 417 | dsp_rx_off(dsp); |
415 | break; | 418 | break; |
416 | case DSP_ECHO_ON: /* enable echo */ | 419 | case DSP_ECHO_ON: /* enable echo */ |
417 | dsp->echo = 1; /* soft echo */ | 420 | dsp->echo.software = 1; /* soft echo */ |
418 | if (dsp_debug & DEBUG_DSP_CORE) | 421 | if (dsp_debug & DEBUG_DSP_CORE) |
419 | printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__); | 422 | printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__); |
420 | dsp_cmx_hardware(dsp->conf, dsp); | 423 | dsp_cmx_hardware(dsp->conf, dsp); |
@@ -423,7 +426,8 @@ tone_off: | |||
423 | dsp_cmx_debug(dsp); | 426 | dsp_cmx_debug(dsp); |
424 | break; | 427 | break; |
425 | case DSP_ECHO_OFF: /* disable echo */ | 428 | case DSP_ECHO_OFF: /* disable echo */ |
426 | dsp->echo = 0; | 429 | dsp->echo.software = 0; |
430 | dsp->echo.hardware = 0; | ||
427 | if (dsp_debug & DEBUG_DSP_CORE) | 431 | if (dsp_debug & DEBUG_DSP_CORE) |
428 | printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__); | 432 | printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__); |
429 | dsp_cmx_hardware(dsp->conf, dsp); | 433 | dsp_cmx_hardware(dsp->conf, dsp); |
@@ -556,7 +560,7 @@ tone_off: | |||
556 | dsp->pipeline.inuse = 1; | 560 | dsp->pipeline.inuse = 1; |
557 | dsp_cmx_hardware(dsp->conf, dsp); | 561 | dsp_cmx_hardware(dsp->conf, dsp); |
558 | ret = dsp_pipeline_build(&dsp->pipeline, | 562 | ret = dsp_pipeline_build(&dsp->pipeline, |
559 | len > 0 ? (char *)data : NULL); | 563 | len > 0 ? data : NULL); |
560 | dsp_cmx_hardware(dsp->conf, dsp); | 564 | dsp_cmx_hardware(dsp->conf, dsp); |
561 | dsp_rx_off(dsp); | 565 | dsp_rx_off(dsp); |
562 | } | 566 | } |
@@ -657,11 +661,10 @@ get_features(struct mISDNchannel *ch) | |||
657 | static int | 661 | static int |
658 | dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | 662 | dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) |
659 | { | 663 | { |
660 | struct dsp *dsp = container_of(ch, struct dsp, ch); | 664 | struct dsp *dsp = container_of(ch, struct dsp, ch); |
661 | struct mISDNhead *hh; | 665 | struct mISDNhead *hh; |
662 | int ret = 0; | 666 | int ret = 0; |
663 | u8 *digits; | 667 | u8 *digits = NULL; |
664 | int cont; | ||
665 | u_long flags; | 668 | u_long flags; |
666 | 669 | ||
667 | hh = mISDN_HEAD_P(skb); | 670 | hh = mISDN_HEAD_P(skb); |
@@ -704,50 +707,55 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | |||
704 | break; | 707 | break; |
705 | } | 708 | } |
706 | 709 | ||
710 | spin_lock_irqsave(&dsp_lock, flags); | ||
711 | |||
707 | /* decrypt if enabled */ | 712 | /* decrypt if enabled */ |
708 | if (dsp->bf_enable) | 713 | if (dsp->bf_enable) |
709 | dsp_bf_decrypt(dsp, skb->data, skb->len); | 714 | dsp_bf_decrypt(dsp, skb->data, skb->len); |
710 | /* pipeline */ | 715 | /* pipeline */ |
711 | if (dsp->pipeline.inuse) | 716 | if (dsp->pipeline.inuse) |
712 | dsp_pipeline_process_rx(&dsp->pipeline, skb->data, | 717 | dsp_pipeline_process_rx(&dsp->pipeline, skb->data, |
713 | skb->len); | 718 | skb->len, hh->id); |
714 | /* change volume if requested */ | 719 | /* change volume if requested */ |
715 | if (dsp->rx_volume) | 720 | if (dsp->rx_volume) |
716 | dsp_change_volume(skb, dsp->rx_volume); | 721 | dsp_change_volume(skb, dsp->rx_volume); |
717 | |||
718 | /* check if dtmf soft decoding is turned on */ | 722 | /* check if dtmf soft decoding is turned on */ |
719 | if (dsp->dtmf.software) { | 723 | if (dsp->dtmf.software) { |
720 | digits = dsp_dtmf_goertzel_decode(dsp, skb->data, | 724 | digits = dsp_dtmf_goertzel_decode(dsp, skb->data, |
721 | skb->len, (dsp_options&DSP_OPT_ULAW)?1:0); | 725 | skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0); |
726 | } | ||
727 | /* we need to process receive data if software */ | ||
728 | if (dsp->conf && dsp->conf->software) { | ||
729 | /* process data from card at cmx */ | ||
730 | dsp_cmx_receive(dsp, skb); | ||
731 | } | ||
732 | |||
733 | spin_unlock_irqrestore(&dsp_lock, flags); | ||
734 | |||
735 | /* send dtmf result, if any */ | ||
736 | if (digits) { | ||
722 | while (*digits) { | 737 | while (*digits) { |
738 | int k; | ||
723 | struct sk_buff *nskb; | 739 | struct sk_buff *nskb; |
724 | if (dsp_debug & DEBUG_DSP_DTMF) | 740 | if (dsp_debug & DEBUG_DSP_DTMF) |
725 | printk(KERN_DEBUG "%s: digit" | 741 | printk(KERN_DEBUG "%s: digit" |
726 | "(%c) to layer %s\n", | 742 | "(%c) to layer %s\n", |
727 | __func__, *digits, dsp->name); | 743 | __func__, *digits, dsp->name); |
728 | cont = DTMF_TONE_VAL | *digits; | 744 | k = *digits | DTMF_TONE_VAL; |
729 | nskb = _alloc_mISDN_skb(PH_CONTROL_IND, | 745 | nskb = _alloc_mISDN_skb(PH_CONTROL_IND, |
730 | MISDN_ID_ANY, sizeof(int), &cont, | 746 | MISDN_ID_ANY, sizeof(int), &k, |
731 | GFP_ATOMIC); | 747 | GFP_ATOMIC); |
732 | if (nskb) { | 748 | if (nskb) { |
733 | if (dsp->up) { | 749 | if (dsp->up) { |
734 | if (dsp->up->send( | 750 | if (dsp->up->send( |
735 | dsp->up, nskb)) | 751 | dsp->up, nskb)) |
736 | dev_kfree_skb(nskb); | 752 | dev_kfree_skb(nskb); |
737 | } else | 753 | } else |
738 | dev_kfree_skb(nskb); | 754 | dev_kfree_skb(nskb); |
739 | } | 755 | } |
740 | digits++; | 756 | digits++; |
741 | } | 757 | } |
742 | } | 758 | } |
743 | /* we need to process receive data if software */ | ||
744 | spin_lock_irqsave(&dsp_lock, flags); | ||
745 | if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) { | ||
746 | /* process data from card at cmx */ | ||
747 | dsp_cmx_receive(dsp, skb); | ||
748 | } | ||
749 | spin_unlock_irqrestore(&dsp_lock, flags); | ||
750 | |||
751 | if (dsp->rx_disabled) { | 759 | if (dsp->rx_disabled) { |
752 | /* if receive is not allowed */ | 760 | /* if receive is not allowed */ |
753 | break; | 761 | break; |
@@ -787,7 +795,7 @@ dsp_function(struct mISDNchannel *ch, struct sk_buff *skb) | |||
787 | if (dsp->up) { | 795 | if (dsp->up) { |
788 | if (dsp->up->send( | 796 | if (dsp->up->send( |
789 | dsp->up, nskb)) | 797 | dsp->up, nskb)) |
790 | dev_kfree_skb(nskb); | 798 | dev_kfree_skb(nskb); |
791 | } else | 799 | } else |
792 | dev_kfree_skb(nskb); | 800 | dev_kfree_skb(nskb); |
793 | } | 801 | } |
@@ -946,7 +954,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
946 | int err = 0; | 954 | int err = 0; |
947 | 955 | ||
948 | if (debug & DEBUG_DSP_CTRL) | 956 | if (debug & DEBUG_DSP_CTRL) |
949 | printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd); | 957 | printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd); |
950 | 958 | ||
951 | switch (cmd) { | 959 | switch (cmd) { |
952 | case OPEN_CHANNEL: | 960 | case OPEN_CHANNEL: |
@@ -1169,9 +1177,9 @@ static int dsp_init(void) | |||
1169 | 1177 | ||
1170 | /* init conversion tables */ | 1178 | /* init conversion tables */ |
1171 | dsp_audio_generate_law_tables(); | 1179 | dsp_audio_generate_law_tables(); |
1172 | dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a; | 1180 | dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a; |
1173 | dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32: | 1181 | dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ? |
1174 | dsp_audio_alaw_to_s32; | 1182 | dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32; |
1175 | dsp_audio_generate_s2law_table(); | 1183 | dsp_audio_generate_s2law_table(); |
1176 | dsp_audio_generate_seven(); | 1184 | dsp_audio_generate_seven(); |
1177 | dsp_audio_generate_mix_table(); | 1185 | dsp_audio_generate_mix_table(); |
diff --git a/drivers/isdn/mISDN/dsp_dtmf.c b/drivers/isdn/mISDN/dsp_dtmf.c index efc371c1f0dc..9ae2d33b06f7 100644 --- a/drivers/isdn/mISDN/dsp_dtmf.c +++ b/drivers/isdn/mISDN/dsp_dtmf.c | |||
@@ -51,6 +51,9 @@ void dsp_dtmf_hardware(struct dsp *dsp) | |||
51 | { | 51 | { |
52 | int hardware = 1; | 52 | int hardware = 1; |
53 | 53 | ||
54 | if (!dsp->dtmf.enable) | ||
55 | return; | ||
56 | |||
54 | if (!dsp->features.hfc_dtmf) | 57 | if (!dsp->features.hfc_dtmf) |
55 | hardware = 0; | 58 | hardware = 0; |
56 | 59 | ||
diff --git a/drivers/isdn/mISDN/dsp_ecdis.h b/drivers/isdn/mISDN/dsp_ecdis.h index 8a20af43308b..21dbd153ee26 100644 --- a/drivers/isdn/mISDN/dsp_ecdis.h +++ b/drivers/isdn/mISDN/dsp_ecdis.h | |||
@@ -91,7 +91,7 @@ int16_t amp) | |||
91 | && det->tone_cycle_duration <= 475*8) { | 91 | && det->tone_cycle_duration <= 475*8) { |
92 | det->good_cycles++; | 92 | det->good_cycles++; |
93 | if (det->good_cycles > 2) | 93 | if (det->good_cycles > 2) |
94 | det->hit = TRUE; | 94 | det->hit = TRUE; |
95 | } | 95 | } |
96 | det->tone_cycle_duration = 0; | 96 | det->tone_cycle_duration = 0; |
97 | } | 97 | } |
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c index 18cf87c113e7..e9941678edfa 100644 --- a/drivers/isdn/mISDN/dsp_pipeline.c +++ b/drivers/isdn/mISDN/dsp_pipeline.c | |||
@@ -55,20 +55,19 @@ static ssize_t | |||
55 | attr_show_args(struct device *dev, struct device_attribute *attr, char *buf) | 55 | attr_show_args(struct device *dev, struct device_attribute *attr, char *buf) |
56 | { | 56 | { |
57 | struct mISDN_dsp_element *elem = dev_get_drvdata(dev); | 57 | struct mISDN_dsp_element *elem = dev_get_drvdata(dev); |
58 | ssize_t len = 0; | 58 | int i; |
59 | int i = 0; | 59 | char *p = buf; |
60 | 60 | ||
61 | *buf = 0; | 61 | *buf = 0; |
62 | for (; i < elem->num_args; ++i) | 62 | for (i = 0; i < elem->num_args; i++) |
63 | len = sprintf(buf, "%sName: %s\n%s%s%sDescription: %s\n" | 63 | p += sprintf(p, "Name: %s\n%s%s%sDescription: %s\n\n", |
64 | "\n", buf, | ||
65 | elem->args[i].name, | 64 | elem->args[i].name, |
66 | elem->args[i].def ? "Default: " : "", | 65 | elem->args[i].def ? "Default: " : "", |
67 | elem->args[i].def ? elem->args[i].def : "", | 66 | elem->args[i].def ? elem->args[i].def : "", |
68 | elem->args[i].def ? "\n" : "", | 67 | elem->args[i].def ? "\n" : "", |
69 | elem->args[i].desc); | 68 | elem->args[i].desc); |
70 | 69 | ||
71 | return len; | 70 | return p - buf; |
72 | } | 71 | } |
73 | 72 | ||
74 | static struct device_attribute element_attributes[] = { | 73 | static struct device_attribute element_attributes[] = { |
@@ -347,7 +346,8 @@ void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len) | |||
347 | entry->elem->process_tx(entry->p, data, len); | 346 | entry->elem->process_tx(entry->p, data, len); |
348 | } | 347 | } |
349 | 348 | ||
350 | void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len) | 349 | void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len, |
350 | unsigned int txlen) | ||
351 | { | 351 | { |
352 | struct dsp_pipeline_entry *entry; | 352 | struct dsp_pipeline_entry *entry; |
353 | 353 | ||
@@ -356,7 +356,7 @@ void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len) | |||
356 | 356 | ||
357 | list_for_each_entry_reverse(entry, &pipeline->list, list) | 357 | list_for_each_entry_reverse(entry, &pipeline->list, list) |
358 | if (entry->elem->process_rx) | 358 | if (entry->elem->process_rx) |
359 | entry->elem->process_rx(entry->p, data, len); | 359 | entry->elem->process_rx(entry->p, data, len, txlen); |
360 | } | 360 | } |
361 | 361 | ||
362 | 362 | ||
diff --git a/drivers/isdn/mISDN/dsp_tones.c b/drivers/isdn/mISDN/dsp_tones.c index 7a9af66f4b19..1debf53670de 100644 --- a/drivers/isdn/mISDN/dsp_tones.c +++ b/drivers/isdn/mISDN/dsp_tones.c | |||
@@ -253,18 +253,24 @@ static struct pattern { | |||
253 | {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, | 253 | {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, |
254 | 254 | ||
255 | {TONE_GERMAN_DIALPBX, | 255 | {TONE_GERMAN_DIALPBX, |
256 | {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL}, | 256 | {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, |
257 | {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL}, | 257 | NULL}, |
258 | {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, | ||
259 | NULL}, | ||
258 | {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, | 260 | {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, |
259 | 261 | ||
260 | {TONE_GERMAN_OLDDIALPBX, | 262 | {TONE_GERMAN_OLDDIALPBX, |
261 | {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL}, | 263 | {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, |
262 | {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL}, | 264 | NULL}, |
265 | {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, | ||
266 | NULL}, | ||
263 | {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, | 267 | {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, |
264 | 268 | ||
265 | {TONE_AMERICAN_DIALPBX, | 269 | {TONE_AMERICAN_DIALPBX, |
266 | {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, NULL}, | 270 | {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, |
267 | {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, NULL}, | 271 | NULL}, |
272 | {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, | ||
273 | NULL}, | ||
268 | {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, | 274 | {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} }, |
269 | 275 | ||
270 | {TONE_GERMAN_RINGING, | 276 | {TONE_GERMAN_RINGING, |
@@ -434,7 +440,7 @@ dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len) | |||
434 | 440 | ||
435 | /* unlocking is not required, because we don't expect a response */ | 441 | /* unlocking is not required, because we don't expect a response */ |
436 | nskb = _alloc_mISDN_skb(PH_CONTROL_REQ, | 442 | nskb = _alloc_mISDN_skb(PH_CONTROL_REQ, |
437 | (len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample, | 443 | (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample, |
438 | GFP_ATOMIC); | 444 | GFP_ATOMIC); |
439 | if (nskb) { | 445 | if (nskb) { |
440 | if (dsp->ch.peer) { | 446 | if (dsp->ch.peer) { |
@@ -498,8 +504,7 @@ dsp_tone(struct dsp *dsp, int tone) | |||
498 | 504 | ||
499 | /* we turn off the tone */ | 505 | /* we turn off the tone */ |
500 | if (!tone) { | 506 | if (!tone) { |
501 | if (dsp->features.hfc_loops) | 507 | if (dsp->features.hfc_loops && timer_pending(&tonet->tl)) |
502 | if (timer_pending(&tonet->tl)) | ||
503 | del_timer(&tonet->tl); | 508 | del_timer(&tonet->tl); |
504 | if (dsp->features.hfc_loops) | 509 | if (dsp->features.hfc_loops) |
505 | dsp_tone_hw_message(dsp, NULL, 0); | 510 | dsp_tone_hw_message(dsp, NULL, 0); |
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index ab1168a110ae..0481a0cdf6db 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c | |||
@@ -185,13 +185,13 @@ recv_Echannel(struct dchannel *ech, struct dchannel *dch) | |||
185 | EXPORT_SYMBOL(recv_Echannel); | 185 | EXPORT_SYMBOL(recv_Echannel); |
186 | 186 | ||
187 | void | 187 | void |
188 | recv_Bchannel(struct bchannel *bch) | 188 | recv_Bchannel(struct bchannel *bch, unsigned int id) |
189 | { | 189 | { |
190 | struct mISDNhead *hh; | 190 | struct mISDNhead *hh; |
191 | 191 | ||
192 | hh = mISDN_HEAD_P(bch->rx_skb); | 192 | hh = mISDN_HEAD_P(bch->rx_skb); |
193 | hh->prim = PH_DATA_IND; | 193 | hh->prim = PH_DATA_IND; |
194 | hh->id = MISDN_ID_ANY; | 194 | hh->id = id; |
195 | if (bch->rcount >= 64) { | 195 | if (bch->rcount >= 64) { |
196 | printk(KERN_WARNING "B-channel %p receive queue overflow, " | 196 | printk(KERN_WARNING "B-channel %p receive queue overflow, " |
197 | "fushing!\n", bch); | 197 | "fushing!\n", bch); |
diff --git a/drivers/isdn/mISDN/l1oip.h b/drivers/isdn/mISDN/l1oip.h index a23d575449f6..bc26c890d9a2 100644 --- a/drivers/isdn/mISDN/l1oip.h +++ b/drivers/isdn/mISDN/l1oip.h | |||
@@ -76,7 +76,7 @@ struct l1oip { | |||
76 | struct sockaddr_in sin_local; /* local socket name */ | 76 | struct sockaddr_in sin_local; /* local socket name */ |
77 | struct sockaddr_in sin_remote; /* remote socket name */ | 77 | struct sockaddr_in sin_remote; /* remote socket name */ |
78 | struct msghdr sendmsg; /* ip message to send */ | 78 | struct msghdr sendmsg; /* ip message to send */ |
79 | struct iovec sendiov; /* iov for message */ | 79 | struct kvec sendiov; /* iov for message */ |
80 | 80 | ||
81 | /* frame */ | 81 | /* frame */ |
82 | struct l1oip_chan chan[128]; /* channel instances */ | 82 | struct l1oip_chan chan[128]; /* channel instances */ |
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c index e4ecba3d48df..bbfd1b863ed3 100644 --- a/drivers/isdn/mISDN/l1oip_codec.c +++ b/drivers/isdn/mISDN/l1oip_codec.c | |||
@@ -48,6 +48,7 @@ NOTE: The bytes are handled as they are law-encoded. | |||
48 | 48 | ||
49 | #include <linux/vmalloc.h> | 49 | #include <linux/vmalloc.h> |
50 | #include <linux/mISDNif.h> | 50 | #include <linux/mISDNif.h> |
51 | #include <linux/in.h> | ||
51 | #include "core.h" | 52 | #include "core.h" |
52 | #include "l1oip.h" | 53 | #include "l1oip.h" |
53 | 54 | ||
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index abe574989572..990e6a7e6674 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -279,7 +279,6 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, | |||
279 | int multi = 0; | 279 | int multi = 0; |
280 | u8 frame[len+32]; | 280 | u8 frame[len+32]; |
281 | struct socket *socket = NULL; | 281 | struct socket *socket = NULL; |
282 | mm_segment_t oldfs; | ||
283 | 282 | ||
284 | if (debug & DEBUG_L1OIP_MSG) | 283 | if (debug & DEBUG_L1OIP_MSG) |
285 | printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n", | 284 | printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n", |
@@ -308,8 +307,8 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, | |||
308 | 307 | ||
309 | /* assemble frame */ | 308 | /* assemble frame */ |
310 | *p++ = (L1OIP_VERSION<<6) /* version and coding */ | 309 | *p++ = (L1OIP_VERSION<<6) /* version and coding */ |
311 | | (hc->pri?0x20:0x00) /* type */ | 310 | | (hc->pri ? 0x20 : 0x00) /* type */ |
312 | | (hc->id?0x10:0x00) /* id */ | 311 | | (hc->id ? 0x10 : 0x00) /* id */ |
313 | | localcodec; | 312 | | localcodec; |
314 | if (hc->id) { | 313 | if (hc->id) { |
315 | *p++ = hc->id>>24; /* id */ | 314 | *p++ = hc->id>>24; /* id */ |
@@ -317,7 +316,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, | |||
317 | *p++ = hc->id>>8; | 316 | *p++ = hc->id>>8; |
318 | *p++ = hc->id; | 317 | *p++ = hc->id; |
319 | } | 318 | } |
320 | *p++ = (multi == 1)?0x80:0x00 + channel; /* m-flag, channel */ | 319 | *p++ = (multi == 1) ? 0x80 : 0x00 + channel; /* m-flag, channel */ |
321 | if (multi == 1) | 320 | if (multi == 1) |
322 | *p++ = len; /* length */ | 321 | *p++ = len; /* length */ |
323 | *p++ = timebase>>8; /* time base */ | 322 | *p++ = timebase>>8; /* time base */ |
@@ -352,10 +351,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, | |||
352 | "= %d)\n", __func__, len); | 351 | "= %d)\n", __func__, len); |
353 | hc->sendiov.iov_base = frame; | 352 | hc->sendiov.iov_base = frame; |
354 | hc->sendiov.iov_len = len; | 353 | hc->sendiov.iov_len = len; |
355 | oldfs = get_fs(); | 354 | len = kernel_sendmsg(socket, &hc->sendmsg, &hc->sendiov, 1, len); |
356 | set_fs(KERNEL_DS); | ||
357 | len = sock_sendmsg(socket, &hc->sendmsg, len); | ||
358 | set_fs(oldfs); | ||
359 | /* give socket back */ | 355 | /* give socket back */ |
360 | hc->socket = socket; /* no locking required */ | 356 | hc->socket = socket; /* no locking required */ |
361 | 357 | ||
@@ -401,12 +397,12 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase, | |||
401 | } | 397 | } |
402 | 398 | ||
403 | /* prepare message */ | 399 | /* prepare message */ |
404 | nskb = mI_alloc_skb((remotecodec == 3)?(len<<1):len, GFP_ATOMIC); | 400 | nskb = mI_alloc_skb((remotecodec == 3) ? (len<<1) : len, GFP_ATOMIC); |
405 | if (!nskb) { | 401 | if (!nskb) { |
406 | printk(KERN_ERR "%s: No mem for skb.\n", __func__); | 402 | printk(KERN_ERR "%s: No mem for skb.\n", __func__); |
407 | return; | 403 | return; |
408 | } | 404 | } |
409 | p = skb_put(nskb, (remotecodec == 3)?(len<<1):len); | 405 | p = skb_put(nskb, (remotecodec == 3) ? (len<<1) : len); |
410 | 406 | ||
411 | if (remotecodec == 1 && ulaw) | 407 | if (remotecodec == 1 && ulaw) |
412 | l1oip_alaw_to_ulaw(buf, len, p); | 408 | l1oip_alaw_to_ulaw(buf, len, p); |
@@ -458,7 +454,7 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase, | |||
458 | hc->chan[channel].disorder_flag ^= 1; | 454 | hc->chan[channel].disorder_flag ^= 1; |
459 | if (nskb) | 455 | if (nskb) |
460 | #endif | 456 | #endif |
461 | queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb); | 457 | queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb); |
462 | } | 458 | } |
463 | } | 459 | } |
464 | 460 | ||
@@ -660,21 +656,29 @@ l1oip_socket_thread(void *data) | |||
660 | struct l1oip *hc = (struct l1oip *)data; | 656 | struct l1oip *hc = (struct l1oip *)data; |
661 | int ret = 0; | 657 | int ret = 0; |
662 | struct msghdr msg; | 658 | struct msghdr msg; |
663 | struct iovec iov; | ||
664 | mm_segment_t oldfs; | ||
665 | struct sockaddr_in sin_rx; | 659 | struct sockaddr_in sin_rx; |
666 | unsigned char recvbuf[1500]; | 660 | unsigned char *recvbuf; |
661 | size_t recvbuf_size = 1500; | ||
667 | int recvlen; | 662 | int recvlen; |
668 | struct socket *socket = NULL; | 663 | struct socket *socket = NULL; |
669 | DECLARE_COMPLETION(wait); | 664 | DECLARE_COMPLETION(wait); |
670 | 665 | ||
666 | /* allocate buffer memory */ | ||
667 | recvbuf = kmalloc(recvbuf_size, GFP_KERNEL); | ||
668 | if (!recvbuf) { | ||
669 | printk(KERN_ERR "%s: Failed to alloc recvbuf.\n", __func__); | ||
670 | ret = -ENOMEM; | ||
671 | goto fail; | ||
672 | } | ||
673 | |||
671 | /* make daemon */ | 674 | /* make daemon */ |
672 | allow_signal(SIGTERM); | 675 | allow_signal(SIGTERM); |
673 | 676 | ||
674 | /* create socket */ | 677 | /* create socket */ |
675 | if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) { | 678 | if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) { |
676 | printk(KERN_ERR "%s: Failed to create socket.\n", __func__); | 679 | printk(KERN_ERR "%s: Failed to create socket.\n", __func__); |
677 | return -EIO; | 680 | ret = -EIO; |
681 | goto fail; | ||
678 | } | 682 | } |
679 | 683 | ||
680 | /* set incoming address */ | 684 | /* set incoming address */ |
@@ -708,16 +712,12 @@ l1oip_socket_thread(void *data) | |||
708 | msg.msg_namelen = sizeof(sin_rx); | 712 | msg.msg_namelen = sizeof(sin_rx); |
709 | msg.msg_control = NULL; | 713 | msg.msg_control = NULL; |
710 | msg.msg_controllen = 0; | 714 | msg.msg_controllen = 0; |
711 | msg.msg_iov = &iov; | ||
712 | msg.msg_iovlen = 1; | ||
713 | 715 | ||
714 | /* build send message */ | 716 | /* build send message */ |
715 | hc->sendmsg.msg_name = &hc->sin_remote; | 717 | hc->sendmsg.msg_name = &hc->sin_remote; |
716 | hc->sendmsg.msg_namelen = sizeof(hc->sin_remote); | 718 | hc->sendmsg.msg_namelen = sizeof(hc->sin_remote); |
717 | hc->sendmsg.msg_control = NULL; | 719 | hc->sendmsg.msg_control = NULL; |
718 | hc->sendmsg.msg_controllen = 0; | 720 | hc->sendmsg.msg_controllen = 0; |
719 | hc->sendmsg.msg_iov = &hc->sendiov; | ||
720 | hc->sendmsg.msg_iovlen = 1; | ||
721 | 721 | ||
722 | /* give away socket */ | 722 | /* give away socket */ |
723 | spin_lock(&hc->socket_lock); | 723 | spin_lock(&hc->socket_lock); |
@@ -729,18 +729,18 @@ l1oip_socket_thread(void *data) | |||
729 | printk(KERN_DEBUG "%s: socket created and open\n", | 729 | printk(KERN_DEBUG "%s: socket created and open\n", |
730 | __func__); | 730 | __func__); |
731 | while (!signal_pending(current)) { | 731 | while (!signal_pending(current)) { |
732 | iov.iov_base = recvbuf; | 732 | struct kvec iov = { |
733 | iov.iov_len = sizeof(recvbuf); | 733 | .iov_base = recvbuf, |
734 | oldfs = get_fs(); | 734 | .iov_len = sizeof(recvbuf), |
735 | set_fs(KERNEL_DS); | 735 | }; |
736 | recvlen = sock_recvmsg(socket, &msg, sizeof(recvbuf), 0); | 736 | recvlen = kernel_recvmsg(socket, &msg, &iov, 1, |
737 | set_fs(oldfs); | 737 | sizeof(recvbuf), 0); |
738 | if (recvlen > 0) { | 738 | if (recvlen > 0) { |
739 | l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen); | 739 | l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen); |
740 | } else { | 740 | } else { |
741 | if (debug & DEBUG_L1OIP_SOCKET) | 741 | if (debug & DEBUG_L1OIP_SOCKET) |
742 | printk(KERN_WARNING "%s: broken pipe on socket\n", | 742 | printk(KERN_WARNING |
743 | __func__); | 743 | "%s: broken pipe on socket\n", __func__); |
744 | } | 744 | } |
745 | } | 745 | } |
746 | 746 | ||
@@ -760,6 +760,9 @@ l1oip_socket_thread(void *data) | |||
760 | __func__); | 760 | __func__); |
761 | 761 | ||
762 | fail: | 762 | fail: |
763 | /* free recvbuf */ | ||
764 | kfree(recvbuf); | ||
765 | |||
763 | /* close socket */ | 766 | /* close socket */ |
764 | if (socket) | 767 | if (socket) |
765 | sock_release(socket); | 768 | sock_release(socket); |
@@ -912,7 +915,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
912 | p = skb->data; | 915 | p = skb->data; |
913 | l = skb->len; | 916 | l = skb->len; |
914 | while (l) { | 917 | while (l) { |
915 | ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME; | 918 | ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME; |
916 | l1oip_socket_send(hc, 0, dch->slot, 0, | 919 | l1oip_socket_send(hc, 0, dch->slot, 0, |
917 | hc->chan[dch->slot].tx_counter++, p, ll); | 920 | hc->chan[dch->slot].tx_counter++, p, ll); |
918 | p += ll; | 921 | p += ll; |
@@ -1160,7 +1163,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) | |||
1160 | p = skb->data; | 1163 | p = skb->data; |
1161 | l = skb->len; | 1164 | l = skb->len; |
1162 | while (l) { | 1165 | while (l) { |
1163 | ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME; | 1166 | ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME; |
1164 | l1oip_socket_send(hc, hc->codec, bch->slot, 0, | 1167 | l1oip_socket_send(hc, hc->codec, bch->slot, 0, |
1165 | hc->chan[bch->slot].tx_counter, p, ll); | 1168 | hc->chan[bch->slot].tx_counter, p, ll); |
1166 | hc->chan[bch->slot].tx_counter += ll; | 1169 | hc->chan[bch->slot].tx_counter += ll; |
@@ -1318,8 +1321,8 @@ init_card(struct l1oip *hc, int pri, int bundle) | |||
1318 | spin_lock_init(&hc->socket_lock); | 1321 | spin_lock_init(&hc->socket_lock); |
1319 | hc->idx = l1oip_cnt; | 1322 | hc->idx = l1oip_cnt; |
1320 | hc->pri = pri; | 1323 | hc->pri = pri; |
1321 | hc->d_idx = pri?16:3; | 1324 | hc->d_idx = pri ? 16 : 3; |
1322 | hc->b_num = pri?30:2; | 1325 | hc->b_num = pri ? 30 : 2; |
1323 | hc->bundle = bundle; | 1326 | hc->bundle = bundle; |
1324 | if (hc->pri) | 1327 | if (hc->pri) |
1325 | sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1); | 1328 | sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1); |
@@ -1504,9 +1507,9 @@ l1oip_init(void) | |||
1504 | 1507 | ||
1505 | if (debug & DEBUG_L1OIP_INIT) | 1508 | if (debug & DEBUG_L1OIP_INIT) |
1506 | printk(KERN_DEBUG "%s: interface %d is %s with %s.\n", | 1509 | printk(KERN_DEBUG "%s: interface %d is %s with %s.\n", |
1507 | __func__, l1oip_cnt, pri?"PRI":"BRI", | 1510 | __func__, l1oip_cnt, pri ? "PRI" : "BRI", |
1508 | bundle?"bundled IP packet for all B-channels" | 1511 | bundle ? "bundled IP packet for all B-channels" : |
1509 | :"seperate IP packets for every B-channel"); | 1512 | "seperate IP packets for every B-channel"); |
1510 | 1513 | ||
1511 | hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); | 1514 | hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); |
1512 | if (!hc) { | 1515 | if (!hc) { |
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index d6e2863f224a..9c2589e986d6 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c | |||
@@ -99,7 +99,7 @@ l2m_debug(struct FsmInst *fi, char *fmt, ...) | |||
99 | if (!(*debug & DEBUG_L2_FSM)) | 99 | if (!(*debug & DEBUG_L2_FSM)) |
100 | return; | 100 | return; |
101 | va_start(va, fmt); | 101 | va_start(va, fmt); |
102 | printk(KERN_DEBUG "l2 (tei %d): ", l2->tei); | 102 | printk(KERN_DEBUG "l2 (sapi %d tei %d): ", l2->sapi, l2->tei); |
103 | vprintk(fmt, va); | 103 | vprintk(fmt, va); |
104 | printk("\n"); | 104 | printk("\n"); |
105 | va_end(va); | 105 | va_end(va); |
@@ -1859,20 +1859,18 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb) | |||
1859 | psapi >>= 2; | 1859 | psapi >>= 2; |
1860 | ptei >>= 1; | 1860 | ptei >>= 1; |
1861 | if (psapi != l2->sapi) { | 1861 | if (psapi != l2->sapi) { |
1862 | /* not our bussiness | 1862 | /* not our bussiness */ |
1863 | * printk(KERN_DEBUG "%s: sapi %d/%d sapi mismatch\n", | 1863 | if (*debug & DEBUG_L2) |
1864 | * __func__, | 1864 | printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n", |
1865 | * psapi, l2->sapi); | 1865 | __func__, psapi, l2->sapi); |
1866 | */ | ||
1867 | dev_kfree_skb(skb); | 1866 | dev_kfree_skb(skb); |
1868 | return 0; | 1867 | return 0; |
1869 | } | 1868 | } |
1870 | if ((ptei != l2->tei) && (ptei != GROUP_TEI)) { | 1869 | if ((ptei != l2->tei) && (ptei != GROUP_TEI)) { |
1871 | /* not our bussiness | 1870 | /* not our bussiness */ |
1872 | * printk(KERN_DEBUG "%s: tei %d/%d sapi %d mismatch\n", | 1871 | if (*debug & DEBUG_L2) |
1873 | * __func__, | 1872 | printk(KERN_DEBUG "%s: tei %d/%d mismatch\n", |
1874 | * ptei, l2->tei, psapi); | 1873 | __func__, ptei, l2->tei); |
1875 | */ | ||
1876 | dev_kfree_skb(skb); | 1874 | dev_kfree_skb(skb); |
1877 | return 0; | 1875 | return 0; |
1878 | } | 1876 | } |
@@ -1927,8 +1925,8 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb) | |||
1927 | int ret = -EINVAL; | 1925 | int ret = -EINVAL; |
1928 | 1926 | ||
1929 | if (*debug & DEBUG_L2_RECV) | 1927 | if (*debug & DEBUG_L2_RECV) |
1930 | printk(KERN_DEBUG "%s: prim(%x) id(%x) tei(%d)\n", | 1928 | printk(KERN_DEBUG "%s: prim(%x) id(%x) sapi(%d) tei(%d)\n", |
1931 | __func__, hh->prim, hh->id, l2->tei); | 1929 | __func__, hh->prim, hh->id, l2->sapi, l2->tei); |
1932 | switch (hh->prim) { | 1930 | switch (hh->prim) { |
1933 | case PH_DATA_IND: | 1931 | case PH_DATA_IND: |
1934 | ret = ph_data_indication(l2, hh, skb); | 1932 | ret = ph_data_indication(l2, hh, skb); |
@@ -2068,7 +2066,8 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg) | |||
2068 | } | 2066 | } |
2069 | 2067 | ||
2070 | struct layer2 * | 2068 | struct layer2 * |
2071 | create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | 2069 | create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei, |
2070 | int sapi) | ||
2072 | { | 2071 | { |
2073 | struct layer2 *l2; | 2072 | struct layer2 *l2; |
2074 | struct channel_req rq; | 2073 | struct channel_req rq; |
@@ -2089,7 +2088,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2089 | test_and_set_bit(FLG_LAPD, &l2->flag); | 2088 | test_and_set_bit(FLG_LAPD, &l2->flag); |
2090 | test_and_set_bit(FLG_LAPD_NET, &l2->flag); | 2089 | test_and_set_bit(FLG_LAPD_NET, &l2->flag); |
2091 | test_and_set_bit(FLG_MOD128, &l2->flag); | 2090 | test_and_set_bit(FLG_MOD128, &l2->flag); |
2092 | l2->sapi = 0; | 2091 | l2->sapi = sapi; |
2093 | l2->maxlen = MAX_DFRAME_LEN; | 2092 | l2->maxlen = MAX_DFRAME_LEN; |
2094 | if (test_bit(OPTION_L2_PMX, &options)) | 2093 | if (test_bit(OPTION_L2_PMX, &options)) |
2095 | l2->window = 7; | 2094 | l2->window = 7; |
@@ -2099,7 +2098,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2099 | test_and_set_bit(FLG_PTP, &l2->flag); | 2098 | test_and_set_bit(FLG_PTP, &l2->flag); |
2100 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) | 2099 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) |
2101 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); | 2100 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); |
2102 | l2->tei = (u_int)arg; | 2101 | l2->tei = tei; |
2103 | l2->T200 = 1000; | 2102 | l2->T200 = 1000; |
2104 | l2->N200 = 3; | 2103 | l2->N200 = 3; |
2105 | l2->T203 = 10000; | 2104 | l2->T203 = 10000; |
@@ -2114,7 +2113,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2114 | test_and_set_bit(FLG_LAPD, &l2->flag); | 2113 | test_and_set_bit(FLG_LAPD, &l2->flag); |
2115 | test_and_set_bit(FLG_MOD128, &l2->flag); | 2114 | test_and_set_bit(FLG_MOD128, &l2->flag); |
2116 | test_and_set_bit(FLG_ORIG, &l2->flag); | 2115 | test_and_set_bit(FLG_ORIG, &l2->flag); |
2117 | l2->sapi = 0; | 2116 | l2->sapi = sapi; |
2118 | l2->maxlen = MAX_DFRAME_LEN; | 2117 | l2->maxlen = MAX_DFRAME_LEN; |
2119 | if (test_bit(OPTION_L2_PMX, &options)) | 2118 | if (test_bit(OPTION_L2_PMX, &options)) |
2120 | l2->window = 7; | 2119 | l2->window = 7; |
@@ -2124,7 +2123,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg) | |||
2124 | test_and_set_bit(FLG_PTP, &l2->flag); | 2123 | test_and_set_bit(FLG_PTP, &l2->flag); |
2125 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) | 2124 | if (test_bit(OPTION_L2_FIXEDTEI, &options)) |
2126 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); | 2125 | test_and_set_bit(FLG_FIXED_TEI, &l2->flag); |
2127 | l2->tei = (u_int)arg; | 2126 | l2->tei = tei; |
2128 | l2->T200 = 1000; | 2127 | l2->T200 = 1000; |
2129 | l2->N200 = 3; | 2128 | l2->N200 = 3; |
2130 | l2->T203 = 10000; | 2129 | l2->T203 = 10000; |
@@ -2180,7 +2179,7 @@ x75create(struct channel_req *crq) | |||
2180 | 2179 | ||
2181 | if (crq->protocol != ISDN_P_B_X75SLP) | 2180 | if (crq->protocol != ISDN_P_B_X75SLP) |
2182 | return -EPROTONOSUPPORT; | 2181 | return -EPROTONOSUPPORT; |
2183 | l2 = create_l2(crq->ch, crq->protocol, 0, 0); | 2182 | l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0); |
2184 | if (!l2) | 2183 | if (!l2) |
2185 | return -ENOMEM; | 2184 | return -ENOMEM; |
2186 | crq->ch = &l2->ch; | 2185 | crq->ch = &l2->ch; |
diff --git a/drivers/isdn/mISDN/layer2.h b/drivers/isdn/mISDN/layer2.h index 6293f80dc2d3..9547fb3707a3 100644 --- a/drivers/isdn/mISDN/layer2.h +++ b/drivers/isdn/mISDN/layer2.h | |||
@@ -90,7 +90,7 @@ enum { | |||
90 | #define L2_STATE_COUNT (ST_L2_8+1) | 90 | #define L2_STATE_COUNT (ST_L2_8+1) |
91 | 91 | ||
92 | extern struct layer2 *create_l2(struct mISDNchannel *, u_int, | 92 | extern struct layer2 *create_l2(struct mISDNchannel *, u_int, |
93 | u_long, u_long); | 93 | u_long, int, int); |
94 | extern int tei_l2(struct layer2 *, u_int, u_long arg); | 94 | extern int tei_l2(struct layer2 *, u_int, u_long arg); |
95 | 95 | ||
96 | 96 | ||
diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index 508945d1b9c1..c36f52137456 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c | |||
@@ -209,7 +209,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
209 | 209 | ||
210 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { | 210 | if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { |
211 | err = -EFAULT; | 211 | err = -EFAULT; |
212 | goto drop; | 212 | goto done; |
213 | } | 213 | } |
214 | 214 | ||
215 | memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN); | 215 | memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN); |
@@ -222,7 +222,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
222 | } else { /* use default for L2 messages */ | 222 | } else { /* use default for L2 messages */ |
223 | if ((sk->sk_protocol == ISDN_P_LAPD_TE) || | 223 | if ((sk->sk_protocol == ISDN_P_LAPD_TE) || |
224 | (sk->sk_protocol == ISDN_P_LAPD_NT)) | 224 | (sk->sk_protocol == ISDN_P_LAPD_NT)) |
225 | mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr; | 225 | mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr; |
226 | } | 226 | } |
227 | 227 | ||
228 | if (*debug & DEBUG_SOCKET) | 228 | if (*debug & DEBUG_SOCKET) |
@@ -230,19 +230,21 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
230 | __func__, mISDN_HEAD_ID(skb)); | 230 | __func__, mISDN_HEAD_ID(skb)); |
231 | 231 | ||
232 | err = -ENODEV; | 232 | err = -ENODEV; |
233 | if (!_pms(sk)->ch.peer || | 233 | if (!_pms(sk)->ch.peer) |
234 | (err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb))) | 234 | goto done; |
235 | goto drop; | 235 | err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb); |
236 | 236 | if (err) | |
237 | err = len; | 237 | goto done; |
238 | else { | ||
239 | skb = NULL; | ||
240 | err = len; | ||
241 | } | ||
238 | 242 | ||
239 | done: | 243 | done: |
244 | if (skb) | ||
245 | kfree_skb(skb); | ||
240 | release_sock(sk); | 246 | release_sock(sk); |
241 | return err; | 247 | return err; |
242 | |||
243 | drop: | ||
244 | kfree_skb(skb); | ||
245 | goto done; | ||
246 | } | 248 | } |
247 | 249 | ||
248 | static int | 250 | static int |
@@ -292,7 +294,7 @@ static int | |||
292 | data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) | 294 | data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) |
293 | { | 295 | { |
294 | struct mISDN_ctrl_req cq; | 296 | struct mISDN_ctrl_req cq; |
295 | int err = -EINVAL, val; | 297 | int err = -EINVAL, val[2]; |
296 | struct mISDNchannel *bchan, *next; | 298 | struct mISDNchannel *bchan, *next; |
297 | 299 | ||
298 | lock_sock(sk); | 300 | lock_sock(sk); |
@@ -328,12 +330,27 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p) | |||
328 | err = -EINVAL; | 330 | err = -EINVAL; |
329 | break; | 331 | break; |
330 | } | 332 | } |
331 | if (get_user(val, (int __user *)p)) { | 333 | val[0] = cmd; |
334 | if (get_user(val[1], (int __user *)p)) { | ||
335 | err = -EFAULT; | ||
336 | break; | ||
337 | } | ||
338 | err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr, | ||
339 | CONTROL_CHANNEL, val); | ||
340 | break; | ||
341 | case IMHOLD_L1: | ||
342 | if (sk->sk_protocol != ISDN_P_LAPD_NT | ||
343 | && sk->sk_protocol != ISDN_P_LAPD_TE) { | ||
344 | err = -EINVAL; | ||
345 | break; | ||
346 | } | ||
347 | val[0] = cmd; | ||
348 | if (get_user(val[1], (int __user *)p)) { | ||
332 | err = -EFAULT; | 349 | err = -EFAULT; |
333 | break; | 350 | break; |
334 | } | 351 | } |
335 | err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr, | 352 | err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr, |
336 | CONTROL_CHANNEL, &val); | 353 | CONTROL_CHANNEL, val); |
337 | break; | 354 | break; |
338 | default: | 355 | default: |
339 | err = -EINVAL; | 356 | err = -EINVAL; |
diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index b452dead8fd0..e04bad6c5baf 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c | |||
@@ -122,8 +122,11 @@ da_deactivate(struct FsmInst *fi, int event, void *arg) | |||
122 | } | 122 | } |
123 | read_unlock_irqrestore(&mgr->lock, flags); | 123 | read_unlock_irqrestore(&mgr->lock, flags); |
124 | /* All TEI are inactiv */ | 124 | /* All TEI are inactiv */ |
125 | mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1); | 125 | if (!test_bit(OPTION_L1_HOLD, &mgr->options)) { |
126 | mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING); | 126 | mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, |
127 | NULL, 1); | ||
128 | mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING); | ||
129 | } | ||
127 | } | 130 | } |
128 | 131 | ||
129 | static void | 132 | static void |
@@ -132,9 +135,11 @@ da_ui(struct FsmInst *fi, int event, void *arg) | |||
132 | struct manager *mgr = fi->userdata; | 135 | struct manager *mgr = fi->userdata; |
133 | 136 | ||
134 | /* restart da timer */ | 137 | /* restart da timer */ |
135 | mISDN_FsmDelTimer(&mgr->datimer, 2); | 138 | if (!test_bit(OPTION_L1_HOLD, &mgr->options)) { |
136 | mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2); | 139 | mISDN_FsmDelTimer(&mgr->datimer, 2); |
137 | 140 | mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, | |
141 | NULL, 2); | ||
142 | } | ||
138 | } | 143 | } |
139 | 144 | ||
140 | static void | 145 | static void |
@@ -222,7 +227,7 @@ tei_debug(struct FsmInst *fi, char *fmt, ...) | |||
222 | if (!(*debug & DEBUG_L2_TEIFSM)) | 227 | if (!(*debug & DEBUG_L2_TEIFSM)) |
223 | return; | 228 | return; |
224 | va_start(va, fmt); | 229 | va_start(va, fmt); |
225 | printk(KERN_DEBUG "tei(%d): ", tm->l2->tei); | 230 | printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei); |
226 | vprintk(fmt, va); | 231 | vprintk(fmt, va); |
227 | printk("\n"); | 232 | printk("\n"); |
228 | va_end(va); | 233 | va_end(va); |
@@ -421,7 +426,7 @@ done: | |||
421 | } | 426 | } |
422 | 427 | ||
423 | static void | 428 | static void |
424 | put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei) | 429 | put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei) |
425 | { | 430 | { |
426 | struct sk_buff *skb; | 431 | struct sk_buff *skb; |
427 | u_char bp[8]; | 432 | u_char bp[8]; |
@@ -435,9 +440,8 @@ put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei) | |||
435 | bp[4] = ri >> 8; | 440 | bp[4] = ri >> 8; |
436 | bp[5] = ri & 0xff; | 441 | bp[5] = ri & 0xff; |
437 | bp[6] = m_id; | 442 | bp[6] = m_id; |
438 | bp[7] = (tei << 1) | 1; | 443 | bp[7] = ((tei << 1) & 0xff) | 1; |
439 | skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), | 444 | skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC); |
440 | 8, bp, GFP_ATOMIC); | ||
441 | if (!skb) { | 445 | if (!skb) { |
442 | printk(KERN_WARNING "%s: no skb for tei msg\n", __func__); | 446 | printk(KERN_WARNING "%s: no skb for tei msg\n", __func__); |
443 | return; | 447 | return; |
@@ -772,7 +776,7 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len) | |||
772 | } | 776 | } |
773 | 777 | ||
774 | static struct layer2 * | 778 | static struct layer2 * |
775 | create_new_tei(struct manager *mgr, int tei) | 779 | create_new_tei(struct manager *mgr, int tei, int sapi) |
776 | { | 780 | { |
777 | u_long opt = 0; | 781 | u_long opt = 0; |
778 | u_long flags; | 782 | u_long flags; |
@@ -781,12 +785,12 @@ create_new_tei(struct manager *mgr, int tei) | |||
781 | 785 | ||
782 | if (!mgr->up) | 786 | if (!mgr->up) |
783 | return NULL; | 787 | return NULL; |
784 | if (tei < 64) | 788 | if ((tei >= 0) && (tei < 64)) |
785 | test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); | 789 | test_and_set_bit(OPTION_L2_FIXEDTEI, &opt); |
786 | if (mgr->ch.st->dev->Dprotocols | 790 | if (mgr->ch.st->dev->Dprotocols |
787 | & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) | 791 | & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1))) |
788 | test_and_set_bit(OPTION_L2_PMX, &opt); | 792 | test_and_set_bit(OPTION_L2_PMX, &opt); |
789 | l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei); | 793 | l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi); |
790 | if (!l2) { | 794 | if (!l2) { |
791 | printk(KERN_WARNING "%s:no memory for layer2\n", __func__); | 795 | printk(KERN_WARNING "%s:no memory for layer2\n", __func__); |
792 | return NULL; | 796 | return NULL; |
@@ -834,12 +838,17 @@ new_tei_req(struct manager *mgr, u_char *dp) | |||
834 | ri += dp[1]; | 838 | ri += dp[1]; |
835 | if (!mgr->up) | 839 | if (!mgr->up) |
836 | goto denied; | 840 | goto denied; |
837 | tei = get_free_tei(mgr); | 841 | if (!(dp[3] & 1)) /* Extension bit != 1 */ |
842 | goto denied; | ||
843 | if (dp[3] != 0xff) | ||
844 | tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */ | ||
845 | else | ||
846 | tei = get_free_tei(mgr); | ||
838 | if (tei < 0) { | 847 | if (tei < 0) { |
839 | printk(KERN_WARNING "%s:No free tei\n", __func__); | 848 | printk(KERN_WARNING "%s:No free tei\n", __func__); |
840 | goto denied; | 849 | goto denied; |
841 | } | 850 | } |
842 | l2 = create_new_tei(mgr, tei); | 851 | l2 = create_new_tei(mgr, tei, CTRL_SAPI); |
843 | if (!l2) | 852 | if (!l2) |
844 | goto denied; | 853 | goto denied; |
845 | else | 854 | else |
@@ -853,8 +862,7 @@ static int | |||
853 | ph_data_ind(struct manager *mgr, struct sk_buff *skb) | 862 | ph_data_ind(struct manager *mgr, struct sk_buff *skb) |
854 | { | 863 | { |
855 | int ret = -EINVAL; | 864 | int ret = -EINVAL; |
856 | struct layer2 *l2; | 865 | struct layer2 *l2, *nl2; |
857 | u_long flags; | ||
858 | u_char mt; | 866 | u_char mt; |
859 | 867 | ||
860 | if (skb->len < 8) { | 868 | if (skb->len < 8) { |
@@ -863,7 +871,6 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb) | |||
863 | __func__, skb->len); | 871 | __func__, skb->len); |
864 | goto done; | 872 | goto done; |
865 | } | 873 | } |
866 | if (*debug & DEBUG_L2_TEI) | ||
867 | 874 | ||
868 | if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */ | 875 | if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */ |
869 | goto done; | 876 | goto done; |
@@ -900,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb) | |||
900 | new_tei_req(mgr, &skb->data[4]); | 907 | new_tei_req(mgr, &skb->data[4]); |
901 | goto done; | 908 | goto done; |
902 | } | 909 | } |
903 | read_lock_irqsave(&mgr->lock, flags); | 910 | list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) { |
904 | list_for_each_entry(l2, &mgr->layer2, list) { | ||
905 | tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4); | 911 | tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4); |
906 | } | 912 | } |
907 | read_unlock_irqrestore(&mgr->lock, flags); | ||
908 | done: | 913 | done: |
909 | return ret; | 914 | return ret; |
910 | } | 915 | } |
@@ -971,8 +976,6 @@ create_teimgr(struct manager *mgr, struct channel_req *crq) | |||
971 | __func__, dev_name(&mgr->ch.st->dev->dev), | 976 | __func__, dev_name(&mgr->ch.st->dev->dev), |
972 | crq->protocol, crq->adr.dev, crq->adr.channel, | 977 | crq->protocol, crq->adr.dev, crq->adr.channel, |
973 | crq->adr.sapi, crq->adr.tei); | 978 | crq->adr.sapi, crq->adr.tei); |
974 | if (crq->adr.sapi != 0) /* not supported yet */ | ||
975 | return -EINVAL; | ||
976 | if (crq->adr.tei > GROUP_TEI) | 979 | if (crq->adr.tei > GROUP_TEI) |
977 | return -EINVAL; | 980 | return -EINVAL; |
978 | if (crq->adr.tei < 64) | 981 | if (crq->adr.tei < 64) |
@@ -1019,8 +1022,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq) | |||
1019 | } | 1022 | } |
1020 | return 0; | 1023 | return 0; |
1021 | } | 1024 | } |
1022 | l2 = create_l2(crq->ch, crq->protocol, (u_int)opt, | 1025 | l2 = create_l2(crq->ch, crq->protocol, opt, |
1023 | (u_long)crq->adr.tei); | 1026 | crq->adr.tei, crq->adr.sapi); |
1024 | if (!l2) | 1027 | if (!l2) |
1025 | return -ENOMEM; | 1028 | return -ENOMEM; |
1026 | l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); | 1029 | l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); |
@@ -1103,6 +1106,7 @@ free_teimanager(struct manager *mgr) | |||
1103 | { | 1106 | { |
1104 | struct layer2 *l2, *nl2; | 1107 | struct layer2 *l2, *nl2; |
1105 | 1108 | ||
1109 | test_and_clear_bit(OPTION_L1_HOLD, &mgr->options); | ||
1106 | if (test_bit(MGR_OPT_NETWORK, &mgr->options)) { | 1110 | if (test_bit(MGR_OPT_NETWORK, &mgr->options)) { |
1107 | /* not locked lock is taken in release tei */ | 1111 | /* not locked lock is taken in release tei */ |
1108 | mgr->up = NULL; | 1112 | mgr->up = NULL; |
@@ -1133,13 +1137,26 @@ static int | |||
1133 | ctrl_teimanager(struct manager *mgr, void *arg) | 1137 | ctrl_teimanager(struct manager *mgr, void *arg) |
1134 | { | 1138 | { |
1135 | /* currently we only have one option */ | 1139 | /* currently we only have one option */ |
1136 | int clean = *((int *)arg); | 1140 | int *val = (int *)arg; |
1137 | 1141 | int ret = 0; | |
1138 | if (clean) | 1142 | |
1139 | test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options); | 1143 | switch (val[0]) { |
1140 | else | 1144 | case IMCLEAR_L2: |
1141 | test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options); | 1145 | if (val[1]) |
1142 | return 0; | 1146 | test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options); |
1147 | else | ||
1148 | test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options); | ||
1149 | break; | ||
1150 | case IMHOLD_L1: | ||
1151 | if (val[1]) | ||
1152 | test_and_set_bit(OPTION_L1_HOLD, &mgr->options); | ||
1153 | else | ||
1154 | test_and_clear_bit(OPTION_L1_HOLD, &mgr->options); | ||
1155 | break; | ||
1156 | default: | ||
1157 | ret = -EINVAL; | ||
1158 | } | ||
1159 | return ret; | ||
1143 | } | 1160 | } |
1144 | 1161 | ||
1145 | /* This function does create a L2 for fixed TEI in NT Mode */ | 1162 | /* This function does create a L2 for fixed TEI in NT Mode */ |
@@ -1147,7 +1164,7 @@ static int | |||
1147 | check_data(struct manager *mgr, struct sk_buff *skb) | 1164 | check_data(struct manager *mgr, struct sk_buff *skb) |
1148 | { | 1165 | { |
1149 | struct mISDNhead *hh = mISDN_HEAD_P(skb); | 1166 | struct mISDNhead *hh = mISDN_HEAD_P(skb); |
1150 | int ret, tei; | 1167 | int ret, tei, sapi; |
1151 | struct layer2 *l2; | 1168 | struct layer2 *l2; |
1152 | 1169 | ||
1153 | if (*debug & DEBUG_L2_CTRL) | 1170 | if (*debug & DEBUG_L2_CTRL) |
@@ -1159,20 +1176,27 @@ check_data(struct manager *mgr, struct sk_buff *skb) | |||
1159 | return -ENOTCONN; | 1176 | return -ENOTCONN; |
1160 | if (skb->len != 3) | 1177 | if (skb->len != 3) |
1161 | return -ENOTCONN; | 1178 | return -ENOTCONN; |
1162 | if (skb->data[0] != 0) | 1179 | if (skb->data[0] & 3) /* EA0 and CR must be 0 */ |
1163 | /* only SAPI 0 command */ | 1180 | return -EINVAL; |
1164 | return -ENOTCONN; | 1181 | sapi = skb->data[0] >> 2; |
1165 | if (!(skb->data[1] & 1)) /* invalid EA1 */ | 1182 | if (!(skb->data[1] & 1)) /* invalid EA1 */ |
1166 | return -EINVAL; | 1183 | return -EINVAL; |
1167 | tei = skb->data[1] >> 0; | 1184 | tei = skb->data[1] >> 1; |
1168 | if (tei > 63) /* not a fixed tei */ | 1185 | if (tei > 63) /* not a fixed tei */ |
1169 | return -ENOTCONN; | 1186 | return -ENOTCONN; |
1170 | if ((skb->data[2] & ~0x10) != SABME) | 1187 | if ((skb->data[2] & ~0x10) != SABME) |
1171 | return -ENOTCONN; | 1188 | return -ENOTCONN; |
1172 | /* We got a SABME for a fixed TEI */ | 1189 | /* We got a SABME for a fixed TEI */ |
1173 | l2 = create_new_tei(mgr, tei); | 1190 | if (*debug & DEBUG_L2_CTRL) |
1174 | if (!l2) | 1191 | printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n", |
1192 | __func__, sapi, tei); | ||
1193 | l2 = create_new_tei(mgr, tei, sapi); | ||
1194 | if (!l2) { | ||
1195 | if (*debug & DEBUG_L2_CTRL) | ||
1196 | printk(KERN_DEBUG "%s: failed to create new tei\n", | ||
1197 | __func__); | ||
1175 | return -ENOMEM; | 1198 | return -ENOMEM; |
1199 | } | ||
1176 | ret = l2->ch.send(&l2->ch, skb); | 1200 | ret = l2->ch.send(&l2->ch, skb); |
1177 | return ret; | 1201 | return ret; |
1178 | } | 1202 | } |
diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index bbd99d3282c0..5b7e9bf514f1 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c | |||
@@ -259,7 +259,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, | |||
259 | return ret; | 259 | return ret; |
260 | } | 260 | } |
261 | 261 | ||
262 | static struct file_operations mISDN_fops = { | 262 | static const struct file_operations mISDN_fops = { |
263 | .read = mISDN_read, | 263 | .read = mISDN_read, |
264 | .poll = mISDN_poll, | 264 | .poll = mISDN_poll, |
265 | .ioctl = mISDN_ioctl, | 265 | .ioctl = mISDN_ioctl, |