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 | |
| 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>
| -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); |
