(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:
parent
e420314971
commit
1d19193852
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue