0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <linux/module.h>
0019 #include <linux/device.h>
0020 #include "xp.h"
0021
0022
0023
0024 static struct device_driver xp_dbg_name = {
0025 .name = "xp"
0026 };
0027
0028 static struct device xp_dbg_subname = {
0029 .init_name = "",
0030 .driver = &xp_dbg_name
0031 };
0032
0033 struct device *xp = &xp_dbg_subname;
0034
0035
0036 short xp_max_npartitions;
0037 EXPORT_SYMBOL_GPL(xp_max_npartitions);
0038
0039 short xp_partition_id;
0040 EXPORT_SYMBOL_GPL(xp_partition_id);
0041
0042 u8 xp_region_size;
0043 EXPORT_SYMBOL_GPL(xp_region_size);
0044
0045 unsigned long (*xp_pa) (void *addr);
0046 EXPORT_SYMBOL_GPL(xp_pa);
0047
0048 unsigned long (*xp_socket_pa) (unsigned long gpa);
0049 EXPORT_SYMBOL_GPL(xp_socket_pa);
0050
0051 enum xp_retval (*xp_remote_memcpy) (unsigned long dst_gpa,
0052 const unsigned long src_gpa, size_t len);
0053 EXPORT_SYMBOL_GPL(xp_remote_memcpy);
0054
0055 int (*xp_cpu_to_nasid) (int cpuid);
0056 EXPORT_SYMBOL_GPL(xp_cpu_to_nasid);
0057
0058 enum xp_retval (*xp_expand_memprotect) (unsigned long phys_addr,
0059 unsigned long size);
0060 EXPORT_SYMBOL_GPL(xp_expand_memprotect);
0061 enum xp_retval (*xp_restrict_memprotect) (unsigned long phys_addr,
0062 unsigned long size);
0063 EXPORT_SYMBOL_GPL(xp_restrict_memprotect);
0064
0065
0066
0067
0068
0069 struct xpc_registration xpc_registrations[XPC_MAX_NCHANNELS];
0070 EXPORT_SYMBOL_GPL(xpc_registrations);
0071
0072
0073
0074
0075 struct xpc_interface xpc_interface = { };
0076 EXPORT_SYMBOL_GPL(xpc_interface);
0077
0078
0079
0080
0081 void
0082 xpc_set_interface(void (*connect) (int),
0083 void (*disconnect) (int),
0084 enum xp_retval (*send) (short, int, u32, void *, u16),
0085 enum xp_retval (*send_notify) (short, int, u32, void *, u16,
0086 xpc_notify_func, void *),
0087 void (*received) (short, int, void *),
0088 enum xp_retval (*partid_to_nasids) (short, void *))
0089 {
0090 xpc_interface.connect = connect;
0091 xpc_interface.disconnect = disconnect;
0092 xpc_interface.send = send;
0093 xpc_interface.send_notify = send_notify;
0094 xpc_interface.received = received;
0095 xpc_interface.partid_to_nasids = partid_to_nasids;
0096 }
0097 EXPORT_SYMBOL_GPL(xpc_set_interface);
0098
0099
0100
0101
0102 void
0103 xpc_clear_interface(void)
0104 {
0105 memset(&xpc_interface, 0, sizeof(xpc_interface));
0106 }
0107 EXPORT_SYMBOL_GPL(xpc_clear_interface);
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 enum xp_retval
0134 xpc_connect(int ch_number, xpc_channel_func func, void *key, u16 payload_size,
0135 u16 nentries, u32 assigned_limit, u32 idle_limit)
0136 {
0137 struct xpc_registration *registration;
0138
0139 DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
0140 DBUG_ON(payload_size == 0 || nentries == 0);
0141 DBUG_ON(func == NULL);
0142 DBUG_ON(assigned_limit == 0 || idle_limit > assigned_limit);
0143
0144 if (XPC_MSG_SIZE(payload_size) > XPC_MSG_MAX_SIZE)
0145 return xpPayloadTooBig;
0146
0147 registration = &xpc_registrations[ch_number];
0148
0149 if (mutex_lock_interruptible(®istration->mutex) != 0)
0150 return xpInterrupted;
0151
0152
0153 if (registration->func != NULL) {
0154 mutex_unlock(®istration->mutex);
0155 return xpAlreadyRegistered;
0156 }
0157
0158
0159 registration->entry_size = XPC_MSG_SIZE(payload_size);
0160 registration->nentries = nentries;
0161 registration->assigned_limit = assigned_limit;
0162 registration->idle_limit = idle_limit;
0163 registration->key = key;
0164 registration->func = func;
0165
0166 mutex_unlock(®istration->mutex);
0167
0168 if (xpc_interface.connect)
0169 xpc_interface.connect(ch_number);
0170
0171 return xpSuccess;
0172 }
0173 EXPORT_SYMBOL_GPL(xpc_connect);
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 void
0189 xpc_disconnect(int ch_number)
0190 {
0191 struct xpc_registration *registration;
0192
0193 DBUG_ON(ch_number < 0 || ch_number >= XPC_MAX_NCHANNELS);
0194
0195 registration = &xpc_registrations[ch_number];
0196
0197
0198
0199
0200
0201
0202 mutex_lock(®istration->mutex);
0203
0204
0205 if (registration->func == NULL) {
0206 mutex_unlock(®istration->mutex);
0207 return;
0208 }
0209
0210
0211 registration->func = NULL;
0212 registration->key = NULL;
0213 registration->nentries = 0;
0214 registration->entry_size = 0;
0215 registration->assigned_limit = 0;
0216 registration->idle_limit = 0;
0217
0218 if (xpc_interface.disconnect)
0219 xpc_interface.disconnect(ch_number);
0220
0221 mutex_unlock(®istration->mutex);
0222
0223 return;
0224 }
0225 EXPORT_SYMBOL_GPL(xpc_disconnect);
0226
0227 static int __init
0228 xp_init(void)
0229 {
0230 enum xp_retval ret;
0231 int ch_number;
0232
0233
0234 for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
0235 mutex_init(&xpc_registrations[ch_number].mutex);
0236
0237 if (is_uv_system())
0238 ret = xp_init_uv();
0239 else
0240 ret = 0;
0241
0242 if (ret != xpSuccess)
0243 return ret;
0244
0245 return 0;
0246 }
0247
0248 module_init(xp_init);
0249
0250 static void __exit
0251 xp_exit(void)
0252 {
0253 if (is_uv_system())
0254 xp_exit_uv();
0255 }
0256
0257 module_exit(xp_exit);
0258
0259 MODULE_AUTHOR("Silicon Graphics, Inc.");
0260 MODULE_DESCRIPTION("Cross Partition (XP) base");
0261 MODULE_LICENSE("GPL");