Browse Source

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>
Ching Huang 11 years ago
parent
commit
3b8155d582
1 changed files with 40 additions and 81 deletions
  1. 40 81
      drivers/scsi/arcmsr/arcmsr_hba.c

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