aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorRobin Holt <holt@sgi.com>2009-04-13 17:40:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-13 18:04:33 -0400
commitefdd06ed181a88a11e612238c1ac04668e665395 (patch)
tree6d66f74c82edf9986eeab5b3edef4697d5b6bb5c /drivers/misc
parenta374c57b0764432a80303abee3d1afd1939b5a0a (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.h56
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c97
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c2
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c8
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c22
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
239struct xpc_activate_mq_msg_uv { 240struct 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
282struct 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
635static inline int 645static inline int
@@ -866,6 +876,8 @@ extern void (*xpc_send_chctl_closereply) (struct xpc_channel *,
866extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *, 876extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
867 unsigned long *); 877 unsigned long *);
868extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *); 878extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
879extern void (*xpc_send_chctl_opencomplete) (struct xpc_channel *,
880 unsigned long *);
869 881
870extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *, 882extern 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
452out:
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);
221void (*xpc_send_chctl_openreply) (struct xpc_channel *ch, 221void (*xpc_send_chctl_openreply) (struct xpc_channel *ch,
222 unsigned long *irq_flags); 222 unsigned long *irq_flags);
223void (*xpc_send_chctl_opencomplete) (struct xpc_channel *ch,
224 unsigned long *irq_flags);
223 225
224enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch, 226enum 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
433static void 433static void
434xpc_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
440static void
434xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch) 441xpc_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
1204static void 1215static void
1216xpc_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
1225static void
1205xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number) 1226xpc_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