All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tomas Henzl <thenzl@redhat.com>
To: Ching Huang <ching2048@areca.com.tw>,
	hch@infradead.org, jbottomley@parallels.com,
	dan.carpenter@oracle.com, agordeev@redhat.com,
	linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C
Date: Fri, 22 Aug 2014 18:00:13 +0200	[thread overview]
Message-ID: <53F7690D.5070007@redhat.com> (raw)
In-Reply-To: <1408432665.4748.65.camel@Centos6.3-64>

On 08/19/2014 09:17 AM, Ching Huang wrote:
> From: Ching Huang <ching2048@areca.com.tw>
>
> Rewrite ioctl entry and its relate function.
> This patch fix ioctl data read/write error and change data I/O access from byte to Dword.
>
> Signed-off-by: Ching Huang <ching2048@areca.com.tw>
> ---
>
> diff -uprN a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c
> --- a/drivers/scsi/arcmsr/arcmsr_attr.c	2014-02-06 17:47:24.000000000 +0800
> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c	2014-04-29 17:10:42.000000000 +0800
> @@ -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) {

Hi - does this condition (acb->rqbuf_firstindex == acb->rqbuf_lastindex) mean we could just release 
the spinlock and return ?
 

>  		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));

This code looks like you were copying some data from a ring buffer,
in that case - shouldn't be acb->rqbuf_lastindex used instead of firstindex?

What does the 1032 mean is that a hw. limit, actually could you explain the code 
should do? Maybe I'm just wrong with my assumptions.

Thanks,
Tomas

> +					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;
> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
> --- a/drivers/scsi/arcmsr/arcmsr.h	2014-05-06 15:28:38.000000000 +0800
> +++ b/drivers/scsi/arcmsr/arcmsr.h	2014-05-06 15:28:58.000000000 +0800
> @@ -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;
> @@ -693,8 +695,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 *);
> diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
> --- a/drivers/scsi/arcmsr/arcmsr_hba.c	2014-08-14 18:40:38.000000000 +0800
> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c	2014-08-14 18:40:48.000000000 +0800
> @@ -627,6 +627,8 @@ static int arcmsr_probe(struct pci_dev *
>  	}
>  	spin_lock_init(&acb->eh_lock);
>  	spin_lock_init(&acb->ccblist_lock);
> +	spin_lock_init(&acb->rqbuffer_lock);
> +	spin_lock_init(&acb->wqbuffer_lock);
>  	acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
>  			ACB_F_MESSAGE_RQBUFFER_CLEARED |
>  			ACB_F_MESSAGE_WQBUFFER_READED);
> @@ -1423,68 +1425,174 @@ static struct QBUFFER __iomem *arcmsr_ge
>  	return pqbuffer;
>  }
>  
> -static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
> -{
> -	struct QBUFFER __iomem *prbuffer;
> -	struct QBUFFER *pQbuffer;
> -	uint8_t __iomem *iop_data;
> -	int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
> -	rqbuf_lastindex = acb->rqbuf_lastindex;
> -	rqbuf_firstindex = acb->rqbuf_firstindex;
> -	prbuffer = arcmsr_get_iop_rqbuffer(acb);
> -	iop_data = (uint8_t __iomem *)prbuffer->data;
> -	iop_len = prbuffer->data_len;
> -	my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) & (ARCMSR_MAX_QBUFFER - 1);
> +static uint32_t arcmsr_Read_iop_rqbuffer_in_DWORD(struct AdapterControlBlock *acb,
> +	struct QBUFFER __iomem *prbuffer) {
>  
> -	if (my_empty_len >= iop_len)
> -	{
> -		while (iop_len > 0) {
> -			pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex];
> -			memcpy(pQbuffer, iop_data, 1);
> -			rqbuf_lastindex++;
> -			rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
> +	uint8_t *pQbuffer;
> +	uint8_t *buf1 = NULL;
> +	uint32_t __iomem *iop_data;
> +	uint32_t iop_len, data_len, *buf2 = NULL;
> +
> +	iop_data = (uint32_t __iomem *)prbuffer->data;
> +	iop_len = readl(&prbuffer->data_len);
> +	if (iop_len > 0) {
> +		buf1 = kmalloc(128, GFP_ATOMIC);
> +		buf2 = (uint32_t *)buf1;
> +		if (buf1 == NULL)
> +			return 0;
> +		data_len = iop_len;
> +		while (data_len >= 4) {
> +			*buf2++ = readl(iop_data);
>  			iop_data++;
> -			iop_len--;
> +			data_len -= 4;
>  		}
> -		acb->rqbuf_lastindex = rqbuf_lastindex;
> -		arcmsr_iop_message_read(acb);
> +		if (data_len)
> +			*buf2 = readl(iop_data);
> +		buf2 = (uint32_t *)buf1;
> +	}
> +	while (iop_len > 0) {
> +		pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
> +		*pQbuffer = *buf1;
> +		acb->rqbuf_lastindex++;
> +		/* if last, index number set it to 0 */
> +		acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
> +		buf1++;
> +		iop_len--;
> +	}
> +	if (buf2)

This test is not needed.

> +		kfree(buf2);
> +	/* let IOP know data has been read */
> +	arcmsr_iop_message_read(acb);
> +	return 1;
> +}
> +
> +uint32_t
> +arcmsr_Read_iop_rqbuffer_data(struct AdapterControlBlock *acb,
> +	struct QBUFFER __iomem *prbuffer) {
> +
> +	uint8_t *pQbuffer;
> +	uint8_t __iomem *iop_data;
> +	uint32_t iop_len;
> +
> +	if (acb->adapter_type & ACB_ADAPTER_TYPE_C)
> +		return arcmsr_Read_iop_rqbuffer_in_DWORD(acb, prbuffer);
> +	iop_data = (uint8_t __iomem *)prbuffer->data;
> +	iop_len = readl(&prbuffer->data_len);
> +	while (iop_len > 0) {
> +		pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex];
> +		*pQbuffer = readb(iop_data);
> +		acb->rqbuf_lastindex++;
> +		acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
> +		iop_data++;
> +		iop_len--;
>  	}
> +	arcmsr_iop_message_read(acb);
> +	return 1;
> +}
> +
> +static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
> +{
> +	unsigned long flags;
> +	struct QBUFFER __iomem  *prbuffer;
> +	int32_t buf_empty_len;
>  
> -	else {
> +	spin_lock_irqsave(&acb->rqbuffer_lock, flags);
> +	prbuffer = arcmsr_get_iop_rqbuffer(acb);
> +	buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) &
> +		(ARCMSR_MAX_QBUFFER - 1);
> +	if (buf_empty_len >= readl(&prbuffer->data_len)) {
> +		if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
> +			acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
> +	} else
>  		acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
> +	spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
> +}
> +
> +static void arcmsr_write_ioctldata2iop_in_DWORD(struct AdapterControlBlock *acb)
> +{
> +	uint8_t *pQbuffer;
> +	struct QBUFFER __iomem *pwbuffer;
> +	uint8_t *buf1 = NULL;
> +	uint32_t __iomem *iop_data;
> +	uint32_t allxfer_len = 0, data_len, *buf2 = NULL, data;
> +
> +	if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
> +		buf1 = kmalloc(128, GFP_ATOMIC);
> +		buf2 = (uint32_t *)buf1;
> +		if (buf1 == NULL)
> +			return;
> +
> +		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
> +		pwbuffer = arcmsr_get_iop_wqbuffer(acb);
> +		iop_data = (uint32_t __iomem *)pwbuffer->data;
> +		while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
> +			&& (allxfer_len < 124)) {
> +			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
> +			*buf1 = *pQbuffer;
> +			acb->wqbuf_firstindex++;
> +			acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
> +			buf1++;
> +			allxfer_len++;
> +		}
> +		data_len = allxfer_len;
> +		buf1 = (uint8_t *)buf2;
> +		while (data_len >= 4) {
> +			data = *buf2++;
> +			writel(data, iop_data);
> +			iop_data++;
> +			data_len -= 4;
> +		}
> +		if (data_len) {
> +			data = *buf2;
> +			writel(data, iop_data);
> +		}
> +		writel(allxfer_len, &pwbuffer->data_len);
> +		kfree(buf1);
> +		arcmsr_iop_message_wrote(acb);
>  	}
>  }
>  
> -static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
> +void
> +arcmsr_write_ioctldata2iop(struct AdapterControlBlock *acb)
>  {
> -	acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
> -	if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) {
> -		uint8_t *pQbuffer;
> -		struct QBUFFER __iomem *pwbuffer;
> -		uint8_t __iomem *iop_data;
> -		int32_t allxfer_len = 0;
> +	uint8_t *pQbuffer;
> +	struct QBUFFER __iomem *pwbuffer;
> +	uint8_t __iomem *iop_data;
> +	int32_t allxfer_len = 0;
>  
> +	if (acb->adapter_type & ACB_ADAPTER_TYPE_C) {
> +		arcmsr_write_ioctldata2iop_in_DWORD(acb);
> +		return;
> +	}
> +	if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
>  		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
>  		pwbuffer = arcmsr_get_iop_wqbuffer(acb);
>  		iop_data = (uint8_t __iomem *)pwbuffer->data;
> -
> -		while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) && \
> -							(allxfer_len < 124)) {
> +		while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex)
> +			&& (allxfer_len < 124)) {
>  			pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex];
> -			memcpy(iop_data, pQbuffer, 1);
> +			writeb(*pQbuffer, iop_data);
>  			acb->wqbuf_firstindex++;
>  			acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
>  			iop_data++;
>  			allxfer_len++;
>  		}
> -		pwbuffer->data_len = allxfer_len;
> -
> +		writel(allxfer_len, &pwbuffer->data_len);
>  		arcmsr_iop_message_wrote(acb);
>  	}
> +}
>  
> -	if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) {
> +static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&acb->wqbuffer_lock, flags);
> +	acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
> +	if (acb->wqbuf_firstindex != acb->wqbuf_lastindex)
> +		arcmsr_write_ioctldata2iop(acb);
> +	if (acb->wqbuf_firstindex == acb->wqbuf_lastindex)
>  		acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED;
> -	}
> +	spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
>  }
>  
>  static void arcmsr_hbaA_doorbell_isr(struct AdapterControlBlock *acb)
> @@ -1742,296 +1850,344 @@ static void arcmsr_iop_parking(struct Ad
>  	}
>  }
>  
> -void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb)
> +
> +void arcmsr_clear_iop2drv_rqueue_buffer(struct AdapterControlBlock *acb)
>  {
> -	int32_t wqbuf_firstindex, wqbuf_lastindex;
> -	uint8_t *pQbuffer;
> -	struct QBUFFER __iomem *pwbuffer;
> -	uint8_t __iomem *iop_data;
> -	int32_t allxfer_len = 0;
> -	pwbuffer = arcmsr_get_iop_wqbuffer(acb);
> -	iop_data = (uint8_t __iomem *)pwbuffer->data;
> -	if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) {
> -		acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
> -		wqbuf_firstindex = acb->wqbuf_firstindex;
> -		wqbuf_lastindex = acb->wqbuf_lastindex;
> -		while ((wqbuf_firstindex != wqbuf_lastindex) && (allxfer_len < 124)) {
> -			pQbuffer = &acb->wqbuffer[wqbuf_firstindex];
> -			memcpy(iop_data, pQbuffer, 1);
> -			wqbuf_firstindex++;
> -			wqbuf_firstindex %= ARCMSR_MAX_QBUFFER;
> -			iop_data++;
> -			allxfer_len++;
> +	uint32_t	i;
> +
> +	if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
> +		for (i = 0; i < 15; i++) {
> +			if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
> +				acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
> +				acb->rqbuf_firstindex = 0;
> +				acb->rqbuf_lastindex = 0;
> +				arcmsr_iop_message_read(acb);
> +				mdelay(30);
> +			} else if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) {
> +				acb->rqbuf_firstindex = 0;
> +				acb->rqbuf_lastindex = 0;
> +				mdelay(30);
> +			} else
> +				break;
>  		}
> -		acb->wqbuf_firstindex = wqbuf_firstindex;
> -		pwbuffer->data_len = allxfer_len;
> -		arcmsr_iop_message_wrote(acb);
>  	}
>  }
>  
> -static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
> -					struct scsi_cmnd *cmd)
> +static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd)
>  {
> -	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
> -	int retvalue = 0, transfer_len = 0;
>  	char *buffer;
> +	unsigned short use_sg;
> +	int retvalue = 0, transfer_len = 0;
> +	unsigned long flags;
> +	struct CMD_MESSAGE_FIELD *pcmdmessagefld;
> +	uint32_t controlcode = (uint32_t)cmd->cmnd[5] << 24 |
> +		(uint32_t)cmd->cmnd[6] << 16 |
> +		(uint32_t)cmd->cmnd[7] << 8 |
> +		(uint32_t)cmd->cmnd[8];
>  	struct scatterlist *sg;
> -	uint32_t controlcode = (uint32_t ) cmd->cmnd[5] << 24 |
> -						(uint32_t ) cmd->cmnd[6] << 16 |
> -						(uint32_t ) cmd->cmnd[7] << 8  |
> -						(uint32_t ) cmd->cmnd[8];
> -						/* 4 bytes: Areca io control code */
> +
> +	use_sg = scsi_sg_count(cmd);
>  	sg = scsi_sglist(cmd);
>  	buffer = kmap_atomic(sg_page(sg)) + sg->offset;
> -	if (scsi_sg_count(cmd) > 1) {
> +	if (use_sg > 1) {
>  		retvalue = ARCMSR_MESSAGE_FAIL;
>  		goto message_out;
>  	}
>  	transfer_len += sg->length;
> -
>  	if (transfer_len > sizeof(struct CMD_MESSAGE_FIELD)) {
>  		retvalue = ARCMSR_MESSAGE_FAIL;
> +		pr_info("%s: ARCMSR_MESSAGE_FAIL!\n", __func__);
>  		goto message_out;
>  	}
> -	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer;
> -	switch(controlcode) {
> -
> +	pcmdmessagefld = (struct CMD_MESSAGE_FIELD *)buffer;
> +	switch (controlcode) {
>  	case ARCMSR_MESSAGE_READ_RQBUFFER: {
>  		unsigned char *ver_addr;
>  		uint8_t *pQbuffer, *ptmpQbuffer;
> -		int32_t allxfer_len = 0;
> -
> +		uint32_t allxfer_len = 0;
>  		ver_addr = kmalloc(1032, GFP_ATOMIC);
>  		if (!ver_addr) {
>  			retvalue = ARCMSR_MESSAGE_FAIL;
> +			pr_info("%s: memory not enough!\n", __func__);
>  			goto message_out;
>  		}
> -				
>  		ptmpQbuffer = ver_addr;
> -		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;
> +				}
> +			}
>  		}
> +		memcpy(pcmdmessagefld->messagedatabuffer, ver_addr,
> +			allxfer_len);
>  		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);
> -		}
> -		memcpy(pcmdmessagefld->messagedatabuffer, ver_addr, allxfer_len);
> -		pcmdmessagefld->cmdmessage.Length = allxfer_len;
> -		if(acb->fw_flag == FW_DEADLOCK) {
> -			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> -			pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK;
> +			if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0)
> +				acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW;
>  		}
> +		spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
>  		kfree(ver_addr);
> -		}
> +		pcmdmessagefld->cmdmessage.Length = allxfer_len;
> +		if (acb->fw_flag == FW_DEADLOCK)
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		break;
> -
> +	}
>  	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
>  		unsigned char *ver_addr;
>  		int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex;
>  		uint8_t *pQbuffer, *ptmpuserbuffer;
> -
>  		ver_addr = kmalloc(1032, GFP_ATOMIC);
>  		if (!ver_addr) {
>  			retvalue = ARCMSR_MESSAGE_FAIL;
>  			goto message_out;
>  		}
> -		if(acb->fw_flag == FW_DEADLOCK) {
> -			pcmdmessagefld->cmdmessage.ReturnCode = 
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> -			pcmdmessagefld->cmdmessage.ReturnCode = 
> -			ARCMSR_MESSAGE_RETURNCODE_OK;
> -		}
>  		ptmpuserbuffer = ver_addr;
>  		user_len = pcmdmessagefld->cmdmessage.Length;
> -		memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len);
> +		memcpy(ptmpuserbuffer,
> +			pcmdmessagefld->messagedatabuffer, user_len);
> +		spin_lock_irqsave(&acb->wqbuffer_lock, flags);
>  		wqbuf_lastindex = acb->wqbuf_lastindex;
>  		wqbuf_firstindex = acb->wqbuf_firstindex;
>  		if (wqbuf_lastindex != wqbuf_firstindex) {
>  			struct SENSE_DATA *sensebuffer =
>  				(struct SENSE_DATA *)cmd->sense_buffer;
> -			arcmsr_post_ioctldata2iop(acb);
> +			arcmsr_write_ioctldata2iop(acb);
>  			/* has error report sensedata */
> -			sensebuffer->ErrorCode = 0x70;
> +			sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS;
>  			sensebuffer->SenseKey = ILLEGAL_REQUEST;
>  			sensebuffer->AdditionalSenseLength = 0x0A;
>  			sensebuffer->AdditionalSenseCode = 0x20;
>  			sensebuffer->Valid = 1;
>  			retvalue = ARCMSR_MESSAGE_FAIL;
>  		} else {
> -			my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1)
> -				&(ARCMSR_MAX_QBUFFER - 1);
> +			my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1)
> +				& (ARCMSR_MAX_QBUFFER - 1);
>  			if (my_empty_len >= user_len) {
>  				while (user_len > 0) {
> -					pQbuffer =
> -					&acb->wqbuffer[acb->wqbuf_lastindex];
> -					memcpy(pQbuffer, ptmpuserbuffer, 1);
> -					acb->wqbuf_lastindex++;
> -					acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER;
> -					ptmpuserbuffer++;
> -					user_len--;
> +					pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex];
> +					if ((acb->wqbuf_lastindex + user_len)
> +						> ARCMSR_MAX_QBUFFER) {
> +						memcpy(pQbuffer, ptmpuserbuffer,
> +							ARCMSR_MAX_QBUFFER -
> +							acb->wqbuf_lastindex);
> +						ptmpuserbuffer +=
> +							(ARCMSR_MAX_QBUFFER
> +							- acb->wqbuf_lastindex);
> +						user_len -= (ARCMSR_MAX_QBUFFER
> +							- acb->wqbuf_lastindex);
> +						acb->wqbuf_lastindex = 0;
> +					} else {
> +						memcpy(pQbuffer, ptmpuserbuffer,
> +							user_len);
> +						acb->wqbuf_lastindex += user_len;
> +						acb->wqbuf_lastindex %=
> +							ARCMSR_MAX_QBUFFER;
> +						user_len = 0;
> +					}
>  				}
> -				if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
> +				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);
>  				}
>  			} else {
> -				/* has error report sensedata */
>  				struct SENSE_DATA *sensebuffer =
>  					(struct SENSE_DATA *)cmd->sense_buffer;
> -				sensebuffer->ErrorCode = 0x70;
> +				/* has error report sensedata */
> +				sensebuffer->ErrorCode =
> +					SCSI_SENSE_CURRENT_ERRORS;
>  				sensebuffer->SenseKey = ILLEGAL_REQUEST;
>  				sensebuffer->AdditionalSenseLength = 0x0A;
>  				sensebuffer->AdditionalSenseCode = 0x20;
>  				sensebuffer->Valid = 1;
>  				retvalue = ARCMSR_MESSAGE_FAIL;
>  			}
> -			}
> -			kfree(ver_addr);
>  		}
> +		spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
> +		kfree(ver_addr);
> +		if (acb->fw_flag == FW_DEADLOCK)
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		break;
> -
> +	}
>  	case ARCMSR_MESSAGE_CLEAR_RQBUFFER: {
>  		uint8_t *pQbuffer = acb->rqbuffer;
> -		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);
> +		spin_lock_irqsave(&acb->rqbuffer_lock, flags);
>  		acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
>  		acb->rqbuf_firstindex = 0;
>  		acb->rqbuf_lastindex = 0;
>  		memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
> -		if(acb->fw_flag == FW_DEADLOCK) {
> +		spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
> +		if (acb->fw_flag == FW_DEADLOCK)
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_OK;
> -		}
> -		}
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		break;
> -
> +	}
>  	case ARCMSR_MESSAGE_CLEAR_WQBUFFER: {
>  		uint8_t *pQbuffer = acb->wqbuffer;
> -		if(acb->fw_flag == FW_DEADLOCK) {
> -			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> -			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_OK;
> -		}
> -
> -		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
> -			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
> -			arcmsr_iop_message_read(acb);
> -		}
> -		acb->acb_flags |=
> -			(ACB_F_MESSAGE_WQBUFFER_CLEARED |
> -				ACB_F_MESSAGE_WQBUFFER_READED);
> +		spin_lock_irqsave(&acb->wqbuffer_lock, flags);
> +		acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
> +			ACB_F_MESSAGE_WQBUFFER_READED);
>  		acb->wqbuf_firstindex = 0;
>  		acb->wqbuf_lastindex = 0;
>  		memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER);
> -		}
> +		spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
> +		if (acb->fw_flag == FW_DEADLOCK)
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		break;
> -
> +	}
>  	case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: {
>  		uint8_t *pQbuffer;
> -
> -		if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
> -			acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
> -			arcmsr_iop_message_read(acb);
> -		}
> -		acb->acb_flags |=
> -			(ACB_F_MESSAGE_WQBUFFER_CLEARED
> -			| ACB_F_MESSAGE_RQBUFFER_CLEARED
> -			| ACB_F_MESSAGE_WQBUFFER_READED);
> +		arcmsr_clear_iop2drv_rqueue_buffer(acb);
> +		spin_lock_irqsave(&acb->rqbuffer_lock, flags);
> +		acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED;
>  		acb->rqbuf_firstindex = 0;
>  		acb->rqbuf_lastindex = 0;
> -		acb->wqbuf_firstindex = 0;
> -		acb->wqbuf_lastindex = 0;
>  		pQbuffer = acb->rqbuffer;
>  		memset(pQbuffer, 0, sizeof(struct QBUFFER));
> +		spin_unlock_irqrestore(&acb->rqbuffer_lock, flags);
> +		spin_lock_irqsave(&acb->wqbuffer_lock, flags);
> +		acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED |
> +			ACB_F_MESSAGE_WQBUFFER_READED);
> +		acb->wqbuf_firstindex = 0;
> +		acb->wqbuf_lastindex = 0;
>  		pQbuffer = acb->wqbuffer;
>  		memset(pQbuffer, 0, sizeof(struct QBUFFER));
> -		if(acb->fw_flag == FW_DEADLOCK) {
> +		spin_unlock_irqrestore(&acb->wqbuffer_lock, flags);
> +		if (acb->fw_flag == FW_DEADLOCK)
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_OK;
> -		}
> -		}
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		break;
> -
> +	}
>  	case ARCMSR_MESSAGE_RETURN_CODE_3F: {
> -		if(acb->fw_flag == FW_DEADLOCK) {
> +		if (acb->fw_flag == FW_DEADLOCK)
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_3F;
> -		}
> +				ARCMSR_MESSAGE_RETURNCODE_3F;
>  		break;
> -		}
> +	}
>  	case ARCMSR_MESSAGE_SAY_HELLO: {
>  		int8_t *hello_string = "Hello! I am ARCMSR";
> -		if(acb->fw_flag == FW_DEADLOCK) {
> +		if (acb->fw_flag == FW_DEADLOCK)
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}else{
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_OK;
> -		}
> -		memcpy(pcmdmessagefld->messagedatabuffer, hello_string
> -			, (int16_t)strlen(hello_string));
> -		}
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
> +		memcpy(pcmdmessagefld->messagedatabuffer,
> +			hello_string, (int16_t)strlen(hello_string));
>  		break;
> -
> -	case ARCMSR_MESSAGE_SAY_GOODBYE:
> -		if(acb->fw_flag == FW_DEADLOCK) {
> +	}
> +	case ARCMSR_MESSAGE_SAY_GOODBYE: {
> +		if (acb->fw_flag == FW_DEADLOCK)
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		arcmsr_iop_parking(acb);
>  		break;
> -
> -	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE:
> -		if(acb->fw_flag == FW_DEADLOCK) {
> +	}
> +	case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: {
> +		if (acb->fw_flag == FW_DEADLOCK)
>  			pcmdmessagefld->cmdmessage.ReturnCode =
> -			ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> -		}
> +				ARCMSR_MESSAGE_RETURNCODE_BUS_HANG_ON;
> +		else
> +			pcmdmessagefld->cmdmessage.ReturnCode =
> +				ARCMSR_MESSAGE_RETURNCODE_OK;
>  		arcmsr_flush_adapter_cache(acb);
>  		break;
> -
> +	}
>  	default:
>  		retvalue = ARCMSR_MESSAGE_FAIL;
> +		pr_info("%s: unknown controlcode!\n", __func__);
> +	}
> +message_out:
> +	if (use_sg) {
> +		struct scatterlist *sg;
> +		sg = scsi_sglist(cmd);
> +		kunmap_atomic(buffer - sg->offset);
>  	}
> -	message_out:
> -	sg = scsi_sglist(cmd);
> -	kunmap_atomic(buffer - sg->offset);
>  	return retvalue;
>  }
>  
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


  reply	other threads:[~2014-08-22 16:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-19  7:17 [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C Ching Huang
2014-08-22 16:00 ` Tomas Henzl [this message]
2014-08-25 17:59   ` Ching Huang
2014-08-25 10:29     ` Tomas Henzl
2014-08-25 12:52       ` Tomas Henzl
2014-08-26 20:27       ` Ching Huang
2014-08-26 13:20         ` Tomas Henzl
2014-08-27 20:19           ` Ching Huang
2014-08-27 12:29             ` Tomas Henzl
2014-08-28 11:40               ` Ching Huang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53F7690D.5070007@redhat.com \
    --to=thenzl@redhat.com \
    --cc=agordeev@redhat.com \
    --cc=ching2048@areca.com.tw \
    --cc=dan.carpenter@oracle.com \
    --cc=hch@infradead.org \
    --cc=jbottomley@parallels.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.