patch-pre2.0.10 linux/drivers/isdn/isdn_common.c
Next file: linux/drivers/isdn/isdn_common.h
Previous file: linux/drivers/char/ftape/kernel-interface.c
Back to the patch index
Back to the overall index
- Lines: 319
- Date:
Sat Jun 1 11:56:51 1996
- Orig file:
pre2.0.9/linux/drivers/isdn/isdn_common.c
- Orig date:
Mon May 20 08:20:59 1996
diff -u --recursive --new-file pre2.0.9/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.14 1996/05/18 01:36:55 fritz Exp $
+/* $Id: isdn_common.c,v 1.15 1996/05/31 01:10:54 fritz Exp $
*
* Linux ISDN subsystem, common used functions (linklevel).
*
@@ -21,6 +21,13 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: isdn_common.c,v $
+ * 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.
@@ -102,7 +109,7 @@
isdn_dev *dev = (isdn_dev *) 0;
static int has_exported = 0;
-static char *isdn_revision = "$Revision: 1.14 $";
+static char *isdn_revision = "$Revision: 1.15 $";
extern char *isdn_net_revision;
extern char *isdn_tty_revision;
@@ -265,29 +272,22 @@
}
info = &dev->mdm.info[midx];
if ((info->online < 2) &&
- (info->vonline != 1)) {
+ (!(info->vonline & 1))) {
/* If Modem not listening, drop data */
isdn_trash_skb(skb, FREE_READ);
return;
}
if (info->emu.mdmreg[13] & 2)
/* T.70 decoding: Simply throw away the T.70 header (4 bytes) */
- if ((skb->data[0] == 1) && ((skb->data[1] == 0) || (skb->data[1] == 1))) {
-#ifdef ISDN_DEBUG_MODEM_DUMP
- isdn_dumppkt("T70strip1:", skb->data, skb->len, skb->len);
-#endif
+ if ((skb->data[0] == 1) && ((skb->data[1] == 0) || (skb->data[1] == 1)))
skb_pull(skb,4);
-#ifdef ISDN_DEBUG_MODEM_DUMP
- isdn_dumppkt("T70strip2:", skb->data, skb->len, skb->len);
-#endif
- }
/* The users field of an sk_buff is used in a special way
* with tty's incoming data:
* users is set to the number of DLE codes when in audio mode.
*/
skb->users = 0;
#ifdef CONFIG_ISDN_AUDIO
- if (info->vonline == 1) {
+ if (info->vonline & 1) {
int ifmt = 1;
/* voice conversion/compression */
switch (info->emu.vpar[3]) {
@@ -405,6 +405,10 @@
}
/* Try to find a network-interface which will accept incoming call */
+ cmd.driver = di;
+ cmd.arg = c->arg;
+ cmd.command = ISDN_CMD_LOCK;
+ dev->drv[di]->interface->command(&cmd);
r = isdn_net_find_icall(di, c->arg, i, c->num);
switch (r) {
case 0:
@@ -416,6 +420,7 @@
info->msr |= UART_MSR_RI;
isdn_tty_modem_result(2, info);
isdn_timer_ctrl(ISDN_TIMER_MODEMRING, 1);
+ return 0;
} else if (dev->drv[di]->reject_bus) {
cmd.driver = di;
cmd.arg = c->arg;
@@ -430,6 +435,7 @@
cmd.arg = c->arg;
cmd.command = ISDN_CMD_ACCEPTD;
dev->drv[di]->interface->command(&cmd);
+ return 0;
break;
case 2: /* For calling back, first reject incoming call ... */
case 3: /* Interface found, but down, reject call actively */
@@ -444,7 +450,12 @@
case 4:
/* ... then start callback. */
isdn_net_dial();
+ return 0;
}
+ cmd.driver = di;
+ cmd.arg = c->arg;
+ cmd.command = ISDN_CMD_UNLOCK;
+ dev->drv[di]->interface->command(&cmd);
return 0;
break;
case ISDN_STAT_CINF:
@@ -615,10 +626,19 @@
if (dev->drvmap[i] == di) {
dev->drvmap[i] = -1;
dev->chanmap[i] = -1;
- dev->mdm.info[i].isdn_driver = -1;
- dev->mdm.info[i].isdn_channel = -1;
- isdn_info_update();
}
+ for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+ modem_info *info = &dev->mdm.info[i];
+
+ if (info->isdn_driver == di) {
+ info->isdn_driver = -1;
+ info->isdn_channel = -1;
+ if (info->online) {
+ isdn_tty_modem_result(3, info);
+ isdn_tty_modem_hup(info);
+ }
+ }
+ }
dev->drivers--;
dev->channels -= dev->drv[di]->channels;
kfree(dev->drv[di]->rcverr);
@@ -1014,7 +1034,7 @@
restore_flags(flags);
return ret;
}
- memcpy_tofs((char *) &cfg, src, sizeof(cfg));
+ memcpy_fromfs((char *) &cfg, src, sizeof(cfg));
src += sizeof(cfg);
if (!isdn_net_new(cfg.name, NULL)) {
restore_flags(flags);
@@ -1264,9 +1284,9 @@
case IIOCNETDNM:
/* Delete a phone-number of a network-interface */
if (arg) {
- memcpy_fromfs((char *) &phone, (char *) arg, sizeof(phone));
if ((ret = verify_area(VERIFY_READ, (void *) arg, sizeof(phone))))
return ret;
+ memcpy_fromfs((char *) &phone, (char *) arg, sizeof(phone));
return isdn_net_delphone(&phone);
} else
return -EINVAL;
@@ -1589,10 +1609,10 @@
int drvidx;
isdn_ctrl c;
+ MOD_DEC_USE_COUNT;
if (minor == ISDN_MINOR_STATUS) {
infostruct *p = dev->infochain;
infostruct *q = NULL;
- MOD_DEC_USE_COUNT;
while (p) {
if (p->private == (char *) &(filep->private_data)) {
if (q)
@@ -1607,9 +1627,6 @@
printk(KERN_WARNING "isdn: No private data while closing isdnctrl\n");
return;
}
- if (!dev->channels)
- return;
- MOD_DEC_USE_COUNT;
if (minor < ISDN_MINOR_CTRL) {
drvidx = isdn_minor2drv(minor);
if (drvidx < 0)
@@ -1675,6 +1692,7 @@
int i;
ulong flags;
ulong features;
+ isdn_ctrl cmd;
save_flags(flags);
cli();
@@ -1692,6 +1710,10 @@
dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
dev->usage[i] |= usage;
isdn_info_update();
+ cmd.driver = i;
+ cmd.arg = 0;
+ cmd.command = ISDN_CMD_LOCK;
+ (void) dev->drv[i]->interface->command(&cmd);
restore_flags(flags);
return i;
} else {
@@ -1699,6 +1721,10 @@
dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
dev->usage[i] |= usage;
isdn_info_update();
+ cmd.driver = i;
+ cmd.arg = 0;
+ cmd.command = ISDN_CMD_LOCK;
+ (void) dev->drv[i]->interface->command(&cmd);
restore_flags(flags);
return i;
}
@@ -1717,6 +1743,7 @@
{
int i;
ulong flags;
+ isdn_ctrl cmd;
save_flags(flags);
cli();
@@ -1730,6 +1757,10 @@
dev->obytes[i] = 0;
isdn_info_update();
isdn_free_queue(&dev->drv[di]->rpqueue[ch]);
+ cmd.driver = di;
+ cmd.arg = ch;
+ cmd.command = ISDN_CMD_UNLOCK;
+ (void) dev->drv[di]->interface->command(&cmd);
restore_flags(flags);
return;
}
@@ -1810,6 +1841,8 @@
ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx,
chan, skb);
+ if (ret <= 0)
+ kfree_skb(skb, FREE_WRITE);
}
if (ret > 0)
dev->obytes[isdn_dc2minor(drvidx,chan)] += ret;
@@ -1831,9 +1864,9 @@
if (dev->drv[drvidx]->interface->writebuf_skb)
ret = dev->drv[drvidx]->interface->
writebuf_skb(drvidx, chan, skb);
- else {
+ else {
if ((ret = dev->drv[drvidx]->interface->
- writebuf(drvidx,chan,skb->data,skb->len,0))==skb->len)
+ writebuf(drvidx,chan,skb->data,skb->len,0)) == skb->len)
dev_kfree_skb(skb, FREE_WRITE);
}
if (ret > 0)
@@ -1970,15 +2003,15 @@
static char *isdn_getrev(const char *revision)
{
- static char rev[20];
+ char *rev;
char *p;
if ((p = strchr(revision, ':'))) {
- strcpy(rev, p + 2);
+ rev = p + 2;
p = strchr(rev, '$');
*--p = 0;
} else
- strcpy(rev, "???");
+ rev = "???";
return rev;
}
@@ -2000,6 +2033,11 @@
int isdn_init(void)
{
int i;
+ char irev[50];
+ char trev[50];
+ char nrev[50];
+ char prev[50];
+ char arev[50];
sti();
if (!(dev = (isdn_dev *) kmalloc(sizeof(isdn_dev), GFP_KERNEL))) {
@@ -2007,9 +2045,8 @@
return -EIO;
}
memset((char *) dev, 0, sizeof(isdn_dev));
- for (i = 0; i < ISDN_MAX_CHANNELS; i++)
- dev->drvmap[i] = -1;
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+ dev->drvmap[i] = -1;
dev->chanmap[i] = -1;
dev->m_idx[i] = -1;
strcpy(dev->num[i], "???");
@@ -2035,7 +2072,7 @@
tty_unregister_driver(&dev->mdm.tty_modem);
tty_unregister_driver(&dev->mdm.cua_modem);
for (i = 0; i < ISDN_MAX_CHANNELS; i++)
- kfree(dev->mdm.info[i].xmit_buf);
+ kfree(dev->mdm.info[i].xmit_buf - 4);
unregister_chrdev(ISDN_MAJOR, "isdn");
kfree(dev);
return -EIO;
@@ -2045,11 +2082,16 @@
if (!has_exported)
isdn_export_syms();
- printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(isdn_revision));
- printk("%s/", isdn_getrev(isdn_tty_revision));
- printk("%s/", isdn_getrev(isdn_net_revision));
- printk("%s/", isdn_getrev(isdn_ppp_revision));
- printk("%s", isdn_getrev(isdn_audio_revision));
+ strcpy(irev,isdn_revision);
+ strcpy(trev,isdn_tty_revision);
+ strcpy(nrev,isdn_net_revision);
+ strcpy(prev,isdn_ppp_revision);
+ strcpy(arev,isdn_audio_revision);
+ printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(irev));
+ printk("%s/", isdn_getrev(trev));
+ printk("%s/", isdn_getrev(nrev));
+ printk("%s/", isdn_getrev(prev));
+ printk("%s", isdn_getrev(arev));
#ifdef MODULE
printk(" loaded\n");
@@ -2092,7 +2134,7 @@
}
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
isdn_tty_cleanup_xmit(&dev->mdm.info[i]);
- kfree(dev->mdm.info[i].xmit_buf);
+ kfree(dev->mdm.info[i].xmit_buf - 4);
}
if (unregister_chrdev(ISDN_MAJOR, "isdn") != 0) {
printk(KERN_WARNING "isdn: controldevice busy, remove cancelled\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this