blob: ad312a98c34d970c679bc4f32253910267c02513 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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);
}
|