OSDN Git Service

arcmsr: simplify of updating doneq_index and postq_index
authorChing Huang <ching2048@areca.com.tw>
Mon, 15 Sep 2014 11:05:33 +0000 (19:05 +0800)
committerChristoph Hellwig <hch@lst.de>
Tue, 16 Sep 2014 16:40:14 +0000 (09:40 -0700)
Signed-off-by: Ching Huang <ching2048@areca.com.tw>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/arcmsr/arcmsr_hba.c

index 3d3cdfe..0dd38cc 100644 (file)
@@ -1120,7 +1120,7 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct Comma
 static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 {
        int i = 0;
-       uint32_t flag_ccb;
+       uint32_t flag_ccb, ccb_cdb_phy;
        struct ARCMSR_CDB *pARCMSR_CDB;
        bool error;
        struct CommandControlBlock *pCCB;
@@ -1164,10 +1164,6 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
                break;
        case ACB_ADAPTER_TYPE_C: {
                struct MessageUnit_C __iomem *reg = acb->pmuC;
-               struct  ARCMSR_CDB *pARCMSR_CDB;
-               uint32_t flag_ccb, ccb_cdb_phy;
-               bool error;
-               struct CommandControlBlock *pCCB;
                while ((readl(&reg->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
                        /*need to do*/
                        flag_ccb = readl(&reg->outbound_queueport_low);
@@ -1181,35 +1177,25 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
                break;
        case ACB_ADAPTER_TYPE_D: {
                struct MessageUnit_D  *pmu = acb->pmuD;
-               uint32_t ccb_cdb_phy, outbound_write_pointer;
-               uint32_t doneq_index, index_stripped, addressLow, residual;
-               bool error;
-               struct CommandControlBlock *pCCB;
+               uint32_t outbound_write_pointer;
+               uint32_t doneq_index, index_stripped, addressLow, residual, toggle;
+               unsigned long flags;
 
-               outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
-               doneq_index = pmu->doneq_index;
                residual = atomic_read(&acb->ccboutstandingcount);
                for (i = 0; i < residual; i++) {
-                       while ((doneq_index & 0xFFF) !=
+                       spin_lock_irqsave(&acb->doneq_lock, flags);
+                       outbound_write_pointer =
+                               pmu->done_qbuffer[0].addressLow + 1;
+                       doneq_index = pmu->doneq_index;
+                       if ((doneq_index & 0xFFF) !=
                                (outbound_write_pointer & 0xFFF)) {
-                               if (doneq_index & 0x4000) {
-                                       index_stripped = doneq_index & 0xFFF;
-                                       index_stripped += 1;
-                                       index_stripped %=
-                                               ARCMSR_MAX_ARC1214_DONEQUEUE;
-                                       pmu->doneq_index = index_stripped ?
-                                               (index_stripped | 0x4000) :
-                                               (index_stripped + 1);
-                               } else {
-                                       index_stripped = doneq_index;
-                                       index_stripped += 1;
-                                       index_stripped %=
-                                               ARCMSR_MAX_ARC1214_DONEQUEUE;
-                                       pmu->doneq_index = index_stripped ?
-                                               index_stripped :
-                                               ((index_stripped | 0x4000) + 1);
-                               }
+                               toggle = doneq_index & 0x4000;
+                               index_stripped = (doneq_index & 0xFFF) + 1;
+                               index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+                               pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
+                                       ((toggle ^ 0x4000) + 1);
                                doneq_index = pmu->doneq_index;
+                               spin_unlock_irqrestore(&acb->doneq_lock, flags);
                                addressLow = pmu->done_qbuffer[doneq_index &
                                        0xFFF].addressLow;
                                ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
@@ -1223,11 +1209,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
                                arcmsr_drain_donequeue(acb, pCCB, error);
                                writel(doneq_index,
                                        pmu->outboundlist_read_pointer);
+                       } else {
+                               spin_unlock_irqrestore(&acb->doneq_lock, flags);
+                               mdelay(10);
                        }
-                       mdelay(10);
-                       outbound_write_pointer =
-                               pmu->done_qbuffer[0].addressLow + 1;
-                       doneq_index = pmu->doneq_index;
                }
                pmu->postq_index = 0;
                pmu->doneq_index = 0x40FF;
@@ -1460,7 +1445,7 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
        case ACB_ADAPTER_TYPE_D: {
                struct MessageUnit_D  *pmu = acb->pmuD;
                u16 index_stripped;
-               u16 postq_index;
+               u16 postq_index, toggle;
                unsigned long flags;
                struct InBound_SRB *pinbound_srb;
 
@@ -1471,19 +1456,11 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
                pinbound_srb->addressLow = dma_addr_lo32(cdb_phyaddr);
                pinbound_srb->length = ccb->arc_cdb_size >> 2;
                arcmsr_cdb->msgContext = dma_addr_lo32(cdb_phyaddr);
-               if (postq_index & 0x4000) {
-                       index_stripped = postq_index & 0xFF;
-                       index_stripped += 1;
-                       index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
-                       pmu->postq_index = index_stripped ?
-                               (index_stripped | 0x4000) : index_stripped;
-               } else {
-                       index_stripped = postq_index;
-                       index_stripped += 1;
-                       index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
-                       pmu->postq_index = index_stripped ? index_stripped :
-                               (index_stripped | 0x4000);
-               }
+               toggle = postq_index & 0x4000;
+               index_stripped = postq_index + 1;
+               index_stripped &= (ARCMSR_MAX_ARC1214_POSTQUEUE - 1);
+               pmu->postq_index = index_stripped ? (index_stripped | toggle) :
+                       (toggle ^ 0x4000);
                writel(postq_index, pmu->inboundlist_write_pointer);
                spin_unlock_irqrestore(&acb->postq_lock, flags);
                break;
@@ -1999,7 +1976,7 @@ static void arcmsr_hbaC_postqueue_isr(struct AdapterControlBlock *acb)
 
 static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
 {
-       u32 outbound_write_pointer, doneq_index, index_stripped;
+       u32 outbound_write_pointer, doneq_index, index_stripped, toggle;
        uint32_t addressLow, ccb_cdb_phy;
        int error;
        struct MessageUnit_D  *pmu;
@@ -2013,21 +1990,11 @@ static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
        doneq_index = pmu->doneq_index;
        if ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) {
                do {
-                       if (doneq_index & 0x4000) {
-                               index_stripped = doneq_index & 0xFFF;
-                               index_stripped += 1;
-                               index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
-                               pmu->doneq_index = index_stripped
-                                       ? (index_stripped | 0x4000) :
-                                       (index_stripped + 1);
-                       } else {
-                               index_stripped = doneq_index;
-                               index_stripped += 1;
-                               index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
-                               pmu->doneq_index = index_stripped
-                                       ? index_stripped :
-                                       ((index_stripped | 0x4000) + 1);
-                       }
+                       toggle = doneq_index & 0x4000;
+                       index_stripped = (doneq_index & 0xFFF) + 1;
+                       index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+                       pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
+                               ((toggle ^ 0x4000) + 1);
                        doneq_index = pmu->doneq_index;
                        addressLow = pmu->done_qbuffer[doneq_index &
                                0xFFF].addressLow;
@@ -2890,7 +2857,7 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb)
        char __iomem *iop_firm_version;
        char __iomem *iop_device_map;
        u32 count;
-       struct MessageUnit_D *reg ;
+       struct MessageUnit_D *reg;
        void *dma_coherent2;
        dma_addr_t dma_coherent_handle2;
        struct pci_dev *pdev = acb->pdev;
@@ -3223,7 +3190,7 @@ static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
 {
        bool error;
        uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
-       int rtn, doneq_index, index_stripped, outbound_write_pointer;
+       int rtn, doneq_index, index_stripped, outbound_write_pointer, toggle;
        unsigned long flags;
        struct ARCMSR_CDB *arcmsr_cdb;
        struct CommandControlBlock *pCCB;
@@ -3232,9 +3199,11 @@ static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
 polling_hbaD_ccb_retry:
        poll_count++;
        while (1) {
+               spin_lock_irqsave(&acb->doneq_lock, flags);
                outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
                doneq_index = pmu->doneq_index;
                if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) {
+                       spin_unlock_irqrestore(&acb->doneq_lock, flags);
                        if (poll_ccb_done) {
                                rtn = SUCCESS;
                                break;
@@ -3247,23 +3216,13 @@ polling_hbaD_ccb_retry:
                                goto polling_hbaD_ccb_retry;
                        }
                }
-               spin_lock_irqsave(&acb->doneq_lock, flags);
-               if (doneq_index & 0x4000) {
-                       index_stripped = doneq_index & 0xFFF;
-                       index_stripped += 1;
-                       index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
-                       pmu->doneq_index = index_stripped ?
-                               (index_stripped | 0x4000) :
-                               (index_stripped + 1);
-               } else {
-                       index_stripped = doneq_index;
-                       index_stripped += 1;
-                       index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
-                       pmu->doneq_index = index_stripped ? index_stripped :
-                               ((index_stripped | 0x4000) + 1);
-               }
-               spin_unlock_irqrestore(&acb->doneq_lock, flags);
+               toggle = doneq_index & 0x4000;
+               index_stripped = (doneq_index & 0xFFF) + 1;
+               index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+               pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
+                               ((toggle ^ 0x4000) + 1);
                doneq_index = pmu->doneq_index;
+               spin_unlock_irqrestore(&acb->doneq_lock, flags);
                flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
                ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
                arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +