diff options
author | Ching Huang <ching2048@areca.com.tw> | 2014-09-15 07:05:33 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-09-16 12:40:14 -0400 |
commit | 3b8155d582968f79a62c79358d5e137f99f04407 (patch) | |
tree | a24c2c30de189a9d5edcc18e4378c63a8cfa9b71 | |
parent | b4eb6ae9075a958ffe24620f985f6bd729a1b138 (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.c | 121 |
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 | |||
1120 | static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | 1120 | static 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(®->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { | 1167 | while ((readl(®->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(®->outbound_queueport_low); | 1169 | flag_ccb = readl(®->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 | ||
2000 | static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb) | 1977 | static 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, | |||
3232 | polling_hbaD_ccb_retry: | 3199 | polling_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 + |