Skip to contentSkip to conversation

arcmsr: rewrite IOCTL and its relate function

PATCH In review ching 1 participant 1 message Apr 30, 2014 SCSI

lore
Share & tools
lore

ching

author
#0 lore raw

PATCH 13/16 arcmsr: rewrite IOCTL and its relate function

From: Ching<[email protected]>

Rewrite IOCTL entry and its relate functions.

---

drivers/scsi/arcmsr/arcmsr_attr.c +71 -30
diff -uprN a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c
@@ -70,40 +70,75 @@ static ssize_t arcmsr_sysfs_iop_message_
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
 	uint8_t *pQbuffer,*ptmpQbuffer;
 	int32_t allxfer_len = 0;
+	unsigned long flags;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
 	/* do message unit read. */
 	ptmpQbuffer = (uint8_t *)buf;
-	while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex)
-		&& (allxfer_len < 1031)) {
+	spin_lock_irqsave(&acb->rqbuffer_lock, flags);
+	if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) {
 		pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex];
-		memcpy(ptmpQbuffer, pQbuffer, 1);
-		acb->rqbuf_firstindex++;
-		acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
-		ptmpQbuffer++;
-		allxfer_len++;
+		if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) {
+			if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) >= 1032) {
+				memcpy(ptmpQbuffer, pQbuffer, 1032);
+				acb->rqbuf_firstindex += 1032;
+				acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
+				allxfer_len = 1032;
+			} else {
+				if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)
+					+ acb->rqbuf_lastindex) > 1032) {
+					memcpy(ptmpQbuffer, pQbuffer,
+						ARCMSR_MAX_QBUFFER
+						- acb->rqbuf_firstindex);
+					ptmpQbuffer += ARCMSR_MAX_QBUFFER
+						- acb->rqbuf_firstindex;
+					memcpy(ptmpQbuffer, acb->rqbuffer, 1032
+						- (ARCMSR_MAX_QBUFFER -
+						acb->rqbuf_firstindex));
+					acb->rqbuf_firstindex = 1032 -
+						(ARCMSR_MAX_QBUFFER -
+						acb->rqbuf_firstindex);
+					allxfer_len = 1032;
+				} else {
+					memcpy(ptmpQbuffer, pQbuffer,
+						ARCMSR_MAX_QBUFFER -
+						acb->rqbuf_firstindex);
+					ptmpQbuffer += ARCMSR_MAX_QBUFFER -
+						acb->rqbuf_firstindex;
+					memcpy(ptmpQbuffer, acb->rqbuffer,
+						acb->rqbuf_lastindex);
+					allxfer_len = ARCMSR_MAX_QBUFFER -
+						acb->rqbuf_firstindex +
+						acb->rqbuf_lastindex;
+					acb->rqbuf_firstindex =
+						acb->rqbuf_lastindex;
+				}
+			}
+		} else {
+			if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) {
+				memcpy(ptmpQbuffer, pQbuffer, 1032);
+				acb->rqbuf_firstindex += 1032;
+				allxfer_len = 1032;
+			} else {
+				memcpy(ptmpQbuffer, pQbuffer, acb->rqbuf_lastindex
+					- acb->rqbuf_firstindex);
+				allxfer_len = acb->rqbuf_lastindex -
+					acb->rqbuf_firstindex;
+				acb->rqbuf_firstindex = acb->rqbuf_lastindex;
+			}
+		}
 	}
 	if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 		struct QBUFFER __iomem *prbuffer;
-		uint8_t __iomem *iop_data;
-		int32_t iop_len;
-
 		acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
 		prbuffer = arcmsr_get_iop_rqbuffer(acb);
-		iop_data = prbuffer->data;
-		iop_len = readl(&prbuffer->data_len);
-		while (iop_len > 0) {
-			acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
-			acb->rqbuf_lastindex++;
-			acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
-			iop_data++;
-			iop_len--;
-		}
-		arcmsr_iop_message_read(acb);
+		if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
+			acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
 	}
