Commit 2267e86d authored by Chas Williams's avatar Chas Williams Committed by David S. Miller

[ATM]: [ioctl][2/8] Add registration functions (from levon@movementarian.org)

parent f962d6bc
......@@ -445,6 +445,28 @@ int atm_pcr_goal(struct atm_trafprm *tp);
void vcc_release_async(struct atm_vcc *vcc, int reply);
struct atm_ioctl {
struct module *owner;
/* A module reference is kept if appropriate over this call.
* Return -ENOIOCTLCMD if you don't handle it. */
int (*ioctl)(struct socket *, unsigned int cmd, unsigned long arg);
struct list_head list;
};
/**
* register_atm_ioctl - register handler for ioctl operations
*
* Special (non-device) handlers of ioctl's should
* register here. If you're a normal device, you should
* set .ioctl in your atmdev_ops instead.
*/
void register_atm_ioctl(struct atm_ioctl *);
/**
* deregister_atm_ioctl - remove the ioctl handler
*/
void deregister_atm_ioctl(struct atm_ioctl *);
#endif /* __KERNEL__ */
#endif
/* net/atm/common.c - ATM sockets (common part for PVC and SVC) */
/* ATM ioctl handling */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
/* 2003 John Levon <levon@movementarian.org> */
#include <linux/config.h>
......@@ -18,7 +19,7 @@
#ifdef CONFIG_ATM_CLIP
#include <net/atmclip.h> /* for clip_create */
#endif
#include "resources.h" /* atm_find_dev */
#include "resources.h"
#include "signaling.h" /* for WAITING and sigd_attach */
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
......@@ -153,11 +154,32 @@ EXPORT_SYMBOL(br2684_ioctl_set);
#endif
#endif
static DECLARE_MUTEX(ioctl_mutex);
static LIST_HEAD(ioctl_list);
void register_atm_ioctl(struct atm_ioctl *ioctl)
{
down(&ioctl_mutex);
list_add_tail(&ioctl->list, &ioctl_list);
up(&ioctl_mutex);
}
void deregister_atm_ioctl(struct atm_ioctl *ioctl)
{
down(&ioctl_mutex);
list_del(&ioctl->list);
up(&ioctl_mutex);
}
EXPORT_SYMBOL(register_atm_ioctl);
EXPORT_SYMBOL(deregister_atm_ioctl);
int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct atm_vcc *vcc;
int error;
struct list_head * pos;
vcc = ATM_SD(sock);
switch (cmd) {
......@@ -396,6 +418,22 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break;
}
error = -ENOIOCTLCMD;
down(&ioctl_mutex);
list_for_each(pos, &ioctl_list) {
struct atm_ioctl * ic = list_entry(pos, struct atm_ioctl, list);
if (try_module_get(ic->owner)) {
error = ic->ioctl(sock, cmd, arg);
module_put(ic->owner);
if (error != -ENOIOCTLCMD)
break;
}
}
up(&ioctl_mutex);
if (error != -ENOIOCTLCMD)
goto done;
#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
down(&pppoatm_ioctl_mutex);
if (pppoatm_ioctl_hook)
......
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