]> git.hungrycats.org Git - linux/commitdiff
[ATM]: [ioctl][2/8] Add registration functions (from levon@movementarian.org)
authorChas Williams <chas@cmf.nrl.navy.mil>
Thu, 25 Sep 2003 14:11:27 +0000 (07:11 -0700)
committerDavid S. Miller <davem@nuts.ninka.net>
Thu, 25 Sep 2003 14:11:27 +0000 (07:11 -0700)
include/linux/atmdev.h
net/atm/ioctl.c

index 0bf8106530b971fa5c135087ae105d2f0711f5fd..d4617e465c60d7b4181035429bed093c48e91c19 100644 (file)
@@ -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
index 3ae335f4a5dbecbd9cd74be0b66086134f9f1455..f654b35c7e6c9868432e96c04490581b82eb153e 100644 (file)
@@ -1,6 +1,7 @@
-/* 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)