patch-2.4.0-test6 linux/drivers/isdn/isdn_common.c
Next file: linux/drivers/isdn/isdn_common.h
Previous file: linux/drivers/isdn/isdn_cards.h
Back to the patch index
Back to the overall index
- Lines: 825
- Date:
Tue Aug 8 15:03:57 2000
- Orig file:
v2.4.0-test5/linux/drivers/isdn/isdn_common.c
- Orig date:
Fri Jul 14 12:12:10 2000
diff -u --recursive --new-file v2.4.0-test5/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.101 2000/04/07 14:50:34 calle Exp $
+/* $Id: isdn_common.c,v 1.108 2000/06/24 15:52:47 keil Exp $
* Linux ISDN subsystem, common used functions (linklevel).
*
@@ -20,417 +20,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Log: isdn_common.c,v $
- * Revision 1.101 2000/04/07 14:50:34 calle
- * Bugfix: on my system 2.3.99-pre3 Dual PII 350, unload of module isdn.o
- * hangs if vfree is called with interrupt disabled. After moving
- * restore_flags in front of vfree it doesn't hang.
- *
- * Revision 1.100 2000/03/03 16:37:11 kai
- * incorporated some cosmetic changes from the official kernel tree back
- * into CVS
- *
- * Revision 1.99 2000/02/26 01:00:52 keil
- * changes from 2.3.47
- *
- * Revision 1.98 2000/02/16 14:56:27 paul
- * translated ISDN_MODEM_ANZREG to ISDN_MODEM_NUMREG for english speakers
- *
- * Revision 1.97 2000/01/23 18:45:37 keil
- * Change EAZ mapping to forbit the use of cards (insert a "-" for the MSN)
- *
- * Revision 1.96 2000/01/20 19:55:33 keil
- * Add FAX Class 1 support
- *
- * Revision 1.95 2000/01/09 20:43:13 detabc
- * exand logical bind-group's for both call's (in and out).
- * add first part of kernel-config-help for abc-extension.
- *
- * Revision 1.94 1999/11/20 22:14:13 detabc
- * added channel dial-skip in case of external use
- * (isdn phone or another isdn device) on the same NTBA.
- * usefull with two or more card's connected the different NTBA's.
- * global switchable in kernel-config and also per netinterface.
- *
- * add auto disable of netinterface's in case of:
- * to many connection's in short time.
- * config mistakes (wrong encapsulation, B2-protokoll or so on) on local
- * or remote side.
- * wrong password's or something else to a ISP (syncppp).
- *
- * possible encapsulations for this future are:
- * ISDN_NET_ENCAP_SYNCPPP, ISDN_NET_ENCAP_UIHDLC, ISDN_NET_ENCAP_RAWIP,
- * and ISDN_NET_ENCAP_CISCOHDLCK.
- *
- * Revision 1.93 1999/11/04 13:11:36 keil
- * Reinit of v110 structs
- *
- * Revision 1.92 1999/10/31 15:59:50 he
- * more skb headroom checks
- *
- * Revision 1.91 1999/10/28 22:48:45 armin
- * Bugfix: isdn_free_channel() now frees the channel,
- * even when the usage of the ttyI has changed.
- *
- * Revision 1.90 1999/10/27 21:21:17 detabc
- * Added support for building logically-bind-group's per interface.
- * usefull for outgoing call's with more then one isdn-card.
- *
- * Switchable support to dont reset the hangup-timeout for
- * receive frames. Most part's of the timru-rules for receiving frames
- * are now obsolete. If the input- or forwarding-firewall deny
- * the frame, the line will be not hold open.
- *
- * Revision 1.89 1999/10/16 14:46:47 keil
- * replace kmalloc with vmalloc for the big dev struct
- *
- * Revision 1.88 1999/10/02 00:39:26 he
- * Fixed a 2.3.x wait queue initialization (was causing panics)
- *
- * Revision 1.87 1999/09/12 16:19:39 detabc
- * added abc features
- * low cost routing for net-interfaces (only the HL side).
- * need more implementation in the isdnlog-utility
- * udp info support (first part).
- * different EAZ on outgoing call's.
- * more checks on D-Channel callbacks (double use of channels).
- * tested and running with kernel 2.3.17
- *
- * Revision 1.86 1999/07/31 12:59:42 armin
- * Added tty fax capabilities.
- *
- * Revision 1.85 1999/07/29 16:58:35 armin
- * Bugfix: DLE handling in isdn_readbchan()
- *
- * Revision 1.84 1999/07/25 16:21:10 keil
- * fix number matching
- *
- * Revision 1.83 1999/07/13 21:02:05 werner
- * Added limit possibilty of driver b_channel resources (ISDN_STAT_DISCH)
- *
- * Revision 1.82 1999/07/12 21:06:50 werner
- * Fixed problem when loading more than one driver temporary
- *
- * Revision 1.81 1999/07/11 17:14:09 armin
- * Added new layer 2 and 3 protocols for Fax and DSP functions.
- * Moved "Add CPN to RING message" to new register S23,
- * "Display message" is now correct on register S13 bit 7.
- * New audio command AT+VDD implemented (deactivate DTMF decoder and
- * activate possible existing hardware/DSP decoder).
- * Moved some tty defines to .h file.
- * Made whitespace possible in AT command line.
- * Some AT-emulator output bugfixes.
- * First Fax G3 implementations.
- *
- * Revision 1.80 1999/07/07 10:14:00 detabc
- * remove unused messages
- *
- * Revision 1.79 1999/07/05 23:51:30 werner
- * Allow limiting of available HiSax B-chans per card. Controlled by hisaxctrl
- * hisaxctrl id 10 <nr. of chans 0-2>
- *
- * Revision 1.78 1999/07/05 20:21:15 werner
- * changes to use diversion sources for all kernel versions.
- * removed static device, only proc filesystem used
- *
- * Revision 1.77 1999/07/01 08:29:50 keil
- * compatibility to 2.3 kernel
- *
- * Revision 1.76 1999/06/29 16:16:44 calle
- * Let ISDN_CMD_UNLOAD work with open isdn devices without crash again.
- * Also right unlocking (ISDN_CMD_UNLOCK) is done now.
- * isdnlog should check returncode of read(2) calls.
- *
- * Revision 1.75 1999/04/18 14:06:47 fritz
- * Removed TIMRU stuff.
- *
- * Revision 1.74 1999/04/12 13:16:45 fritz
- * Changes from 2.0 tree.
- *
- * Revision 1.73 1999/04/12 12:33:15 fritz
- * Changes from 2.0 tree.
- *
- * Revision 1.72 1999/03/02 12:04:44 armin
- * -added ISDN_STAT_ADDCH to increase supported channels after
- * register_isdn().
- * -ttyI now goes on-hook on ATZ when B-Ch is connected.
- * -added timer-function for register S7 (Wait for Carrier).
- * -analog modem (ISDN_PROTO_L2_MODEM) implementations.
- * -on L2_MODEM a string will be appended to the CONNECT-Message,
- * which is provided by the HL-Driver in parm.num in ISDN_STAT_BCONN.
- * -variable "dialing" used for ATA also, for interrupting call
- * establishment and register S7.
- *
- * Revision 1.71 1999/01/28 09:10:43 armin
- * Fixed bad while-loop in isdn_readbch().
- *
- * Revision 1.70 1999/01/15 19:58:54 he
- * removed compatibiltity macro
- *
- * Revision 1.69 1998/09/07 21:59:58 he
- * flush method for 2.1.118 and above
- * updated IIOCTLNETGPN
- *
- * Revision 1.68 1998/08/31 21:09:45 he
- * new ioctl IIOCNETGPN for /dev/isdninfo (get network interface'
- * peer phone number)
- *
- * Revision 1.67 1998/06/26 15:12:21 fritz
- * Added handling of STAT_ICALL with incomplete CPN.
- * Added AT&L for ttyI emulator.
- * Added more locking stuff in tty_write.
- *
- * Revision 1.66 1998/06/17 19:50:41 he
- * merged with 2.1.10[34] (cosmetics and udelay() -> mdelay())
- * brute force fix to avoid Ugh's in isdn_tty_write()
- * cleaned up some dead code
- *
- *
- * Revision 1.62 1998/04/14 16:28:43 he
- * Fixed user space access with interrupts off and remaining
- * copy_{to,from}_user() -> -EFAULT return codes
- *
- * Revision 1.61 1998/03/22 18:50:46 hipp
- * Added BSD Compression for syncPPP .. UNTESTED at the moment
- *
- * Revision 1.60 1998/03/19 13:18:18 keil
- * Start of a CAPI like interface for supplementary Service
- * first service: SUSPEND
- *
- * Revision 1.59 1998/03/09 17:46:23 he
- * merged in 2.1.89 changes
- *
- * Revision 1.58 1998/03/07 22:35:24 fritz
- * Starting generic module support (Nothing usable yet).
- *
- * Revision 1.57 1998/03/07 18:21:01 cal
- * Dynamic Timeout-Rule-Handling vs. 971110 included
- *
- * Revision 1.56 1998/02/25 17:49:38 he
- * Changed return codes caused be failing copy_{to,from}_user to -EFAULT
- *
- * Revision 1.55 1998/02/23 23:35:32 fritz
- * Eliminated some compiler warnings.
- *
- * Revision 1.54 1998/02/22 19:44:19 fritz
- * Bugfixes and improvements regarding V.110, V.110 now running.
- *
- * Revision 1.53 1998/02/20 17:18:05 fritz
- * Changes for recent kernels.
- * Added common stub for sending commands to lowlevel.
- * Added V.110.
- *
- * Revision 1.52 1998/01/31 22:05:57 keil
- * Lots of changes for X.25 support:
- * Added generic support for connection-controlling encapsulation protocols
- * Added support of BHUP status message
- * Added support for additional p_encap X25IFACE
- * Added support for kernels >= 2.1.72
- *
- * Revision 1.51 1998/01/31 19:17:29 calle
- * merged changes from and for 2.1.82
- *
- * Revision 1.50 1997/12/12 06:12:11 calle
- * moved EXPORT_SYMBOL(register_isdn) from isdn_syms.c to isdn_common.c
- *
- * Revision 1.49 1997/11/06 17:16:52 keil
- * Sync to 2.1.62 changes
- *
- * Revision 1.48 1997/11/02 23:55:50 keil
- * Andi Kleen's changes for 2.1.60
- * without it the isdninfo and isdnctrl devices won't work
- *
- * Revision 1.47 1997/10/09 21:28:46 fritz
- * New HL<->LL interface:
- * New BSENT callback with nr. of bytes included.
- * Sending without ACK.
- * New L1 error status (not yet in use).
- * Cleaned up obsolete structures.
- * Implemented Cisco-SLARP.
- * Changed local net-interface data to be dynamically allocated.
- * Removed old 2.0 compatibility stuff.
- *
- * Revision 1.46 1997/10/01 09:20:27 fritz
- * Removed old compatibility stuff for 2.0.X kernels.
- * From now on, this code is for 2.1.X ONLY!
- * Old stuff is still in the separate branch.
- *
- * Revision 1.45 1997/08/21 23:11:41 fritz
- * Added changes for kernels >= 2.1.45
- *
- * Revision 1.44 1997/05/27 15:17:23 fritz
- * Added changes for recent 2.1.x kernels:
- * changed return type of isdn_close
- * queue_task_* -> queue_task
- * clear/set_bit -> test_and_... where apropriate.
- * changed type of hard_header_cache parameter.
- *
- * Revision 1.43 1997/03/31 14:09:43 fritz
- * Fixed memory leak in isdn_close().
- *
- * Revision 1.42 1997/03/30 16:51:08 calle
- * changed calls to copy_from_user/copy_to_user and removed verify_area
- * were possible.
- *
- * Revision 1.41 1997/03/24 22:54:41 fritz
- * Some small fixes in debug code.
- *
- * Revision 1.40 1997/03/08 08:13:51 fritz
- * Bugfix: IIOCSETMAP (Set mapping) was broken.
- *
- * Revision 1.39 1997/03/07 01:32:54 fritz
- * Added proper ifdef's for CONFIG_ISDN_AUDIO
- *
- * Revision 1.38 1997/03/05 21:15:02 fritz
- * Fix: reduced stack usage of isdn_ioctl() and isdn_set_allcfg()
- *
- * Revision 1.37 1997/03/02 14:29:18 fritz
- * More ttyI related cleanup.
- *
- * Revision 1.36 1997/02/28 02:32:40 fritz
- * Cleanup: Moved some tty related stuff from isdn_common.c
- * to isdn_tty.c
- * Bugfix: Bisync protocol did not behave like documented.
- *
- * Revision 1.35 1997/02/21 13:01:19 fritz
- * Changes CAUSE message output in kernel log.
- *
- * Revision 1.34 1997/02/10 20:12:43 fritz
- * Changed interface for reporting incoming calls.
- *
- * Revision 1.33 1997/02/10 10:05:42 fritz
- * More changes for Kernel 2.1.X
- * Symbol information moved to isdn_syms.c
- *
- * Revision 1.32 1997/02/03 22:55:26 fritz
- * Reformatted according CodingStyle.
- * Changed isdn_writebuf_stub static.
- * Slow down tty-RING counter.
- * skb->free stuff replaced by macro.
- * Bugfix in audio-skb locking.
- * Bugfix in HL-driver locking.
- *
- * Revision 1.31 1997/01/17 01:19:18 fritz
- * Applied chargeint patch.
- *
- * Revision 1.30 1997/01/14 01:27:47 fritz
- * Changed audio receive not to rely on skb->users and skb->lock.
- * Added ATI2 and related variables.
- * Started adding full-duplex audio capability.
- *
- * Revision 1.29 1997/01/12 23:33:03 fritz
- * Made isdn_all_eaz foolproof.
- *
- * Revision 1.28 1996/11/13 02:33:19 fritz
- * Fixed a race condition.
- *
- * Revision 1.27 1996/10/27 22:02:41 keil
- * return codes for ISDN_STAT_ICALL
- *
- * Revision 1.26 1996/10/23 11:59:40 fritz
- * More compatibility changes.
- *
- * Revision 1.25 1996/10/22 23:13:54 fritz
- * Changes for compatibility to 2.0.X and 2.1.X kernels.
- *
- * Revision 1.24 1996/10/11 14:02:03 fritz
- * Bugfix: call to isdn_ppp_timer_timeout() never compiled, because of
- * typo in #ifdef.
- *
- * Revision 1.23 1996/06/25 18:35:38 fritz
- * Fixed bogus memory access in isdn_set_allcfg().
- *
- * Revision 1.22 1996/06/24 17:37:37 fritz
- * Bugfix: isdn_timer_ctrl() did restart timer, even if it
- * was already running.
- * lowlevel driver locking did use wrong parameters.
- *
- * Revision 1.21 1996/06/15 14:58:20 fritz
- * Added version signatures for data structures used
- * by userlevel programs.
- *
- * Revision 1.20 1996/06/12 16:01:49 fritz
- * Bugfix: Remote B-channel hangup sometimes did not result
- * in a NO CARRIER on tty.
- *
- * Revision 1.19 1996/06/11 14:52:04 hipp
- * minor bugfix in isdn_writebuf_skb_stub()
- *
- * Revision 1.18 1996/06/06 14:51:51 fritz
- * Changed to support DTMF decoding on audio playback also.
- *
- * Revision 1.17 1996/06/05 02:24:10 fritz
- * Added DTMF decoder for audio mode.
- *
- * Revision 1.16 1996/06/03 20:09:05 fritz
- * Bugfix: called wrong function pointer for locking in
- * isdn_get_free_channel().
- *
- * Revision 1.15 1996/05/31 01:10:54 fritz
- * Bugfixes:
- * Lowlevel modules did not get locked correctly.
- * Did show wrong revision when initializing.
- * Minor fixes in ioctl code.
- * sk_buff did not get freed, if error in writebuf_stub.
- *
- * Revision 1.14 1996/05/18 01:36:55 fritz
- * Added spelling corrections and some minor changes
- * to stay in sync with kernel.
- *
- * Revision 1.13 1996/05/17 15:43:30 fritz
- * Bugfix: decrement of rcvcount in readbchan() corrected.
- *
- * Revision 1.12 1996/05/17 03:55:43 fritz
- * Changed DLE handling for audio receive.
- * Some cleanup.
- * Added display of isdn_audio_revision.
- *
- * Revision 1.11 1996/05/11 21:51:32 fritz
- * Changed queue management to use sk_buffs.
- *
- * Revision 1.10 1996/05/10 08:49:16 fritz
- * Checkin before major changes of tty-code.
- *
- * Revision 1.9 1996/05/07 09:19:41 fritz
- * Adapted to changes in isdn_tty.c
- *
- * Revision 1.8 1996/05/06 11:34:51 hipp
- * fixed a few bugs
- *
- * Revision 1.7 1996/05/02 03:55:17 fritz
- * Bugfixes:
- * - B-channel connect message for modem devices
- * sometimes did not result in a CONNECT-message.
- * - register_isdn did not check for driverId-conflicts.
- *
- * Revision 1.6 1996/04/30 20:57:21 fritz
- * Commit test
- *
- * Revision 1.5 1996/04/20 16:19:07 fritz
- * Changed slow timer handlers to increase accuracy.
- * Added statistic information for usage by xisdnload.
- * Fixed behaviour of isdnctrl-device on non-blocked io.
- * Fixed all io to go through generic writebuf-function without
- * bypassing. Same for incoming data.
- * Fixed bug: Last channel had been unusable.
- * Fixed kfree of tty xmit_buf on ppp initialization failure.
- *
- * Revision 1.4 1996/02/11 02:33:26 fritz
- * Fixed bug in main timer-dispatcher.
- * Bugfix: Lot of tty-callbacks got called regardless of the events already
- * been handled by network-devices.
- * Changed ioctl-names.
- *
- * Revision 1.3 1996/01/22 05:16:11 fritz
- * Changed ioctl-names.
- * Fixed bugs in isdn_open and isdn_close regarding PPP_MINOR.
- *
- * Revision 1.2 1996/01/21 16:52:40 fritz
- * Support for sk_buffs added, changed header-stuffing.
- *
- * Revision 1.1 1996/01/09 04:12:52 fritz
- * Initial revision
- *
*/
#include <linux/config.h>
@@ -459,7 +48,7 @@
isdn_dev *dev = (isdn_dev *) 0;
-static char *isdn_revision = "$Revision: 1.101 $";
+static char *isdn_revision = "$Revision: 1.108 $";
extern char *isdn_net_revision;
extern char *isdn_tty_revision;
@@ -484,6 +73,7 @@
static void set_global_features(void);
static void isdn_register_devfs(int);
static void isdn_unregister_devfs(int);
+static int isdn_wildmat(char *s, char *p);
void
isdn_lock_drivers(void)
@@ -577,7 +167,7 @@
* [^xyz] matches any single character not in the set of characters
*/
-int
+static int
isdn_wildmat(char *s, char *p)
{
register int last;
@@ -623,6 +213,23 @@
return (*s == '\0')?0:nostar;
}
+int isdn_msncmp( const char * msn1, const char * msn2 )
+{
+ char TmpMsn1[ ISDN_MSNLEN ];
+ char TmpMsn2[ ISDN_MSNLEN ];
+ char *p;
+
+ for ( p = TmpMsn1; *msn1 && *msn1 != ':'; ) // Strip off a SPID
+ *p++ = *msn1++;
+ *p = '\0';
+
+ for ( p = TmpMsn2; *msn2 && *msn2 != ':'; ) // Strip off a SPID
+ *p++ = *msn2++;
+ *p = '\0';
+
+ return isdn_wildmat( TmpMsn1, TmpMsn2 );
+}
+
static void
isdn_free_queue(struct sk_buff_head *queue)
{
@@ -686,10 +293,6 @@
}
if (tf & ISDN_TIMER_CARRIER)
isdn_tty_carrier_timeout();
-#if (defined CONFIG_ISDN_PPP) && (defined CONFIG_ISDN_MPP)
- if (tf & ISDN_TIMER_IPPP)
- isdn_ppp_timer_timeout();
-#endif
}
}
if (tf)
@@ -850,6 +453,7 @@
int r;
int retval = 0;
isdn_ctrl cmd;
+ isdn_net_dev *p;
di = c->driver;
i = isdn_dc2minor(di, c->arg);
@@ -898,7 +502,7 @@
return 0;
}
/* Try to find a network-interface which will accept incoming call */
- r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, c->parm.setup));
+ r = ((c->command == ISDN_STAT_ICALLW) ? 0 : isdn_net_find_icall(di, c->arg, i, &c->parm.setup));
switch (r) {
case 0:
/* No network-device replies.
@@ -907,7 +511,7 @@
* 3 on eventually match, if CID is longer.
*/
if (c->command == ISDN_STAT_ICALL)
- if ((retval = isdn_tty_find_icall(di, c->arg, c->parm.setup))) return(retval);
+ if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval);
#ifdef CONFIG_ISDN_DIVERSION
if (divert_if)
if ((retval = divert_if->stat_callback(c)))
@@ -928,9 +532,16 @@
cmd.driver = di;
cmd.arg = c->arg;
cmd.command = ISDN_CMD_ACCEPTD;
- isdn_command(&cmd);
- retval = 1;
+ for ( p = dev->netdev; p; p = p->next )
+ if ( p->local->isdn_channel == cmd.arg )
+ {
+ strcpy( cmd.parm.setup.eazmsn, p->local->msn );
+ isdn_command(&cmd);
+ retval = 1;
+ break;
+ }
break;
+
case 2: /* For calling back, first reject incoming call ... */
case 3: /* Interface found, but down, reject call actively */
retval = 2;
@@ -1379,54 +990,78 @@
ulong flags;
int drvidx;
int chidx;
+ int retval;
char *p;
if (off != &file->f_pos)
return -ESPIPE;
+ lock_kernel();
if (minor == ISDN_MINOR_STATUS) {
if (!file->private_data) {
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto out;
+ }
interruptible_sleep_on(&(dev->info_waitq));
}
p = isdn_statstr();
file->private_data = 0;
if ((len = strlen(p)) <= count) {
- if (copy_to_user(buf, p, len))
- return -EFAULT;
+ if (copy_to_user(buf, p, len)) {
+ retval = -EFAULT;
+ goto out;
+ }
*off += len;
- return len;
+ retval = len;
+ goto out;
}
- return 0;
+ retval = 0;
+ goto out;
+ }
+ if (!dev->drivers) {
+ retval = -ENODEV;
+ goto out;
}
- if (!dev->drivers)
- return -ENODEV;
if (minor < ISDN_MINOR_CTRL) {
+ printk(KERN_WARNING "isdn_read minor %d obsolete!\n", minor);
drvidx = isdn_minor2drv(minor);
- if (drvidx < 0)
- return -ENODEV;
- if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
- return -ENODEV;
+ if (drvidx < 0) {
+ retval = -ENODEV;
+ goto out;
+ }
+ if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) {
+ retval = -ENODEV;
+ goto out;
+ }
chidx = isdn_minor2chan(minor);
- if( ! (p = kmalloc(count,GFP_KERNEL)) ) return -ENOMEM;
+ if (!(p = kmalloc(count, GFP_KERNEL))) {
+ retval = -ENOMEM;
+ goto out;
+ }
save_flags(flags);
cli();
len = isdn_readbchan(drvidx, chidx, p, 0, count,
&dev->drv[drvidx]->rcv_waitq[chidx]);
*off += len;
restore_flags(flags);
- if( copy_to_user(buf,p,len) ) len = -EFAULT;
+ if (copy_to_user(buf,p,len))
+ len = -EFAULT;
kfree(p);
- return len;
+ retval = len;
+ goto out;
}
if (minor <= ISDN_MINOR_CTRLMAX) {
drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
- if (drvidx < 0)
- return -ENODEV;
+ if (drvidx < 0) {
+ retval = -ENODEV;
+ goto out;
+ }
if (!dev->drv[drvidx]->stavail) {
- if (file->f_flags & O_NONBLOCK)
- return -EAGAIN;
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto out;
+ }
interruptible_sleep_on(&(dev->drv[drvidx]->st_waitq));
}
if (dev->drv[drvidx]->interface->readstat)
@@ -1443,17 +1078,23 @@
dev->drv[drvidx]->stavail = 0;
restore_flags(flags);
*off += len;
- return len;
+ retval = len;
+ goto out;
}
#ifdef CONFIG_ISDN_PPP
- if (minor <= ISDN_MINOR_PPPMAX)
- return (isdn_ppp_read(minor - ISDN_MINOR_PPP, file, buf, count));
+ if (minor <= ISDN_MINOR_PPPMAX) {
+ retval = isdn_ppp_read(minor - ISDN_MINOR_PPP, file, buf, count);
+ goto out;
+ }
#endif
- return -ENODEV;
+ retval = -ENODEV;
+ out:
+ unlock_kernel();
+ return retval;
}
static loff_t
-isdn_lseek(struct file *file, loff_t offset, int orig)
+isdn_llseek(struct file *file, loff_t offset, int orig)
{
return -ESPIPE;
}
@@ -1464,6 +1105,7 @@
uint minor = MINOR(file->f_dentry->d_inode->i_rdev);
int drvidx;
int chidx;
+ int retval;
if (off != &file->f_pos)
return -ESPIPE;
@@ -1472,21 +1114,31 @@
return -EPERM;
if (!dev->drivers)
return -ENODEV;
+
+ lock_kernel();
if (minor < ISDN_MINOR_CTRL) {
+ printk(KERN_WARNING "isdn_write minor %d obsolete!\n", minor);
drvidx = isdn_minor2drv(minor);
- if (drvidx < 0)
- return -ENODEV;
- if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
- return -ENODEV;
+ if (drvidx < 0) {
+ retval = -ENODEV;
+ goto out;
+ }
+ if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING)) {
+ retval = -ENODEV;
+ goto out;
+ }
chidx = isdn_minor2chan(minor);
while (isdn_writebuf_stub(drvidx, chidx, buf, count, 1) != count)
interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]);
- return count;
+ retval = count;
+ goto out;
}
if (minor <= ISDN_MINOR_CTRLMAX) {
drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
- if (drvidx < 0)
- return -ENODEV;
+ if (drvidx < 0) {
+ retval = -ENODEV;
+ goto out;
+ }
/*
* We want to use the isdnctrl device to load the firmware
*
@@ -1494,16 +1146,22 @@
return -ENODEV;
*/
if (dev->drv[drvidx]->interface->writecmd)
- return (dev->drv[drvidx]->interface->
- writecmd(buf, count, 1, drvidx, isdn_minor2chan(minor)));
+ retval = dev->drv[drvidx]->interface->
+ writecmd(buf, count, 1, drvidx, isdn_minor2chan(minor));
else
- return count;
+ retval = count;
+ goto out;
}
#ifdef CONFIG_ISDN_PPP
- if (minor <= ISDN_MINOR_PPPMAX)
- return (isdn_ppp_write(minor - ISDN_MINOR_PPP, file, buf, count));
+ if (minor <= ISDN_MINOR_PPPMAX) {
+ retval = isdn_ppp_write(minor - ISDN_MINOR_PPP, file, buf, count);
+ goto out;
+ }
#endif
- return -ENODEV;
+ retval = -ENODEV;
+ out:
+ unlock_kernel();
+ return retval;
}
static unsigned int
@@ -1513,32 +1171,38 @@
unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);
int drvidx = isdn_minor2drv(minor - ISDN_MINOR_CTRL);
+ lock_kernel();
if (minor == ISDN_MINOR_STATUS) {
poll_wait(file, &(dev->info_waitq), wait);
/* mask = POLLOUT | POLLWRNORM; */
if (file->private_data) {
mask |= POLLIN | POLLRDNORM;
}
- return mask;
+ goto out;
}
if (minor >= ISDN_MINOR_CTRL && minor <= ISDN_MINOR_CTRLMAX) {
if (drvidx < 0) {
/* driver deregistered while file open */
- return POLLHUP;
+ mask = POLLHUP;
+ goto out;
}
poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait);
mask = POLLOUT | POLLWRNORM;
if (dev->drv[drvidx]->stavail) {
mask |= POLLIN | POLLRDNORM;
}
- return mask;
+ goto out;
}
#ifdef CONFIG_ISDN_PPP
- if (minor <= ISDN_MINOR_PPPMAX)
- return (isdn_ppp_poll(file, wait));
+ if (minor <= ISDN_MINOR_PPPMAX) {
+ mask = isdn_ppp_poll(file, wait);
+ goto out;
+ }
#endif
- printk(KERN_ERR "isdn_common: isdn_poll 2 -> what the hell\n");
- return POLLERR;
+ mask = POLLERR;
+ out:
+ unlock_kernel();
+ return mask;
}
@@ -2013,6 +1677,7 @@
if (!dev->channels)
return -ENODEV;
if (minor < ISDN_MINOR_CTRL) {
+ printk(KERN_WARNING "isdn_open minor %d obsolete!\n", minor);
drvidx = isdn_minor2drv(minor);
if (drvidx < 0)
return -ENODEV;
@@ -2091,7 +1756,7 @@
static struct file_operations isdn_fops =
{
owner: THIS_MODULE,
- llseek: isdn_lseek,
+ llseek: isdn_llseek,
read: isdn_read,
write: isdn_write,
poll: isdn_poll,
@@ -2276,7 +1941,6 @@
skb_pull(nskb, sizeof(int));
if (!nskb->len) {
dev_kfree_skb(nskb);
- dev_kfree_skb(skb);
return v110_ret;
}
/* V.110 must always be acknowledged */
@@ -2315,9 +1979,10 @@
atomic_inc(&dev->v110use[idx]);
dev->v110[idx]->skbuser++;
atomic_dec(&dev->v110use[idx]);
- dev_kfree_skb(skb);
/* For V.110 return unencoded data length */
ret = v110_ret;
+ /* if the complete frame was send we free the skb;
+ if not upper function will requeue the skb */
if (ret == skb->len)
dev_kfree_skb(skb);
}
@@ -2639,7 +2304,7 @@
&isdn_fops, NULL);
dev->devfs_handle_isdnctrl =
devfs_register (devfs_handle, "isdnctrl", DEVFS_FL_DEFAULT,
- ISDN_MAJOR, ISDN_MINOR_CTRL, 0600 | S_IFCHR,
+ ISDN_MAJOR, ISDN_MINOR_CTRL, 0600 | S_IFCHR,
&isdn_fops, NULL);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)