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.
This commit is contained in:
parent
f6b3ceed37
commit
c10db89681
2 changed files with 84 additions and 12 deletions
|
@ -6,6 +6,9 @@
|
|||
* Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
|
||||
*
|
||||
* $Log$
|
||||
* Revision 1.18 1999/06/21 15:24:15 calle
|
||||
* extend information in /proc.
|
||||
*
|
||||
* Revision 1.17 1999/06/10 16:53:55 calle
|
||||
* Removing of module b1pci will now remove card from lower level.
|
||||
*
|
||||
|
@ -1443,7 +1446,7 @@ static void capidrv_signal(__u16 applid, __u32 dummy)
|
|||
|
||||
while ((*capifuncs->capi_get_message) (global.appid, &skb) == CAPI_NOERROR) {
|
||||
capi_message2cmsg(&s_cmsg, skb->data);
|
||||
if (debugmode > 1)
|
||||
if (debugmode > 2)
|
||||
printk(KERN_DEBUG "capidrv_signal: applid=%d %s\n",
|
||||
applid, capi_cmsg2str(&s_cmsg));
|
||||
|
||||
|
@ -1526,6 +1529,11 @@ static _cmsg cmdcmsg;
|
|||
static int capidrv_ioctl(isdn_ctrl * c, capidrv_contr * card)
|
||||
{
|
||||
switch (c->arg) {
|
||||
case 1:
|
||||
debugmode = (int)(*((unsigned int *)c->parm.num));
|
||||
printk(KERN_DEBUG "capidrv-%d: debugmode=%d\n",
|
||||
card->contrnr, debugmode);
|
||||
return 0;
|
||||
default:
|
||||
printk(KERN_DEBUG "capidrv-%d: capidrv_ioctl(%ld) called ??\n",
|
||||
card->contrnr, c->arg);
|
||||
|
@ -2023,8 +2031,8 @@ static void enable_dchannel_trace(capidrv_contr *card)
|
|||
return;
|
||||
}
|
||||
if (strstr(manufacturer, "AVM") == 0) {
|
||||
printk(KERN_ERR "%s: not from AVM, no d-channel trace possible\n",
|
||||
card->name);
|
||||
printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
|
||||
card->name, manufacturer);
|
||||
return;
|
||||
}
|
||||
errcode = (*capifuncs->capi_get_version)(contr, &version);
|
||||
|
@ -2060,6 +2068,51 @@ static void enable_dchannel_trace(capidrv_contr *card)
|
|||
send_message(card, &cmdcmsg);
|
||||
}
|
||||
|
||||
static void disable_dchannel_trace(capidrv_contr *card)
|
||||
{
|
||||
__u8 manufacturer[CAPI_MANUFACTURER_LEN];
|
||||
capi_version version;
|
||||
__u16 contr = card->contrnr;
|
||||
__u16 errcode;
|
||||
__u16 avmversion[3];
|
||||
|
||||
errcode = (*capifuncs->capi_get_manufacturer)(contr, manufacturer);
|
||||
if (errcode != CAPI_NOERROR) {
|
||||
printk(KERN_ERR "%s: can't get manufacturer (0x%x)\n",
|
||||
card->name, errcode);
|
||||
return;
|
||||
}
|
||||
if (strstr(manufacturer, "AVM") == 0) {
|
||||
printk(KERN_ERR "%s: not from AVM, no d-channel trace possible (%s)\n",
|
||||
card->name, manufacturer);
|
||||
return;
|
||||
}
|
||||
errcode = (*capifuncs->capi_get_version)(contr, &version);
|
||||
if (errcode != CAPI_NOERROR) {
|
||||
printk(KERN_ERR "%s: can't get version (0x%x)\n",
|
||||
card->name, errcode);
|
||||
return;
|
||||
}
|
||||
avmversion[0] = (version.majormanuversion >> 4) & 0x0f;
|
||||
avmversion[1] = (version.majormanuversion << 4) & 0xf0;
|
||||
avmversion[1] |= (version.minormanuversion >> 4) & 0x0f;
|
||||
avmversion[2] |= version.minormanuversion & 0x0f;
|
||||
|
||||
if (avmversion[0] > 3 || (avmversion[0] == 3 && avmversion[1] > 6)) {
|
||||
printk(KERN_INFO "%s: D2 trace disabled\n", card->name);
|
||||
} else {
|
||||
printk(KERN_INFO "%s: D3 trace disabled\n", card->name);
|
||||
}
|
||||
capi_fill_MANUFACTURER_REQ(&cmdcmsg, global.appid,
|
||||
card->msgid++,
|
||||
contr,
|
||||
0x214D5641, /* ManuID */
|
||||
0, /* Class */
|
||||
1, /* Function */
|
||||
(_cstruct)"\004\000\000\000\000");
|
||||
send_message(card, &cmdcmsg);
|
||||
}
|
||||
|
||||
static int capidrv_addcontr(__u16 contr, struct capi_profile *profp)
|
||||
{
|
||||
capidrv_contr *card;
|
||||
|
@ -2143,8 +2196,7 @@ static int capidrv_addcontr(__u16 contr, struct capi_profile *profp)
|
|||
printk(KERN_INFO "%s: now up (%d B channels)\n",
|
||||
card->name, card->nbchan);
|
||||
|
||||
if (card->nbchan == 2) /* no T1 */
|
||||
enable_dchannel_trace(card);
|
||||
enable_dchannel_trace(card);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2164,6 +2216,15 @@ static int capidrv_delcontr(__u16 contr)
|
|||
return -1;
|
||||
}
|
||||
card = *pp;
|
||||
|
||||
if (debugmode)
|
||||
printk(KERN_DEBUG "capidrv-%d: id=%d unloading\n",
|
||||
card->contrnr, card->myid);
|
||||
|
||||
cmd.command = ISDN_STAT_UNLOAD;
|
||||
cmd.driver = card->myid;
|
||||
card->interface.statcallb(&cmd);
|
||||
|
||||
*pp = (*pp)->next;
|
||||
global.ncontr--;
|
||||
|
||||
|
@ -2177,10 +2238,6 @@ static int capidrv_delcontr(__u16 contr)
|
|||
}
|
||||
kfree(card->bchans);
|
||||
|
||||
cmd.command = ISDN_STAT_UNLOAD;
|
||||
cmd.driver = card->myid;
|
||||
card->interface.statcallb(&cmd);
|
||||
|
||||
printk(KERN_INFO "%s: now down.\n", card->name);
|
||||
|
||||
kfree(card);
|
||||
|
@ -2191,11 +2248,14 @@ static int capidrv_delcontr(__u16 contr)
|
|||
|
||||
static void lower_callback(unsigned int cmd, __u16 contr, void *data)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case KCI_CONTRUP:
|
||||
printk(KERN_INFO "capidrv: controller %hu up\n", contr);
|
||||
(void) capidrv_addcontr(contr, (capi_profile *) data);
|
||||
break;
|
||||
case KCI_CONTRDOWN:
|
||||
printk(KERN_INFO "capidrv: controller %hu down\n", contr);
|
||||
(void) capidrv_delcontr(contr);
|
||||
break;
|
||||
}
|
||||
|
@ -2336,6 +2396,7 @@ void cleanup_module(void)
|
|||
|
||||
for (card = global.contr_list; card; card = next) {
|
||||
next = card->next;
|
||||
disable_dchannel_trace(card);
|
||||
capidrv_delcontr(card->contrnr);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* $Log$
|
||||
* 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.
|
||||
*
|
||||
|
@ -922,6 +925,14 @@ isdn_status_callback(isdn_ctrl * c)
|
|||
isdn_info_update();
|
||||
break;
|
||||
case ISDN_STAT_UNLOAD:
|
||||
while (dev->drv[di]->locks > 0) {
|
||||
isdn_ctrl cmd;
|
||||
cmd.driver = di;
|
||||
cmd.arg = 0;
|
||||
cmd.command = ISDN_CMD_UNLOCK;
|
||||
isdn_command(&cmd);
|
||||
dev->drv[di]->locks--;
|
||||
}
|
||||
save_flags(flags);
|
||||
cli();
|
||||
isdn_tty_stat_callback(i, c);
|
||||
|
@ -1311,11 +1322,11 @@ isdn_poll(struct file *file, poll_table * wait)
|
|||
return mask;
|
||||
}
|
||||
if (minor >= ISDN_MINOR_CTRL && minor <= ISDN_MINOR_CTRLMAX) {
|
||||
poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait);
|
||||
if (drvidx < 0) {
|
||||
printk(KERN_ERR "isdn_common: isdn_poll 1 -> what the hell\n");
|
||||
return POLLERR;
|
||||
/* driver deregistered while file open */
|
||||
return POLLHUP;
|
||||
}
|
||||
poll_wait(file, &(dev->drv[drvidx]->st_waitq), wait);
|
||||
mask = POLLOUT | POLLWRNORM;
|
||||
if (dev->drv[drvidx]->stavail) {
|
||||
mask |= POLLIN | POLLRDNORM;
|
||||
|
|
Loading…
Reference in a new issue