Commit 315c77b4 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Introduce .owner

The current way of passing a command to inc the module use count is
inherently racy, so expose a struct module *owner instead (which makes
it possible to fix this race, though that's not done yet).

Also, add some missing #include <linux/interrupt.h>
parent 0aafcbc6
......@@ -436,12 +436,6 @@ act2000_command(act2000_card * card, isdn_ctrl * c)
return -ENODEV;
printk(KERN_DEBUG "act2000 CMD_GETSIL not implemented\n");
return 0;
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
return 0;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
return 0;
}
return -EINVAL;
......@@ -620,6 +614,7 @@ act2000_alloccard(int bus, int port, int irq, char *id)
INIT_WORK(&card->rcv_tq, (void *) (void *) actcapi_dispatch, card);
INIT_WORK(&card->poll_tq, (void *) (void *) act2000_receive, card);
init_timer(&card->ptimer);
SET_MODULE_OWNER(&card->interface);
card->interface.channels = ACT2000_BCH;
card->interface.maxbufsize = 4000;
card->interface.command = if_command;
......
......@@ -1787,20 +1787,6 @@ static int capidrv_command(isdn_ctrl * c, capidrv_contr * card)
bchan->msn[0] = 0;
return 0;
case ISDN_CMD_LOCK:
if (debugmode > 1)
printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_LOCK (%ld)\n", card->contrnr, c->arg);
MOD_INC_USE_COUNT;
break;
case ISDN_CMD_UNLOCK:
if (debugmode > 1)
printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_UNLOCK (%ld)\n",
card->contrnr, c->arg);
MOD_DEC_USE_COUNT;
break;
/* never called */
case ISDN_CMD_GETL2:
if (debugmode)
printk(KERN_DEBUG "capidrv-%d: ISDN_CMD_GETL2\n",
......
......@@ -569,12 +569,6 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
return -ENODEV;
eicon_log(card, 1, "eicon CMD_GETSIL not implemented\n");
return 0;
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
return 0;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
return 0;
#ifdef CONFIG_ISDN_TTY_FAX
case ISDN_CMD_FAXCMD:
if (!card->flags & EICON_FLAGS_RUNNING)
......@@ -877,6 +871,7 @@ eicon_alloccard(int Type, int membase, int irq, char *id, int card_id)
tasklet_init(&card->snd_tq, eicon_transmit, (unsigned long)card);
tasklet_init(&card->rcv_tq, eicon_rcv_dispatch, (unsigned long)card);
tasklet_init(&card->ack_tq, eicon_ack_dispatch, (unsigned long)card);
SET_MODULE_OWNER(&card->interface);
card->interface.maxbufsize = 4000;
card->interface.command = if_command;
card->interface.writebuf_skb = if_sendbuf;
......
......@@ -629,12 +629,6 @@ eicon_command(eicon_card * card, isdn_ctrl * c)
return -ENODEV;
eicon_log(card, 1, "%s: CMD_GETSIL not implemented\n", DRIVERLNAME);
return 0;
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
return 0;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
return 0;
#ifdef CONFIG_ISDN_TTY_FAX
case ISDN_CMD_FAXCMD:
if (!card->flags & EICON_FLAGS_RUNNING)
......@@ -961,6 +955,7 @@ eicon_alloccard(DESCRIPTOR *d)
skb_queue_head_init(&card->sackq);
skb_queue_head_init(&card->statq);
card->statq_entries = 0;
SET_MODULE_OWNER(&card->interface);
card->interface.maxbufsize = 4000;
card->interface.command = if_command;
card->interface.writebuf_skb = if_sendbuf;
......
......@@ -29,8 +29,6 @@ const char *lli_revision = "$Revision: 2.51.6.6 $";
extern struct IsdnCard cards[];
extern int nrcards;
extern void HiSax_mod_dec_use_count(struct IsdnCardState *cs);
extern void HiSax_mod_inc_use_count(struct IsdnCardState *cs);
static int init_b_st(struct Channel *chanp, int incoming);
static void release_b_st(struct Channel *chanp);
......@@ -1584,22 +1582,6 @@ HiSax_command(isdn_ctrl * ic)
break;
}
break;
case (ISDN_CMD_LOCK):
HiSax_mod_inc_use_count(csta);
#ifdef MODULE
if (csta->channel[0].debug & 0x400)
HiSax_putstatus(csta, " LOCK ", "modcnt %lx",
MOD_USE_COUNT);
#endif /* MODULE */
break;
case (ISDN_CMD_UNLOCK):
HiSax_mod_dec_use_count(csta);
#ifdef MODULE
if (csta->channel[0].debug & 0x400)
HiSax_putstatus(csta, " UNLOCK ", "modcnt %lx",
MOD_USE_COUNT);
#endif /* MODULE */
break;
case (ISDN_CMD_IOCTL):
switch (ic->arg) {
case (0):
......
......@@ -942,6 +942,7 @@ static int __devinit checkcard(int cardnr, char *id, int *busy_flag)
cs->status_write = cs->status_buf;
cs->status_end = cs->status_buf + HISAX_STATUS_BUFSIZE - 1;
cs->typ = card->typ;
SET_MODULE_OWNER(&cs->iif);
strcpy(cs->iif.id, id);
cs->iif.channels = 2;
cs->iif.maxbufsize = MAX_DATA_SIZE;
......@@ -1769,6 +1770,7 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
hisax_d_if->cs = cs;
cs->hw.hisax_d_if = hisax_d_if;
cs->cardmsg = hisax_cardmsg;
cs->iif.owner = hisax_d_if->owner; // FIXME should be done before registering
INIT_WORK(&cs->work, hisax_bh, cs);
cs->channel[0].d_st->l1.l2l1 = hisax_d_l2l1;
for (i = 0; i < 2; i++) {
......@@ -2053,33 +2055,6 @@ static void EChannel_proc_rcv(struct hisax_d_if *d_if)
}
}
void HiSax_mod_dec_use_count(struct IsdnCardState *cs)
{
struct module *mod;
if (cs && cs->cardmsg == hisax_cardmsg) {
mod = cs->hw.hisax_d_if->owner;
if (mod)
__MOD_DEC_USE_COUNT(mod);
} else {
MOD_DEC_USE_COUNT;
}
}
void HiSax_mod_inc_use_count(struct IsdnCardState *cs)
{
struct module *mod;
if (cs && cs->cardmsg == hisax_cardmsg) {
mod = cs->hw.hisax_d_if->owner;
if (mod)
// hope we do win the race...
try_inc_mod_count(mod);
} else {
MOD_INC_USE_COUNT;
}
}
#include <linux/pci.h>
static struct pci_device_id hisax_pci_tbl[] __initdata = {
......
......@@ -429,7 +429,6 @@ struct isdn_driver {
atomic_t refcnt;
unsigned long flags; /* Misc driver Flags */
unsigned long features;
int locks; /* Number of locks */
int channels; /* Number of channels */
wait_queue_head_t st_waitq; /* Wait-Queue for status-reads */
int maxbufsize; /* Maximum Buffersize supported*/
......@@ -630,14 +629,6 @@ drv_stat_unload(struct fsm_inst *fi, int pr, void *arg)
spin_unlock_irqrestore(&drivers_lock, flags);
put_drv(drv);
while (drv->locks > 0) {
isdn_ctrl cmd;
cmd.driver = drv->di;
cmd.arg = 0;
cmd.command = ISDN_CMD_UNLOCK;
__drv_command(drv, &cmd);
drv->locks--;
}
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
if (slots[i].di == drv->di) {
slots[i].di = -1;
......@@ -993,23 +984,14 @@ static int isdn_wildmat(char *s, char *p);
static void
isdn_lock_driver(struct isdn_driver *drv)
{
isdn_ctrl cmd;
cmd.driver = drv->di;
cmd.arg = 0;
cmd.command = ISDN_CMD_LOCK;
__drv_command(drv, &cmd);
// FIXME don't ignore return value
try_module_get(drv->interface->owner);
}
static void
isdn_unlock_driver(struct isdn_driver *drv)
{
isdn_ctrl cmd;
cmd.driver = drv->di;
cmd.arg = 0;
cmd.command = ISDN_CMD_UNLOCK;
__drv_command(drv, &cmd);
module_put(drv->interface->owner);
}
#if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
......@@ -1135,10 +1117,6 @@ __drv_command(struct isdn_driver *drv, isdn_ctrl *c)
{
#ifdef ISDN_DEBUG_COMMAND
switch (c->command) {
case ISDN_CMD_LOCK:
printk(KERN_DEBUG "ISDN_CMD_LOCK %d/%ld\n", c->driver, c->arg & 0xff); break;
case ISDN_CMD_UNLOCK:
printk(KERN_DEBUG "ISDN_CMD_UNLOCK %d/%ld\n", c->driver, c->arg & 0xff); break;
case ISDN_CMD_SETL2:
printk(KERN_DEBUG "ISDN_CMD_SETL2 %d/%ld\n", c->driver, c->arg & 0xff); break;
case ISDN_CMD_SETL3:
......
......@@ -1471,12 +1471,6 @@ icn_command(isdn_ctrl * c, icn_card * card)
if (!card->flags & ICN_FLAGS_RUNNING)
return -ENODEV;
break;
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
break;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
break;
default:
return -EINVAL;
}
......@@ -1577,6 +1571,7 @@ icn_initcard(int port, char *id)
}
memset((char *) card, 0, sizeof(icn_card));
card->port = port;
SET_MODULE_OWNER(&card->interface);
card->interface.hl_hdrlen = 1;
card->interface.channels = ICN_BCH;
card->interface.maxbufsize = 4000;
......
......@@ -1375,12 +1375,6 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card)
if (!card->flags & ISDNLOOP_FLAGS_RUNNING)
return -ENODEV;
break;
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
break;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
break;
default:
return -EINVAL;
}
......@@ -1482,6 +1476,7 @@ isdnloop_initcard(char *id)
return (isdnloop_card *) 0;
}
memset((char *) card, 0, sizeof(isdnloop_card));
SET_MODULE_OWNER(&card->interface);
card->interface.channels = ISDNLOOP_BCH;
card->interface.hl_hdrlen = 1; /* scratch area for storing ack flag*/
card->interface.maxbufsize = 4000;
......
......@@ -171,9 +171,10 @@ int pcbit_init_dev(int board, int mem_base, int irq)
dev->dev_if = dev_if;
dev_if->channels = 2;
SET_MODULE_OWNER(dev_if);
dev_if->channels = 2;
dev_if->features = (ISDN_FEATURE_P_EURO | ISDN_FEATURE_L3_TRANS |
ISDN_FEATURE_L2_HDLC | ISDN_FEATURE_L2_TRANS );
......@@ -279,12 +280,6 @@ int pcbit_command(isdn_ctrl* ctl)
case ISDN_CMD_GETL2:
return chan->proto;
break;
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
break;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
break;
case ISDN_CMD_CLREAZ:
pcbit_clear_msn(dev);
break;
......
......@@ -34,8 +34,6 @@ int setl2(int card, unsigned long arg);
int getl2(int card, unsigned long arg);
int setl3(int card, unsigned long arg);
int getl3(int card, unsigned long arg);
int lock(void);
int unlock(void);
int acceptb(int card, unsigned long channel);
extern int cinst;
......@@ -70,8 +68,8 @@ static char *commands[] = { "ISDN_CMD_IOCTL",
"ISDN_CMD_GETL2",
"ISDN_CMD_SETL3",
"ISDN_CMD_GETL3",
"ISDN_CMD_LOCK",
"ISDN_CMD_UNLOCK",
NULL,
NULL,
"ISDN_CMD_SUSPEND",
"ISDN_CMD_RESUME" };
......@@ -158,10 +156,6 @@ int command(isdn_ctrl *cmd)
return setl3(card, cmd->arg);
case ISDN_CMD_GETL3:
return getl3(card, cmd->arg);
case ISDN_CMD_LOCK:
return lock();
case ISDN_CMD_UNLOCK:
return unlock();
default:
return -EINVAL;
}
......@@ -499,19 +493,6 @@ int getsil(int card, unsigned long arg, char *num)
return 0;
}
int lock()
{
MOD_INC_USE_COUNT;
return 0;
}
int unlock()
{
MOD_DEC_USE_COUNT;
return 0;
}
int reset(int card)
{
unsigned long flags;
......
......@@ -6,6 +6,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include "includes.h"
#include "hardware.h"
#include "card.h"
......@@ -286,6 +287,7 @@ static int __init sc_init(void)
}
memset(interface, 0, sizeof(isdn_if));
SET_MODULE_OWNER(interface);
interface->hl_hdrlen = 0;
interface->channels = channels;
interface->maxbufsize = BUFFER_SIZE;
......
......@@ -95,12 +95,6 @@ int tpam_command(isdn_ctrl *c) {
c->arg >> 8);
case ISDN_CMD_GETL2:
return tpam_command_getl2(card, c->arg);
case ISDN_CMD_LOCK:
MOD_INC_USE_COUNT;
return 0;
case ISDN_CMD_UNLOCK:
MOD_DEC_USE_COUNT;
return 0;
case ISDN_CMD_PROCEED:
return tpam_command_proceed(card, c->arg);
default:
......
......@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <asm/io.h>
......@@ -131,6 +132,7 @@ static int __devinit tpam_probe(struct pci_dev *dev, const struct pci_device_id
copy_to_pam_dword(card, (void *)0x01840070, 0x00000010);
/* fill the ISDN link layer structure */
SET_MODULE_OWNER(&card->interface);
card->interface.channels = TPAM_NBCHANNEL;
card->interface.maxbufsize = TPAM_MAXBUFSIZE;
card->interface.features =
......
......@@ -173,8 +173,6 @@ typedef struct
#define ISDN_CMD_GETL2 11 /* Get B-Chan. Layer2-Parameter */
#define ISDN_CMD_SETL3 12 /* Set B-Chan. Layer3-Parameter */
#define ISDN_CMD_GETL3 13 /* Get B-Chan. Layer3-Parameter */
#define ISDN_CMD_LOCK 14 /* Signal usage by upper levels */
#define ISDN_CMD_UNLOCK 15 /* Release usage-lock */
#define ISDN_CMD_SUSPEND 16 /* Suspend connection */
#define ISDN_CMD_RESUME 17 /* Resume connection */
#define ISDN_CMD_PROCEED 18 /* Proceed with call establishment */
......@@ -423,6 +421,8 @@ typedef struct {
*
*/
typedef struct {
struct module *owner;
/* Number of channels supported by this driver
*/
int channels;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment