diff options
Diffstat (limited to 'drivers/isdn')
48 files changed, 466 insertions, 565 deletions
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c index b4147c0b14b..c3a1b061838 100644 --- a/drivers/isdn/act2000/module.c +++ b/drivers/isdn/act2000/module.c @@ -796,7 +796,7 @@ static void __exit act2000_exit(void) act2000_card *last; while (card) { unregister_card(card); - del_timer(&card->ptimer); + del_timer_sync(&card->ptimer); card = card->next; } card = cards; diff --git a/drivers/isdn/capi/Kconfig b/drivers/isdn/capi/Kconfig index f0468658004..7641b3096ea 100644 --- a/drivers/isdn/capi/Kconfig +++ b/drivers/isdn/capi/Kconfig @@ -1,11 +1,3 @@ -config ISDN_DRV_AVMB1_VERBOSE_REASON - bool "Verbose reason code reporting" - default y - help - If you say Y here, the CAPI drivers will give verbose reasons for - disconnecting. This will increase the size of the kernel by 7 KB. If - unsure, say Y. - config CAPI_TRACE bool "CAPI trace support" default y @@ -16,9 +8,17 @@ config CAPI_TRACE This will increase the size of the kernelcapi module by 20 KB. If unsure, say Y. +config ISDN_CAPI_CAPI20 + tristate "CAPI2.0 /dev/capi20 support" + help + This option will provide the CAPI 2.0 interface to userspace + applications via /dev/capi20. Applications should use the + standardized libcapi20 to access this functionality. You should say + Y/M here. + config ISDN_CAPI_MIDDLEWARE bool "CAPI2.0 Middleware support" - depends on TTY + depends on ISDN_CAPI_CAPI20 && TTY help This option will enhance the capabilities of the /dev/capi20 interface. It will provide a means of moving a data connection, @@ -26,14 +26,6 @@ config ISDN_CAPI_MIDDLEWARE device. If you want to use pppd with pppdcapiplugin to dial up to your ISP, say Y here. -config ISDN_CAPI_CAPI20 - tristate "CAPI2.0 /dev/capi support" - help - This option will provide the CAPI 2.0 interface to userspace - applications via /dev/capi20. Applications should use the - standardized libcapi20 to access this functionality. You should say - Y/M here. - config ISDN_CAPI_CAPIDRV tristate "CAPI2.0 capidrv interface support" depends on ISDN_I4L @@ -42,3 +34,11 @@ config ISDN_CAPI_CAPIDRV the legacy isdn4linux link layer. If you have a card which is supported by a CAPI driver, but still want to use old features like ippp interfaces or ttyI emulation, say Y/M here. + +config ISDN_CAPI_CAPIDRV_VERBOSE + bool "Verbose reason code reporting" + depends on ISDN_CAPI_CAPIDRV + help + If you say Y here, the capidrv interface will give verbose reasons + for disconnecting. This will increase the size of the kernel by 7 KB. + If unsure, say N. diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index ac6f72b455d..f9a87ed2392 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1271,7 +1271,7 @@ static int __init capinc_tty_init(void) return -ENOMEM; } drv->driver_name = "capi_nc"; - drv->name = "capi"; + drv->name = "capi!"; drv->major = 0; drv->minor_start = 0; drv->type = TTY_DRIVER_TYPE_SERIAL; @@ -1417,7 +1417,7 @@ static int __init capi_init(void) return PTR_ERR(capi_class); } - device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi"); + device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi20"); if (capinc_tty_init() < 0) { device_destroy(capi_class, MKDEV(capi_major, 0)); diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index cc9f1927a32..fd6d28f3fc3 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -763,6 +763,201 @@ static inline int new_bchan(capidrv_contr *card) } /* ------------------------------------------------------------------- */ +static char *capi_info2str(u16 reason) +{ +#ifndef CONFIG_ISDN_CAPI_CAPIDRV_VERBOSE + return ".."; +#else + switch (reason) { + +/*-- informative values (corresponding message was processed) -----*/ + case 0x0001: + return "NCPI not supported by current protocol, NCPI ignored"; + case 0x0002: + return "Flags not supported by current protocol, flags ignored"; + case 0x0003: + return "Alert already sent by another application"; + +/*-- error information concerning CAPI_REGISTER -----*/ + case 0x1001: + return "Too many applications"; + case 0x1002: + return "Logical block size too small, must be at least 128 Bytes"; + case 0x1003: + return "Buffer exceeds 64 kByte"; + case 0x1004: + return "Message buffer size too small, must be at least 1024 Bytes"; + case 0x1005: + return "Max. number of logical connections not supported"; + case 0x1006: + return "Reserved"; + case 0x1007: + return "The message could not be accepted because of an internal busy condition"; + case 0x1008: + return "OS resource error (no memory ?)"; + case 0x1009: + return "CAPI not installed"; + case 0x100A: + return "Controller does not support external equipment"; + case 0x100B: + return "Controller does only support external equipment"; + +/*-- error information concerning message exchange functions -----*/ + case 0x1101: + return "Illegal application number"; + case 0x1102: + return "Illegal command or subcommand or message length less than 12 bytes"; + case 0x1103: + return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI"; + case 0x1104: + return "Queue is empty"; + case 0x1105: + return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE"; + case 0x1106: + return "Unknown notification parameter"; + case 0x1107: + return "The Message could not be accepted because of an internal busy condition"; + case 0x1108: + return "OS Resource error (no memory ?)"; + case 0x1109: + return "CAPI not installed"; + case 0x110A: + return "Controller does not support external equipment"; + case 0x110B: + return "Controller does only support external equipment"; + +/*-- error information concerning resource / coding problems -----*/ + case 0x2001: + return "Message not supported in current state"; + case 0x2002: + return "Illegal Controller / PLCI / NCCI"; + case 0x2003: + return "Out of PLCI"; + case 0x2004: + return "Out of NCCI"; + case 0x2005: + return "Out of LISTEN"; + case 0x2006: + return "Out of FAX resources (protocol T.30)"; + case 0x2007: + return "Illegal message parameter coding"; + +/*-- error information concerning requested services -----*/ + case 0x3001: + return "B1 protocol not supported"; + case 0x3002: + return "B2 protocol not supported"; + case 0x3003: + return "B3 protocol not supported"; + case 0x3004: + return "B1 protocol parameter not supported"; + case 0x3005: + return "B2 protocol parameter not supported"; + case 0x3006: + return "B3 protocol parameter not supported"; + case 0x3007: + return "B protocol combination not supported"; + case 0x3008: + return "NCPI not supported"; + case 0x3009: + return "CIP Value unknown"; + case 0x300A: + return "Flags not supported (reserved bits)"; + case 0x300B: + return "Facility not supported"; + case 0x300C: + return "Data length not supported by current protocol"; + case 0x300D: + return "Reset procedure not supported by current protocol"; + +/*-- informations about the clearing of a physical connection -----*/ + case 0x3301: + return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)"; + case 0x3302: + return "Protocol error layer 2"; + case 0x3303: + return "Protocol error layer 3"; + case 0x3304: + return "Another application got that call"; +/*-- T.30 specific reasons -----*/ + case 0x3311: + return "Connecting not successful (remote station is no FAX G3 machine)"; + case 0x3312: + return "Connecting not successful (training error)"; + case 0x3313: + return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)"; + case 0x3314: + return "Disconnected during transfer (remote abort)"; + case 0x3315: + return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)"; + case 0x3316: + return "Disconnected during transfer (local tx data underrun)"; + case 0x3317: + return "Disconnected during transfer (local rx data overflow)"; + case 0x3318: + return "Disconnected during transfer (local abort)"; + case 0x3319: + return "Illegal parameter coding (e.g. SFF coding error)"; + +/*-- disconnect causes from the network according to ETS 300 102-1/Q.931 -----*/ + case 0x3481: return "Unallocated (unassigned) number"; + case 0x3482: return "No route to specified transit network"; + case 0x3483: return "No route to destination"; + case 0x3486: return "Channel unacceptable"; + case 0x3487: + return "Call awarded and being delivered in an established channel"; + case 0x3490: return "Normal call clearing"; + case 0x3491: return "User busy"; + case 0x3492: return "No user responding"; + case 0x3493: return "No answer from user (user alerted)"; + case 0x3495: return "Call rejected"; + case 0x3496: return "Number changed"; + case 0x349A: return "Non-selected user clearing"; + case 0x349B: return "Destination out of order"; + case 0x349C: return "Invalid number format"; + case 0x349D: return "Facility rejected"; + case 0x349E: return "Response to STATUS ENQUIRY"; + case 0x349F: return "Normal, unspecified"; + case 0x34A2: return "No circuit / channel available"; + case 0x34A6: return "Network out of order"; + case 0x34A9: return "Temporary failure"; + case 0x34AA: return "Switching equipment congestion"; + case 0x34AB: return "Access information discarded"; + case 0x34AC: return "Requested circuit / channel not available"; + case 0x34AF: return "Resources unavailable, unspecified"; + case 0x34B1: return "Quality of service unavailable"; + case 0x34B2: return "Requested facility not subscribed"; + case 0x34B9: return "Bearer capability not authorized"; + case 0x34BA: return "Bearer capability not presently available"; + case 0x34BF: return "Service or option not available, unspecified"; + case 0x34C1: return "Bearer capability not implemented"; + case 0x34C2: return "Channel type not implemented"; + case 0x34C5: return "Requested facility not implemented"; + case 0x34C6: return "Only restricted digital information bearer capability is available"; + case 0x34CF: return "Service or option not implemented, unspecified"; + case 0x34D1: return "Invalid call reference value"; + case 0x34D2: return "Identified channel does not exist"; + case 0x34D3: return "A suspended call exists, but this call identity does not"; + case 0x34D4: return "Call identity in use"; + case 0x34D5: return "No call suspended"; + case 0x34D6: return "Call having the requested call identity has been cleared"; + case 0x34D8: return "Incompatible destination"; + case 0x34DB: return "Invalid transit network selection"; + case 0x34DF: return "Invalid message, unspecified"; + case 0x34E0: return "Mandatory information element is missing"; + case 0x34E1: return "Message type non-existent or not implemented"; + case 0x34E2: return "Message not compatible with call state or message type non-existent or not implemented"; + case 0x34E3: return "Information element non-existent or not implemented"; + case 0x34E4: return "Invalid information element contents"; + case 0x34E5: return "Message not compatible with call state"; + case 0x34E6: return "Recovery on timer expiry"; + case 0x34EF: return "Protocol error, unspecified"; + case 0x34FF: return "Interworking, unspecified"; + + default: return "No additional information"; + } +#endif +} static void handle_controller(_cmsg *cmsg) { diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index d26f17033b6..6e797e502cf 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c @@ -22,205 +22,6 @@ /* from CAPI2.0 DDK AVM Berlin GmbH */ -#ifndef CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON -char *capi_info2str(u16 reason) -{ - return ".."; -} -#else -char *capi_info2str(u16 reason) -{ - switch (reason) { - -/*-- informative values (corresponding message was processed) -----*/ - case 0x0001: - return "NCPI not supported by current protocol, NCPI ignored"; - case 0x0002: - return "Flags not supported by current protocol, flags ignored"; - case 0x0003: - return "Alert already sent by another application"; - -/*-- error information concerning CAPI_REGISTER -----*/ - case 0x1001: - return "Too many applications"; - case 0x1002: - return "Logical block size too small, must be at least 128 Bytes"; - case 0x1003: - return "Buffer exceeds 64 kByte"; - case 0x1004: - return "Message buffer size too small, must be at least 1024 Bytes"; - case 0x1005: - return "Max. number of logical connections not supported"; - case 0x1006: - return "Reserved"; - case 0x1007: - return "The message could not be accepted because of an internal busy condition"; - case 0x1008: - return "OS resource error (no memory ?)"; - case 0x1009: - return "CAPI not installed"; - case 0x100A: - return "Controller does not support external equipment"; - case 0x100B: - return "Controller does only support external equipment"; - -/*-- error information concerning message exchange functions -----*/ - case 0x1101: - return "Illegal application number"; - case 0x1102: - return "Illegal command or subcommand or message length less than 12 bytes"; - case 0x1103: - return "The message could not be accepted because of a queue full condition !! The error code does not imply that CAPI cannot receive messages directed to another controller, PLCI or NCCI"; - case 0x1104: - return "Queue is empty"; - case 0x1105: - return "Queue overflow, a message was lost !! This indicates a configuration error. The only recovery from this error is to perform a CAPI_RELEASE"; - case 0x1106: - return "Unknown notification parameter"; - case 0x1107: - return "The Message could not be accepted because of an internal busy condition"; - case 0x1108: - return "OS Resource error (no memory ?)"; - case 0x1109: - return "CAPI not installed"; - case 0x110A: - return "Controller does not support external equipment"; - case 0x110B: - return "Controller does only support external equipment"; - -/*-- error information concerning resource / coding problems -----*/ - case 0x2001: - return "Message not supported in current state"; - case 0x2002: - return "Illegal Controller / PLCI / NCCI"; - case 0x2003: - return "Out of PLCI"; - case 0x2004: - return "Out of NCCI"; - case 0x2005: - return "Out of LISTEN"; - case 0x2006: - return "Out of FAX resources (protocol T.30)"; - case 0x2007: - return "Illegal message parameter coding"; - -/*-- error information concerning requested services -----*/ - case 0x3001: - return "B1 protocol not supported"; - case 0x3002: - return "B2 protocol not supported"; - case 0x3003: - return "B3 protocol not supported"; - case 0x3004: - return "B1 protocol parameter not supported"; - case 0x3005: - return "B2 protocol parameter not supported"; - case 0x3006: - return "B3 protocol parameter not supported"; - case 0x3007: - return "B protocol combination not supported"; - case 0x3008: - return "NCPI not supported"; - case 0x3009: - return "CIP Value unknown"; - case 0x300A: - return "Flags not supported (reserved bits)"; - case 0x300B: - return "Facility not supported"; - case 0x300C: - return "Data length not supported by current protocol"; - case 0x300D: - return "Reset procedure not supported by current protocol"; - -/*-- informations about the clearing of a physical connection -----*/ - case 0x3301: - return "Protocol error layer 1 (broken line or B-channel removed by signalling protocol)"; - case 0x3302: - return "Protocol error layer 2"; - case 0x3303: - return "Protocol error layer 3"; - case 0x3304: - return "Another application got that call"; -/*-- T.30 specific reasons -----*/ - case 0x3311: - return "Connecting not successful (remote station is no FAX G3 machine)"; - case 0x3312: - return "Connecting not successful (training error)"; - case 0x3313: - return "Disconnected before transfer (remote station does not support transfer mode, e.g. resolution)"; - case 0x3314: - return "Disconnected during transfer (remote abort)"; - case 0x3315: - return "Disconnected during transfer (remote procedure error, e.g. unsuccessful repetition of T.30 commands)"; - case 0x3316: - return "Disconnected during transfer (local tx data underrun)"; - case 0x3317: - return "Disconnected during transfer (local rx data overflow)"; - case 0x3318: - return "Disconnected during transfer (local abort)"; - case 0x3319: - return "Illegal parameter coding (e.g. SFF coding error)"; - -/*-- disconnect causes from the network according to ETS 300 102-1/Q.931 -----*/ - case 0x3481: return "Unallocated (unassigned) number"; - case 0x3482: return "No route to specified transit network"; - case 0x3483: return "No route to destination"; - case 0x3486: return "Channel unacceptable"; - case 0x3487: - return "Call awarded and being delivered in an established channel"; - case 0x3490: return "Normal call clearing"; - case 0x3491: return "User busy"; - case 0x3492: return "No user responding"; - case 0x3493: return "No answer from user (user alerted)"; - case 0x3495: return "Call rejected"; - case 0x3496: return "Number changed"; - case 0x349A: return "Non-selected user clearing"; - case 0x349B: return "Destination out of order"; - case 0x349C: return "Invalid number format"; - case 0x349D: return "Facility rejected"; - case 0x349E: return "Response to STATUS ENQUIRY"; - case 0x349F: return "Normal, unspecified"; - case 0x34A2: return "No circuit / channel available"; - case 0x34A6: return "Network out of order"; - case 0x34A9: return "Temporary failure"; - case 0x34AA: return "Switching equipment congestion"; - case 0x34AB: return "Access information discarded"; - case 0x34AC: return "Requested circuit / channel not available"; - case 0x34AF: return "Resources unavailable, unspecified"; - case 0x34B1: return "Quality of service unavailable"; - case 0x34B2: return "Requested facility not subscribed"; - case 0x34B9: return "Bearer capability not authorized"; - case 0x34BA: return "Bearer capability not presently available"; - case 0x34BF: return "Service or option not available, unspecified"; - case 0x34C1: return "Bearer capability not implemented"; - case 0x34C2: return "Channel type not implemented"; - case 0x34C5: return "Requested facility not implemented"; - case 0x34C6: return "Only restricted digital information bearer capability is available"; - case 0x34CF: return "Service or option not implemented, unspecified"; - case 0x34D1: return "Invalid call reference value"; - case 0x34D2: return "Identified channel does not exist"; - case 0x34D3: return "A suspended call exists, but this call identity does not"; - case 0x34D4: return "Call identity in use"; - case 0x34D5: return "No call suspended"; - case 0x34D6: return "Call having the requested call identity has been cleared"; - case 0x34D8: return "Incompatible destination"; - case 0x34DB: return "Invalid transit network selection"; - case 0x34DF: return "Invalid message, unspecified"; - case 0x34E0: return "Mandatory information element is missing"; - case 0x34E1: return "Message type non-existent or not implemented"; - case 0x34E2: return "Message not compatible with call state or message type non-existent or not implemented"; - case 0x34E3: return "Information element non-existent or not implemented"; - case 0x34E4: return "Invalid information element contents"; - case 0x34E5: return "Message not compatible with call state"; - case 0x34E6: return "Recovery on timer expiry"; - case 0x34EF: return "Protocol error, unspecified"; - case 0x34FF: return "Interworking, unspecified"; - - default: return "No additional information"; - } -} -#endif - typedef struct { int typ; size_t off; @@ -1073,4 +874,3 @@ EXPORT_SYMBOL(capi_cmsg_header); EXPORT_SYMBOL(capi_cmd2str); EXPORT_SYMBOL(capi_cmsg2str); EXPORT_SYMBOL(capi_message2str); -EXPORT_SYMBOL(capi_info2str); diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c index fb4f1bac013..1c5dc345e7c 100644 --- a/drivers/isdn/divert/divert_procfs.c +++ b/drivers/isdn/divert/divert_procfs.c @@ -86,12 +86,13 @@ isdn_divert_read(struct file *file, char __user *buf, size_t count, loff_t *off) struct divert_info *inf; int len; - if (!*((struct divert_info **) file->private_data)) { + if (!(inf = *((struct divert_info **) file->private_data))) { if (file->f_flags & O_NONBLOCK) return -EAGAIN; - interruptible_sleep_on(&(rd_queue)); + wait_event_interruptible(rd_queue, (inf = + *((struct divert_info **) file->private_data))); } - if (!(inf = *((struct divert_info **) file->private_data))) + if (!inf) return (0); inf->usage_cnt--; /* new usage count */ diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index c44950d3eb7..b7ae0a0dd5b 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -2400,6 +2400,7 @@ allocerr: error: freeurbs(cs); usb_set_intfdata(interface, NULL); + usb_put_dev(udev); gigaset_freecs(cs); return rc; } diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c index 52377b4bf03..a2e0ed6c9a4 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c @@ -481,7 +481,7 @@ void __inline__ outpp(void __iomem *addr, word p) int diva_os_register_irq(void *context, byte irq, const char *name) { int result = request_irq(irq, diva_os_irq_wrapper, - IRQF_DISABLED | IRQF_SHARED, name, context); + IRQF_SHARED, name, context); return (result); } diff --git a/drivers/isdn/hardware/eicon/um_idi.c b/drivers/isdn/hardware/eicon/um_idi.c index 7cab5c3276c..e1519718ce6 100644 --- a/drivers/isdn/hardware/eicon/um_idi.c +++ b/drivers/isdn/hardware/eicon/um_idi.c @@ -288,9 +288,9 @@ int divas_um_idi_delete_entity(int adapter_nr, void *entity) cleanup_entity(e); diva_os_free(0, e->os_context); memset(e, 0x00, sizeof(*e)); - diva_os_free(0, e); DBG_LOG(("A(%d) remove E:%08x", adapter_nr, e)); + diva_os_free(0, e); return (0); } diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index a7e4939787c..3c92780bda0 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -1307,11 +1307,11 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) } if (fifo2 & 2) { hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B2; - hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS + + hc->hw.int_m1 &= ~(HFCPCI_INTS_B2TRANS | HFCPCI_INTS_B2REC); } else { hc->hw.fifo_en &= ~HFCPCI_FIFOEN_B1; - hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS + + hc->hw.int_m1 &= ~(HFCPCI_INTS_B1TRANS | HFCPCI_INTS_B1REC); } #ifdef REVERSE_BITORDER @@ -1346,14 +1346,14 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) if (fifo2 & 2) { hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; if (!tics) - hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + + hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS | HFCPCI_INTS_B2REC); hc->hw.ctmt |= 2; hc->hw.conn &= ~0x18; } else { hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; if (!tics) - hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + + hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS | HFCPCI_INTS_B1REC); hc->hw.ctmt |= 1; hc->hw.conn &= ~0x03; @@ -1375,14 +1375,14 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol) if (fifo2 & 2) { hc->hw.last_bfifo_cnt[1] = 0; hc->hw.fifo_en |= HFCPCI_FIFOEN_B2; - hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS + + hc->hw.int_m1 |= (HFCPCI_INTS_B2TRANS | HFCPCI_INTS_B2REC); hc->hw.ctmt &= ~2; hc->hw.conn &= ~0x18; } else { hc->hw.last_bfifo_cnt[0] = 0; hc->hw.fifo_en |= HFCPCI_FIFOEN_B1; - hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS + + hc->hw.int_m1 |= (HFCPCI_INTS_B1TRANS | HFCPCI_INTS_B1REC); hc->hw.ctmt &= ~1; hc->hw.conn &= ~0x03; @@ -2295,8 +2295,8 @@ _hfcpci_softirq(struct device *dev, void *arg) static void hfcpci_softirq(void *arg) { - (void) driver_for_each_device(&hfc_driver.driver, NULL, arg, - _hfcpci_softirq); + WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, arg, + _hfcpci_softirq) != 0); /* if next event would be in the past ... */ if ((s32)(hfc_jiffies + tics - jiffies) <= 0) diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index d9edcc94c2a..97465ac5a2d 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -16,7 +16,7 @@ config ISDN_DRV_HISAX also to the configuration option of the driver for your particular card, below. -if ISDN_DRV_HISAX!=n +if ISDN_DRV_HISAX comment "D-channel protocol features" @@ -348,10 +348,6 @@ config HISAX_ENTERNOW_PCI This enables HiSax support for the Formula-n enter:now PCI ISDN card. -endif - -if ISDN_DRV_HISAX - config HISAX_DEBUG bool "HiSax debugging" help @@ -420,11 +416,6 @@ config HISAX_FRITZ_PCIPNP (the latter also needs you to select "ISA Plug and Play support" from the menu "Plug and Play configuration") -config HISAX_AVM_A1_PCMCIA - bool - depends on HISAX_AVM_A1_CS - default y - endif endmenu diff --git a/drivers/isdn/hisax/amd7930_fn.c b/drivers/isdn/hisax/amd7930_fn.c index 1063babe1d3..36817e0a0b9 100644 --- a/drivers/isdn/hisax/amd7930_fn.c +++ b/drivers/isdn/hisax/amd7930_fn.c @@ -314,7 +314,7 @@ Amd7930_empty_Dfifo(struct IsdnCardState *cs, int flag) t += sprintf(t, "Amd7930: empty_Dfifo cnt: %d |", cs->rcvidx); QuickHex(t, cs->rcvbuf, cs->rcvidx); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } /* moves received data in sk-buffer */ memcpy(skb_put(skb, cs->rcvidx), cs->rcvbuf, cs->rcvidx); @@ -406,7 +406,7 @@ Amd7930_fill_Dfifo(struct IsdnCardState *cs) t += sprintf(t, "Amd7930: fill_Dfifo cnt: %d |", count); QuickHex(t, deb_ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } /* AMD interrupts on */ AmdIrqOn(cs); diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index ee9b9a03cff..d1427bd6452 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c @@ -285,7 +285,7 @@ hdlc_empty_fifo(struct BCState *bcs, int count) t += sprintf(t, "hdlc_empty_fifo %c cnt %d", bcs->channel ? 'B' : 'A', count); QuickHex(t, p, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } @@ -345,7 +345,7 @@ hdlc_fill_fifo(struct BCState *bcs) t += sprintf(t, "hdlc_fill_fifo %c cnt %d", bcs->channel ? 'B' : 'A', count); QuickHex(t, p, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index bf04d2a3cf4..b33f53b3ca9 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c @@ -1896,7 +1896,7 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if) ptr--; *ptr++ = '\n'; *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); + HiSax_putstatus(cs, NULL, "%s", cs->dlog); } else HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", diff --git a/drivers/isdn/hisax/diva.c b/drivers/isdn/hisax/diva.c index 8d0cf6e4dc0..4fc90de68d1 100644 --- a/drivers/isdn/hisax/diva.c +++ b/drivers/isdn/hisax/diva.c @@ -427,7 +427,7 @@ Memhscx_empty_fifo(struct BCState *bcs, int count) t += sprintf(t, "hscx_empty_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } @@ -469,7 +469,7 @@ Memhscx_fill_fifo(struct BCState *bcs) t += sprintf(t, "hscx_fill_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } diff --git a/drivers/isdn/hisax/elsa.c b/drivers/isdn/hisax/elsa.c index 1df6f9a56ca..d8ef64da26f 100644 --- a/drivers/isdn/hisax/elsa.c +++ b/drivers/isdn/hisax/elsa.c @@ -509,7 +509,8 @@ static void set_arcofi(struct IsdnCardState *cs, int bc) { cs->dc.isac.arcofi_bc = bc; arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5); - interruptible_sleep_on(&cs->dc.isac.arcofi_wait); + wait_event_interruptible(cs->dc.isac.arcofi_wait, + cs->dc.isac.arcofi_state == ARCOFI_NOP); } static int @@ -528,14 +529,15 @@ check_arcofi(struct IsdnCardState *cs) } cs->dc.isac.arcofi_bc = 0; arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION); - interruptible_sleep_on(&cs->dc.isac.arcofi_wait); + wait_event_interruptible(cs->dc.isac.arcofi_wait, + cs->dc.isac.arcofi_state == ARCOFI_NOP); if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) { debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp); p = cs->dc.isac.mon_rx; t = tmp; t += sprintf(tmp, "Arcofi data"); QuickHex(t, p, cs->dc.isac.mon_rxp); - debugl1(cs, tmp); + debugl1(cs, "%s", tmp); if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) { switch (cs->dc.isac.mon_rx[1]) { case 0x80: @@ -595,7 +597,8 @@ check_arcofi(struct IsdnCardState *cs) Elsa_Types[cs->subtyp], cs->hw.elsa.base + 8); arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0); - interruptible_sleep_on(&cs->dc.isac.arcofi_wait); + wait_event_interruptible(cs->dc.isac.arcofi_wait, + cs->dc.isac.arcofi_state == ARCOFI_NOP); return (1); } return (0); diff --git a/drivers/isdn/hisax/elsa_ser.c b/drivers/isdn/hisax/elsa_ser.c index d4c98d330bf..a2a358c1dc8 100644 --- a/drivers/isdn/hisax/elsa_ser.c +++ b/drivers/isdn/hisax/elsa_ser.c @@ -344,7 +344,7 @@ static inline void receive_chars(struct IsdnCardState *cs, t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt); QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt); - debugl1(cs, tmp); + debugl1(cs, "%s", tmp); } cs->hw.elsa.rcvcnt = 0; } @@ -573,7 +573,8 @@ modem_l2l1(struct PStack *st, int pr, void *arg) test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag); bcs->cs->dc.isac.arcofi_bc = st->l1.bc; arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0); - interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait); + wait_event_interruptible(bcs->cs->dc.isac.arcofi_wait, + bcs->cs->dc.isac.arcofi_state == ARCOFI_NOP); bcs->cs->hw.elsa.MFlag = 1; } else { printk(KERN_WARNING "ElsaSer: unknown pr %x\n", pr); diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index c49c294fc81..fc9f9d03fa1 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c @@ -197,25 +197,6 @@ typedef struct _hfc4s8s_hw { -/***************************/ -/* inline function defines */ -/***************************/ -#ifdef HISAX_HFC4S8S_PCIMEM /* inline functions memory mapped */ - -/* memory write and dummy IO read to avoid PCI byte merge problems */ -#define Write_hfc8(a, b, c) {(*((volatile u_char *)(a->membase + b)) = c); inb(a->iobase + 4);} -/* memory write without dummy IO access for fifo data access */ -#define fWrite_hfc8(a, b, c) (*((volatile u_char *)(a->membase + b)) = c) -#define Read_hfc8(a, b) (*((volatile u_char *)(a->membase + b))) -#define Write_hfc16(a, b, c) (*((volatile unsigned short *)(a->membase + b)) = c) -#define Read_hfc16(a, b) (*((volatile unsigned short *)(a->membase + b))) -#define Write_hfc32(a, b, c) (*((volatile unsigned long *)(a->membase + b)) = c) -#define Read_hfc32(a, b) (*((volatile unsigned long *)(a->membase + b))) -#define wait_busy(a) {while ((Read_hfc8(a, R_STATUS) & M_BUSY));} -#define PCI_ENA_MEMIO 0x03 - -#else - /* inline functions io mapped */ static inline void SetRegAddr(hfc4s8s_hw *a, u_char b) @@ -306,8 +287,6 @@ wait_busy(hfc4s8s_hw *a) #define PCI_ENA_REGIO 0x01 -#endif /* HISAX_HFC4S8S_PCIMEM */ - /******************************************************/ /* function to read critical counter registers that */ /* may be updated by the chip during read */ @@ -724,26 +703,15 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech) return; } else { /* read errornous D frame */ - -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); -#endif while (z1 >= 4) { -#ifdef HISAX_HFC4S8S_PCIMEM - Read_hfc32(l1p->hw, A_FIFO_DATA0); -#else fRead_hfc32(l1p->hw); -#endif z1 -= 4; } while (z1--) -#ifdef HISAX_HFC4S8S_PCIMEM - Read_hfc8(l1p->hw, A_FIFO_DATA0); -#else - fRead_hfc8(l1p->hw); -#endif + fRead_hfc8(l1p->hw); Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); wait_busy(l1p->hw); @@ -753,27 +721,16 @@ rx_d_frame(struct hfc4s8s_l1 *l1p, int ech) cp = skb->data; -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); -#endif while (z1 >= 4) { -#ifdef HISAX_HFC4S8S_PCIMEM - *((unsigned long *) cp) = - Read_hfc32(l1p->hw, A_FIFO_DATA0); -#else *((unsigned long *) cp) = fRead_hfc32(l1p->hw); -#endif cp += 4; z1 -= 4; } while (z1--) -#ifdef HISAX_HFC4S8S_PCIMEM - *cp++ = Read_hfc8(l1p->hw, A_FIFO_DATA0); -#else - *cp++ = fRead_hfc8(l1p->hw); -#endif + *cp++ = fRead_hfc8(l1p->hw); Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ wait_busy(l1p->hw); @@ -859,28 +816,17 @@ rx_b_frame(struct hfc4s8s_btype *bch) wait_busy(l1->hw); return; } -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1->hw, A_FIFO_DATA0); -#endif while (z1 >= 4) { -#ifdef HISAX_HFC4S8S_PCIMEM - *((unsigned long *) bch->rx_ptr) = - Read_hfc32(l1->hw, A_FIFO_DATA0); -#else *((unsigned long *) bch->rx_ptr) = fRead_hfc32(l1->hw); -#endif bch->rx_ptr += 4; z1 -= 4; } while (z1--) -#ifdef HISAX_HFC4S8S_PCIMEM - *(bch->rx_ptr++) = Read_hfc8(l1->hw, A_FIFO_DATA0); -#else - *(bch->rx_ptr++) = fRead_hfc8(l1->hw); -#endif + *(bch->rx_ptr++) = fRead_hfc8(l1->hw); if (hdlc_complete) { /* increment f counter */ @@ -940,29 +886,17 @@ tx_d_frame(struct hfc4s8s_l1 *l1p) if ((skb = skb_dequeue(&l1p->d_tx_queue))) { cp = skb->data; cnt = skb->len; -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1p->hw, A_FIFO_DATA0); -#endif while (cnt >= 4) { -#ifdef HISAX_HFC4S8S_PCIMEM - fWrite_hfc32(l1p->hw, A_FIFO_DATA0, - *(unsigned long *) cp); -#else SetRegAddr(l1p->hw, A_FIFO_DATA0); fWrite_hfc32(l1p->hw, *(unsigned long *) cp); -#endif cp += 4; cnt -= 4; } -#ifdef HISAX_HFC4S8S_PCIMEM - while (cnt--) - fWrite_hfc8(l1p->hw, A_FIFO_DATA0, *cp++); -#else while (cnt--) fWrite_hfc8(l1p->hw, *cp++); -#endif l1p->tx_cnt = skb->truesize; Write_hfc8(l1p->hw, A_INC_RES_FIFO, 1); /* increment f counter */ @@ -1037,26 +971,15 @@ tx_b_frame(struct hfc4s8s_btype *bch) cp = skb->data + bch->tx_cnt; bch->tx_cnt += cnt; -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(l1->hw, A_FIFO_DATA0); -#endif while (cnt >= 4) { -#ifdef HISAX_HFC4S8S_PCIMEM - fWrite_hfc32(l1->hw, A_FIFO_DATA0, - *(unsigned long *) cp); -#else fWrite_hfc32(l1->hw, *(unsigned long *) cp); -#endif cp += 4; cnt -= 4; } while (cnt--) -#ifdef HISAX_HFC4S8S_PCIMEM - fWrite_hfc8(l1->hw, A_FIFO_DATA0, *cp++); -#else - fWrite_hfc8(l1->hw, *cp++); -#endif + fWrite_hfc8(l1->hw, *cp++); if (bch->tx_cnt >= skb->len) { if (bch->mode == L1_MODE_HDLC) { @@ -1281,10 +1204,8 @@ hfc4s8s_interrupt(int intno, void *dev_id) if (!hw || !(hw->mr.r_irq_ctrl & M_GLOB_IRQ_EN)) return IRQ_NONE; -#ifndef HISAX_HFC4S8S_PCIMEM /* read current selected regsister */ old_ioreg = GetRegAddr(hw); -#endif /* Layer 1 State change */ hw->mr.r_irq_statech |= @@ -1292,9 +1213,7 @@ hfc4s8s_interrupt(int intno, void *dev_id) if (! (b = (Read_hfc8(hw, R_STATUS) & (M_MISC_IRQSTA | M_FR_IRQSTA))) && !hw->mr.r_irq_statech) { -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(hw, old_ioreg); -#endif return IRQ_NONE; } @@ -1322,9 +1241,7 @@ hfc4s8s_interrupt(int intno, void *dev_id) /* queue the request to allow other cards to interrupt */ schedule_work(&hw->tqueue); -#ifndef HISAX_HFC4S8S_PCIMEM SetRegAddr(hw, old_ioreg); -#endif return IRQ_HANDLED; } /* hfc4s8s_interrupt */ @@ -1471,13 +1388,8 @@ static void release_pci_ports(hfc4s8s_hw *hw) { pci_write_config_word(hw->pdev, PCI_COMMAND, 0); -#ifdef HISAX_HFC4S8S_PCIMEM - if (hw->membase) - iounmap((void *) hw->membase); -#else if (hw->iobase) release_region(hw->iobase, 8); -#endif } /*****************************************/ @@ -1486,11 +1398,7 @@ release_pci_ports(hfc4s8s_hw *hw) static void enable_pci_ports(hfc4s8s_hw *hw) { -#ifdef HISAX_HFC4S8S_PCIMEM - pci_write_config_word(hw->pdev, PCI_COMMAND, PCI_ENA_MEMIO); -#else pci_write_config_word(hw->pdev, PCI_COMMAND, PCI_ENA_REGIO); -#endif } /*************************************/ @@ -1561,15 +1469,9 @@ setup_instance(hfc4s8s_hw *hw) hw->irq); goto out; } -#ifdef HISAX_HFC4S8S_PCIMEM - printk(KERN_INFO - "HFC-4S/8S: found PCI card at membase 0x%p, irq %d\n", - hw->hw_membase, hw->irq); -#else printk(KERN_INFO "HFC-4S/8S: found PCI card at iobase 0x%x, irq %d\n", hw->iobase, hw->irq); -#endif hfc_hardware_enable(hw, 1, 0); @@ -1614,17 +1516,12 @@ hfc4s8s_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw->irq = pdev->irq; hw->iobase = pci_resource_start(pdev, 0); -#ifdef HISAX_HFC4S8S_PCIMEM - hw->hw_membase = (u_char *) pci_resource_start(pdev, 1); - hw->membase = ioremap((ulong) hw->hw_membase, 256); -#else if (!request_region(hw->iobase, 8, hw->card_name)) { printk(KERN_INFO - "HFC-4S/8S: failed to rquest address space at 0x%04x\n", + "HFC-4S/8S: failed to request address space at 0x%04x\n", hw->iobase); goto out; } -#endif pci_set_drvdata(pdev, hw); err = setup_instance(hw); diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 3ccd724ff8c..4a482552818 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c @@ -901,7 +901,7 @@ Begin: ptr--; *ptr++ = '\n'; *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); + HiSax_putstatus(cs, NULL, "%s", cs->dlog); } else HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", total - 3); } @@ -1643,10 +1643,6 @@ setup_hfcpci(struct IsdnCard *card) int i; struct pci_dev *tmp_hfcpci = NULL; -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - strcpy(tmp, hfcpci_revision); printk(KERN_INFO "HiSax: HFC-PCI driver Rev. %s\n", HiSax_getrev(tmp)); diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index dc4574f735e..fa1fefd711c 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -674,7 +674,7 @@ receive_emsg(struct IsdnCardState *cs) ptr--; *ptr++ = '\n'; *ptr = 0; - HiSax_putstatus(cs, NULL, cs->dlog); + HiSax_putstatus(cs, NULL, "%s", cs->dlog); } else HiSax_putstatus(cs, "LogEcho: ", "warning Frame too big (%d)", skb->len); } diff --git a/drivers/isdn/hisax/hscx_irq.c b/drivers/isdn/hisax/hscx_irq.c index f398d483893..a8d6188402c 100644 --- a/drivers/isdn/hisax/hscx_irq.c +++ b/drivers/isdn/hisax/hscx_irq.c @@ -75,7 +75,7 @@ hscx_empty_fifo(struct BCState *bcs, int count) t += sprintf(t, "hscx_empty_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } @@ -115,7 +115,7 @@ hscx_fill_fifo(struct BCState *bcs) t += sprintf(t, "hscx_fill_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index db5321f6379..96d1df05044 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c @@ -134,7 +134,7 @@ icc_empty_fifo(struct IsdnCardState *cs, int count) t += sprintf(t, "icc_empty_fifo cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -176,7 +176,7 @@ icc_fill_fifo(struct IsdnCardState *cs) t += sprintf(t, "icc_fill_fifo cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -425,7 +425,7 @@ afterXPR: if (cs->debug & L1_DEB_MONITOR) debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]); } - AfterMOX1: + AfterMOX1: ; #endif } } diff --git a/drivers/isdn/hisax/ipacx.c b/drivers/isdn/hisax/ipacx.c index 74feb5c8306..5faa5de2430 100644 --- a/drivers/isdn/hisax/ipacx.c +++ b/drivers/isdn/hisax/ipacx.c @@ -260,7 +260,7 @@ dch_empty_fifo(struct IsdnCardState *cs, int count) t += sprintf(t, "dch_empty_fifo() cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -307,7 +307,7 @@ dch_fill_fifo(struct IsdnCardState *cs) t += sprintf(t, "dch_fill_fifo() cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -539,7 +539,7 @@ bch_empty_fifo(struct BCState *bcs, int count) t += sprintf(t, "bch_empty_fifo() B-%d cnt %d", hscx, count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } @@ -582,7 +582,7 @@ bch_fill_fifo(struct BCState *bcs) t += sprintf(t, "chb_fill_fifo() B-%d cnt %d", hscx, count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } diff --git a/drivers/isdn/hisax/isac.c b/drivers/isdn/hisax/isac.c index a365ccc1c99..7fdf78f4643 100644 --- a/drivers/isdn/hisax/isac.c +++ b/drivers/isdn/hisax/isac.c @@ -137,7 +137,7 @@ isac_empty_fifo(struct IsdnCardState *cs, int count) t += sprintf(t, "isac_empty_fifo cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -179,7 +179,7 @@ isac_fill_fifo(struct IsdnCardState *cs) t += sprintf(t, "isac_fill_fifo cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 7fdf34704fe..f4956c73aa1 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -74,7 +74,7 @@ sendmsg(struct IsdnCardState *cs, u_char his, u_char creg, u_char len, t = tmp; t += sprintf(t, "sendmbox cnt %d", len); QuickHex(t, &msg[len-i], (i > 64) ? 64 : i); - debugl1(cs, tmp); + debugl1(cs, "%s", tmp); i -= 64; } } @@ -105,7 +105,7 @@ rcv_mbox(struct IsdnCardState *cs, struct isar_reg *ireg, u_char *msg) t = tmp; t += sprintf(t, "rcv_mbox cnt %d", ireg->clsb); QuickHex(t, &msg[ireg->clsb - i], (i > 64) ? 64 : i); - debugl1(cs, tmp); + debugl1(cs, "%s", tmp); i -= 64; } } @@ -1248,7 +1248,7 @@ isar_int_main(struct IsdnCardState *cs) tp += sprintf(debbuf, "msg iis(%x) msb(%x)", ireg->iis, ireg->cmsb); QuickHex(tp, (u_char *)ireg->par, ireg->clsb); - debugl1(cs, debbuf); + debugl1(cs, "%s", debbuf); } break; case ISAR_IIS_INVMSG: diff --git a/drivers/isdn/hisax/jade.c b/drivers/isdn/hisax/jade.c index f946c58d8ab..e2ae7871a20 100644 --- a/drivers/isdn/hisax/jade.c +++ b/drivers/isdn/hisax/jade.c @@ -81,10 +81,7 @@ modejade(struct BCState *bcs, int mode, int bc) int jade = bcs->hw.hscx.hscx; if (cs->debug & L1_DEB_HSCX) { - char tmp[40]; - sprintf(tmp, "jade %c mode %d ichan %d", - 'A' + jade, mode, bc); - debugl1(cs, tmp); + debugl1(cs, "jade %c mode %d ichan %d", 'A' + jade, mode, bc); } bcs->mode = mode; bcs->channel = bc; @@ -257,23 +254,18 @@ void clear_pending_jade_ints(struct IsdnCardState *cs) { int val; - char tmp[64]; cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0x00); cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0x00); val = cs->BC_Read_Reg(cs, 1, jade_HDLC_ISR); - sprintf(tmp, "jade B ISTA %x", val); - debugl1(cs, tmp); + debugl1(cs, "jade B ISTA %x", val); val = cs->BC_Read_Reg(cs, 0, jade_HDLC_ISR); - sprintf(tmp, "jade A ISTA %x", val); - debugl1(cs, tmp); + debugl1(cs, "jade A ISTA %x", val); val = cs->BC_Read_Reg(cs, 1, jade_HDLC_STAR); - sprintf(tmp, "jade B STAR %x", val); - debugl1(cs, tmp); + debugl1(cs, "jade B STAR %x", val); val = cs->BC_Read_Reg(cs, 0, jade_HDLC_STAR); - sprintf(tmp, "jade A STAR %x", val); - debugl1(cs, tmp); + debugl1(cs, "jade A STAR %x", val); /* Unmask ints */ cs->BC_Write_Reg(cs, 0, jade_HDLC_IMR, 0xF8); cs->BC_Write_Reg(cs, 1, jade_HDLC_IMR, 0xF8); diff --git a/drivers/isdn/hisax/jade_irq.c b/drivers/isdn/hisax/jade_irq.c index f521fc83dc7..b930da9b5aa 100644 --- a/drivers/isdn/hisax/jade_irq.c +++ b/drivers/isdn/hisax/jade_irq.c @@ -65,7 +65,7 @@ jade_empty_fifo(struct BCState *bcs, int count) t += sprintf(t, "jade_empty_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } @@ -105,7 +105,7 @@ jade_fill_fifo(struct BCState *bcs) t += sprintf(t, "jade_fill_fifo %c cnt %d", bcs->hw.hscx.hscx ? 'B' : 'A', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } diff --git a/drivers/isdn/hisax/l3_1tr6.c b/drivers/isdn/hisax/l3_1tr6.c index 4c1bca5caa1..875402e76d0 100644 --- a/drivers/isdn/hisax/l3_1tr6.c +++ b/drivers/isdn/hisax/l3_1tr6.c @@ -63,7 +63,7 @@ l3_1tr6_error(struct l3_process *pc, u_char *msg, struct sk_buff *skb) { dev_kfree_skb(skb); if (pc->st->l3.debug & L3_DEB_WARN) - l3_debug(pc->st, msg); + l3_debug(pc->st, "%s", msg); l3_1tr6_release_req(pc, 0, NULL); } @@ -161,7 +161,6 @@ l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg) { u_char *p; int bcfound = 0; - char tmp[80]; struct sk_buff *skb = arg; /* Channel Identification */ @@ -214,10 +213,9 @@ l3_1tr6_setup(struct l3_process *pc, u_char pr, void *arg) /* Signal all services, linklevel takes care of Service-Indicator */ if (bcfound) { if ((pc->para.setup.si1 != 7) && (pc->st->l3.debug & L3_DEB_WARN)) { - sprintf(tmp, "non-digital call: %s -> %s", + l3_debug(pc->st, "non-digital call: %s -> %s", pc->para.setup.phone, pc->para.setup.eazmsn); - l3_debug(pc->st, tmp); } newl3state(pc, 6); pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc); @@ -301,7 +299,7 @@ l3_1tr6_info(struct l3_process *pc, u_char pr, void *arg) { u_char *p; int i, tmpcharge = 0; - char a_charge[8], tmp[32]; + char a_charge[8]; struct sk_buff *skb = arg; p = skb->data; @@ -316,8 +314,8 @@ l3_1tr6_info(struct l3_process *pc, u_char pr, void *arg) pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); } if (pc->st->l3.debug & L3_DEB_CHARGE) { - sprintf(tmp, "charging info %d", pc->para.chargeinfo); - l3_debug(pc->st, tmp); + l3_debug(pc->st, "charging info %d", + pc->para.chargeinfo); } } else if (pc->st->l3.debug & L3_DEB_CHARGE) l3_debug(pc->st, "charging info not found"); @@ -399,7 +397,7 @@ l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg) struct sk_buff *skb = arg; u_char *p; int i, tmpcharge = 0; - char a_charge[8], tmp[32]; + char a_charge[8]; StopAllL3Timer(pc); p = skb->data; @@ -414,8 +412,8 @@ l3_1tr6_disc(struct l3_process *pc, u_char pr, void *arg) pc->st->l3.l3l4(pc->st, CC_CHARGE | INDICATION, pc); } if (pc->st->l3.debug & L3_DEB_CHARGE) { - sprintf(tmp, "charging info %d", pc->para.chargeinfo); - l3_debug(pc->st, tmp); + l3_debug(pc->st, "charging info %d", + pc->para.chargeinfo); } } else if (pc->st->l3.debug & L3_DEB_CHARGE) l3_debug(pc->st, "charging info not found"); @@ -746,7 +744,6 @@ up1tr6(struct PStack *st, int pr, void *arg) int i, mt, cr; struct l3_process *proc; struct sk_buff *skb = arg; - char tmp[80]; switch (pr) { case (DL_DATA | INDICATION): @@ -762,26 +759,23 @@ up1tr6(struct PStack *st, int pr, void *arg) } if (skb->len < 4) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6 len only %d", skb->len); - l3_debug(st, tmp); + l3_debug(st, "up1tr6 len only %d", skb->len); } dev_kfree_skb(skb); return; } if ((skb->data[0] & 0xfe) != PROTO_DIS_N0) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6%sunexpected discriminator %x message len %d", + l3_debug(st, "up1tr6%sunexpected discriminator %x message len %d", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", skb->data[0], skb->len); - l3_debug(st, tmp); } dev_kfree_skb(skb); return; } if (skb->data[1] != 1) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6 CR len not 1"); - l3_debug(st, tmp); + l3_debug(st, "up1tr6 CR len not 1"); } dev_kfree_skb(skb); return; @@ -791,9 +785,8 @@ up1tr6(struct PStack *st, int pr, void *arg) if (skb->data[0] == PROTO_DIS_N0) { dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { - sprintf(tmp, "up1tr6%s N0 mt %x unhandled", + l3_debug(st, "up1tr6%s N0 mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", mt); - l3_debug(st, tmp); } } else if (skb->data[0] == PROTO_DIS_N1) { if (!(proc = getl3proc(st, cr))) { @@ -801,8 +794,7 @@ up1tr6(struct PStack *st, int pr, void *arg) if (cr < 128) { if (!(proc = new_l3_process(st, cr))) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6 no roc mem"); - l3_debug(st, tmp); + l3_debug(st, "up1tr6 no roc mem"); } dev_kfree_skb(skb); return; @@ -821,8 +813,7 @@ up1tr6(struct PStack *st, int pr, void *arg) } else { if (!(proc = new_l3_process(st, cr))) { if (st->l3.debug & L3_DEB_PROTERR) { - sprintf(tmp, "up1tr6 no roc mem"); - l3_debug(st, tmp); + l3_debug(st, "up1tr6 no roc mem"); } dev_kfree_skb(skb); return; @@ -837,18 +828,16 @@ up1tr6(struct PStack *st, int pr, void *arg) if (i == ARRAY_SIZE(datastln1)) { dev_kfree_skb(skb); if (st->l3.debug & L3_DEB_STATE) { - sprintf(tmp, "up1tr6%sstate %d mt %x unhandled", + l3_debug(st, "up1tr6%sstate %d mt %x unhandled", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", proc->state, mt); - l3_debug(st, tmp); } return; } else { if (st->l3.debug & L3_DEB_STATE) { - sprintf(tmp, "up1tr6%sstate %d mt %x", + l3_debug(st, "up1tr6%sstate %d mt %x", (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ", proc->state, mt); - l3_debug(st, tmp); } datastln1[i].rout(proc, pr, skb); } @@ -861,7 +850,6 @@ down1tr6(struct PStack *st, int pr, void *arg) int i, cr; struct l3_process *proc; struct Channel *chan; - char tmp[80]; if ((DL_ESTABLISH | REQUEST) == pr) { l3_msg(st, pr, NULL); @@ -888,15 +876,13 @@ down1tr6(struct PStack *st, int pr, void *arg) break; if (i == ARRAY_SIZE(downstl)) { if (st->l3.debug & L3_DEB_STATE) { - sprintf(tmp, "down1tr6 state %d prim %d unhandled", + l3_debug(st, "down1tr6 state %d prim %d unhandled", proc->state, pr); - l3_debug(st, tmp); } } else { if (st->l3.debug & L3_DEB_STATE) { - sprintf(tmp, "down1tr6 state %d prim %d", + l3_debug(st, "down1tr6 state %d prim %d", proc->state, pr); - l3_debug(st, tmp); } downstl[i].rout(proc, pr, arg); } diff --git a/drivers/isdn/hisax/l3ni1.c b/drivers/isdn/hisax/l3ni1.c index 0df6691d045..8dc791bfaa6 100644 --- a/drivers/isdn/hisax/l3ni1.c +++ b/drivers/isdn/hisax/l3ni1.c @@ -2059,13 +2059,17 @@ static int l3ni1_cmd_global(struct PStack *st, isdn_ctrl *ic) memcpy(p, ic->parm.ni1_io.data, ic->parm.ni1_io.datalen); /* copy data */ l = (p - temp) + ic->parm.ni1_io.datalen; /* total length */ - if (ic->parm.ni1_io.timeout > 0) - if (!(pc = ni1_new_l3_process(st, -1))) - { free_invoke_id(st, id); + if (ic->parm.ni1_io.timeout > 0) { + pc = ni1_new_l3_process(st, -1); + if (!pc) { + free_invoke_id(st, id); return (-2); } - pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; /* remember id */ - pc->prot.ni1.proc = ic->parm.ni1_io.proc; /* and procedure */ + /* remember id */ + pc->prot.ni1.ll_id = ic->parm.ni1_io.ll_id; + /* and procedure */ + pc->prot.ni1.proc = ic->parm.ni1_io.proc; + } if (!(skb = l3_alloc_skb(l))) { free_invoke_id(st, id); diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index b646eed379d..233e432e06f 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -176,7 +176,7 @@ static void printframe(struct IsdnCardState *cs, u_char *buf, int count, char *s else j = i; QuickHex(t, p, j); - debugl1(cs, tmp); + debugl1(cs, "%s", tmp); p += j; i -= j; t = tmp; diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index 041bf52d9d0..b420f8bd862 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c @@ -810,7 +810,7 @@ prfeatureind(char *dest, u_char *p) dp += sprintf(dp, " octet 3 "); dp += prbits(dp, *p, 8, 8); *dp++ = '\n'; - if (!(*p++ & 80)) { + if (!(*p++ & 0x80)) { dp += sprintf(dp, " octet 4 "); dp += prbits(dp, *p++, 8, 8); *dp++ = '\n'; @@ -1179,7 +1179,7 @@ LogFrame(struct IsdnCardState *cs, u_char *buf, int size) dp--; *dp++ = '\n'; *dp = 0; - HiSax_putstatus(cs, NULL, cs->dlog); + HiSax_putstatus(cs, NULL, "%s", cs->dlog); } else HiSax_putstatus(cs, "LogFrame: ", "warning Frame too big (%d)", size); } @@ -1246,7 +1246,7 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) } if (finish) { *dp = 0; - HiSax_putstatus(cs, NULL, cs->dlog); + HiSax_putstatus(cs, NULL, "%s", cs->dlog); return; } if ((0xfe & buf[0]) == PROTO_DIS_N0) { /* 1TR6 */ @@ -1509,5 +1509,5 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) dp += sprintf(dp, "Unknown protocol %x!", buf[0]); } *dp = 0; - HiSax_putstatus(cs, NULL, cs->dlog); + HiSax_putstatus(cs, NULL, "%s", cs->dlog); } diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index f6ab63aa699..33eeb4602c7 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c @@ -290,10 +290,6 @@ int setup_telespci(struct IsdnCard *card) struct IsdnCardState *cs = card->cs; char tmp[64]; -#ifdef __BIG_ENDIAN -#error "not running on big endian machines now" -#endif - strcpy(tmp, telespci_revision); printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_TELESPCI) diff --git a/drivers/isdn/hisax/w6692.c b/drivers/isdn/hisax/w6692.c index d8cac693581..a85895585d9 100644 --- a/drivers/isdn/hisax/w6692.c +++ b/drivers/isdn/hisax/w6692.c @@ -154,7 +154,7 @@ W6692_empty_fifo(struct IsdnCardState *cs, int count) t += sprintf(t, "W6692_empty_fifo cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -196,7 +196,7 @@ W6692_fill_fifo(struct IsdnCardState *cs) t += sprintf(t, "W6692_fill_fifo cnt %d", count); QuickHex(t, ptr, count); - debugl1(cs, cs->dlog); + debugl1(cs, "%s", cs->dlog); } } @@ -226,7 +226,7 @@ W6692B_empty_fifo(struct BCState *bcs, int count) t += sprintf(t, "W6692B_empty_fifo %c cnt %d", bcs->channel + '1', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } @@ -264,7 +264,7 @@ W6692B_fill_fifo(struct BCState *bcs) t += sprintf(t, "W6692B_fill_fifo %c cnt %d", bcs->channel + '1', count); QuickHex(t, ptr, count); - debugl1(cs, bcs->blog); + debugl1(cs, "%s", bcs->blog); } } diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index b61e8d5e84a..7b5fd8fb176 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -175,14 +175,15 @@ hysdn_log_read(struct file *file, char __user *buf, size_t count, loff_t *off) int len; hysdn_card *card = PDE_DATA(file_inode(file)); - if (!*((struct log_data **) file->private_data)) { + if (!(inf = *((struct log_data **) file->private_data))) { struct procdata *pd = card->proclog; if (file->f_flags & O_NONBLOCK) return (-EAGAIN); - interruptible_sleep_on(&(pd->rd_queue)); + wait_event_interruptible(pd->rd_queue, (inf = + *((struct log_data **) file->private_data))); } - if (!(inf = *((struct log_data **) file->private_data))) + if (!inf) return (0); inf->usage_cnt--; /* new usage count */ diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 9bb12ba3191..9b856e1890d 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -777,7 +777,8 @@ isdn_readbchan(int di, int channel, u_char *buf, u_char *fp, int len, wait_queue return 0; if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) { if (sleep) - interruptible_sleep_on(sleep); + wait_event_interruptible(*sleep, + !skb_queue_empty(&dev->drv[di]->rpqueue[channel])); else return 0; } @@ -1072,7 +1073,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off) retval = -EAGAIN; goto out; } - interruptible_sleep_on(&(dev->info_waitq)); + wait_event_interruptible(dev->info_waitq, + file->private_data); } p = isdn_statstr(); file->private_data = NULL; @@ -1128,7 +1130,8 @@ isdn_read(struct file *file, char __user *buf, size_t count, loff_t *off) retval = -EAGAIN; goto out; } - interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq)); + wait_event_interruptible(dev->drv[drvidx]->st_waitq, + dev->drv[drvidx]->stavail); } if (dev->drv[drvidx]->interface->readstat) { if (count > dev->drv[drvidx]->stavail) @@ -1188,8 +1191,8 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t *off) goto out; } chidx = isdn_minor2chan(minor); - while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0) - interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); + wait_event_interruptible(dev->drv[drvidx]->snd_waitq[chidx], + (retval = isdn_writebuf_stub(drvidx, chidx, buf, count))); goto out; } if (minor <= ISDN_MINOR_CTRLMAX) { @@ -2378,7 +2381,7 @@ static void __exit isdn_exit(void) } isdn_tty_exit(); unregister_chrdev(ISDN_MAJOR, "isdn"); - del_timer(&dev->timer); + del_timer_sync(&dev->timer); /* call vfree with interrupts enabled, else it will hang */ vfree(dev); printk(KERN_NOTICE "ISDN-subsystem unloaded\n"); diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c index 88d657dff47..d9aebbc510c 100644 --- a/drivers/isdn/i4l/isdn_net.c +++ b/drivers/isdn/i4l/isdn_net.c @@ -885,7 +885,7 @@ isdn_net_log_skb(struct sk_buff *skb, isdn_net_local *lp) addinfo[0] = '\0'; /* This check stolen from 2.1.72 dev_queue_xmit_nit() */ - if (p < skb->data || skb->network_header >= skb->tail) { + if (p < skb->data || skb_network_header(skb) >= skb_tail_pointer(skb)) { /* fall back to old isdn_net_log_packet method() */ char *buf = skb->data; @@ -1371,7 +1371,7 @@ isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev) eth = eth_hdr(skb); if (*eth->h_dest & 1) { - if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0) + if (ether_addr_equal(eth->h_dest, dev->broadcast)) skb->pkt_type = PACKET_BROADCAST; else skb->pkt_type = PACKET_MULTICAST; @@ -1382,7 +1382,7 @@ isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev) */ else if (dev->flags & (IFF_PROMISC /*| IFF_ALLMULTI*/)) { - if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN)) + if (!ether_addr_equal(eth->h_dest, dev->dev_addr)) skb->pkt_type = PACKET_OTHERHOST; } if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN) diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 38ceac5053a..62f0688d45a 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -378,10 +378,15 @@ isdn_ppp_release(int min, struct file *file) is->slcomp = NULL; #endif #ifdef CONFIG_IPPP_FILTER - kfree(is->pass_filter); - is->pass_filter = NULL; - kfree(is->active_filter); - is->active_filter = NULL; + if (is->pass_filter) { + sk_unattached_filter_destroy(is->pass_filter); + is->pass_filter = NULL; + } + + if (is->active_filter) { + sk_unattached_filter_destroy(is->active_filter); + is->active_filter = NULL; + } #endif /* TODO: if this was the previous master: link the stuff to the new master */ @@ -437,7 +442,7 @@ static int get_filter(void __user *arg, struct sock_filter **p) { struct sock_fprog uprog; struct sock_filter *code = NULL; - int len, err; + int len; if (copy_from_user(&uprog, arg, sizeof(uprog))) return -EFAULT; @@ -453,12 +458,6 @@ static int get_filter(void __user *arg, struct sock_filter **p) if (IS_ERR(code)) return PTR_ERR(code); - err = sk_chk_filter(code, uprog.len); - if (err) { - kfree(code); - return err; - } - *p = code; return uprog.len; } @@ -629,25 +628,53 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg) #ifdef CONFIG_IPPP_FILTER case PPPIOCSPASS: { + struct sock_fprog_kern fprog; struct sock_filter *code; - int len = get_filter(argp, &code); + int err, len = get_filter(argp, &code); + if (len < 0) return len; - kfree(is->pass_filter); - is->pass_filter = code; - is->pass_len = len; - break; + + fprog.len = len; + fprog.filter = code; + + if (is->pass_filter) { + sk_unattached_filter_destroy(is->pass_filter); + is->pass_filter = NULL; + } + if (fprog.filter != NULL) + err = sk_unattached_filter_create(&is->pass_filter, + &fprog); + else + err = 0; + kfree(code); + + return err; } case PPPIOCSACTIVE: { + struct sock_fprog_kern fprog; struct sock_filter *code; - int len = get_filter(argp, &code); + int err, len = get_filter(argp, &code); + if (len < 0) return len; - kfree(is->active_filter); - is->active_filter = code; - is->active_len = len; - break; + + fprog.len = len; + fprog.filter = code; + + if (is->active_filter) { + sk_unattached_filter_destroy(is->active_filter); + is->active_filter = NULL; + } + if (fprog.filter != NULL) + err = sk_unattached_filter_create(&is->active_filter, + &fprog); + else + err = 0; + kfree(code); + + return err; } #endif /* CONFIG_IPPP_FILTER */ default: @@ -1147,14 +1174,14 @@ isdn_ppp_push_higher(isdn_net_dev *net_dev, isdn_net_local *lp, struct sk_buff * } if (is->pass_filter - && sk_run_filter(skb, is->pass_filter) == 0) { + && SK_RUN_FILTER(is->pass_filter, skb) == 0) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: inbound frame filtered.\n"); kfree_skb(skb); return; } if (!(is->active_filter - && sk_run_filter(skb, is->active_filter) == 0)) { + && SK_RUN_FILTER(is->active_filter, skb) == 0)) { if (is->debug & 0x2) printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n"); lp->huptimer = 0; @@ -1293,14 +1320,14 @@ isdn_ppp_xmit(struct sk_buff *skb, struct net_device *netdev) } if (ipt->pass_filter - && sk_run_filter(skb, ipt->pass_filter) == 0) { + && SK_RUN_FILTER(ipt->pass_filter, skb) == 0) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: outbound frame filtered.\n"); kfree_skb(skb); goto unlock; } if (!(ipt->active_filter - && sk_run_filter(skb, ipt->active_filter) == 0)) { + && SK_RUN_FILTER(ipt->active_filter, skb) == 0)) { if (ipt->debug & 0x4) printk(KERN_DEBUG "IPPP: link-active filter: resetting huptimer.\n"); lp->huptimer = 0; @@ -1490,9 +1517,9 @@ int isdn_ppp_autodial_filter(struct sk_buff *skb, isdn_net_local *lp) } drop |= is->pass_filter - && sk_run_filter(skb, is->pass_filter) == 0; + && SK_RUN_FILTER(is->pass_filter, skb) == 0; drop |= is->active_filter - && sk_run_filter(skb, is->active_filter) == 0; + && SK_RUN_FILTER(is->active_filter, skb) == 0; skb_push(skb, IPPP_MAX_HEADER - 4); return drop; diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index e74df7c4658..6a7447c304a 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -1155,7 +1155,7 @@ icn_command(isdn_ctrl *c, icn_card *card) ulong a; ulong flags; int i; - char cbuf[60]; + char cbuf[80]; isdn_ctrl cmd; icn_cdef cdef; char __user *arg; @@ -1309,7 +1309,6 @@ icn_command(isdn_ctrl *c, icn_card *card) break; if ((c->arg & 255) < ICN_BCH) { char *p; - char dial[50]; char dcode[4]; a = c->arg; @@ -1321,10 +1320,10 @@ icn_command(isdn_ctrl *c, icn_card *card) } else /* Normal Dial */ strcpy(dcode, "CAL"); - strcpy(dial, p); - sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), - dcode, dial, c->parm.setup.si1, - c->parm.setup.si2, c->parm.setup.eazmsn); + snprintf(cbuf, sizeof(cbuf), + "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), + dcode, p, c->parm.setup.si1, + c->parm.setup.si2, c->parm.setup.eazmsn); i = icn_writecmd(cbuf, strlen(cbuf), 0, card); } break; @@ -1580,8 +1579,7 @@ icn_addcard(int port, char *id1, char *id2) } if (!(card2 = icn_initcard(port, id2))) { printk(KERN_INFO - "icn: (%s) half ICN-4B, port 0x%x added\n", - card2->interface.id, port); + "icn: (%s) half ICN-4B, port 0x%x added\n", id2, port); return 0; } card->doubleS0 = 1; diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index baf2686aa8e..5a4da94aefb 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c @@ -518,9 +518,9 @@ static isdnloop_stat isdnloop_cmd_table[] = static void isdnloop_fake_err(isdnloop_card *card) { - char buf[60]; + char buf[64]; - sprintf(buf, "E%s", card->omsg); + snprintf(buf, sizeof(buf), "E%s", card->omsg); isdnloop_fake(card, buf, -1); isdnloop_fake(card, "NAK", -1); } @@ -903,6 +903,8 @@ isdnloop_parse_cmd(isdnloop_card *card) case 7: /* 0x;EAZ */ p += 3; + if (strlen(p) >= sizeof(card->eazlist[0])) + break; strcpy(card->eazlist[ch - 1], p); break; case 8: @@ -1070,6 +1072,12 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) return -EBUSY; if (copy_from_user((char *) &sdef, (char *) sdefp, sizeof(sdef))) return -EFAULT; + + for (i = 0; i < 3; i++) { + if (!memchr(sdef.num[i], 0, sizeof(sdef.num[i]))) + return -EINVAL; + } + spin_lock_irqsave(&card->isdnloop_lock, flags); switch (sdef.ptype) { case ISDN_PTYPE_EURO: @@ -1083,8 +1091,10 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) spin_unlock_irqrestore(&card->isdnloop_lock, flags); return -ENOMEM; } - for (i = 0; i < 3; i++) - strcpy(card->s0num[i], sdef.num[i]); + for (i = 0; i < 3; i++) { + strlcpy(card->s0num[i], sdef.num[i], + sizeof(card->s0num[0])); + } break; case ISDN_PTYPE_1TR6: if (isdnloop_fake(card, "DRV1.04TC-1TR6-CAPI-CNS-BASIS-29.11.95", @@ -1097,7 +1107,7 @@ isdnloop_start(isdnloop_card *card, isdnloop_sdef *sdefp) spin_unlock_irqrestore(&card->isdnloop_lock, flags); return -ENOMEM; } - strcpy(card->s0num[0], sdef.num[0]); + strlcpy(card->s0num[0], sdef.num[0], sizeof(card->s0num[0])); card->s0num[1][0] = '\0'; card->s0num[2][0] = '\0'; break; @@ -1125,7 +1135,7 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card) { ulong a; int i; - char cbuf[60]; + char cbuf[80]; isdn_ctrl cmd; isdnloop_cdef cdef; @@ -1190,7 +1200,6 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card) break; if ((c->arg & 255) < ISDNLOOP_BCH) { char *p; - char dial[50]; char dcode[4]; a = c->arg; @@ -1202,10 +1211,10 @@ isdnloop_command(isdn_ctrl *c, isdnloop_card *card) } else /* Normal Dial */ strcpy(dcode, "CAL"); - strcpy(dial, p); - sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), - dcode, dial, c->parm.setup.si1, - c->parm.setup.si2, c->parm.setup.eazmsn); + snprintf(cbuf, sizeof(cbuf), + "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), + dcode, p, c->parm.setup.si1, + c->parm.setup.si2, c->parm.setup.eazmsn); i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); } break; diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig index 1747a02a019..c0730d5c734 100644 --- a/drivers/isdn/mISDN/Kconfig +++ b/drivers/isdn/mISDN/Kconfig @@ -17,7 +17,7 @@ config MISDN_DSP This module may be used for special applications that require cross connecting of bchannels, conferencing, dtmf decoding, - echo cancelation, tone generation, and Blowfish encryption and + echo cancellation, tone generation, and Blowfish encryption and decryption. It may use hardware features if available. E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index da30c5cb960..faf505462a4 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c @@ -37,8 +37,8 @@ static void mISDN_dev_release(struct device *dev) /* nothing to do: the device is part of its parent's data structure */ } -static ssize_t _show_id(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t id_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mISDNdevice *mdev = dev_to_mISDN(dev); @@ -46,9 +46,10 @@ static ssize_t _show_id(struct device *dev, return -ENODEV; return sprintf(buf, "%d\n", mdev->id); } +static DEVICE_ATTR_RO(id); -static ssize_t _show_nrbchan(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t nrbchan_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mISDNdevice *mdev = dev_to_mISDN(dev); @@ -56,9 +57,10 @@ static ssize_t _show_nrbchan(struct device *dev, return -ENODEV; return sprintf(buf, "%d\n", mdev->nrbchan); } +static DEVICE_ATTR_RO(nrbchan); -static ssize_t _show_d_protocols(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t d_protocols_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mISDNdevice *mdev = dev_to_mISDN(dev); @@ -66,9 +68,10 @@ static ssize_t _show_d_protocols(struct device *dev, return -ENODEV; return sprintf(buf, "%d\n", mdev->Dprotocols); } +static DEVICE_ATTR_RO(d_protocols); -static ssize_t _show_b_protocols(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t b_protocols_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mISDNdevice *mdev = dev_to_mISDN(dev); @@ -76,9 +79,10 @@ static ssize_t _show_b_protocols(struct device *dev, return -ENODEV; return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols()); } +static DEVICE_ATTR_RO(b_protocols); -static ssize_t _show_protocol(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t protocol_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mISDNdevice *mdev = dev_to_mISDN(dev); @@ -86,17 +90,19 @@ static ssize_t _show_protocol(struct device *dev, return -ENODEV; return sprintf(buf, "%d\n", mdev->D.protocol); } +static DEVICE_ATTR_RO(protocol); -static ssize_t _show_name(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, char *buf) { strcpy(buf, dev_name(dev)); return strlen(buf); } +static DEVICE_ATTR_RO(name); #if 0 /* hangs */ -static ssize_t _set_name(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t name_set(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { int err = 0; char *out = kmalloc(count + 1, GFP_KERNEL); @@ -113,10 +119,11 @@ static ssize_t _set_name(struct device *dev, struct device_attribute *attr, return (err < 0) ? err : count; } +static DEVICE_ATTR_RW(name); #endif -static ssize_t _show_channelmap(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t channelmap_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct mISDNdevice *mdev = dev_to_mISDN(dev); char *bp = buf; @@ -127,18 +134,19 @@ static ssize_t _show_channelmap(struct device *dev, return bp - buf; } - -static struct device_attribute mISDN_dev_attrs[] = { - __ATTR(id, S_IRUGO, _show_id, NULL), - __ATTR(d_protocols, S_IRUGO, _show_d_protocols, NULL), - __ATTR(b_protocols, S_IRUGO, _show_b_protocols, NULL), - __ATTR(protocol, S_IRUGO, _show_protocol, NULL), - __ATTR(channelmap, S_IRUGO, _show_channelmap, NULL), - __ATTR(nrbchan, S_IRUGO, _show_nrbchan, NULL), - __ATTR(name, S_IRUGO, _show_name, NULL), -/* __ATTR(name, S_IRUGO | S_IWUSR, _show_name, _set_name), */ - {} +static DEVICE_ATTR_RO(channelmap); + +static struct attribute *mISDN_attrs[] = { + &dev_attr_id.attr, + &dev_attr_d_protocols.attr, + &dev_attr_b_protocols.attr, + &dev_attr_protocol.attr, + &dev_attr_channelmap.attr, + &dev_attr_nrbchan.attr, + &dev_attr_name.attr, + NULL, }; +ATTRIBUTE_GROUPS(mISDN); static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env) { @@ -162,7 +170,7 @@ static struct class mISDN_class = { .name = "mISDN", .owner = THIS_MODULE, .dev_uevent = mISDN_uevent, - .dev_attrs = mISDN_dev_attrs, + .dev_groups = mISDN_groups, .dev_release = mISDN_dev_release, .class_release = mISDN_class_release, }; diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 22b720ec80c..77025f5cb57 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -288,8 +288,10 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb) u8 *data; int len; - if (skb->len < sizeof(int)) + if (skb->len < sizeof(int)) { printk(KERN_ERR "%s: PH_CONTROL message too short\n", __func__); + return -EINVAL; + } cont = *((int *)skb->data); len = skb->len - sizeof(int); data = skb->data + sizeof(int); diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c index 88305c9cbff..8b1a66c6ca8 100644 --- a/drivers/isdn/mISDN/dsp_pipeline.c +++ b/drivers/isdn/mISDN/dsp_pipeline.c @@ -102,7 +102,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem) entry->dev.class = elements_class; entry->dev.release = mISDN_dsp_dev_release; dev_set_drvdata(&entry->dev, elem); - dev_set_name(&entry->dev, elem->name); + dev_set_name(&entry->dev, "%s", elem->name); ret = device_register(&entry->dev); if (ret) { printk(KERN_ERR "%s: failed to register %s\n", diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 2c0d2c2bf94..9f454d76cc0 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -287,11 +287,9 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask, p = frame; /* restart timer */ - if ((int)(hc->keep_tl.expires-jiffies) < 5 * HZ) { - del_timer(&hc->keep_tl); - hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; - add_timer(&hc->keep_tl); - } else + if (time_before(hc->keep_tl.expires, jiffies + 5 * HZ)) + mod_timer(&hc->keep_tl, jiffies + L1OIP_KEEPALIVE * HZ); + else hc->keep_tl.expires = jiffies + L1OIP_KEEPALIVE * HZ; if (debug & DEBUG_L1OIP_MSG) @@ -621,11 +619,9 @@ multiframe: goto multiframe; /* restart timer */ - if ((int)(hc->timeout_tl.expires-jiffies) < 5 * HZ || !hc->timeout_on) { + if (time_before(hc->timeout_tl.expires, jiffies + 5 * HZ) || !hc->timeout_on) { hc->timeout_on = 1; - del_timer(&hc->timeout_tl); - hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; - add_timer(&hc->timeout_tl); + mod_timer(&hc->timeout_tl, jiffies + L1OIP_TIMEOUT * HZ); } else /* only adjust timer */ hc->timeout_tl.expires = jiffies + L1OIP_TIMEOUT * HZ; diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index e47dcb9d1e9..1be82284cf9 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -117,7 +117,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, { struct sk_buff *skb; struct sock *sk = sock->sk; - struct sockaddr_mISDN *maddr; int copied, err; @@ -135,9 +134,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, if (!skb) return err; - if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { - msg->msg_namelen = sizeof(struct sockaddr_mISDN); - maddr = (struct sockaddr_mISDN *)msg->msg_name; + if (msg->msg_name) { + DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name); + maddr->family = AF_ISDN; maddr->dev = _pms(sk)->dev->id; if ((sk->sk_protocol == ISDN_P_LAPD_TE) || @@ -150,11 +149,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock, maddr->sapi = _pms(sk)->ch.addr & 0xFF; maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF; } - } else { - if (msg->msg_namelen) - printk(KERN_WARNING "%s: too small namelen %d\n", - __func__, msg->msg_namelen); - msg->msg_namelen = 0; + msg->msg_namelen = sizeof(*maddr); } copied = skb->len + MISDN_HEADER_LEN; @@ -184,7 +179,6 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct sock *sk = sock->sk; struct sk_buff *skb; int err = -ENOMEM; - struct sockaddr_mISDN *maddr; if (*debug & DEBUG_SOCKET) printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n", @@ -219,7 +213,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock, if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { /* if we have a address, we use it */ - maddr = (struct sockaddr_mISDN *)msg->msg_name; + DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name); mISDN_HEAD_ID(skb) = maddr->channel; } else { /* use default for L2 messages */ if ((sk->sk_protocol == ISDN_P_LAPD_TE) || diff --git a/drivers/isdn/pcbit/drv.c b/drivers/isdn/pcbit/drv.c index 1eaf6227390..f02cc506fbf 100644 --- a/drivers/isdn/pcbit/drv.c +++ b/drivers/isdn/pcbit/drv.c @@ -796,6 +796,7 @@ static void set_running_timeout(unsigned long ptr) #endif dev = (struct pcbit_dev *) ptr; + dev->l2_state = L2_DOWN; wake_up_interruptible(&dev->set_running_wq); } @@ -818,7 +819,8 @@ static int set_protocol_running(struct pcbit_dev *dev) add_timer(&dev->set_running_timer); - interruptible_sleep_on(&dev->set_running_wq); + wait_event(dev->set_running_wq, dev->l2_state == L2_RUNNING || + dev->l2_state == L2_DOWN); del_timer(&dev->set_running_timer); @@ -842,8 +844,6 @@ static int set_protocol_running(struct pcbit_dev *dev) printk(KERN_DEBUG "pcbit: initialization failed\n"); printk(KERN_DEBUG "pcbit: firmware not loaded\n"); - dev->l2_state = L2_DOWN; - #ifdef DEBUG printk(KERN_DEBUG "Bank3 = %02x\n", readb(dev->sh_mem + BANK3)); diff --git a/drivers/isdn/sc/event.c b/drivers/isdn/sc/event.c index 717003a3bdf..833d96c2cf9 100644 --- a/drivers/isdn/sc/event.c +++ b/drivers/isdn/sc/event.c @@ -57,7 +57,7 @@ int indicate_status(int card, int event, ulong Channel, char *Data) memcpy(&cmd.parm.setup, Data, sizeof(cmd.parm.setup)); break; default: - strcpy(cmd.parm.num, Data); + strlcpy(cmd.parm.num, Data, sizeof(cmd.parm.num)); } } diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c index ca997bd4e81..d6f19b168e8 100644 --- a/drivers/isdn/sc/init.c +++ b/drivers/isdn/sc/init.c @@ -336,7 +336,7 @@ static int __init sc_init(void) */ sc_adapter[cinst]->interrupt = irq[b]; if (request_irq(sc_adapter[cinst]->interrupt, interrupt_handler, - IRQF_DISABLED, interface->id, + 0, interface->id, (void *)(unsigned long) cinst)) { kfree(sc_adapter[cinst]->channel); @@ -390,8 +390,8 @@ static void __exit sc_exit(void) /* * kill the timers */ - del_timer(&(sc_adapter[i]->reset_timer)); - del_timer(&(sc_adapter[i]->stat_timer)); + del_timer_sync(&(sc_adapter[i]->reset_timer)); + del_timer_sync(&(sc_adapter[i]->stat_timer)); /* * Tell I4L we're toast |
