aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/io/drivers/hubdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/sn/io/drivers/hubdev.c')
-rw-r--r--arch/ia64/sn/io/drivers/hubdev.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/arch/ia64/sn/io/drivers/hubdev.c b/arch/ia64/sn/io/drivers/hubdev.c
new file mode 100644
index 00000000000000..ad312a98c34d97
--- /dev/null
+++ b/arch/ia64/sn/io/drivers/hubdev.c
@@ -0,0 +1,100 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+struct hubdev_callout {
+ int (*attach_method)(vertex_hdl_t);
+ struct hubdev_callout *fp;
+};
+
+typedef struct hubdev_callout hubdev_callout_t;
+
+mutex_t hubdev_callout_mutex;
+static hubdev_callout_t *hubdev_callout_list;
+
+void
+hubdev_init(void)
+{
+ mutex_init(&hubdev_callout_mutex);
+ hubdev_callout_list = NULL;
+}
+
+void
+hubdev_register(int (*attach_method)(vertex_hdl_t))
+{
+ hubdev_callout_t *callout;
+
+ ASSERT(attach_method);
+
+ callout = (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
+ ASSERT(callout);
+
+ mutex_lock(&hubdev_callout_mutex);
+ /*
+ * Insert at the end of the list
+ */
+ callout->fp = hubdev_callout_list;
+ hubdev_callout_list = callout;
+ callout->attach_method = attach_method;
+ mutex_unlock(&hubdev_callout_mutex);
+}
+
+int
+hubdev_unregister(int (*attach_method)(vertex_hdl_t))
+{
+ hubdev_callout_t **p;
+
+ ASSERT(attach_method);
+
+ mutex_lock(&hubdev_callout_mutex);
+ /*
+ * Remove registry element containing attach_method
+ */
+ for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
+ if ((*p)->attach_method == attach_method) {
+ hubdev_callout_t* victim = *p;
+ *p = (*p)->fp;
+ kfree(victim);
+ mutex_unlock(&hubdev_callout_mutex);
+ return (0);
+ }
+ }
+ mutex_unlock(&hubdev_callout_mutex);
+ return (ENOENT);
+}
+
+
+int
+hubdev_docallouts(vertex_hdl_t hub)
+{
+ hubdev_callout_t *p;
+ int errcode;
+
+ mutex_lock(&hubdev_callout_mutex);
+
+ for (p = hubdev_callout_list; p != NULL; p = p->fp) {
+ ASSERT(p->attach_method);
+ errcode = (*p->attach_method)(hub);
+ if (errcode != 0) {
+ mutex_unlock(&hubdev_callout_mutex);
+ return (errcode);
+ }
+ }
+ mutex_unlock(&hubdev_callout_mutex);
+ return (0);
+}