aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/sgi-gru/grukservices.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/sgi-gru/grukservices.c')
-rw-r--r--drivers/misc/sgi-gru/grukservices.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 50b4dd8b0c9f..a0f981022a6c 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -503,6 +503,29 @@ static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
503 mqd->interrupt_vector); 503 mqd->interrupt_vector);
504} 504}
505 505
506/*
507 * Handle a PUT failure. Note: if message was a 2-line message, one of the
508 * lines might have successfully have been written. Before sending the
509 * message, "present" must be cleared in BOTH lines to prevent the receiver
510 * from prematurely seeing the full message.
511 */
512static int send_message_put_nacked(void *cb, struct gru_message_queue_desc *mqd,
513 void *mesg, int lines)
514{
515 unsigned long m;
516
517 m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
518 if (lines == 2) {
519 gru_vset(cb, m, 0, XTYPE_CL, lines, 1, IMA);
520 if (gru_wait(cb) != CBS_IDLE)
521 return MQE_UNEXPECTED_CB_ERR;
522 }
523 gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
524 if (gru_wait(cb) != CBS_IDLE)
525 return MQE_UNEXPECTED_CB_ERR;
526 send_message_queue_interrupt(mqd);
527 return MQE_OK;
528}
506 529
507/* 530/*
508 * Handle a gru_mesq failure. Some of these failures are software recoverable 531 * Handle a gru_mesq failure. Some of these failures are software recoverable
@@ -512,7 +535,6 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
512 void *mesg, int lines) 535 void *mesg, int lines)
513{ 536{
514 int substatus, ret = 0; 537 int substatus, ret = 0;
515 unsigned long m;
516 538
517 substatus = gru_get_cb_message_queue_substatus(cb); 539 substatus = gru_get_cb_message_queue_substatus(cb);
518 switch (substatus) { 540 switch (substatus) {
@@ -534,14 +556,7 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
534 break; 556 break;
535 case CBSS_PUT_NACKED: 557 case CBSS_PUT_NACKED:
536 STAT(mesq_send_put_nacked); 558 STAT(mesq_send_put_nacked);
537 m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6); 559 ret = send_message_put_nacked(cb, mqd, mesg, lines);
538 gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
539 if (gru_wait(cb) == CBS_IDLE) {
540 ret = MQE_OK;
541 send_message_queue_interrupt(mqd);
542 } else {
543 ret = MQE_UNEXPECTED_CB_ERR;
544 }
545 break; 560 break;
546 default: 561 default:
547 BUG(); 562 BUG();