aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2008-07-30 01:34:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 12:41:49 -0400
commit97bf1aa1e1bb18de9bb1987c6eb9ad751bf08aab (patch)
treec07472cdffc9c53aefa7f7eeb6098b18bc4f7ac1 /drivers/misc/sgi-xp
parentaaa3cd694c0c4ae534e8aafdf4227e395c57d6bd (diff)
sgi-xp: move xpc_allocate() into xpc_send()/xpc_send_notify()
Move xpc_allocate() functionality into xpc_send()/xpc_send_notify() so xpc_allocate() no longer needs to be called by XPNET. Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp')
-rw-r--r--drivers/misc/sgi-xp/xp.h44
-rw-r--r--drivers/misc/sgi-xp/xp_main.c23
-rw-r--r--drivers/misc/sgi-xp/xpc.h9
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c112
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c14
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c64
-rw-r--r--drivers/misc/sgi-xp/xpnet.c11
7 files changed, 106 insertions, 171 deletions
diff --git a/drivers/misc/sgi-xp/xp.h b/drivers/misc/sgi-xp/xp.h
index 0f75592896dd..43bf2470850e 100644
--- a/drivers/misc/sgi-xp/xp.h
+++ b/drivers/misc/sgi-xp/xp.h
@@ -116,12 +116,6 @@
116 * The size of the payload is defined by the user via xpc_connect(). A user- 116 * The size of the payload is defined by the user via xpc_connect(). A user-
117 * defined message resides in the payload area. 117 * defined message resides in the payload area.
118 * 118 *
119 * The user should have no dealings with the message header, but only the
120 * message's payload. When a message entry is allocated (via xpc_allocate())
121 * a pointer to the payload area is returned and not the actual beginning of
122 * the XPC message. The user then constructs a message in the payload area
123 * and passes that pointer as an argument on xpc_send() or xpc_send_notify().
124 *
125 * The size of a message entry (within a message queue) must be a cacheline 119 * The size of a message entry (within a message queue) must be a cacheline
126 * sized multiple in order to facilitate the BTE transfer of messages from one 120 * sized multiple in order to facilitate the BTE transfer of messages from one
127 * message queue to another. A macro, XPC_MSG_SIZE(), is provided for the user 121 * message queue to another. A macro, XPC_MSG_SIZE(), is provided for the user
@@ -221,9 +215,10 @@ enum xp_retval {
221 xpBteCopyError, /* 52: bte_copy() returned error */ 215 xpBteCopyError, /* 52: bte_copy() returned error */
222 xpSalError, /* 53: sn SAL error */ 216 xpSalError, /* 53: sn SAL error */
223 xpRsvdPageNotSet, /* 54: the reserved page is not set up */ 217 xpRsvdPageNotSet, /* 54: the reserved page is not set up */
218 xpPayloadTooBig, /* 55: payload too large for message slot */
224 219
225 xpUnsupported, /* 55: unsupported functionality or resource */ 220 xpUnsupported, /* 56: unsupported functionality or resource */
226 xpUnknownReason /* 56: unknown reason - must be last in enum */ 221 xpUnknownReason /* 57: unknown reason - must be last in enum */
227}; 222};
228 223
229/* 224/*
@@ -304,16 +299,15 @@ struct xpc_registration {
304 299
305#define XPC_CHANNEL_REGISTERED(_c) (xpc_registrations[_c].func != NULL) 300#define XPC_CHANNEL_REGISTERED(_c) (xpc_registrations[_c].func != NULL)
306 301
307/* the following are valid xpc_allocate() flags */ 302/* the following are valid xpc_send() or xpc_send_notify() flags */
308#define XPC_WAIT 0 /* wait flag */ 303#define XPC_WAIT 0 /* wait flag */
309#define XPC_NOWAIT 1 /* no wait flag */ 304#define XPC_NOWAIT 1 /* no wait flag */
310 305
311struct xpc_interface { 306struct xpc_interface {
312 void (*connect) (int); 307 void (*connect) (int);
313 void (*disconnect) (int); 308 void (*disconnect) (int);
314 enum xp_retval (*allocate) (short, int, u32, void **); 309 enum xp_retval (*send) (short, int, u32, void *, u16);
315 enum xp_retval (*send) (short, int, void *); 310 enum xp_retval (*send_notify) (short, int, u32, void *, u16,
316 enum xp_retval (*send_notify) (short, int, void *,
317 xpc_notify_func, void *); 311 xpc_notify_func, void *);
318 void (*received) (short, int, void *); 312 void (*received) (short, int, void *);
319 enum xp_retval (*partid_to_nasids) (short, void *); 313 enum xp_retval (*partid_to_nasids) (short, void *);
@@ -323,10 +317,9 @@ extern struct xpc_interface xpc_interface;
323 317
324extern void xpc_set_interface(void (*)(int), 318extern void xpc_set_interface(void (*)(int),
325 void (*)(int), 319 void (*)(int),
326 enum xp_retval (*)(short, int, u32, void **), 320 enum xp_retval (*)(short, int, u32, void *, u16),
327 enum xp_retval (*)(short, int, void *), 321 enum xp_retval (*)(short, int, u32, void *, u16,
328 enum xp_retval (*)(short, int, void *, 322 xpc_notify_func, void *),
329 xpc_notify_func, void *),
330 void (*)(short, int, void *), 323 void (*)(short, int, void *),
331 enum xp_retval (*)(short, void *)); 324 enum xp_retval (*)(short, void *));
332extern void xpc_clear_interface(void); 325extern void xpc_clear_interface(void);
@@ -336,22 +329,19 @@ extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16,
336extern void xpc_disconnect(int); 329extern void xpc_disconnect(int);
337 330
338static inline enum xp_retval 331static inline enum xp_retval
339xpc_allocate(short partid, int ch_number, u32 flags, void **payload) 332xpc_send(short partid, int ch_number, u32 flags, void *payload,
340{ 333 u16 payload_size)
341 return xpc_interface.allocate(partid, ch_number, flags, payload);
342}
343
344static inline enum xp_retval
345xpc_send(short partid, int ch_number, void *payload)
346{ 334{
347 return xpc_interface.send(partid, ch_number, payload); 335 return xpc_interface.send(partid, ch_number, flags, payload,
336 payload_size);
348} 337}
349 338
350static inline enum xp_retval 339static inline enum xp_retval
351xpc_send_notify(short partid, int ch_number, void *payload, 340xpc_send_notify(short partid, int ch_number, u32 flags, void *payload,
352 xpc_notify_func func, void *key) 341 u16 payload_size, xpc_notify_func func, void *key)
353{ 342{
354 return xpc_interface.send_notify(partid, ch_number, payload, func, key); 343 return xpc_interface.send_notify(partid, ch_number, flags, payload,
344 payload_size, func, key);
355} 345}
356 346
357static inline void 347static inline void
diff --git a/drivers/misc/sgi-xp/xp_main.c b/drivers/misc/sgi-xp/xp_main.c
index 6f25613b27e3..9c0ce2f15ff6 100644
--- a/drivers/misc/sgi-xp/xp_main.c
+++ b/drivers/misc/sgi-xp/xp_main.c
@@ -58,10 +58,9 @@ xpc_notloaded(void)
58struct xpc_interface xpc_interface = { 58struct xpc_interface xpc_interface = {
59 (void (*)(int))xpc_notloaded, 59 (void (*)(int))xpc_notloaded,
60 (void (*)(int))xpc_notloaded, 60 (void (*)(int))xpc_notloaded,
61 (enum xp_retval(*)(short, int, u32, void **))xpc_notloaded, 61 (enum xp_retval(*)(short, int, u32, void *, u16))xpc_notloaded,
62 (enum xp_retval(*)(short, int, void *))xpc_notloaded, 62 (enum xp_retval(*)(short, int, u32, void *, u16, xpc_notify_func,
63 (enum xp_retval(*)(short, int, void *, xpc_notify_func, void *)) 63 void *))xpc_notloaded,
64 xpc_notloaded,
65 (void (*)(short, int, void *))xpc_notloaded, 64 (void (*)(short, int, void *))xpc_notloaded,
66 (enum xp_retval(*)(short, void *))xpc_notloaded 65 (enum xp_retval(*)(short, void *))xpc_notloaded
67}; 66};
@@ -73,16 +72,14 @@ EXPORT_SYMBOL_GPL(xpc_interface);
73void 72void
74xpc_set_interface(void (*connect) (int), 73xpc_set_interface(void (*connect) (int),
75 void (*disconnect) (int), 74 void (*disconnect) (int),
76 enum xp_retval (*allocate) (short, int, u32, void **), 75 enum xp_retval (*send) (short, int, u32, void *, u16),
77 enum xp_retval (*send) (short, int, void *), 76 enum xp_retval (*send_notify) (short, int, u32, void *, u16,
78 enum xp_retval (*send_notify) (short, int, void *,
79 xpc_notify_func, void *), 77 xpc_notify_func, void *),
80 void (*received) (short, int, void *), 78 void (*received) (short, int, void *),
81 enum xp_retval (*partid_to_nasids) (short, void *)) 79 enum xp_retval (*partid_to_nasids) (short, void *))
82{ 80{
83 xpc_interface.connect = connect; 81 xpc_interface.connect = connect;
84 xpc_interface.disconnect = disconnect; 82 xpc_interface.disconnect = disconnect;
85 xpc_interface.allocate = allocate;
86 xpc_interface.send = send; 83 xpc_interface.send = send;
87 xpc_interface.send_notify = send_notify; 84 xpc_interface.send_notify = send_notify;
88 xpc_interface.received = received; 85 xpc_interface.received = received;
@@ -98,13 +95,11 @@ xpc_clear_interface(void)
98{ 95{
99 xpc_interface.connect = (void (*)(int))xpc_notloaded; 96 xpc_interface.connect = (void (*)(int))xpc_notloaded;
100 xpc_interface.disconnect = (void (*)(int))xpc_notloaded; 97 xpc_interface.disconnect = (void (*)(int))xpc_notloaded;
101 xpc_interface.allocate = (enum xp_retval(*)(short, int, u32, 98 xpc_interface.send = (enum xp_retval(*)(short, int, u32, void *, u16))
102 void **))xpc_notloaded;
103 xpc_interface.send = (enum xp_retval(*)(short, int, void *))
104 xpc_notloaded; 99 xpc_notloaded;
105 xpc_interface.send_notify = (enum xp_retval(*)(short, int, void *, 100 xpc_interface.send_notify = (enum xp_retval(*)(short, int, u32, void *,
106 xpc_notify_func, 101 u16, xpc_notify_func,
107 void *))xpc_notloaded; 102 void *))xpc_notloaded;
108 xpc_interface.received = (void (*)(short, int, void *)) 103 xpc_interface.received = (void (*)(short, int, void *))
109 xpc_notloaded; 104 xpc_notloaded;
110 xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *)) 105 xpc_interface.partid_to_nasids = (enum xp_retval(*)(short, void *))
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 56bf5dcc391d..6b622b091bde 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -624,9 +624,7 @@ extern void (*xpc_IPI_send_closereply) (struct xpc_channel *, unsigned long *);
624extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *); 624extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *);
625extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *); 625extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *);
626 626
627extern enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *, u32, 627extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16,
628 struct xpc_msg **);
629extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, struct xpc_msg *,
630 u8, xpc_notify_func, void *); 628 u8, xpc_notify_func, void *);
631extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *); 629extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *);
632 630
@@ -664,9 +662,8 @@ extern void *xpc_kzalloc_cacheline_aligned(size_t, gfp_t, void **);
664extern void xpc_initiate_connect(int); 662extern void xpc_initiate_connect(int);
665extern void xpc_initiate_disconnect(int); 663extern void xpc_initiate_disconnect(int);
666extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *); 664extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *);
667extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **); 665extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16);
668extern enum xp_retval xpc_initiate_send(short, int, void *); 666extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16,
669extern enum xp_retval xpc_initiate_send_notify(short, int, void *,
670 xpc_notify_func, void *); 667 xpc_notify_func, void *);
671extern void xpc_initiate_received(short, int, void *); 668extern void xpc_initiate_received(short, int, void *);
672extern void xpc_process_channel_activity(struct xpc_partition *); 669extern void xpc_process_channel_activity(struct xpc_partition *);
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 26c5e12c1220..55182c8dd32a 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -1192,87 +1192,54 @@ xpc_allocate_msg_wait(struct xpc_channel *ch)
1192} 1192}
1193 1193
1194/* 1194/*
1195 * Allocate an entry for a message from the message queue associated with the 1195 * Send a message that contains the user's payload on the specified channel
1196 * specified channel. NOTE that this routine can sleep waiting for a message 1196 * connected to the specified partition.
1197 * entry to become available. To not sleep, pass in the XPC_NOWAIT flag.
1198 * 1197 *
1199 * Arguments: 1198 * NOTE that this routine can sleep waiting for a message entry to become
1199 * available. To not sleep, pass in the XPC_NOWAIT flag.
1200 * 1200 *
1201 * partid - ID of partition to which the channel is connected. 1201 * Once sent, this routine will not wait for the message to be received, nor
1202 * ch_number - channel #. 1202 * will notification be given when it does happen.
1203 * flags - see xpc.h for valid flags.
1204 * payload - address of the allocated payload area pointer (filled in on
1205 * return) in which the user-defined message is constructed.
1206 */
1207enum xp_retval
1208xpc_initiate_allocate(short partid, int ch_number, u32 flags, void **payload)
1209{
1210 struct xpc_partition *part = &xpc_partitions[partid];
1211 enum xp_retval ret = xpUnknownReason;
1212 struct xpc_msg *msg = NULL;
1213
1214 DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
1215 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
1216
1217 *payload = NULL;
1218
1219 if (xpc_part_ref(part)) {
1220 ret = xpc_allocate_msg(&part->channels[ch_number], flags, &msg);
1221 xpc_part_deref(part);
1222
1223 if (msg != NULL)
1224 *payload = &msg->payload;
1225 }
1226
1227 return ret;
1228}
1229
1230/*
1231 * Send a message previously allocated using xpc_initiate_allocate() on the
1232 * specified channel connected to the specified partition.
1233 *
1234 * This routine will not wait for the message to be received, nor will
1235 * notification be given when it does happen. Once this routine has returned
1236 * the message entry allocated via xpc_initiate_allocate() is no longer
1237 * accessable to the caller.
1238 *
1239 * This routine, although called by users, does not call xpc_part_ref() to
1240 * ensure that the partition infrastructure is in place. It relies on the
1241 * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg().
1242 * 1203 *
1243 * Arguments: 1204 * Arguments:
1244 * 1205 *
1245 * partid - ID of partition to which the channel is connected. 1206 * partid - ID of partition to which the channel is connected.
1246 * ch_number - channel # to send message on. 1207 * ch_number - channel # to send message on.
1247 * payload - pointer to the payload area allocated via 1208 * flags - see xp.h for valid flags.
1248 * xpc_initiate_allocate(). 1209 * payload - pointer to the payload which is to be sent.
1210 * payload_size - size of the payload in bytes.
1249 */ 1211 */
1250enum xp_retval 1212enum xp_retval
1251xpc_initiate_send(short partid, int ch_number, void *payload) 1213xpc_initiate_send(short partid, int ch_number, u32 flags, void *payload,
1214 u16 payload_size)
1252{ 1215{
1253 struct xpc_partition *part = &xpc_partitions[partid]; 1216 struct xpc_partition *part = &xpc_partitions[partid];
1254 struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); 1217 enum xp_retval ret = xpUnknownReason;
1255 enum xp_retval ret;
1256 1218
1257 dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg, 1219 dev_dbg(xpc_chan, "payload=0x%p, partid=%d, channel=%d\n", payload,
1258 partid, ch_number); 1220 partid, ch_number);
1259 1221
1260 DBUG_ON(partid < 0 || partid >= xp_max_npartitions); 1222 DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
1261 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); 1223 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
1262 DBUG_ON(msg == NULL); 1224 DBUG_ON(payload == NULL);
1263 1225
1264 ret = xpc_send_msg(&part->channels[ch_number], msg, 0, NULL, NULL); 1226 if (xpc_part_ref(part)) {
1227 ret = xpc_send_msg(&part->channels[ch_number], flags, payload,
1228 payload_size, 0, NULL, NULL);
1229 xpc_part_deref(part);
1230 }
1265 1231
1266 return ret; 1232 return ret;
1267} 1233}
1268 1234
1269/* 1235/*
1270 * Send a message previously allocated using xpc_initiate_allocate on the 1236 * Send a message that contains the user's payload on the specified channel
1271 * specified channel connected to the specified partition. 1237 * connected to the specified partition.
1272 * 1238 *
1273 * This routine will not wait for the message to be sent. Once this routine 1239 * NOTE that this routine can sleep waiting for a message entry to become
1274 * has returned the message entry allocated via xpc_initiate_allocate() is no 1240 * available. To not sleep, pass in the XPC_NOWAIT flag.
1275 * longer accessable to the caller. 1241 *
1242 * This routine will not wait for the message to be sent or received.
1276 * 1243 *
1277 * Once the remote end of the channel has received the message, the function 1244 * Once the remote end of the channel has received the message, the function
1278 * passed as an argument to xpc_initiate_send_notify() will be called. This 1245 * passed as an argument to xpc_initiate_send_notify() will be called. This
@@ -1282,38 +1249,37 @@ xpc_initiate_send(short partid, int ch_number, void *payload)
1282 * 1249 *
1283 * If this routine returns an error, the caller's function will NOT be called. 1250 * If this routine returns an error, the caller's function will NOT be called.
1284 * 1251 *
1285 * This routine, although called by users, does not call xpc_part_ref() to
1286 * ensure that the partition infrastructure is in place. It relies on the
1287 * fact that we called xpc_msgqueue_ref() in xpc_allocate_msg().
1288 *
1289 * Arguments: 1252 * Arguments:
1290 * 1253 *
1291 * partid - ID of partition to which the channel is connected. 1254 * partid - ID of partition to which the channel is connected.
1292 * ch_number - channel # to send message on. 1255 * ch_number - channel # to send message on.
1293 * payload - pointer to the payload area allocated via 1256 * flags - see xp.h for valid flags.
1294 * xpc_initiate_allocate(). 1257 * payload - pointer to the payload which is to be sent.
1258 * payload_size - size of the payload in bytes.
1295 * func - function to call with asynchronous notification of message 1259 * func - function to call with asynchronous notification of message
1296 * receipt. THIS FUNCTION MUST BE NON-BLOCKING. 1260 * receipt. THIS FUNCTION MUST BE NON-BLOCKING.
1297 * key - user-defined key to be passed to the function when it's called. 1261 * key - user-defined key to be passed to the function when it's called.
1298 */ 1262 */
1299enum xp_retval 1263enum xp_retval
1300xpc_initiate_send_notify(short partid, int ch_number, void *payload, 1264xpc_initiate_send_notify(short partid, int ch_number, u32 flags, void *payload,
1301 xpc_notify_func func, void *key) 1265 u16 payload_size, xpc_notify_func func, void *key)
1302{ 1266{
1303 struct xpc_partition *part = &xpc_partitions[partid]; 1267 struct xpc_partition *part = &xpc_partitions[partid];
1304 struct xpc_msg *msg = XPC_MSG_ADDRESS(payload); 1268 enum xp_retval ret = xpUnknownReason;
1305 enum xp_retval ret;
1306 1269
1307 dev_dbg(xpc_chan, "msg=0x%p, partid=%d, channel=%d\n", (void *)msg, 1270 dev_dbg(xpc_chan, "payload=0x%p, partid=%d, channel=%d\n", payload,
1308 partid, ch_number); 1271 partid, ch_number);
1309 1272
1310 DBUG_ON(partid < 0 || partid >= xp_max_npartitions); 1273 DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
1311 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels); 1274 DBUG_ON(ch_number < 0 || ch_number >= part->nchannels);
1312 DBUG_ON(msg == NULL); 1275 DBUG_ON(payload == NULL);
1313 DBUG_ON(func == NULL); 1276 DBUG_ON(func == NULL);
1314 1277
1315 ret = xpc_send_msg(&part->channels[ch_number], msg, XPC_N_CALL, 1278 if (xpc_part_ref(part)) {
1316 func, key); 1279 ret = xpc_send_msg(&part->channels[ch_number], flags, payload,
1280 payload_size, XPC_N_CALL, func, key);
1281 xpc_part_deref(part);
1282 }
1317 return ret; 1283 return ret;
1318} 1284}
1319 1285
@@ -1372,7 +1338,7 @@ xpc_deliver_msg(struct xpc_channel *ch)
1372 * partid - ID of partition to which the channel is connected. 1338 * partid - ID of partition to which the channel is connected.
1373 * ch_number - channel # message received on. 1339 * ch_number - channel # message received on.
1374 * payload - pointer to the payload area allocated via 1340 * payload - pointer to the payload area allocated via
1375 * xpc_initiate_allocate(). 1341 * xpc_initiate_send() or xpc_initiate_send_notify().
1376 */ 1342 */
1377void 1343void
1378xpc_initiate_received(short partid, int ch_number, void *payload) 1344xpc_initiate_received(short partid, int ch_number, void *payload)
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 4a6eb3774759..aae90f5933b5 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -217,12 +217,9 @@ void (*xpc_IPI_send_openrequest) (struct xpc_channel *ch,
217void (*xpc_IPI_send_openreply) (struct xpc_channel *ch, 217void (*xpc_IPI_send_openreply) (struct xpc_channel *ch,
218 unsigned long *irq_flags); 218 unsigned long *irq_flags);
219 219
220enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *ch, u32 flags, 220enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, u32 flags,
221 struct xpc_msg **address_of_msg); 221 void *payload, u16 payload_size, u8 notify_type,
222 222 xpc_notify_func func, void *key);
223enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, struct xpc_msg *msg,
224 u8 notify_type, xpc_notify_func func,
225 void *key);
226void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg); 223void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg);
227 224
228/* 225/*
@@ -1286,9 +1283,8 @@ xpc_init(void)
1286 1283
1287 /* set the interface to point at XPC's functions */ 1284 /* set the interface to point at XPC's functions */
1288 xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect, 1285 xpc_set_interface(xpc_initiate_connect, xpc_initiate_disconnect,
1289 xpc_initiate_allocate, xpc_initiate_send, 1286 xpc_initiate_send, xpc_initiate_send_notify,
1290 xpc_initiate_send_notify, xpc_initiate_received, 1287 xpc_initiate_received, xpc_initiate_partid_to_nasids);
1291 xpc_initiate_partid_to_nasids);
1292 1288
1293 return 0; 1289 return 0;
1294 1290
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 7216df36bc73..db67d348b35c 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -1532,18 +1532,6 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
1532 enum xp_retval ret; 1532 enum xp_retval ret;
1533 s64 put; 1533 s64 put;
1534 1534
1535 /* this reference will be dropped in xpc_send_msg_sn2() */
1536 xpc_msgqueue_ref(ch);
1537
1538 if (ch->flags & XPC_C_DISCONNECTING) {
1539 xpc_msgqueue_deref(ch);
1540 return ch->reason;
1541 }
1542 if (!(ch->flags & XPC_C_CONNECTED)) {
1543 xpc_msgqueue_deref(ch);
1544 return xpNotConnected;
1545 }
1546
1547 /* 1535 /*
1548 * Get the next available message entry from the local message queue. 1536 * Get the next available message entry from the local message queue.
1549 * If none are available, we'll make sure that we grab the latest 1537 * If none are available, we'll make sure that we grab the latest
@@ -1582,16 +1570,12 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
1582 if (ret == xpTimeout) 1570 if (ret == xpTimeout)
1583 xpc_IPI_send_local_msgrequest_sn2(ch); 1571 xpc_IPI_send_local_msgrequest_sn2(ch);
1584 1572
1585 if (flags & XPC_NOWAIT) { 1573 if (flags & XPC_NOWAIT)
1586 xpc_msgqueue_deref(ch);
1587 return xpNoWait; 1574 return xpNoWait;
1588 }
1589 1575
1590 ret = xpc_allocate_msg_wait(ch); 1576 ret = xpc_allocate_msg_wait(ch);
1591 if (ret != xpInterrupted && ret != xpTimeout) { 1577 if (ret != xpInterrupted && ret != xpTimeout)
1592 xpc_msgqueue_deref(ch);
1593 return ret; 1578 return ret;
1594 }
1595 } 1579 }
1596 1580
1597 /* get the message's address and initialize it */ 1581 /* get the message's address and initialize it */
@@ -1606,7 +1590,6 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
1606 (void *)msg, msg->number, ch->partid, ch->number); 1590 (void *)msg, msg->number, ch->partid, ch->number);
1607 1591
1608 *address_of_msg = msg; 1592 *address_of_msg = msg;
1609
1610 return xpSuccess; 1593 return xpSuccess;
1611} 1594}
1612 1595
@@ -1616,24 +1599,38 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
1616 * message is being sent to. 1599 * message is being sent to.
1617 */ 1600 */
1618static enum xp_retval 1601static enum xp_retval
1619xpc_send_msg_sn2(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, 1602xpc_send_msg_sn2(struct xpc_channel *ch, u32 flags, void *payload,
1620 xpc_notify_func func, void *key) 1603 u16 payload_size, u8 notify_type, xpc_notify_func func,
1604 void *key)
1621{ 1605{
1622 enum xp_retval ret = xpSuccess; 1606 enum xp_retval ret = xpSuccess;
1607 struct xpc_msg *msg = msg;
1623 struct xpc_notify *notify = notify; 1608 struct xpc_notify *notify = notify;
1624 s64 put, msg_number = msg->number; 1609 s64 msg_number;
1610 s64 put;
1625 1611
1626 DBUG_ON(notify_type == XPC_N_CALL && func == NULL); 1612 DBUG_ON(notify_type == XPC_N_CALL && func == NULL);
1627 DBUG_ON((((u64)msg - (u64)ch->local_msgqueue) / ch->msg_size) != 1613
1628 msg_number % ch->local_nentries); 1614 if (XPC_MSG_SIZE(payload_size) > ch->msg_size)
1629 DBUG_ON(msg->flags & XPC_M_READY); 1615 return xpPayloadTooBig;
1616
1617 xpc_msgqueue_ref(ch);
1630 1618
1631 if (ch->flags & XPC_C_DISCONNECTING) { 1619 if (ch->flags & XPC_C_DISCONNECTING) {
1632 /* drop the reference grabbed in xpc_allocate_msg_sn2() */ 1620 ret = ch->reason;
1633 xpc_msgqueue_deref(ch); 1621 goto out_1;
1634 return ch->reason; 1622 }
1623 if (!(ch->flags & XPC_C_CONNECTED)) {
1624 ret = xpNotConnected;
1625 goto out_1;
1635 } 1626 }
1636 1627
1628 ret = xpc_allocate_msg_sn2(ch, flags, &msg);
1629 if (ret != xpSuccess)
1630 goto out_1;
1631
1632 msg_number = msg->number;
1633
1637 if (notify_type != 0) { 1634 if (notify_type != 0) {
1638 /* 1635 /*
1639 * Tell the remote side to send an ACK interrupt when the 1636 * Tell the remote side to send an ACK interrupt when the
@@ -1663,13 +1660,12 @@ xpc_send_msg_sn2(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
1663 atomic_dec(&ch->n_to_notify); 1660 atomic_dec(&ch->n_to_notify);
1664 ret = ch->reason; 1661 ret = ch->reason;
1665 } 1662 }
1666 1663 goto out_1;
1667 /* drop reference grabbed in xpc_allocate_msg_sn2() */
1668 xpc_msgqueue_deref(ch);
1669 return ret;
1670 } 1664 }
1671 } 1665 }
1672 1666
1667 memcpy(&msg->payload, payload, payload_size);
1668
1673 msg->flags |= XPC_M_READY; 1669 msg->flags |= XPC_M_READY;
1674 1670
1675 /* 1671 /*
@@ -1684,7 +1680,7 @@ xpc_send_msg_sn2(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type,
1684 if (put == msg_number) 1680 if (put == msg_number)
1685 xpc_send_msgs_sn2(ch, put); 1681 xpc_send_msgs_sn2(ch, put);
1686 1682
1687 /* drop the reference grabbed in xpc_allocate_msg_sn2() */ 1683out_1:
1688 xpc_msgqueue_deref(ch); 1684 xpc_msgqueue_deref(ch);
1689 return ret; 1685 return ret;
1690} 1686}
@@ -1821,8 +1817,6 @@ xpc_init_sn2(void)
1821 xpc_IPI_send_openrequest = xpc_IPI_send_openrequest_sn2; 1817 xpc_IPI_send_openrequest = xpc_IPI_send_openrequest_sn2;
1822 xpc_IPI_send_openreply = xpc_IPI_send_openreply_sn2; 1818 xpc_IPI_send_openreply = xpc_IPI_send_openreply_sn2;
1823 1819
1824 xpc_allocate_msg = xpc_allocate_msg_sn2;
1825
1826 xpc_send_msg = xpc_send_msg_sn2; 1820 xpc_send_msg = xpc_send_msg_sn2;
1827 xpc_received_msg = xpc_received_msg_sn2; 1821 xpc_received_msg = xpc_received_msg_sn2;
1828} 1822}
diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c
index 9c540eb1847d..f9356ba73155 100644
--- a/drivers/misc/sgi-xp/xpnet.c
+++ b/drivers/misc/sgi-xp/xpnet.c
@@ -438,7 +438,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
438{ 438{
439 struct xpnet_pending_msg *queued_msg; 439 struct xpnet_pending_msg *queued_msg;
440 enum xp_retval ret; 440 enum xp_retval ret;
441 struct xpnet_message *msg; 441 u8 msg_buffer[XPNET_MSG_SIZE];
442 struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer[0];
442 u64 start_addr, end_addr; 443 u64 start_addr, end_addr;
443 long dp; 444 long dp;
444 u8 second_mac_octet; 445 u8 second_mac_octet;
@@ -524,11 +525,6 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
524 525
525 /* found a partition to send to */ 526 /* found a partition to send to */
526 527
527 ret = xpc_allocate(dest_partid, XPC_NET_CHANNEL,
528 XPC_NOWAIT, (void **)&msg);
529 if (unlikely(ret != xpSuccess))
530 continue;
531
532 msg->embedded_bytes = embedded_bytes; 528 msg->embedded_bytes = embedded_bytes;
533 if (unlikely(embedded_bytes != 0)) { 529 if (unlikely(embedded_bytes != 0)) {
534 msg->version = XPNET_VERSION_EMBED; 530 msg->version = XPNET_VERSION_EMBED;
@@ -553,7 +549,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
553 549
554 atomic_inc(&queued_msg->use_count); 550 atomic_inc(&queued_msg->use_count);
555 551
556 ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, msg, 552 ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT,
553 &msg, sizeof(msg) + embedded_bytes - 1,
557 xpnet_send_completed, queued_msg); 554 xpnet_send_completed, queued_msg);
558 if (unlikely(ret != xpSuccess)) { 555 if (unlikely(ret != xpSuccess)) {
559 atomic_dec(&queued_msg->use_count); 556 atomic_dec(&queued_msg->use_count);