diff options
author | Dean Nelson <dcn@sgi.com> | 2008-07-30 01:34:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-30 12:41:49 -0400 |
commit | 97bf1aa1e1bb18de9bb1987c6eb9ad751bf08aab (patch) | |
tree | c07472cdffc9c53aefa7f7eeb6098b18bc4f7ac1 /drivers/misc | |
parent | aaa3cd694c0c4ae534e8aafdf4227e395c57d6bd (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')
-rw-r--r-- | drivers/misc/sgi-xp/xp.h | 44 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xp_main.c | 23 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc.h | 9 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_channel.c | 112 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 14 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 64 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpnet.c | 11 |
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 | ||
311 | struct xpc_interface { | 306 | struct 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 | ||
324 | extern void xpc_set_interface(void (*)(int), | 318 | extern 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 *)); |
332 | extern void xpc_clear_interface(void); | 325 | extern void xpc_clear_interface(void); |
@@ -336,22 +329,19 @@ extern enum xp_retval xpc_connect(int, xpc_channel_func, void *, u16, | |||
336 | extern void xpc_disconnect(int); | 329 | extern void xpc_disconnect(int); |
337 | 330 | ||
338 | static inline enum xp_retval | 331 | static inline enum xp_retval |
339 | xpc_allocate(short partid, int ch_number, u32 flags, void **payload) | 332 | xpc_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 | |||
344 | static inline enum xp_retval | ||
345 | xpc_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 | ||
350 | static inline enum xp_retval | 339 | static inline enum xp_retval |
351 | xpc_send_notify(short partid, int ch_number, void *payload, | 340 | xpc_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 | ||
357 | static inline void | 347 | static 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) | |||
58 | struct xpc_interface xpc_interface = { | 58 | struct 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); | |||
73 | void | 72 | void |
74 | xpc_set_interface(void (*connect) (int), | 73 | xpc_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 *); | |||
624 | extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *); | 624 | extern void (*xpc_IPI_send_openrequest) (struct xpc_channel *, unsigned long *); |
625 | extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *); | 625 | extern void (*xpc_IPI_send_openreply) (struct xpc_channel *, unsigned long *); |
626 | 626 | ||
627 | extern enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *, u32, | 627 | extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, u32, void *, u16, |
628 | struct xpc_msg **); | ||
629 | extern enum xp_retval (*xpc_send_msg) (struct xpc_channel *, struct xpc_msg *, | ||
630 | u8, xpc_notify_func, void *); | 628 | u8, xpc_notify_func, void *); |
631 | extern void (*xpc_received_msg) (struct xpc_channel *, struct xpc_msg *); | 629 | extern 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 **); | |||
664 | extern void xpc_initiate_connect(int); | 662 | extern void xpc_initiate_connect(int); |
665 | extern void xpc_initiate_disconnect(int); | 663 | extern void xpc_initiate_disconnect(int); |
666 | extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *); | 664 | extern enum xp_retval xpc_allocate_msg_wait(struct xpc_channel *); |
667 | extern enum xp_retval xpc_initiate_allocate(short, int, u32, void **); | 665 | extern enum xp_retval xpc_initiate_send(short, int, u32, void *, u16); |
668 | extern enum xp_retval xpc_initiate_send(short, int, void *); | 666 | extern enum xp_retval xpc_initiate_send_notify(short, int, u32, void *, u16, |
669 | extern enum xp_retval xpc_initiate_send_notify(short, int, void *, | ||
670 | xpc_notify_func, void *); | 667 | xpc_notify_func, void *); |
671 | extern void xpc_initiate_received(short, int, void *); | 668 | extern void xpc_initiate_received(short, int, void *); |
672 | extern void xpc_process_channel_activity(struct xpc_partition *); | 669 | extern 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 | */ | ||
1207 | enum xp_retval | ||
1208 | xpc_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 | */ |
1250 | enum xp_retval | 1212 | enum xp_retval |
1251 | xpc_initiate_send(short partid, int ch_number, void *payload) | 1213 | xpc_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 | */ |
1299 | enum xp_retval | 1263 | enum xp_retval |
1300 | xpc_initiate_send_notify(short partid, int ch_number, void *payload, | 1264 | xpc_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 | */ |
1377 | void | 1343 | void |
1378 | xpc_initiate_received(short partid, int ch_number, void *payload) | 1344 | xpc_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, | |||
217 | void (*xpc_IPI_send_openreply) (struct xpc_channel *ch, | 217 | void (*xpc_IPI_send_openreply) (struct xpc_channel *ch, |
218 | unsigned long *irq_flags); | 218 | unsigned long *irq_flags); |
219 | 219 | ||
220 | enum xp_retval (*xpc_allocate_msg) (struct xpc_channel *ch, u32 flags, | 220 | enum 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); | |
223 | enum xp_retval (*xpc_send_msg) (struct xpc_channel *ch, struct xpc_msg *msg, | ||
224 | u8 notify_type, xpc_notify_func func, | ||
225 | void *key); | ||
226 | void (*xpc_received_msg) (struct xpc_channel *ch, struct xpc_msg *msg); | 223 | void (*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 | */ |
1618 | static enum xp_retval | 1601 | static enum xp_retval |
1619 | xpc_send_msg_sn2(struct xpc_channel *ch, struct xpc_msg *msg, u8 notify_type, | 1602 | xpc_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() */ | 1683 | out_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); |