From: Ching Huang <ching2...@areca.com.tw>

Clear outbound doorbell buffer completely for adapter type C.
This is to prevent getting bad data input from IOP before ioctl command 
beginning.

Signed-off-by: Ching Huang <ching2...@areca.com.tw>
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:44:50.000000000 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:45:00.000000000 +0800
@@ -2888,11 +2888,23 @@ static void arcmsr_clear_doorbell_queue_
                break;
        case ACB_ADAPTER_TYPE_C: {
                struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
-               uint32_t outbound_doorbell;
+               uint32_t outbound_doorbell, i;
                /* empty doorbell Qbuffer if door bell ringed */
                outbound_doorbell = readl(&reg->outbound_doorbell);
                writel(outbound_doorbell, &reg->outbound_doorbell_clear);
                writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, 
&reg->inbound_doorbell);
+               for (i = 0; i < 200; i++) {
+                       msleep(20);
+                       outbound_doorbell = readl(&reg->outbound_doorbell);
+                       if (outbound_doorbell &
+                               ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
+                               writel(outbound_doorbell,
+                                       &reg->outbound_doorbell_clear);
+                               writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK,
+                                       &reg->inbound_doorbell);
+                       } else
+                               break;
+               }
                }
        }
 }
@@ -3120,9 +3132,7 @@ sleep:
                                arcmsr_get_firmware_spec(acb);
                                arcmsr_start_adapter_bgrb(acb);
                                /* clear Qbuffer if door bell ringed */
-                               outbound_doorbell = 
readl(&reg->outbound_doorbell);
-                               writel(outbound_doorbell, 
&reg->outbound_doorbell_clear); /*clear interrupt */
-                               writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, 
&reg->inbound_doorbell);
+                               arcmsr_clear_doorbell_queue_buffer(acb);
                                /* enable outbound Post Queue,outbound doorbell 
Interrupt */
                                arcmsr_enable_outbound_ints(acb, intmask_org);
                                atomic_set(&acb->rq_map_token, 16);


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to