diff options
author | Robin Holt <holt@sgi.com> | 2009-04-13 17:40:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-13 18:04:33 -0400 |
commit | efdd06ed181a88a11e612238c1ac04668e665395 (patch) | |
tree | 6d66f74c82edf9986eeab5b3edef4697d5b6bb5c /drivers/misc | |
parent | a374c57b0764432a80303abee3d1afd1939b5a0a (diff) |
sgi-xpc: implement opencomplete messaging
sgi-xpc has a window of failure where an open message can be sent and a
subsequent data message can get lost. We have added a new message
(opencomplete) which closes that window.
Signed-off-by: Robin Holt <holt@sgi.com>
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/xpc.h | 56 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_channel.c | 97 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 2 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_sn2.c | 8 | ||||
-rw-r--r-- | drivers/misc/sgi-xp/xpc_uv.c | 22 |
5 files changed, 124 insertions, 61 deletions
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h index da32bbe8caaf..a54047674785 100644 --- a/drivers/misc/sgi-xp/xpc.h +++ b/drivers/misc/sgi-xp/xpc.h | |||
@@ -232,9 +232,10 @@ struct xpc_activate_mq_msghdr_uv { | |||
232 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4 | 232 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV 4 |
233 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5 | 233 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV 5 |
234 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6 | 234 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV 6 |
235 | #define XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV 7 | ||
235 | 236 | ||
236 | #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 7 | 237 | #define XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV 8 |
237 | #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 8 | 238 | #define XPC_ACTIVATE_MQ_MSG_MARK_DISENGAGED_UV 9 |
238 | 239 | ||
239 | struct xpc_activate_mq_msg_uv { | 240 | struct xpc_activate_mq_msg_uv { |
240 | struct xpc_activate_mq_msghdr_uv hdr; | 241 | struct xpc_activate_mq_msghdr_uv hdr; |
@@ -278,6 +279,11 @@ struct xpc_activate_mq_msg_chctl_openreply_uv { | |||
278 | unsigned long notify_gru_mq_desc_gpa; | 279 | unsigned long notify_gru_mq_desc_gpa; |
279 | }; | 280 | }; |
280 | 281 | ||
282 | struct xpc_activate_mq_msg_chctl_opencomplete_uv { | ||
283 | struct xpc_activate_mq_msghdr_uv hdr; | ||
284 | short ch_number; | ||
285 | }; | ||
286 | |||
281 | /* | 287 | /* |
282 | * Functions registered by add_timer() or called by kernel_thread() only | 288 | * Functions registered by add_timer() or called by kernel_thread() only |
283 | * allow for a single 64-bit argument. The following macros can be used to | 289 | * allow for a single 64-bit argument. The following macros can be used to |
@@ -583,30 +589,32 @@ struct xpc_channel { | |||
583 | 589 | ||
584 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ | 590 | #define XPC_C_WASCONNECTED 0x00000001 /* channel was connected */ |
585 | 591 | ||
586 | #define XPC_C_ROPENREPLY 0x00000002 /* remote open channel reply */ | 592 | #define XPC_C_ROPENCOMPLETE 0x00000002 /* remote open channel complete */ |
587 | #define XPC_C_OPENREPLY 0x00000004 /* local open channel reply */ | 593 | #define XPC_C_OPENCOMPLETE 0x00000004 /* local open channel complete */ |
588 | #define XPC_C_ROPENREQUEST 0x00000008 /* remote open channel request */ | 594 | #define XPC_C_ROPENREPLY 0x00000008 /* remote open channel reply */ |
589 | #define XPC_C_OPENREQUEST 0x00000010 /* local open channel request */ | 595 | #define XPC_C_OPENREPLY 0x00000010 /* local open channel reply */ |
596 | #define XPC_C_ROPENREQUEST 0x00000020 /* remote open channel request */ | ||
597 | #define XPC_C_OPENREQUEST 0x00000040 /* local open channel request */ | ||
590 | 598 | ||
591 | #define XPC_C_SETUP 0x00000020 /* channel's msgqueues are alloc'd */ | 599 | #define XPC_C_SETUP 0x00000080 /* channel's msgqueues are alloc'd */ |
592 | #define XPC_C_CONNECTEDCALLOUT 0x00000040 /* connected callout initiated */ | 600 | #define XPC_C_CONNECTEDCALLOUT 0x00000100 /* connected callout initiated */ |
593 | #define XPC_C_CONNECTEDCALLOUT_MADE \ | 601 | #define XPC_C_CONNECTEDCALLOUT_MADE \ |
594 | 0x00000080 /* connected callout completed */ | 602 | 0x00000200 /* connected callout completed */ |
595 | #define XPC_C_CONNECTED 0x00000100 /* local channel is connected */ | 603 | #define XPC_C_CONNECTED 0x00000400 /* local channel is connected */ |
596 | #define XPC_C_CONNECTING 0x00000200 /* channel is being connected */ | 604 | #define XPC_C_CONNECTING 0x00000800 /* channel is being connected */ |
597 | 605 | ||
598 | #define XPC_C_RCLOSEREPLY 0x00000400 /* remote close channel reply */ | 606 | #define XPC_C_RCLOSEREPLY 0x00001000 /* remote close channel reply */ |
599 | #define XPC_C_CLOSEREPLY 0x00000800 /* local close channel reply */ | 607 | #define XPC_C_CLOSEREPLY 0x00002000 /* local close channel reply */ |
600 | #define XPC_C_RCLOSEREQUEST 0x00001000 /* remote close channel request */ | 608 | #define XPC_C_RCLOSEREQUEST 0x00004000 /* remote close channel request */ |
601 | #define XPC_C_CLOSEREQUEST 0x00002000 /* local close channel request */ | 609 | #define XPC_C_CLOSEREQUEST 0x00008000 /* local close channel request */ |
602 | 610 | ||
603 | #define XPC_C_DISCONNECTED 0x00004000 /* channel is disconnected */ | 611 | #define XPC_C_DISCONNECTED 0x00010000 /* channel is disconnected */ |
604 | #define XPC_C_DISCONNECTING 0x00008000 /* channel is being disconnected */ | 612 | #define XPC_C_DISCONNECTING 0x00020000 /* channel is being disconnected */ |
605 | #define XPC_C_DISCONNECTINGCALLOUT \ | 613 | #define XPC_C_DISCONNECTINGCALLOUT \ |
606 | 0x00010000 /* disconnecting callout initiated */ | 614 | 0x00040000 /* disconnecting callout initiated */ |
607 | #define XPC_C_DISCONNECTINGCALLOUT_MADE \ | 615 | #define XPC_C_DISCONNECTINGCALLOUT_MADE \ |
608 | 0x00020000 /* disconnecting callout completed */ | 616 | 0x00080000 /* disconnecting callout completed */ |
609 | #define XPC_C_WDISCONNECT 0x00040000 /* waiting for channel disconnect */ | 617 | #define XPC_C_WDISCONNECT 0x00100000 /* waiting for channel disconnect */ |
610 | 618 | ||
611 | /* | 619 | /* |
612 | * The channel control flags (chctl) union consists of a 64-bit variable which | 620 | * The channel control flags (chctl) union consists of a 64-bit variable which |
@@ -625,11 +633,13 @@ union xpc_channel_ctl_flags { | |||
625 | #define XPC_CHCTL_CLOSEREPLY 0x02 | 633 | #define XPC_CHCTL_CLOSEREPLY 0x02 |
626 | #define XPC_CHCTL_OPENREQUEST 0x04 | 634 | #define XPC_CHCTL_OPENREQUEST 0x04 |
627 | #define XPC_CHCTL_OPENREPLY 0x08 | 635 | #define XPC_CHCTL_OPENREPLY 0x08 |
628 | #define XPC_CHCTL_MSGREQUEST 0x10 | 636 | #define XPC_CHCTL_OPENCOMPLETE 0x10 |
637 | #define XPC_CHCTL_MSGREQUEST 0x20 | ||
629 | 638 | ||
630 | #define XPC_OPENCLOSE_CHCTL_FLAGS \ | 639 | #define XPC_OPENCLOSE_CHCTL_FLAGS \ |
631 | (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \ | 640 | (XPC_CHCTL_CLOSEREQUEST | XPC_CHCTL_CLOSEREPLY | \ |
632 | XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY) | 641 | XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | \ |
642 | XPC_CHCTL_OPENCOMPLETE) | ||
633 | #define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST | 643 | #define XPC_MSG_CHCTL_FLAGS XPC_CHCTL_MSGREQUEST |
634 | 644 | ||
635 | static inline int | 645 | static inline int |
@@ -866,6 +876,8 @@ extern void (*xpc_send_chctl_closereply) (struct xpc_channel *, | |||
866 | extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *, | 876 | extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *, |
867 | unsigned long *); | 877 | unsigned long *); |
868 | extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *); | 878 | extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *); |
879 | extern void (*xpc_send_chctl_opencomplete) (struct xpc_channel *, | ||
880 | unsigned long *); | ||
869 | 881 | ||
870 | extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, | 882 | extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, |
871 | unsigned long); | 883 | unsigned long); |
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c index 99a2534c38a1..2eb3abff0e3a 100644 --- a/drivers/misc/sgi-xp/xpc_channel.c +++ b/drivers/misc/sgi-xp/xpc_channel.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (c) 2004-2008 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2004-2009 Silicon Graphics, Inc. All Rights Reserved. |
7 | */ | 7 | */ |
8 | 8 | ||
9 | /* | 9 | /* |
@@ -44,10 +44,10 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
44 | 44 | ||
45 | if (ret != xpSuccess) | 45 | if (ret != xpSuccess) |
46 | XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags); | 46 | XPC_DISCONNECT_CHANNEL(ch, ret, irq_flags); |
47 | else | ||
48 | ch->flags |= XPC_C_SETUP; | ||
47 | 49 | ||
48 | ch->flags |= XPC_C_SETUP; | 50 | if (ch->flags & XPC_C_DISCONNECTING) |
49 | |||
50 | if (ch->flags & (XPC_C_CONNECTED | XPC_C_DISCONNECTING)) | ||
51 | return; | 51 | return; |
52 | } | 52 | } |
53 | 53 | ||
@@ -59,14 +59,18 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags) | |||
59 | if (!(ch->flags & XPC_C_ROPENREPLY)) | 59 | if (!(ch->flags & XPC_C_ROPENREPLY)) |
60 | return; | 60 | return; |
61 | 61 | ||
62 | ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */ | 62 | if (!(ch->flags & XPC_C_OPENCOMPLETE)) { |
63 | ch->flags |= (XPC_C_OPENCOMPLETE | XPC_C_CONNECTED); | ||
64 | xpc_send_chctl_opencomplete(ch, irq_flags); | ||
65 | } | ||
66 | |||
67 | if (!(ch->flags & XPC_C_ROPENCOMPLETE)) | ||
68 | return; | ||
63 | 69 | ||
64 | dev_info(xpc_chan, "channel %d to partition %d connected\n", | 70 | dev_info(xpc_chan, "channel %d to partition %d connected\n", |
65 | ch->number, ch->partid); | 71 | ch->number, ch->partid); |
66 | 72 | ||
67 | spin_unlock_irqrestore(&ch->lock, *irq_flags); | 73 | ch->flags = (XPC_C_CONNECTED | XPC_C_SETUP); /* clear all else */ |
68 | xpc_create_kthreads(ch, 1, 0); | ||
69 | spin_lock_irqsave(&ch->lock, *irq_flags); | ||
70 | } | 74 | } |
71 | 75 | ||
72 | /* | 76 | /* |
@@ -184,6 +188,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number, | |||
184 | struct xpc_channel *ch = &part->channels[ch_number]; | 188 | struct xpc_channel *ch = &part->channels[ch_number]; |
185 | enum xp_retval reason; | 189 | enum xp_retval reason; |
186 | enum xp_retval ret; | 190 | enum xp_retval ret; |
191 | int create_kthread = 0; | ||
187 | 192 | ||
188 | spin_lock_irqsave(&ch->lock, irq_flags); | 193 | spin_lock_irqsave(&ch->lock, irq_flags); |
189 | 194 | ||
@@ -196,8 +201,7 @@ again: | |||
196 | * has had a chance to see that the channel is disconnected. | 201 | * has had a chance to see that the channel is disconnected. |
197 | */ | 202 | */ |
198 | ch->delayed_chctl_flags |= chctl_flags; | 203 | ch->delayed_chctl_flags |= chctl_flags; |
199 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 204 | goto out; |
200 | return; | ||
201 | } | 205 | } |
202 | 206 | ||
203 | if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) { | 207 | if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) { |
@@ -239,8 +243,7 @@ again: | |||
239 | XPC_CHCTL_CLOSEREQUEST; | 243 | XPC_CHCTL_CLOSEREQUEST; |
240 | spin_unlock(&part->chctl_lock); | 244 | spin_unlock(&part->chctl_lock); |
241 | } | 245 | } |
242 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 246 | goto out; |
243 | return; | ||
244 | } | 247 | } |
245 | 248 | ||
246 | XPC_SET_REASON(ch, 0, 0); | 249 | XPC_SET_REASON(ch, 0, 0); |
@@ -250,7 +253,8 @@ again: | |||
250 | ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST); | 253 | ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST); |
251 | } | 254 | } |
252 | 255 | ||
253 | chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY); | 256 | chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY | |
257 | XPC_CHCTL_OPENCOMPLETE); | ||
254 | 258 | ||
255 | /* | 259 | /* |
256 | * The meaningful CLOSEREQUEST connection state fields are: | 260 | * The meaningful CLOSEREQUEST connection state fields are: |
@@ -269,8 +273,7 @@ again: | |||
269 | XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); | 273 | XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); |
270 | 274 | ||
271 | DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY); | 275 | DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY); |
272 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 276 | goto out; |
273 | return; | ||
274 | } | 277 | } |
275 | 278 | ||
276 | xpc_process_disconnect(ch, &irq_flags); | 279 | xpc_process_disconnect(ch, &irq_flags); |
@@ -283,8 +286,7 @@ again: | |||
283 | 286 | ||
284 | if (ch->flags & XPC_C_DISCONNECTED) { | 287 | if (ch->flags & XPC_C_DISCONNECTED) { |
285 | DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING); | 288 | DBUG_ON(part->act_state != XPC_P_AS_DEACTIVATING); |
286 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 289 | goto out; |
287 | return; | ||
288 | } | 290 | } |
289 | 291 | ||
290 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); | 292 | DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); |
@@ -299,8 +301,7 @@ again: | |||
299 | XPC_CHCTL_CLOSEREPLY; | 301 | XPC_CHCTL_CLOSEREPLY; |
300 | spin_unlock(&part->chctl_lock); | 302 | spin_unlock(&part->chctl_lock); |
301 | } | 303 | } |
302 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 304 | goto out; |
303 | return; | ||
304 | } | 305 | } |
305 | 306 | ||
306 | ch->flags |= XPC_C_RCLOSEREPLY; | 307 | ch->flags |= XPC_C_RCLOSEREPLY; |
@@ -320,14 +321,12 @@ again: | |||
320 | 321 | ||
321 | if (part->act_state == XPC_P_AS_DEACTIVATING || | 322 | if (part->act_state == XPC_P_AS_DEACTIVATING || |
322 | (ch->flags & XPC_C_ROPENREQUEST)) { | 323 | (ch->flags & XPC_C_ROPENREQUEST)) { |
323 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 324 | goto out; |
324 | return; | ||
325 | } | 325 | } |
326 | 326 | ||
327 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) { | 327 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) { |
328 | ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST; | 328 | ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST; |
329 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 329 | goto out; |
330 | return; | ||
331 | } | 330 | } |
332 | DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED | | 331 | DBUG_ON(!(ch->flags & (XPC_C_DISCONNECTED | |
333 | XPC_C_OPENREQUEST))); | 332 | XPC_C_OPENREQUEST))); |
@@ -341,8 +340,7 @@ again: | |||
341 | */ | 340 | */ |
342 | if (args->entry_size == 0 || args->local_nentries == 0) { | 341 | if (args->entry_size == 0 || args->local_nentries == 0) { |
343 | /* assume OPENREQUEST was delayed by mistake */ | 342 | /* assume OPENREQUEST was delayed by mistake */ |
344 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 343 | goto out; |
345 | return; | ||
346 | } | 344 | } |
347 | 345 | ||
348 | ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING); | 346 | ch->flags |= (XPC_C_ROPENREQUEST | XPC_C_CONNECTING); |
@@ -352,8 +350,7 @@ again: | |||
352 | if (args->entry_size != ch->entry_size) { | 350 | if (args->entry_size != ch->entry_size) { |
353 | XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, | 351 | XPC_DISCONNECT_CHANNEL(ch, xpUnequalMsgSizes, |
354 | &irq_flags); | 352 | &irq_flags); |
355 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 353 | goto out; |
356 | return; | ||
357 | } | 354 | } |
358 | } else { | 355 | } else { |
359 | ch->entry_size = args->entry_size; | 356 | ch->entry_size = args->entry_size; |
@@ -375,15 +372,13 @@ again: | |||
375 | args->local_msgqueue_pa, args->local_nentries, | 372 | args->local_msgqueue_pa, args->local_nentries, |
376 | args->remote_nentries, ch->partid, ch->number); | 373 | args->remote_nentries, ch->partid, ch->number); |
377 | 374 | ||
378 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) { | 375 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) |
379 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 376 | goto out; |
380 | return; | 377 | |
381 | } | ||
382 | if (!(ch->flags & XPC_C_OPENREQUEST)) { | 378 | if (!(ch->flags & XPC_C_OPENREQUEST)) { |
383 | XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, | 379 | XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, |
384 | &irq_flags); | 380 | &irq_flags); |
385 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 381 | goto out; |
386 | return; | ||
387 | } | 382 | } |
388 | 383 | ||
389 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); | 384 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); |
@@ -403,8 +398,7 @@ again: | |||
403 | ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa); | 398 | ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa); |
404 | if (ret != xpSuccess) { | 399 | if (ret != xpSuccess) { |
405 | XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags); | 400 | XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags); |
406 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 401 | goto out; |
407 | return; | ||
408 | } | 402 | } |
409 | ch->flags |= XPC_C_ROPENREPLY; | 403 | ch->flags |= XPC_C_ROPENREPLY; |
410 | 404 | ||
@@ -430,7 +424,36 @@ again: | |||
430 | xpc_process_connect(ch, &irq_flags); | 424 | xpc_process_connect(ch, &irq_flags); |
431 | } | 425 | } |
432 | 426 | ||
427 | if (chctl_flags & XPC_CHCTL_OPENCOMPLETE) { | ||
428 | |||
429 | dev_dbg(xpc_chan, "XPC_CHCTL_OPENCOMPLETE received from " | ||
430 | "partid=%d, channel=%d\n", ch->partid, ch->number); | ||
431 | |||
432 | if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) | ||
433 | goto out; | ||
434 | |||
435 | if (!(ch->flags & XPC_C_OPENREQUEST) || | ||
436 | !(ch->flags & XPC_C_OPENREPLY)) { | ||
437 | XPC_DISCONNECT_CHANNEL(ch, xpOpenCloseError, | ||
438 | &irq_flags); | ||
439 | goto out; | ||
440 | } | ||
441 | |||
442 | DBUG_ON(!(ch->flags & XPC_C_ROPENREQUEST)); | ||
443 | DBUG_ON(!(ch->flags & XPC_C_ROPENREPLY)); | ||
444 | DBUG_ON(!(ch->flags & XPC_C_CONNECTED)); | ||
445 | |||
446 | ch->flags |= XPC_C_ROPENCOMPLETE; | ||
447 | |||
448 | xpc_process_connect(ch, &irq_flags); | ||
449 | create_kthread = 1; | ||
450 | } | ||
451 | |||
452 | out: | ||
433 | spin_unlock_irqrestore(&ch->lock, irq_flags); | 453 | spin_unlock_irqrestore(&ch->lock, irq_flags); |
454 | |||
455 | if (create_kthread) | ||
456 | xpc_create_kthreads(ch, 1, 0); | ||
434 | } | 457 | } |
435 | 458 | ||
436 | /* | 459 | /* |
@@ -564,10 +587,6 @@ xpc_process_sent_chctl_flags(struct xpc_partition *part) | |||
564 | if (!(ch_flags & XPC_C_OPENREQUEST)) { | 587 | if (!(ch_flags & XPC_C_OPENREQUEST)) { |
565 | DBUG_ON(ch_flags & XPC_C_SETUP); | 588 | DBUG_ON(ch_flags & XPC_C_SETUP); |
566 | (void)xpc_connect_channel(ch); | 589 | (void)xpc_connect_channel(ch); |
567 | } else { | ||
568 | spin_lock_irqsave(&ch->lock, irq_flags); | ||
569 | xpc_process_connect(ch, &irq_flags); | ||
570 | spin_unlock_irqrestore(&ch->lock, irq_flags); | ||
571 | } | 590 | } |
572 | continue; | 591 | continue; |
573 | } | 592 | } |
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 34b084cd63da..2bb070e17222 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c | |||
@@ -220,6 +220,8 @@ void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch, | |||
220 | unsigned long *irq_flags); | 220 | unsigned long *irq_flags); |
221 | void (*xpc_send_chctl_openreply) (struct xpc_channel *ch, | 221 | void (*xpc_send_chctl_openreply) (struct xpc_channel *ch, |
222 | unsigned long *irq_flags); | 222 | unsigned long *irq_flags); |
223 | void (*xpc_send_chctl_opencomplete) (struct xpc_channel *ch, | ||
224 | unsigned long *irq_flags); | ||
223 | 225 | ||
224 | enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, | 226 | enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, |
225 | unsigned long msgqueue_pa); | 227 | unsigned long msgqueue_pa); |
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index 43ad2968daf5..09bc1989f216 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c | |||
@@ -431,6 +431,13 @@ xpc_send_chctl_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | static void | 433 | static void |
434 | xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch, | ||
435 | unsigned long *irq_flags) | ||
436 | { | ||
437 | XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags); | ||
438 | } | ||
439 | |||
440 | static void | ||
434 | xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch) | 441 | xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch) |
435 | { | 442 | { |
436 | XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL); | 443 | XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL); |
@@ -2380,6 +2387,7 @@ xpc_init_sn2(void) | |||
2380 | xpc_send_chctl_closereply = xpc_send_chctl_closereply_sn2; | 2387 | xpc_send_chctl_closereply = xpc_send_chctl_closereply_sn2; |
2381 | xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_sn2; | 2388 | xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_sn2; |
2382 | xpc_send_chctl_openreply = xpc_send_chctl_openreply_sn2; | 2389 | xpc_send_chctl_openreply = xpc_send_chctl_openreply_sn2; |
2390 | xpc_send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2; | ||
2383 | 2391 | ||
2384 | xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2; | 2392 | xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2; |
2385 | 2393 | ||
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 97f7cb21a0a2..1e475b4c0887 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -534,6 +534,17 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, | |||
534 | xpc_wakeup_channel_mgr(part); | 534 | xpc_wakeup_channel_mgr(part); |
535 | break; | 535 | break; |
536 | } | 536 | } |
537 | case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { | ||
538 | struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; | ||
539 | |||
540 | msg = container_of(msg_hdr, struct | ||
541 | xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); | ||
542 | spin_lock_irqsave(&part->chctl_lock, irq_flags); | ||
543 | part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENCOMPLETE; | ||
544 | spin_unlock_irqrestore(&part->chctl_lock, irq_flags); | ||
545 | |||
546 | xpc_wakeup_channel_mgr(part); | ||
547 | } | ||
537 | case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: | 548 | case XPC_ACTIVATE_MQ_MSG_MARK_ENGAGED_UV: |
538 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); | 549 | spin_lock_irqsave(&part_uv->flags_lock, irq_flags); |
539 | part_uv->flags |= XPC_P_ENGAGED_UV; | 550 | part_uv->flags |= XPC_P_ENGAGED_UV; |
@@ -1202,6 +1213,16 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags) | |||
1202 | } | 1213 | } |
1203 | 1214 | ||
1204 | static void | 1215 | static void |
1216 | xpc_send_chctl_opencomplete_uv(struct xpc_channel *ch, unsigned long *irq_flags) | ||
1217 | { | ||
1218 | struct xpc_activate_mq_msg_chctl_opencomplete_uv msg; | ||
1219 | |||
1220 | msg.ch_number = ch->number; | ||
1221 | xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg), | ||
1222 | XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV); | ||
1223 | } | ||
1224 | |||
1225 | static void | ||
1205 | xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) | 1226 | xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) |
1206 | { | 1227 | { |
1207 | unsigned long irq_flags; | 1228 | unsigned long irq_flags; |
@@ -1665,6 +1686,7 @@ xpc_init_uv(void) | |||
1665 | xpc_send_chctl_closereply = xpc_send_chctl_closereply_uv; | 1686 | xpc_send_chctl_closereply = xpc_send_chctl_closereply_uv; |
1666 | xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_uv; | 1687 | xpc_send_chctl_openrequest = xpc_send_chctl_openrequest_uv; |
1667 | xpc_send_chctl_openreply = xpc_send_chctl_openreply_uv; | 1688 | xpc_send_chctl_openreply = xpc_send_chctl_openreply_uv; |
1689 | xpc_send_chctl_opencomplete = xpc_send_chctl_opencomplete_uv; | ||
1668 | 1690 | ||
1669 | xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv; | 1691 | xpc_save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_uv; |
1670 | 1692 | ||