Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
misc
sgi-xp
xp_main.c
Go to the documentation of this file.
1
/*
2
* This file is subject to the terms and conditions of the GNU General Public
3
* License. See the file "COPYING" in the main directory of this archive
4
* for more details.
5
*
6
* Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved.
7
*/
8
9
/*
10
* Cross Partition (XP) base.
11
*
12
* XP provides a base from which its users can interact
13
* with XPC, yet not be dependent on XPC.
14
*
15
*/
16
17
#include <linux/module.h>
18
#include <linux/device.h>
19
#include "
xp.h
"
20
21
/* define the XP debug device structures to be used with dev_dbg() et al */
22
23
struct
device_driver
xp_dbg_name
= {
24
.name =
"xp"
25
};
26
27
struct
device
xp_dbg_subname
= {
28
.init_name =
""
,
/* set to "" */
29
.driver = &xp_dbg_name
30
};
31
32
struct
device
*
xp
= &
xp_dbg_subname
;
33
34
/* max #of partitions possible */
35
short
xp_max_npartitions
;
36
EXPORT_SYMBOL_GPL
(
xp_max_npartitions
);
37
38
short
xp_partition_id
;
39
EXPORT_SYMBOL_GPL
(
xp_partition_id
);
40
41
u8
xp_region_size
;
42
EXPORT_SYMBOL_GPL
(
xp_region_size
);
43
44
unsigned
long
(*
xp_pa
) (
void
*
addr
);
45
EXPORT_SYMBOL_GPL
(
xp_pa
);
46
47
unsigned
long
(*
xp_socket_pa
) (
unsigned
long
gpa);
48
EXPORT_SYMBOL_GPL
(
xp_socket_pa
);
49
50
enum
xp_retval
(*
xp_remote_memcpy
) (
unsigned
long
dst_gpa,
51
const
unsigned
long
src_gpa,
size_t
len
);
52
EXPORT_SYMBOL_GPL
(
xp_remote_memcpy
);
53
54
int
(*
xp_cpu_to_nasid
) (
int
cpuid
);
55
EXPORT_SYMBOL_GPL
(
xp_cpu_to_nasid
);
56
57
enum
xp_retval
(*
xp_expand_memprotect
) (
unsigned
long
phys_addr
,
58
unsigned
long
size
);
59
EXPORT_SYMBOL_GPL
(
xp_expand_memprotect
);
60
enum
xp_retval
(*
xp_restrict_memprotect
) (
unsigned
long
phys_addr
,
61
unsigned
long
size
);
62
EXPORT_SYMBOL_GPL
(
xp_restrict_memprotect
);
63
64
/*
65
* xpc_registrations[] keeps track of xpc_connect()'s done by the kernel-level
66
* users of XPC.
67
*/
68
struct
xpc_registration
xpc_registrations
[
XPC_MAX_NCHANNELS
];
69
EXPORT_SYMBOL_GPL
(
xpc_registrations
);
70
71
/*
72
* Initialize the XPC interface to indicate that XPC isn't loaded.
73
*/
74
static
enum
xp_retval
75
xpc_notloaded(
void
)
76
{
77
return
xpNotLoaded
;
78
}
79
80
struct
xpc_interface
xpc_interface
= {
81
(
void
(*)(
int
))xpc_notloaded,
82
(
void
(*)(
int
))xpc_notloaded,
83
(
enum
xp_retval
(*)(
short
,
int
,
u32
,
void
*,
u16
))xpc_notloaded,
84
(
enum
xp_retval
(*)(
short
,
int
,
u32
,
void
*,
u16
,
xpc_notify_func
,
85
void
*))xpc_notloaded,
86
(
void
(*)(
short
,
int
,
void
*))xpc_notloaded,
87
(
enum
xp_retval
(*)(
short
,
void
*))xpc_notloaded
88
};
89
EXPORT_SYMBOL_GPL
(xpc_interface);
90
91
/*
92
* XPC calls this when it (the XPC module) has been loaded.
93
*/
94
void
95
xpc_set_interface
(
void
(*
connect
) (
int
),
96
void
(*
disconnect
) (
int
),
97
enum
xp_retval
(*
send
) (
short
,
int
,
u32
,
void
*,
u16
),
98
enum
xp_retval
(*
send_notify
) (
short
,
int
,
u32
,
void
*,
u16
,
99
xpc_notify_func
,
void
*),
100
void
(*
received
) (
short
,
int
,
void
*),
101
enum
xp_retval
(*
partid_to_nasids
) (
short
,
void
*))
102
{
103
xpc_interface.
connect
=
connect
;
104
xpc_interface.
disconnect
=
disconnect
;
105
xpc_interface.
send
=
send
;
106
xpc_interface.
send_notify
=
send_notify
;
107
xpc_interface.
received
=
received
;
108
xpc_interface.
partid_to_nasids
=
partid_to_nasids
;
109
}
110
EXPORT_SYMBOL_GPL
(
xpc_set_interface
);
111
112
/*
113
* XPC calls this when it (the XPC module) is being unloaded.
114
*/
115
void
116
xpc_clear_interface
(
void
)
117
{
118
xpc_interface.
connect
= (
void
(*)(
int
))xpc_notloaded;
119
xpc_interface.
disconnect
= (
void
(*)(
int
))xpc_notloaded;
120
xpc_interface.
send
= (
enum
xp_retval
(*)(
short
,
int
,
u32
,
void
*,
u16
))
121
xpc_notloaded;
122
xpc_interface.
send_notify
= (
enum
xp_retval
(*)(
short
,
int
,
u32
,
void
*,
123
u16
,
xpc_notify_func
,
124
void
*))xpc_notloaded;
125
xpc_interface.
received
= (
void
(*)(
short
,
int
,
void
*))
126
xpc_notloaded;
127
xpc_interface.
partid_to_nasids
= (
enum
xp_retval
(*)(
short
,
void
*))
128
xpc_notloaded;
129
}
130
EXPORT_SYMBOL_GPL
(
xpc_clear_interface
);
131
132
/*
133
* Register for automatic establishment of a channel connection whenever
134
* a partition comes up.
135
*
136
* Arguments:
137
*
138
* ch_number - channel # to register for connection.
139
* func - function to call for asynchronous notification of channel
140
* state changes (i.e., connection, disconnection, error) and
141
* the arrival of incoming messages.
142
* key - pointer to optional user-defined value that gets passed back
143
* to the user on any callouts made to func.
144
* payload_size - size in bytes of the XPC message's payload area which
145
* contains a user-defined message. The user should make
146
* this large enough to hold their largest message.
147
* nentries - max #of XPC message entries a message queue can contain.
148
* The actual number, which is determined when a connection
149
* is established and may be less then requested, will be
150
* passed to the user via the xpConnected callout.
151
* assigned_limit - max number of kthreads allowed to be processing
152
* messages (per connection) at any given instant.
153
* idle_limit - max number of kthreads allowed to be idle at any given
154
* instant.
155
*/
156
enum
xp_retval
157
xpc_connect
(
int
ch_number,
xpc_channel_func
func
,
void
*
key
,
u16
payload_size
,
158
u16
nentries,
u32
assigned_limit,
u32
idle_limit)
159
{
160
struct
xpc_registration
*registration;
161
162
DBUG_ON
(ch_number < 0 || ch_number >=
XPC_MAX_NCHANNELS
);
163
DBUG_ON
(payload_size == 0 || nentries == 0);
164
DBUG_ON
(func ==
NULL
);
165
DBUG_ON
(assigned_limit == 0 || idle_limit > assigned_limit);
166
167
if
(
XPC_MSG_SIZE
(payload_size) >
XPC_MSG_MAX_SIZE
)
168
return
xpPayloadTooBig
;
169
170
registration = &
xpc_registrations
[ch_number];
171
172
if
(
mutex_lock_interruptible
(®istration->
mutex
) != 0)
173
return
xpInterrupted
;
174
175
/* if XPC_CHANNEL_REGISTERED(ch_number) */
176
if
(registration->
func
!=
NULL
) {
177
mutex_unlock
(®istration->
mutex
);
178
return
xpAlreadyRegistered
;
179
}
180
181
/* register the channel for connection */
182
registration->
entry_size
=
XPC_MSG_SIZE
(payload_size);
183
registration->
nentries
=
nentries
;
184
registration->
assigned_limit
=
assigned_limit
;
185
registration->
idle_limit
=
idle_limit
;
186
registration->
key
=
key
;
187
registration->
func
=
func
;
188
189
mutex_unlock
(®istration->
mutex
);
190
191
xpc_interface.
connect
(ch_number);
192
193
return
xpSuccess
;
194
}
195
EXPORT_SYMBOL_GPL
(
xpc_connect
);
196
197
/*
198
* Remove the registration for automatic connection of the specified channel
199
* when a partition comes up.
200
*
201
* Before returning this xpc_disconnect() will wait for all connections on the
202
* specified channel have been closed/torndown. So the caller can be assured
203
* that they will not be receiving any more callouts from XPC to their
204
* function registered via xpc_connect().
205
*
206
* Arguments:
207
*
208
* ch_number - channel # to unregister.
209
*/
210
void
211
xpc_disconnect
(
int
ch_number)
212
{
213
struct
xpc_registration
*registration;
214
215
DBUG_ON
(ch_number < 0 || ch_number >=
XPC_MAX_NCHANNELS
);
216
217
registration = &
xpc_registrations
[ch_number];
218
219
/*
220
* We've decided not to make this a down_interruptible(), since we
221
* figured XPC's users will just turn around and call xpc_disconnect()
222
* again anyways, so we might as well wait, if need be.
223
*/
224
mutex_lock
(®istration->
mutex
);
225
226
/* if !XPC_CHANNEL_REGISTERED(ch_number) */
227
if
(registration->
func
==
NULL
) {
228
mutex_unlock
(®istration->
mutex
);
229
return
;
230
}
231
232
/* remove the connection registration for the specified channel */
233
registration->
func
=
NULL
;
234
registration->
key
=
NULL
;
235
registration->
nentries
= 0;
236
registration->
entry_size
= 0;
237
registration->
assigned_limit
= 0;
238
registration->
idle_limit
= 0;
239
240
xpc_interface.
disconnect
(ch_number);
241
242
mutex_unlock
(®istration->
mutex
);
243
244
return
;
245
}
246
EXPORT_SYMBOL_GPL
(
xpc_disconnect
);
247
248
int
__init
249
xp_init
(
void
)
250
{
251
enum
xp_retval
ret
;
252
int
ch_number;
253
254
/* initialize the connection registration mutex */
255
for
(ch_number = 0; ch_number <
XPC_MAX_NCHANNELS
; ch_number++)
256
mutex_init
(&
xpc_registrations
[ch_number].
mutex
);
257
258
if
(
is_shub
())
259
ret =
xp_init_sn2
();
260
else
if
(
is_uv
())
261
ret =
xp_init_uv
();
262
else
263
ret = 0;
264
265
if
(ret !=
xpSuccess
)
266
return
ret
;
267
268
return
0;
269
}
270
271
module_init
(
xp_init
);
272
273
void
__exit
274
xp_exit
(
void
)
275
{
276
if
(
is_shub
())
277
xp_exit_sn2
();
278
else
if
(
is_uv
())
279
xp_exit_uv
();
280
}
281
282
module_exit
(
xp_exit
);
283
284
MODULE_AUTHOR
(
"Silicon Graphics, Inc."
);
285
MODULE_DESCRIPTION
(
"Cross Partition (XP) base"
);
286
MODULE_LICENSE
(
"GPL"
);
Generated on Thu Jan 10 2013 13:55:05 for Linux Kernel by
1.8.2