Commit dbc67c41 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Get rid of global drivers count

It's useless information, we need to iterate over all potential
drivers anyway, since possibly the first one has unregistered before
the second, leaving a hole.
parent 98659955
...@@ -114,10 +114,29 @@ static void isdn_receive_skb_callback(int di, int ch, struct sk_buff *skb); ...@@ -114,10 +114,29 @@ static void isdn_receive_skb_callback(int di, int ch, struct sk_buff *skb);
static int isdn_status_callback(isdn_ctrl * c); static int isdn_status_callback(isdn_ctrl * c);
static void set_global_features(void); static void set_global_features(void);
/*
* Helper keeping track of the features the drivers support
*/
static void
set_global_features(void)
{
unsigned long flags;
int drvidx;
dev->global_features = 0;
spin_lock_irqsave(&drivers_lock, flags);
for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) {
if (!drivers[drvidx])
continue;
if (drivers[drvidx]->interface)
dev->global_features |= drivers[drvidx]->interface->features;
}
spin_unlock_irqrestore(&drivers_lock, flags);
}
/* /*
* Register a new ISDN interface * Register a new ISDN interface
*/ */
int int
register_isdn(isdn_if *iif) register_isdn(isdn_if *iif)
{ {
...@@ -125,12 +144,6 @@ register_isdn(isdn_if *iif) ...@@ -125,12 +144,6 @@ register_isdn(isdn_if *iif)
unsigned long flags; unsigned long flags;
int drvidx; int drvidx;
if (dev->drivers >= ISDN_MAX_DRIVERS) {
printk(KERN_WARNING "register_isdn: Max. %d drivers supported\n",
ISDN_MAX_DRIVERS);
goto fail;
}
drv = kmalloc(sizeof(*drv), GFP_KERNEL); drv = kmalloc(sizeof(*drv), GFP_KERNEL);
if (!drv) { if (!drv) {
printk(KERN_WARNING "register_isdn: out of mem\n"); printk(KERN_WARNING "register_isdn: out of mem\n");
...@@ -150,6 +163,9 @@ register_isdn(isdn_if *iif) ...@@ -150,6 +163,9 @@ register_isdn(isdn_if *iif)
if (!drivers[drvidx]) if (!drivers[drvidx])
break; break;
if (drvidx == ISDN_MAX_DRIVERS)
goto fail_unlock;
if (!strlen(iif->id)) if (!strlen(iif->id))
sprintf(iif->id, "line%d", drvidx); sprintf(iif->id, "line%d", drvidx);
...@@ -170,7 +186,6 @@ register_isdn(isdn_if *iif) ...@@ -170,7 +186,6 @@ register_isdn(isdn_if *iif)
iif->statcallb = isdn_status_callback; iif->statcallb = isdn_status_callback;
isdn_info_update(); isdn_info_update();
dev->drivers++;
set_global_features(); set_global_features();
return 1; return 1;
...@@ -200,10 +215,14 @@ static int isdn_command(isdn_ctrl *cmd); ...@@ -200,10 +215,14 @@ static int isdn_command(isdn_ctrl *cmd);
void void
isdn_lock_drivers(void) isdn_lock_drivers(void)
{ {
isdn_ctrl cmd;
unsigned long flags;
int i; int i;
for (i = 0; i < dev->drivers; i++) { spin_lock_irqsave(&drivers_lock, flags);
isdn_ctrl cmd; for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
if (!drivers[i])
continue;
cmd.driver = i; cmd.driver = i;
cmd.arg = 0; cmd.arg = 0;
...@@ -211,6 +230,7 @@ isdn_lock_drivers(void) ...@@ -211,6 +230,7 @@ isdn_lock_drivers(void)
isdn_command(&cmd); isdn_command(&cmd);
drivers[i]->locks++; drivers[i]->locks++;
} }
spin_unlock_irqrestore(&drivers_lock, flags);
} }
void void
...@@ -223,18 +243,24 @@ isdn_MOD_INC_USE_COUNT(void) ...@@ -223,18 +243,24 @@ isdn_MOD_INC_USE_COUNT(void)
void void
isdn_unlock_drivers(void) isdn_unlock_drivers(void)
{ {
isdn_ctrl cmd;
unsigned long flags;
int i; int i;
for (i = 0; i < dev->drivers; i++) spin_lock_irqsave(&drivers_lock, flags);
if (drivers[i]->locks > 0) { for (i = 0; i < ISDN_MAX_DRIVERS; i++) {
isdn_ctrl cmd; if (!drivers[i])
continue;
if (drivers[i]->locks > 0) {
cmd.driver = i; cmd.driver = i;
cmd.arg = 0; cmd.arg = 0;
cmd.command = ISDN_CMD_UNLOCK; cmd.command = ISDN_CMD_UNLOCK;
isdn_command(&cmd); isdn_command(&cmd);
drivers[i]->locks--; drivers[i]->locks--;
} }
}
spin_unlock_irqrestore(&drivers_lock, flags);
} }
void void
...@@ -785,7 +811,6 @@ isdn_status_callback(isdn_ctrl * c) ...@@ -785,7 +811,6 @@ isdn_status_callback(isdn_ctrl * c)
slot[i].usage &= ~ISDN_USAGE_DISABLED; slot[i].usage &= ~ISDN_USAGE_DISABLED;
isdn_unregister_devfs(i); isdn_unregister_devfs(i);
} }
dev->drivers--;
dev->channels -= drivers[di]->channels; dev->channels -= drivers[di]->channels;
kfree(drivers[di]->rcverr); kfree(drivers[di]->rcverr);
kfree(drivers[di]->rcvcount); kfree(drivers[di]->rcvcount);
...@@ -1869,20 +1894,6 @@ isdn_add_channels(struct isdn_driver *d, int drvidx, int n, int adding) ...@@ -1869,20 +1894,6 @@ isdn_add_channels(struct isdn_driver *d, int drvidx, int n, int adding)
* Low-level-driver registration * Low-level-driver registration
*/ */
static void
set_global_features(void)
{
int drvidx;
dev->global_features = 0;
for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++) {
if (!drivers[drvidx])
continue;
if (drivers[drvidx]->interface)
dev->global_features |= drivers[drvidx]->interface->features;
}
}
#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE) #if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
static char *map_drvname(int di) static char *map_drvname(int di)
......
...@@ -417,7 +417,6 @@ typedef struct { ...@@ -417,7 +417,6 @@ typedef struct {
typedef struct isdn_devt { typedef struct isdn_devt {
unsigned short flags; /* Bitmapped Flags: */ unsigned short flags; /* Bitmapped Flags: */
/* */ /* */
int drivers; /* Current number of drivers */
int channels; /* Current number of channels */ int channels; /* Current number of channels */
int net_verbose; /* Verbose-Flag */ int net_verbose; /* Verbose-Flag */
int modempoll; /* Flag: tty-read active */ int modempoll; /* Flag: tty-read active */
......
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