aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChing Huang <ching2048@areca.com.tw>2014-09-15 07:05:33 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:40:14 -0400
commit3b8155d582968f79a62c79358d5e137f99f04407 (patch)
treea24c2c30de189a9d5edcc18e4378c63a8cfa9b71
parentb4eb6ae9075a958ffe24620f985f6bd729a1b138 (diff)
arcmsr: simplify of updating doneq_index and postq_index
Signed-off-by: Ching Huang <ching2048@areca.com.tw> Reviewed-by: Tomas Henzl <thenzl@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c121
1 files changed, 40 insertions, 81 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 3d3cdfe07089..0dd38ccc9470 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
1120static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) 1120static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
1121{ 1121{
1122 int i = 0; 1122 int i = 0;
1123 uint32_t flag_ccb; 1123 uint32_t flag_ccb, ccb_cdb_phy;
1124 struct ARCMSR_CDB *pARCMSR_CDB; 1124 struct ARCMSR_CDB *pARCMSR_CDB;
1125 bool error; 1125 bool error;
1126 struct CommandControlBlock *pCCB; 1126 struct CommandControlBlock *pCCB;
@@ -1164,10 +1164,6 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
1164 break; 1164 break;
1165 case ACB_ADAPTER_TYPE_C: { 1165 case ACB_ADAPTER_TYPE_C: {
1166 struct MessageUnit_C __iomem *reg = acb->pmuC; 1166 struct MessageUnit_C __iomem *reg = acb->pmuC;
1167 struct ARCMSR_CDB *pARCMSR_CDB;
1168 uint32_t flag_ccb, ccb_cdb_phy;
1169 bool error;
1170 struct CommandControlBlock *pCCB;
1171 while ((readl(&reg->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { 1167 while ((readl(&reg->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
1172 /*need to do*/ 1168 /*need to do*/
1173 flag_ccb = readl(&reg->outbound_queueport_low); 1169 flag_ccb = readl(&reg->outbound_queueport_low);
@@ -1181,35 +1177,25 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
1181 break; 1177 break;
1182 case ACB_ADAPTER_TYPE_D: { 1178 case ACB_ADAPTER_TYPE_D: {
1183 struct MessageUnit_D *pmu = acb->pmuD; 1179 struct MessageUnit_D *pmu = acb->pmuD;
1184 uint32_t ccb_cdb_phy, outbound_write_pointer; 1180 uint32_t outbound_write_pointer;
1185 uint32_t doneq_index, index_stripped, addressLow, residual; 1181 uint32_t doneq_index, index_stripped, addressLow, residual, toggle;
1186 bool error; 1182 unsigned long flags;
1187 struct CommandControlBlock *pCCB;
1188 1183
1189 outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
1190 doneq_index = pmu->doneq_index;
1191 residual = atomic_read(&acb->ccboutstandingcount); 1184 residual = atomic_read(&acb->ccboutstandingcount);
1192 for (i = 0; i < residual; i++) { 1185 for (i = 0; i < residual; i++) {
1193 while ((doneq_index & 0xFFF) != 1186 spin_lock_irqsave(&acb->doneq_lock, flags);
1187 outbound_write_pointer =
1188 pmu->done_qbuffer[0].addressLow + 1;
1189 doneq_index = pmu->doneq_index;
1190 if ((doneq_index & 0xFFF) !=
1194 (outbound_write_pointer & 0xFFF)) { 1191 (outbound_write_pointer & 0xFFF)) {
1195 if (doneq_index & 0x4000) { 1192 toggle = doneq_index & 0x4000;
1196 index_stripped = doneq_index & 0xFFF; 1193 index_stripped = (doneq_index & 0xFFF) + 1;
1197 index_stripped += 1; 1194 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
1198 index_stripped %= 1195 pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
1199 ARCMSR_MAX_ARC1214_DONEQUEUE; 1196 ((toggle ^ 0x4000) + 1);
1200 pmu->doneq_index = index_stripped ?
1201 (index_stripped | 0x4000) :
1202 (index_stripped + 1);
1203 } else {
1204 index_stripped = doneq_index;
1205 index_stripped += 1;
1206 index_stripped %=
1207 ARCMSR_MAX_ARC1214_DONEQUEUE;
1208 pmu->doneq_index = index_stripped ?
1209 index_stripped :
1210 ((index_stripped | 0x4000) + 1);
1211 }
1212 doneq_index = pmu->doneq_index; 1197 doneq_index = pmu->doneq_index;
1198 spin_unlock_irqrestore(&acb->doneq_lock, flags);
1213 addressLow = pmu->done_qbuffer[doneq_index & 1199 addressLow = pmu->done_qbuffer[doneq_index &
1214 0xFFF].addressLow; 1200 0xFFF].addressLow;
1215 ccb_cdb_phy = (addressLow & 0xFFFFFFF0); 1201 ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
@@ -1223,11 +1209,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
1223 arcmsr_drain_donequeue(acb, pCCB, error); 1209 arcmsr_drain_donequeue(acb, pCCB, error);
1224 writel(doneq_index, 1210 writel(doneq_index,
1225 pmu->outboundlist_read_pointer); 1211 pmu->outboundlist_read_pointer);
1212 } else {
1213 spin_unlock_irqrestore(&acb->doneq_lock, flags);
1214 mdelay(10);
1226 } 1215 }
1227 mdelay(10);
1228 outbound_write_pointer =
1229 pmu->done_qbuffer[0].addressLow + 1;
1230 doneq_index = pmu->doneq_index;
1231 } 1216 }
1232 pmu->postq_index = 0; 1217 pmu->postq_index = 0;
1233 pmu->doneq_index = 0x40FF; 1218 pmu->doneq_index = 0x40FF;
@@ -1460,7 +1445,7 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
1460 case ACB_ADAPTER_TYPE_D: { 1445 case ACB_ADAPTER_TYPE_D: {
1461 struct MessageUnit_D *pmu = acb->pmuD; 1446 struct MessageUnit_D *pmu = acb->pmuD;
1462 u16 index_stripped; 1447 u16 index_stripped;
1463 u16 postq_index; 1448 u16 postq_index, toggle;
1464 unsigned long flags; 1449 unsigned long flags;
1465 struct InBound_SRB *pinbound_srb; 1450 struct InBound_SRB *pinbound_srb;
1466 1451
@@ -1471,19 +1456,11 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
1471 pinbound_srb->addressLow = dma_addr_lo32(cdb_phyaddr); 1456 pinbound_srb->addressLow = dma_addr_lo32(cdb_phyaddr);
1472 pinbound_srb->length = ccb->arc_cdb_size >> 2; 1457 pinbound_srb->length = ccb->arc_cdb_size >> 2;
1473 arcmsr_cdb->msgContext = dma_addr_lo32(cdb_phyaddr); 1458 arcmsr_cdb->msgContext = dma_addr_lo32(cdb_phyaddr);
1474 if (postq_index & 0x4000) { 1459 toggle = postq_index & 0x4000;
1475 index_stripped = postq_index & 0xFF; 1460 index_stripped = postq_index + 1;
1476 index_stripped += 1; 1461 index_stripped &= (ARCMSR_MAX_ARC1214_POSTQUEUE - 1);
1477 index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE; 1462 pmu->postq_index = index_stripped ? (index_stripped | toggle) :
1478 pmu->postq_index = index_stripped ? 1463 (toggle ^ 0x4000);
1479 (index_stripped | 0x4000) : index_stripped;
1480 } else {
1481 index_stripped = postq_index;
1482 index_stripped += 1;
1483 index_stripped %= ARCMSR_MAX_ARC1214_POSTQUEUE;
1484 pmu->postq_index = index_stripped ? index_stripped :
1485 (index_stripped | 0x4000);
1486 }
1487 writel(postq_index, pmu->inboundlist_write_pointer); 1464 writel(postq_index, pmu->inboundlist_write_pointer);
1488 spin_unlock_irqrestore(&acb->postq_lock, flags); 1465 spin_unlock_irqrestore(&acb->postq_lock, flags);
1489 break; 1466 break;
@@ -1999,7 +1976,7 @@ static void arcmsr_hbaC_postqueue_isr(struct AdapterControlBlock *acb)
1999 1976
2000static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb) 1977static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
2001{ 1978{
2002 u32 outbound_write_pointer, doneq_index, index_stripped; 1979 u32 outbound_write_pointer, doneq_index, index_stripped, toggle;
2003 uint32_t addressLow, ccb_cdb_phy; 1980 uint32_t addressLow, ccb_cdb_phy;
2004 int error; 1981 int error;
2005 struct MessageUnit_D *pmu; 1982 struct MessageUnit_D *pmu;
@@ -2013,21 +1990,11 @@ static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
2013 doneq_index = pmu->doneq_index; 1990 doneq_index = pmu->doneq_index;
2014 if ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) { 1991 if ((doneq_index & 0xFFF) != (outbound_write_pointer & 0xFFF)) {
2015 do { 1992 do {
2016 if (doneq_index & 0x4000) { 1993 toggle = doneq_index & 0x4000;
2017 index_stripped = doneq_index & 0xFFF; 1994 index_stripped = (doneq_index & 0xFFF) + 1;
2018 index_stripped += 1; 1995 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
2019 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE; 1996 pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
2020 pmu->doneq_index = index_stripped 1997 ((toggle ^ 0x4000) + 1);
2021 ? (index_stripped | 0x4000) :
2022 (index_stripped + 1);
2023 } else {
2024 index_stripped = doneq_index;
2025 index_stripped += 1;
2026 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
2027 pmu->doneq_index = index_stripped
2028 ? index_stripped :
2029 ((index_stripped | 0x4000) + 1);
2030 }
2031 doneq_index = pmu->doneq_index; 1998 doneq_index = pmu->doneq_index;
2032 addressLow = pmu->done_qbuffer[doneq_index & 1999 addressLow = pmu->done_qbuffer[doneq_index &
2033 0xFFF].addressLow; 2000 0xFFF].addressLow;
@@ -2890,7 +2857,7 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb)
2890 char __iomem *iop_firm_version; 2857 char __iomem *iop_firm_version;
2891 char __iomem *iop_device_map; 2858 char __iomem *iop_device_map;
2892 u32 count; 2859 u32 count;
2893 struct MessageUnit_D *reg ; 2860 struct MessageUnit_D *reg;
2894 void *dma_coherent2; 2861 void *dma_coherent2;
2895 dma_addr_t dma_coherent_handle2; 2862 dma_addr_t dma_coherent_handle2;
2896 struct pci_dev *pdev = acb->pdev; 2863 struct pci_dev *pdev = acb->pdev;
@@ -3223,7 +3190,7 @@ static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
3223{ 3190{
3224 bool error; 3191 bool error;
3225 uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy; 3192 uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
3226 int rtn, doneq_index, index_stripped, outbound_write_pointer; 3193 int rtn, doneq_index, index_stripped, outbound_write_pointer, toggle;
3227 unsigned long flags; 3194 unsigned long flags;
3228 struct ARCMSR_CDB *arcmsr_cdb; 3195 struct ARCMSR_CDB *arcmsr_cdb;
3229 struct CommandControlBlock *pCCB; 3196 struct CommandControlBlock *pCCB;
@@ -3232,9 +3199,11 @@ static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
3232polling_hbaD_ccb_retry: 3199polling_hbaD_ccb_retry:
3233 poll_count++; 3200 poll_count++;
3234 while (1) { 3201 while (1) {
3202 spin_lock_irqsave(&acb->doneq_lock, flags);
3235 outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1; 3203 outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
3236 doneq_index = pmu->doneq_index; 3204 doneq_index = pmu->doneq_index;
3237 if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) { 3205 if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) {
3206 spin_unlock_irqrestore(&acb->doneq_lock, flags);
3238 if (poll_ccb_done) { 3207 if (poll_ccb_done) {
3239 rtn = SUCCESS; 3208 rtn = SUCCESS;
3240 break; 3209 break;
@@ -3247,23 +3216,13 @@ polling_hbaD_ccb_retry:
3247 goto polling_hbaD_ccb_retry; 3216 goto polling_hbaD_ccb_retry;
3248 } 3217 }
3249 } 3218 }
3250 spin_lock_irqsave(&acb->doneq_lock, flags); 3219 toggle = doneq_index & 0x4000;
3251 if (doneq_index & 0x4000) { 3220 index_stripped = (doneq_index & 0xFFF) + 1;
3252 index_stripped = doneq_index & 0xFFF; 3221 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
3253 index_stripped += 1; 3222 pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
3254 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE; 3223 ((toggle ^ 0x4000) + 1);
3255 pmu->doneq_index = index_stripped ?
3256 (index_stripped | 0x4000) :
3257 (index_stripped + 1);
3258 } else {
3259 index_stripped = doneq_index;
3260 index_stripped += 1;
3261 index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
3262 pmu->doneq_index = index_stripped ? index_stripped :
3263 ((index_stripped | 0x4000) + 1);
3264 }
3265 spin_unlock_irqrestore(&acb->doneq_lock, flags);
3266 doneq_index = pmu->doneq_index; 3224 doneq_index = pmu->doneq_index;
3225 spin_unlock_irqrestore(&acb->doneq_lock, flags);
3267 flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow; 3226 flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
3268 ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0); 3227 ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
3269 arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 3228 arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +