(capi_device_register, release_capi_device, capi_register, capi_release): Module reference counting removed.

(register_capi_device): Increment of nr_capi_devices moved to capi_device_register().
(get_capi_device): Removed.
(capi_peek_message): Pending info is returned.
(capi_device_register): Moved call to capi_device_register_sysfs() to end.
(capi_device_unregister): Moved call to class_device_del() after changing state.
This commit is contained in:
Frank A. Uepping 2004-08-29 18:06:26 +00:00
parent e420314971
commit 1d19193852
1 changed files with 12 additions and 48 deletions

View File

@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/isdn/capidevice.h>
#include <linux/isdn/capiutil.h>
#include <linux/isdn/capicmd.h>
@ -36,13 +35,6 @@ atomic_t nr_capi_devices = ATOMIC_INIT(0);
int capi_device_register_sysfs (struct capi_device* dev);
static inline void
get_capi_device(struct capi_device* dev)
{
kref_get(&dev->refs);
}
static struct capi_device*
try_get_capi_device(struct capi_device* dev)
{
@ -53,7 +45,7 @@ try_get_capi_device(struct capi_device* dev)
if (unlikely(dev->state != CAPI_DEVICE_STATE_RUNNING))
dev = NULL;
else
get_capi_device(dev);
kref_get(&dev->refs);
spin_unlock(&dev->state_lock);
return dev;
@ -87,11 +79,6 @@ static void
release_capi_device(struct kref* kref)
{
struct capi_device* dev = container_of(kref, struct capi_device, refs);
struct module* owner = dev->drv->owner;
int appls = atomic_read(&dev->appls);
while (appls--)
module_put(owner);
complete(&dev->done);
}
@ -123,8 +110,6 @@ register_capi_device(struct capi_device* dev)
capi_devices_table[id] = dev;
spin_unlock(&capi_devices_table_lock);
atomic_inc(&nr_capi_devices);
return dev->id = id + 1;
}
spin_unlock(&capi_devices_table_lock);
@ -136,41 +121,35 @@ register_capi_device(struct capi_device* dev)
int
capi_device_register(struct capi_device* dev)
{
int err;
if (unlikely(!dev))
return -EINVAL;
if (unlikely(!register_capi_device(dev)))
return -EMFILE;
err = capi_device_register_sysfs(dev);
if (unlikely(err))
return err;
atomic_inc(&nr_capi_devices);
kref_init(&dev->refs, release_capi_device);
init_completion(&dev->done);
atomic_set(&dev->appls, 0);
spin_lock_init(&dev->stats.lock);
spin_lock_init(&dev->state_lock);
dev->state = CAPI_DEVICE_STATE_RUNNING;
return 0;
return capi_device_register_sysfs(dev);
}
void
capi_device_unregister(struct capi_device* dev)
{
class_device_del(&dev->class_dev);
spin_lock(&dev->state_lock);
dev->state = CAPI_DEVICE_STATE_ZOMBIE;
spin_unlock(&dev->state_lock);
atomic_dec(&nr_capi_devices);
BUG_ON(!module_is_live(dev->drv->owner) && atomic_read(&dev->refs.refcount) != 1);
class_device_del(&dev->class_dev);
put_capi_device(dev);
wait_for_completion(&dev->done);
}
@ -231,31 +210,18 @@ capi_register(struct capi_appl* appl)
spin_lock(&capi_devices_table_lock);
for (id = 0; id < CAPI_MAX_DEVS; id++) {
dev = capi_devices_table[id];
dev = try_get_capi_device(capi_devices_table[id]);
if (!dev)
continue;
spin_lock(&dev->state_lock);
if (unlikely(!(dev->state == CAPI_DEVICE_STATE_RUNNING && try_module_get(dev->drv->owner)))) {
spin_unlock(&dev->state_lock);
continue;
}
get_capi_device(dev);
spin_unlock(&dev->state_lock);
spin_unlock(&capi_devices_table_lock);
info = dev->drv->capi_register(dev, appl);
if (unlikely(info)) {
struct module* owner = dev->drv->owner;
printk(KERN_NOTICE "capi: CAPI_REGISTER failed on device %d (info: %#x)\n", id + 1, info);
put_capi_device(dev);
module_put(owner);
} else {
__set_bit(id, appl->devs);
atomic_inc(&dev->appls);
smp_mb__after_atomic_inc();
capi_device_get(dev);
put_capi_device(dev);
}
@ -279,11 +245,6 @@ capi_release(struct capi_appl* appl)
BUG_ON(!dev);
if (likely(try_get_capi_device(dev))) {
dev->drv->capi_release(dev, appl);
atomic_dec(&dev->appls);
smp_mb__after_atomic_dec();
module_put(dev->drv->owner);
put_capi_device(dev);
}
capi_device_put(dev);
@ -306,7 +267,7 @@ capi_put_message(struct capi_appl* appl, struct sk_buff* msg)
if (unlikely(info))
return info;
if (!msg || msg->len < CAPIMSG_BASELEN + 4)
if (unlikely(!msg || msg->len < CAPIMSG_BASELEN + 4))
return CAPINFO_0X11_ILLCMDORMSGTOSMALL;
id = CAPIMSG_CONTROLLER(msg->data);
@ -331,7 +292,7 @@ capi_get_message(struct capi_appl* appl, struct sk_buff** msg)
return appl->info;
*msg = skb_dequeue(&appl->msg_queue);
if (unlikely(!*msg))
if (!*msg)
return CAPINFO_0X11_QUEUEEMPTY;
return CAPINFO_0X11_NOERR;
@ -341,7 +302,10 @@ capi_get_message(struct capi_appl* appl, struct sk_buff** msg)
capinfo_0x11
capi_peek_message(struct capi_appl* appl)
{
if (appl->info || !skb_queue_empty(&appl->msg_queue))
if (unlikely(appl->info))
return appl->info;
if (!skb_queue_empty(&appl->msg_queue))
return CAPINFO_0X11_QUEUEFULL;
return CAPINFO_0X11_QUEUEEMPTY;