aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-xp/xpc_channel.c
diff options
context:
space:
mode:
authorDean Nelson <dcn@sgi.com>2008-07-30 01:34:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-30 12:41:49 -0400
commit7fb5e59d63deda89a8eefdbd5b3c8d622076afd4 (patch)
tree4c78f9e016dd0998e8539a1da358b4ba961db8e9 /drivers/misc/sgi-xp/xpc_channel.c
parenta47d5dac9d8481766382f8cf1483dd581df38b99 (diff)
sgi-xp: separate chctl_flags from XPC's notify IRQ
Tie current IPI references to either XPC's notify IRQ or channel control flags. Signed-off-by: Dean Nelson <dcn@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_channel.c')
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c135
1 files changed, 66 insertions, 69 deletions
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 48b16136305..0d3c153d1d0 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -201,7 +201,7 @@ xpc_process_connect(struct xpc_channel *ch, unsigned long *irq_flags)
201 201
202 if (!(ch->flags & XPC_C_OPENREPLY)) { 202 if (!(ch->flags & XPC_C_OPENREPLY)) {
203 ch->flags |= XPC_C_OPENREPLY; 203 ch->flags |= XPC_C_OPENREPLY;
204 xpc_send_channel_openreply(ch, irq_flags); 204 xpc_send_chctl_openreply(ch, irq_flags);
205 } 205 }
206 206
207 if (!(ch->flags & XPC_C_ROPENREPLY)) 207 if (!(ch->flags & XPC_C_ROPENREPLY))
@@ -307,7 +307,7 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
307 307
308 if (!(ch->flags & XPC_C_CLOSEREPLY)) { 308 if (!(ch->flags & XPC_C_CLOSEREPLY)) {
309 ch->flags |= XPC_C_CLOSEREPLY; 309 ch->flags |= XPC_C_CLOSEREPLY;
310 xpc_send_channel_closereply(ch, irq_flags); 310 xpc_send_chctl_closereply(ch, irq_flags);
311 } 311 }
312 312
313 if (!(ch->flags & XPC_C_RCLOSEREPLY)) 313 if (!(ch->flags & XPC_C_RCLOSEREPLY))
@@ -344,15 +344,15 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
344 if (ch->flags & XPC_C_WDISCONNECT) { 344 if (ch->flags & XPC_C_WDISCONNECT) {
345 /* we won't lose the CPU since we're holding ch->lock */ 345 /* we won't lose the CPU since we're holding ch->lock */
346 complete(&ch->wdisconnect_wait); 346 complete(&ch->wdisconnect_wait);
347 } else if (ch->delayed_IPI_flags) { 347 } else if (ch->delayed_chctl_flags) {
348 if (part->act_state != XPC_P_DEACTIVATING) { 348 if (part->act_state != XPC_P_DEACTIVATING) {
349 /* time to take action on any delayed IPI flags */ 349 /* time to take action on any delayed chctl flags */
350 spin_lock(&part->IPI_lock); 350 spin_lock(&part->chctl_lock);
351 XPC_SET_IPI_FLAGS(part->local_IPI_amo, ch->number, 351 part->chctl.flags[ch->number] |=
352 ch->delayed_IPI_flags); 352 ch->delayed_chctl_flags;
353 spin_unlock(&part->IPI_lock); 353 spin_unlock(&part->chctl_lock);
354 } 354 }
355 ch->delayed_IPI_flags = 0; 355 ch->delayed_chctl_flags = 0;
356 } 356 }
357} 357}
358 358
@@ -360,8 +360,8 @@ xpc_process_disconnect(struct xpc_channel *ch, unsigned long *irq_flags)
360 * Process a change in the channel's remote connection state. 360 * Process a change in the channel's remote connection state.
361 */ 361 */
362static void 362static void
363xpc_process_openclose_IPI(struct xpc_partition *part, int ch_number, 363xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
364 u8 IPI_flags) 364 u8 chctl_flags)
365{ 365{
366 unsigned long irq_flags; 366 unsigned long irq_flags;
367 struct xpc_openclose_args *args = 367 struct xpc_openclose_args *args =
@@ -376,24 +376,24 @@ again:
376 if ((ch->flags & XPC_C_DISCONNECTED) && 376 if ((ch->flags & XPC_C_DISCONNECTED) &&
377 (ch->flags & XPC_C_WDISCONNECT)) { 377 (ch->flags & XPC_C_WDISCONNECT)) {
378 /* 378 /*
379 * Delay processing IPI flags until thread waiting disconnect 379 * Delay processing chctl flags until thread waiting disconnect
380 * has had a chance to see that the channel is disconnected. 380 * has had a chance to see that the channel is disconnected.
381 */ 381 */
382 ch->delayed_IPI_flags |= IPI_flags; 382 ch->delayed_chctl_flags |= chctl_flags;
383 spin_unlock_irqrestore(&ch->lock, irq_flags); 383 spin_unlock_irqrestore(&ch->lock, irq_flags);
384 return; 384 return;
385 } 385 }
386 386
387 if (IPI_flags & XPC_IPI_CLOSEREQUEST) { 387 if (chctl_flags & XPC_CHCTL_CLOSEREQUEST) {
388 388
389 dev_dbg(xpc_chan, "XPC_IPI_CLOSEREQUEST (reason=%d) received " 389 dev_dbg(xpc_chan, "XPC_CHCTL_CLOSEREQUEST (reason=%d) received "
390 "from partid=%d, channel=%d\n", args->reason, 390 "from partid=%d, channel=%d\n", args->reason,
391 ch->partid, ch->number); 391 ch->partid, ch->number);
392 392
393 /* 393 /*
394 * If RCLOSEREQUEST is set, we're probably waiting for 394 * If RCLOSEREQUEST is set, we're probably waiting for
395 * RCLOSEREPLY. We should find it and a ROPENREQUEST packed 395 * RCLOSEREPLY. We should find it and a ROPENREQUEST packed
396 * with this RCLOSEREQUEST in the IPI_flags. 396 * with this RCLOSEREQUEST in the chctl_flags.
397 */ 397 */
398 398
399 if (ch->flags & XPC_C_RCLOSEREQUEST) { 399 if (ch->flags & XPC_C_RCLOSEREQUEST) {
@@ -402,8 +402,8 @@ again:
402 DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY)); 402 DBUG_ON(!(ch->flags & XPC_C_CLOSEREPLY));
403 DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY); 403 DBUG_ON(ch->flags & XPC_C_RCLOSEREPLY);
404 404
405 DBUG_ON(!(IPI_flags & XPC_IPI_CLOSEREPLY)); 405 DBUG_ON(!(chctl_flags & XPC_CHCTL_CLOSEREPLY));
406 IPI_flags &= ~XPC_IPI_CLOSEREPLY; 406 chctl_flags &= ~XPC_CHCTL_CLOSEREPLY;
407 ch->flags |= XPC_C_RCLOSEREPLY; 407 ch->flags |= XPC_C_RCLOSEREPLY;
408 408
409 /* both sides have finished disconnecting */ 409 /* both sides have finished disconnecting */
@@ -413,17 +413,15 @@ again:
413 } 413 }
414 414
415 if (ch->flags & XPC_C_DISCONNECTED) { 415 if (ch->flags & XPC_C_DISCONNECTED) {
416 if (!(IPI_flags & XPC_IPI_OPENREQUEST)) { 416 if (!(chctl_flags & XPC_CHCTL_OPENREQUEST)) {
417 if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo, 417 if (part->chctl.flags[ch_number] &
418 ch_number) & 418 XPC_CHCTL_OPENREQUEST) {
419 XPC_IPI_OPENREQUEST)) { 419
420 420 DBUG_ON(ch->delayed_chctl_flags != 0);
421 DBUG_ON(ch->delayed_IPI_flags != 0); 421 spin_lock(&part->chctl_lock);
422 spin_lock(&part->IPI_lock); 422 part->chctl.flags[ch_number] |=
423 XPC_SET_IPI_FLAGS(part->local_IPI_amo, 423 XPC_CHCTL_CLOSEREQUEST;
424 ch_number, 424 spin_unlock(&part->chctl_lock);
425 XPC_IPI_CLOSEREQUEST);
426 spin_unlock(&part->IPI_lock);
427 } 425 }
428 spin_unlock_irqrestore(&ch->lock, irq_flags); 426 spin_unlock_irqrestore(&ch->lock, irq_flags);
429 return; 427 return;
@@ -436,7 +434,7 @@ again:
436 ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST); 434 ch->flags |= (XPC_C_CONNECTING | XPC_C_ROPENREQUEST);
437 } 435 }
438 436
439 IPI_flags &= ~(XPC_IPI_OPENREQUEST | XPC_IPI_OPENREPLY); 437 chctl_flags &= ~(XPC_CHCTL_OPENREQUEST | XPC_CHCTL_OPENREPLY);
440 438
441 /* 439 /*
442 * The meaningful CLOSEREQUEST connection state fields are: 440 * The meaningful CLOSEREQUEST connection state fields are:
@@ -454,7 +452,7 @@ again:
454 452
455 XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags); 453 XPC_DISCONNECT_CHANNEL(ch, reason, &irq_flags);
456 454
457 DBUG_ON(IPI_flags & XPC_IPI_CLOSEREPLY); 455 DBUG_ON(chctl_flags & XPC_CHCTL_CLOSEREPLY);
458 spin_unlock_irqrestore(&ch->lock, irq_flags); 456 spin_unlock_irqrestore(&ch->lock, irq_flags);
459 return; 457 return;
460 } 458 }
@@ -462,10 +460,10 @@ again:
462 xpc_process_disconnect(ch, &irq_flags); 460 xpc_process_disconnect(ch, &irq_flags);
463 } 461 }
464 462
465 if (IPI_flags & XPC_IPI_CLOSEREPLY) { 463 if (chctl_flags & XPC_CHCTL_CLOSEREPLY) {
466 464
467 dev_dbg(xpc_chan, "XPC_IPI_CLOSEREPLY received from partid=%d," 465 dev_dbg(xpc_chan, "XPC_CHCTL_CLOSEREPLY received from partid="
468 " channel=%d\n", ch->partid, ch->number); 466 "%d, channel=%d\n", ch->partid, ch->number);
469 467
470 if (ch->flags & XPC_C_DISCONNECTED) { 468 if (ch->flags & XPC_C_DISCONNECTED) {
471 DBUG_ON(part->act_state != XPC_P_DEACTIVATING); 469 DBUG_ON(part->act_state != XPC_P_DEACTIVATING);
@@ -476,15 +474,14 @@ again:
476 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST)); 474 DBUG_ON(!(ch->flags & XPC_C_CLOSEREQUEST));
477 475
478 if (!(ch->flags & XPC_C_RCLOSEREQUEST)) { 476 if (!(ch->flags & XPC_C_RCLOSEREQUEST)) {
479 if ((XPC_GET_IPI_FLAGS(part->local_IPI_amo, ch_number) 477 if (part->chctl.flags[ch_number] &
480 & XPC_IPI_CLOSEREQUEST)) { 478 XPC_CHCTL_CLOSEREQUEST) {
481 479
482 DBUG_ON(ch->delayed_IPI_flags != 0); 480 DBUG_ON(ch->delayed_chctl_flags != 0);
483 spin_lock(&part->IPI_lock); 481 spin_lock(&part->chctl_lock);
484 XPC_SET_IPI_FLAGS(part->local_IPI_amo, 482 part->chctl.flags[ch_number] |=
485 ch_number, 483 XPC_CHCTL_CLOSEREPLY;
486 XPC_IPI_CLOSEREPLY); 484 spin_unlock(&part->chctl_lock);
487 spin_unlock(&part->IPI_lock);
488 } 485 }
489 spin_unlock_irqrestore(&ch->lock, irq_flags); 486 spin_unlock_irqrestore(&ch->lock, irq_flags);
490 return; 487 return;
@@ -498,9 +495,9 @@ again:
498 } 495 }
499 } 496 }
500 497
501 if (IPI_flags & XPC_IPI_OPENREQUEST) { 498 if (chctl_flags & XPC_CHCTL_OPENREQUEST) {
502 499
503 dev_dbg(xpc_chan, "XPC_IPI_OPENREQUEST (msg_size=%d, " 500 dev_dbg(xpc_chan, "XPC_CHCTL_OPENREQUEST (msg_size=%d, "
504 "local_nentries=%d) received from partid=%d, " 501 "local_nentries=%d) received from partid=%d, "
505 "channel=%d\n", args->msg_size, args->local_nentries, 502 "channel=%d\n", args->msg_size, args->local_nentries,
506 ch->partid, ch->number); 503 ch->partid, ch->number);
@@ -512,7 +509,7 @@ again:
512 } 509 }
513 510
514 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) { 511 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_WDISCONNECT)) {
515 ch->delayed_IPI_flags |= XPC_IPI_OPENREQUEST; 512 ch->delayed_chctl_flags |= XPC_CHCTL_OPENREQUEST;
516 spin_unlock_irqrestore(&ch->lock, irq_flags); 513 spin_unlock_irqrestore(&ch->lock, irq_flags);
517 return; 514 return;
518 } 515 }
@@ -554,13 +551,13 @@ again:
554 xpc_process_connect(ch, &irq_flags); 551 xpc_process_connect(ch, &irq_flags);
555 } 552 }
556 553
557 if (IPI_flags & XPC_IPI_OPENREPLY) { 554 if (chctl_flags & XPC_CHCTL_OPENREPLY) {
558 555
559 dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY (local_msgqueue_pa=0x%lx, " 556 dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY (local_msgqueue_pa="
560 "local_nentries=%d, remote_nentries=%d) received from " 557 "0x%lx, local_nentries=%d, remote_nentries=%d) "
561 "partid=%d, channel=%d\n", args->local_msgqueue_pa, 558 "received from partid=%d, channel=%d\n",
562 args->local_nentries, args->remote_nentries, 559 args->local_msgqueue_pa, args->local_nentries,
563 ch->partid, ch->number); 560 args->remote_nentries, ch->partid, ch->number);
564 561
565 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) { 562 if (ch->flags & (XPC_C_DISCONNECTING | XPC_C_DISCONNECTED)) {
566 spin_unlock_irqrestore(&ch->lock, irq_flags); 563 spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -591,7 +588,7 @@ again:
591 ch->remote_msgqueue_pa = args->local_msgqueue_pa; 588 ch->remote_msgqueue_pa = args->local_msgqueue_pa;
592 589
593 if (args->local_nentries < ch->remote_nentries) { 590 if (args->local_nentries < ch->remote_nentries) {
594 dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new " 591 dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
595 "remote_nentries=%d, old remote_nentries=%d, " 592 "remote_nentries=%d, old remote_nentries=%d, "
596 "partid=%d, channel=%d\n", 593 "partid=%d, channel=%d\n",
597 args->local_nentries, ch->remote_nentries, 594 args->local_nentries, ch->remote_nentries,
@@ -600,7 +597,7 @@ again:
600 ch->remote_nentries = args->local_nentries; 597 ch->remote_nentries = args->local_nentries;
601 } 598 }
602 if (args->remote_nentries < ch->local_nentries) { 599 if (args->remote_nentries < ch->local_nentries) {
603 dev_dbg(xpc_chan, "XPC_IPI_OPENREPLY: new " 600 dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
604 "local_nentries=%d, old local_nentries=%d, " 601 "local_nentries=%d, old local_nentries=%d, "
605 "partid=%d, channel=%d\n", 602 "partid=%d, channel=%d\n",
606 args->remote_nentries, ch->local_nentries, 603 args->remote_nentries, ch->local_nentries,
@@ -690,7 +687,7 @@ xpc_connect_channel(struct xpc_channel *ch)
690 /* initiate the connection */ 687 /* initiate the connection */
691 688
692 ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING); 689 ch->flags |= (XPC_C_OPENREQUEST | XPC_C_CONNECTING);
693 xpc_send_channel_openrequest(ch, &irq_flags); 690 xpc_send_chctl_openrequest(ch, &irq_flags);
694 691
695 xpc_process_connect(ch, &irq_flags); 692 xpc_process_connect(ch, &irq_flags);
696 693
@@ -700,15 +697,15 @@ xpc_connect_channel(struct xpc_channel *ch)
700} 697}
701 698
702void 699void
703xpc_process_channel_activity(struct xpc_partition *part) 700xpc_process_sent_chctl_flags(struct xpc_partition *part)
704{ 701{
705 unsigned long irq_flags; 702 unsigned long irq_flags;
706 u64 IPI_amo, IPI_flags; 703 union xpc_channel_ctl_flags chctl;
707 struct xpc_channel *ch; 704 struct xpc_channel *ch;
708 int ch_number; 705 int ch_number;
709 u32 ch_flags; 706 u32 ch_flags;
710 707
711 IPI_amo = xpc_get_IPI_flags(part); 708 chctl.all_flags = xpc_get_chctl_all_flags(part);
712 709
713 /* 710 /*
714 * Initiate channel connections for registered channels. 711 * Initiate channel connections for registered channels.
@@ -721,14 +718,14 @@ xpc_process_channel_activity(struct xpc_partition *part)
721 ch = &part->channels[ch_number]; 718 ch = &part->channels[ch_number];
722 719
723 /* 720 /*
724 * Process any open or close related IPI flags, and then deal 721 * Process any open or close related chctl flags, and then deal
725 * with connecting or disconnecting the channel as required. 722 * with connecting or disconnecting the channel as required.
726 */ 723 */
727 724
728 IPI_flags = XPC_GET_IPI_FLAGS(IPI_amo, ch_number); 725 if (chctl.flags[ch_number] & XPC_OPENCLOSE_CHCTL_FLAGS) {
729 726 xpc_process_openclose_chctl_flags(part, ch_number,
730 if (XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(IPI_flags)) 727 chctl.flags[ch_number]);
731 xpc_process_openclose_IPI(part, ch_number, IPI_flags); 728 }
732 729
733 ch_flags = ch->flags; /* need an atomic snapshot of flags */ 730 ch_flags = ch->flags; /* need an atomic snapshot of flags */
734 731
@@ -755,13 +752,13 @@ xpc_process_channel_activity(struct xpc_partition *part)
755 } 752 }
756 753
757 /* 754 /*
758 * Process any message related IPI flags, this may involve the 755 * Process any message related chctl flags, this may involve
759 * activation of kthreads to deliver any pending messages sent 756 * the activation of kthreads to deliver any pending messages
760 * from the other partition. 757 * sent from the other partition.
761 */ 758 */
762 759
763 if (XPC_ANY_MSG_IPI_FLAGS_SET(IPI_flags)) 760 if (chctl.flags[ch_number] & XPC_MSG_CHCTL_FLAGS)
764 xpc_process_msg_IPI(part, ch_number); 761 xpc_process_msg_chctl_flags(part, ch_number);
765 } 762 }
766} 763}
767 764
@@ -937,7 +934,7 @@ xpc_disconnect_channel(const int line, struct xpc_channel *ch,
937 XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY | 934 XPC_C_ROPENREQUEST | XPC_C_ROPENREPLY |
938 XPC_C_CONNECTING | XPC_C_CONNECTED); 935 XPC_C_CONNECTING | XPC_C_CONNECTED);
939 936
940 xpc_send_channel_closerequest(ch, irq_flags); 937 xpc_send_chctl_closerequest(ch, irq_flags);
941 938
942 if (channel_was_connected) 939 if (channel_was_connected)
943 ch->flags |= XPC_C_WASCONNECTED; 940 ch->flags |= XPC_C_WASCONNECTED;