233 lines
8.9 KiB
Diff
233 lines
8.9 KiB
Diff
From: Ching Huang <ching2048@areca.com.tw>
|
|
Date: Mon, 15 Sep 2014 19:05:33 +0800
|
|
Subject: [18/19] arcmsr: simplify of updating doneq_index and postq_index
|
|
Origin: https://git.kernel.org/linus/3b8155d582968f79a62c79358d5e137f99f04407
|
|
Bug-Debian: https://bugs.debian.org/698821
|
|
|
|
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 | 121 +++++++++++++--------------------------
|
|
1 file changed, 40 insertions(+), 81 deletions(-)
|
|
|
|
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
|
|
index 3d3cdfe..0dd38cc 100644
|
|
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
|
|
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
|
|
@@ -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(®->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
|
|
/*need to do*/
|
|
flag_ccb = readl(®->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 +
|