-	return (allxfer_len);
+	spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
+	return allxfer_len;
 }
 
 static ssize_t arcmsr_sysfs_iop_message_write(struct file *filp,
@@ -117,6 +152,7 @@ static ssize_t arcmsr_sysfs_iop_message_
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
 	int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
 	uint8_t *pQbuffer, *ptmpuserbuffer;
+	unsigned long flags;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
@@ -125,18 +161,19 @@ static ssize_t arcmsr_sysfs_iop_message_
 	/* do message unit write. */
 	ptmpuserbuffer = (uint8_t *)buf;
 	user_len = (int32_t)count;
+	spin_lock_irqsave(&acb->wqbuffer_lock, flags);
 	wqbuf_lastindex = acb->wqbuf_lastindex;
 	wqbuf_firstindex = acb->wqbuf_firstindex;
 	if (wqbuf_lastindex != wqbuf_firstindex) {
-		arcmsr_post_ioctldata2iop(acb);
+		arcmsr_write_ioctldata2iop(acb);
+		spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
 		return 0;	/*need retry*/
 	} else {
 		my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
-				&(ARCMSR_MAX_QBUFFER - 1);
+			&(ARCMSR_MAX_QBUFFER - 1);
 		if (my_empty_len >= user_len) {
 			while (user_len > 0) {
-				pQbuffer =
-				&acb->wqbuffer[acb->wqbuf_lastindex];
+				pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
 				memcpy(pQbuffer, ptmpuserbuffer, 1);
 				acb->wqbuf_lastindex++;
 				acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
@@ -146,10 +183,12 @@ static ssize_t arcmsr_sysfs_iop_message_
 			if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
 				acb->acb_flags &=
 					~ACB_F_MESSAGE_WQBUFFER_CLEARED;
-				arcmsr_post_ioctldata2iop(acb);
+				arcmsr_write_ioctldata2iop(acb);
 			}
+			spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
 			return count;
 		} else {
+			spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
 			return 0;	/*need retry*/
 		}
 	}
@@ -165,22 +204,24 @@ static ssize_t arcmsr_sysfs_iop_message_
 	struct Scsi_Host *host = class_to_shost(dev);
 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
 	uint8_t *pQbuffer;
+	unsigned long flags;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
 
-	if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
-		acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
-		arcmsr_iop_message_read(acb);
-	}
+	arcmsr_clear_iop2drv_rqueue_buffer(acb);
 	acb->acb_flags |=
 		(ACB_F_MESSAGE_WQBUFFER_CLEARED
 		| ACB_F_MESSAGE_RQBUFFER_CLEARED
 		| ACB_F_MESSAGE_WQBUFFER_READED);
+	spin_lock_irqsave(&acb->rqbuffer_lock, flags);
 	acb->rqbuf_firstindex = 0;
 	acb->rqbuf_lastindex = 0;
+	spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
+	spin_lock_irqsave(&acb->wqbuffer_lock, flags);
 	acb->wqbuf_firstindex = 0;
 	acb->wqbuf_lastindex = 0;
+	spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
 	pQbuffer = acb->rqbuffer;
 	memset(pQbuffer, 0, sizeof (struct QBUFFER));
 	pQbuffer = acb->wqbuffer;
drivers/scsi/arcmsr/arcmsr.h +6 -2
diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
@@ -518,6 +518,8 @@ struct AdapterControlBlock
 	uint32_t			reg_mu_acc_handle0;
 	spinlock_t                      			eh_lock;
 	spinlock_t                      			ccblist_lock;
+	spinlock_t			rqbuffer_lock;
+	spinlock_t			wqbuffer_lock;
 	union {
 		struct MessageUnit_A __iomem *pmuA;
 		struct MessageUnit_B 	*pmuB;
@@ -692,8 +694,10 @@ struct SENSE_DATA
 #define     ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE               0x01
 #define     ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE                    0x1F
 
-extern void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *);
-extern void arcmsr_iop_message_read(struct AdapterControlBlock *);
+extern void arcmsr_write_ioctldata2iop(struct AdapterControlBlock *);
+extern uint32_t arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *,
+	struct QBUFFER __iomem *);
+extern void arcmsr_clear_iop2drv_rqueue_buffer(struct AdapterControlBlock *);
 extern struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *);
 extern struct device_attribute *arcmsr_host_attrs[];
 extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *);
drivers/scsi/arcmsr/arcmsr_hba.c +364 -208

734 lines not on this page · raw message