* [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C @ 2014-08-19 7:17 Ching Huang 2014-08-22 16:00 ` Tomas Henzl 0 siblings, 1 reply; 10+ messages in thread From: Ching Huang @ 2014-08-19 7:17 UTC (permalink / raw) To: hch, jbottomley, dan.carpenter, thenzl, agordeev, linux-scsi, linux-kernel 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) { 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; 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) + 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; } ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 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 2014-08-25 17:59 ` Ching Huang 0 siblings, 1 reply; 10+ messages in thread From: Tomas Henzl @ 2014-08-22 16:00 UTC (permalink / raw) To: Ching Huang, hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 2014-08-22 16:00 ` Tomas Henzl @ 2014-08-25 17:59 ` Ching Huang 2014-08-25 10:29 ` Tomas Henzl 0 siblings, 1 reply; 10+ messages in thread From: Ching Huang @ 2014-08-25 17:59 UTC (permalink / raw) To: Tomas Henzl Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: > 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 ? > NO. We have to check the input buffer that may have message data come from IOP. > > > 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? > Yes, there copying data from a ring buffer. firstindex and lastindex are bad name. For readability, I rename the firstindex to getIndex, lastindex to putIndex. > 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. 1032 is the API data buffer limitation. > > 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 > This patch is relative to branch: git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 change log: 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to rqbuf_putIndex. 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to wqbuf_putIndex. 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN 4. remove a NULL pointer checking before kfree. 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-08-21 12:14:27.000000000 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ /* do message unit read. */ ptmpQbuffer = (uint8_t *)buf; spin_lock_irqsave(&acb->rqbuffer_lock, flags); - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; - 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; + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; + allxfer_len = ARCMSR_API_DATA_BUFLEN; } else { - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) - + acb->rqbuf_lastindex) > 1032) { + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { memcpy(ptmpQbuffer, pQbuffer, ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex); + - acb->rqbuf_getIndex); ptmpQbuffer += ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex; - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 + - acb->rqbuf_getIndex; + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex)); - acb->rqbuf_firstindex = 1032 - + acb->rqbuf_getIndex)); + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex); - allxfer_len = 1032; + acb->rqbuf_getIndex); + allxfer_len = ARCMSR_API_DATA_BUFLEN; } else { memcpy(ptmpQbuffer, pQbuffer, ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex); + acb->rqbuf_getIndex); ptmpQbuffer += ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex; + acb->rqbuf_getIndex; memcpy(ptmpQbuffer, acb->rqbuffer, - acb->rqbuf_lastindex); + acb->rqbuf_putIndex); allxfer_len = ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex + - acb->rqbuf_lastindex; - acb->rqbuf_firstindex = - acb->rqbuf_lastindex; + acb->rqbuf_getIndex + + acb->rqbuf_putIndex; + acb->rqbuf_getIndex = + acb->rqbuf_putIndex; } } } else { - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { - memcpy(ptmpQbuffer, pQbuffer, 1032); - acb->rqbuf_firstindex += 1032; - allxfer_len = 1032; + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; + allxfer_len = ARCMSR_API_DATA_BUFLEN; } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex + - acb->rqbuf_getIndex); + allxfer_len = acb->rqbuf_putIndex - + acb->rqbuf_getIndex; + acb->rqbuf_getIndex = acb->rqbuf_putIndex; } } } @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ struct device *dev = container_of(kobj,struct device,kobj); struct Scsi_Host *host = class_to_shost(dev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; uint8_t *pQbuffer, *ptmpuserbuffer; unsigned long flags; if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (count > 1032) + if (count > ARCMSR_API_DATA_BUFLEN) return -EINVAL; /* 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) { + wqbuf_putIndex = acb->wqbuf_putIndex; + wqbuf_getIndex = acb->wqbuf_getIndex; + if (wqbuf_putIndex != wqbuf_getIndex) { arcmsr_write_ioctldata2iop(acb); spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); return 0; /*need retry*/ } else { - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; memcpy(pQbuffer, ptmpuserbuffer, 1); - acb->wqbuf_lastindex++; - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + acb->wqbuf_putIndex++; + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; ptmpuserbuffer++; user_len--; } @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ | 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; + acb->rqbuf_getIndex = 0; + acb->rqbuf_putIndex = 0; spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); spin_lock_irqsave(&acb->wqbuffer_lock, flags); - acb->wqbuf_firstindex = 0; - acb->wqbuf_lastindex = 0; + acb->wqbuf_getIndex = 0; + acb->wqbuf_putIndex = 0; spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); pQbuffer = acb->rqbuffer; memset(pQbuffer, 0, sizeof (struct QBUFFER)); @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs .name = "mu_read", .mode = S_IRUSR , }, - .size = 1032, + .size = ARCMSR_API_DATA_BUFLEN, .read = arcmsr_sysfs_iop_message_read, }; @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs .name = "mu_write", .mode = S_IWUSR, }, - .size = 1032, + .size = ARCMSR_API_DATA_BUFLEN, .write = arcmsr_sysfs_iop_message_write, }; diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 @@ -107,10 +107,11 @@ struct CMD_MESSAGE ** IOP Message Transfer Data for user space ******************************************************************************* */ +#define ARCMSR_API_DATA_BUFLEN 1032 struct CMD_MESSAGE_FIELD { struct CMD_MESSAGE cmdmessage; - uint8_t messagedatabuffer[1032]; + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; }; /* IOP message transfer */ #define ARCMSR_MESSAGE_FAIL 0x0001 @@ -678,15 +679,15 @@ struct AdapterControlBlock unsigned int uncache_size; uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; /* data collection buffer for read from 80331 */ - int32_t rqbuf_firstindex; + int32_t rqbuf_getIndex; /* first of read buffer */ - int32_t rqbuf_lastindex; + int32_t rqbuf_putIndex; /* last of read buffer */ uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; /* data collection buffer for write to 80331 */ - int32_t wqbuf_firstindex; + int32_t wqbuf_getIndex; /* first of write buffer */ - int32_t wqbuf_lastindex; + int32_t wqbuf_putIndex; /* last of write buffer */ uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; /* id0 ..... id15, lun0...lun7 */ 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-21 12:14:27.000000000 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct buf2 = (uint32_t *)buf1; } while (iop_len > 0) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; *pQbuffer = *buf1; - acb->rqbuf_lastindex++; + acb->rqbuf_putIndex++; /* if last, index number set it to 0 */ - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; buf1++; iop_len--; } - if (buf2) - kfree(buf2); + kfree(buf2); /* let IOP know data has been read */ arcmsr_iop_message_read(acb); return 1; @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada iop_data = (uint8_t __iomem *)prbuffer->data; iop_len = readl(&prbuffer->data_len); while (iop_len > 0) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; *pQbuffer = readb(iop_data); - acb->rqbuf_lastindex++; - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; + acb->rqbuf_putIndex++; + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; iop_data++; iop_len--; } @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha spin_lock_irqsave(&acb->rqbuffer_lock, flags); prbuffer = arcmsr_get_iop_rqbuffer(acb); - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & (ARCMSR_MAX_QBUFFER - 1); if (buf_empty_len >= readl(&prbuffer->data_len)) { if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i 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) + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) && (allxfer_len < 124)) { - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; *buf1 = *pQbuffer; - acb->wqbuf_firstindex++; - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; + acb->wqbuf_getIndex++; + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; buf1++; allxfer_len++; } @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte 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) + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) && (allxfer_len < 124)) { - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; writeb(*pQbuffer, iop_data); - acb->wqbuf_firstindex++; - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; + acb->wqbuf_getIndex++; + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; iop_data++; allxfer_len++; } @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han spin_lock_irqsave(&acb->wqbuffer_lock, flags); acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) arcmsr_write_ioctldata2iop(acb); - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); } @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( 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; + acb->rqbuf_getIndex = 0; + acb->rqbuf_putIndex = 0; arcmsr_iop_message_read(acb); mdelay(30); - } else if (acb->rqbuf_firstindex != - acb->rqbuf_lastindex) { - acb->rqbuf_firstindex = 0; - acb->rqbuf_lastindex = 0; + } else if (acb->rqbuf_getIndex != + acb->rqbuf_putIndex) { + acb->rqbuf_getIndex = 0; + acb->rqbuf_putIndex = 0; mdelay(30); } else break; @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc unsigned char *ver_addr; uint8_t *pQbuffer, *ptmpQbuffer; uint32_t allxfer_len = 0; - ver_addr = kmalloc(1032, GFP_ATOMIC); + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); if (!ver_addr) { retvalue = ARCMSR_MESSAGE_FAIL; pr_info("%s: memory not enough!\n", __func__); @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc } ptmpQbuffer = ver_addr; spin_lock_irqsave(&acb->rqbuffer_lock, flags); - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { 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; + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; + allxfer_len = ARCMSR_API_DATA_BUFLEN; } else { if (((ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex) + - acb->rqbuf_lastindex) > 1032) { + acb->rqbuf_getIndex) + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { memcpy(ptmpQbuffer, pQbuffer, ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex); + - acb->rqbuf_getIndex); ptmpQbuffer += ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex; + acb->rqbuf_getIndex; memcpy(ptmpQbuffer, - acb->rqbuffer, 1032 - + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex)); - acb->rqbuf_firstindex = - 1032 - (ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex); - allxfer_len = 1032; + - acb->rqbuf_getIndex)); + acb->rqbuf_getIndex = + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER + - acb->rqbuf_getIndex); + allxfer_len = ARCMSR_API_DATA_BUFLEN; } else { memcpy(ptmpQbuffer, pQbuffer, ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex); + - acb->rqbuf_getIndex); ptmpQbuffer += ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex; + acb->rqbuf_getIndex; memcpy(ptmpQbuffer, acb->rqbuffer, - acb->rqbuf_lastindex); + acb->rqbuf_putIndex); allxfer_len = ARCMSR_MAX_QBUFFER - - acb->rqbuf_firstindex + - acb->rqbuf_lastindex; - acb->rqbuf_firstindex = - acb->rqbuf_lastindex; + - acb->rqbuf_getIndex + + acb->rqbuf_putIndex; + acb->rqbuf_getIndex = + acb->rqbuf_putIndex; } } } else { - if ((acb->rqbuf_lastindex - - acb->rqbuf_firstindex) > 1032) { - memcpy(ptmpQbuffer, pQbuffer, 1032); - acb->rqbuf_firstindex += 1032; - allxfer_len = 1032; + if ((acb->rqbuf_putIndex - + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; + allxfer_len = ARCMSR_API_DATA_BUFLEN; } else { memcpy(ptmpQbuffer, pQbuffer, - acb->rqbuf_lastindex - - acb->rqbuf_firstindex); - allxfer_len = acb->rqbuf_lastindex - - acb->rqbuf_firstindex; - acb->rqbuf_firstindex = - acb->rqbuf_lastindex; + acb->rqbuf_putIndex - + acb->rqbuf_getIndex); + allxfer_len = acb->rqbuf_putIndex + - acb->rqbuf_getIndex; + acb->rqbuf_getIndex = + acb->rqbuf_putIndex; } } } @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc } case ARCMSR_MESSAGE_WRITE_WQBUFFER: { unsigned char *ver_addr; - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; uint8_t *pQbuffer, *ptmpuserbuffer; - ver_addr = kmalloc(1032, GFP_ATOMIC); + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); if (!ver_addr) { retvalue = ARCMSR_MESSAGE_FAIL; goto message_out; @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc 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) { + wqbuf_putIndex = acb->wqbuf_putIndex; + wqbuf_getIndex = acb->wqbuf_getIndex; + if (wqbuf_putIndex != wqbuf_getIndex) { struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)cmd->sense_buffer; arcmsr_write_ioctldata2iop(acb); @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc sensebuffer->Valid = 1; retvalue = ARCMSR_MESSAGE_FAIL; } else { - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) & (ARCMSR_MAX_QBUFFER - 1); if (my_empty_len >= user_len) { while (user_len > 0) { - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; - if ((acb->wqbuf_lastindex + user_len) + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; + if ((acb->wqbuf_putIndex + user_len) > ARCMSR_MAX_QBUFFER) { memcpy(pQbuffer, ptmpuserbuffer, ARCMSR_MAX_QBUFFER - - acb->wqbuf_lastindex); + acb->wqbuf_putIndex); ptmpuserbuffer += (ARCMSR_MAX_QBUFFER - - acb->wqbuf_lastindex); + - acb->wqbuf_putIndex); user_len -= (ARCMSR_MAX_QBUFFER - - acb->wqbuf_lastindex); - acb->wqbuf_lastindex = 0; + - acb->wqbuf_putIndex); + acb->wqbuf_putIndex = 0; } else { memcpy(pQbuffer, ptmpuserbuffer, user_len); - acb->wqbuf_lastindex += user_len; - acb->wqbuf_lastindex %= + acb->wqbuf_putIndex += user_len; + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; user_len = 0; } @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc 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->rqbuf_getIndex = 0; + acb->rqbuf_putIndex = 0; memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); if (acb->fw_flag == FW_DEADLOCK) @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc 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; + acb->wqbuf_getIndex = 0; + acb->wqbuf_putIndex = 0; memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); if (acb->fw_flag == FW_DEADLOCK) @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc 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->rqbuf_getIndex = 0; + acb->rqbuf_putIndex = 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; + acb->wqbuf_getIndex = 0; + acb->wqbuf_putIndex = 0; pQbuffer = acb->wqbuffer; memset(pQbuffer, 0, sizeof(struct QBUFFER)); spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 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 0 siblings, 2 replies; 10+ messages in thread From: Tomas Henzl @ 2014-08-25 10:29 UTC (permalink / raw) To: Ching Huang Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On 08/25/2014 07:59 PM, Ching Huang wrote: > On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: >> 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 ? >> > NO. We have to check the input buffer that may have message data come > from IOP. >>> 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? >> > Yes, there copying data from a ring buffer. firstindex and lastindex are > bad name. For readability, I rename the firstindex to getIndex, > lastindex to putIndex. My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. Is this correct? >> 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. > 1032 is the API data buffer limitation. >> 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 > This patch is relative to branch: > > git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 > > change log: > 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to > rqbuf_putIndex. > 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to > wqbuf_putIndex. > 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN > 4. remove a NULL pointer checking before kfree. > > 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-08-21 12:14:27.000000000 +0800 > +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 > @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ > /* do message unit read. */ > ptmpQbuffer = (uint8_t *)buf; > spin_lock_irqsave(&acb->rqbuffer_lock, flags); > - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > - 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; > + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > } else { > - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) > - + acb->rqbuf_lastindex) > 1032) { > + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) > + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > memcpy(ptmpQbuffer, pQbuffer, > ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex); > + - acb->rqbuf_getIndex); > ptmpQbuffer += ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex; > - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 > + - acb->rqbuf_getIndex; > + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN > - (ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex)); > - acb->rqbuf_firstindex = 1032 - > + acb->rqbuf_getIndex)); > + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - > (ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex); > - allxfer_len = 1032; > + acb->rqbuf_getIndex); > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > } else { > memcpy(ptmpQbuffer, pQbuffer, > ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex); > + acb->rqbuf_getIndex); > ptmpQbuffer += ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex; > + acb->rqbuf_getIndex; > memcpy(ptmpQbuffer, acb->rqbuffer, > - acb->rqbuf_lastindex); > + acb->rqbuf_putIndex); > allxfer_len = ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex + > - acb->rqbuf_lastindex; > - acb->rqbuf_firstindex = > - acb->rqbuf_lastindex; > + acb->rqbuf_getIndex + > + acb->rqbuf_putIndex; > + acb->rqbuf_getIndex = > + acb->rqbuf_putIndex; > } > } > } else { > - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { > - memcpy(ptmpQbuffer, pQbuffer, 1032); > - acb->rqbuf_firstindex += 1032; > - allxfer_len = 1032; > + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex > + - acb->rqbuf_getIndex); > + allxfer_len = acb->rqbuf_putIndex - > + acb->rqbuf_getIndex; > + acb->rqbuf_getIndex = acb->rqbuf_putIndex; > } > } > } > @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ > struct device *dev = container_of(kobj,struct device,kobj); > struct Scsi_Host *host = class_to_shost(dev); > struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; > - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > uint8_t *pQbuffer, *ptmpuserbuffer; > unsigned long flags; > > if (!capable(CAP_SYS_ADMIN)) > return -EACCES; > - if (count > 1032) > + if (count > ARCMSR_API_DATA_BUFLEN) > return -EINVAL; > /* 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) { > + wqbuf_putIndex = acb->wqbuf_putIndex; > + wqbuf_getIndex = acb->wqbuf_getIndex; > + if (wqbuf_putIndex != wqbuf_getIndex) { > arcmsr_write_ioctldata2iop(acb); > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > return 0; /*need retry*/ > } else { > - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) > + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; > memcpy(pQbuffer, ptmpuserbuffer, 1); > - acb->wqbuf_lastindex++; > - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > + acb->wqbuf_putIndex++; > + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > ptmpuserbuffer++; > user_len--; > } > @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ > | 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; > + acb->rqbuf_getIndex = 0; > + acb->rqbuf_putIndex = 0; > spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > spin_lock_irqsave(&acb->wqbuffer_lock, flags); > - acb->wqbuf_firstindex = 0; > - acb->wqbuf_lastindex = 0; > + acb->wqbuf_getIndex = 0; > + acb->wqbuf_putIndex = 0; > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > pQbuffer = acb->rqbuffer; > memset(pQbuffer, 0, sizeof (struct QBUFFER)); > @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs > .name = "mu_read", > .mode = S_IRUSR , > }, > - .size = 1032, > + .size = ARCMSR_API_DATA_BUFLEN, > .read = arcmsr_sysfs_iop_message_read, > }; > > @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs > .name = "mu_write", > .mode = S_IWUSR, > }, > - .size = 1032, > + .size = ARCMSR_API_DATA_BUFLEN, > .write = arcmsr_sysfs_iop_message_write, > }; > > diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h > --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 > +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 > @@ -107,10 +107,11 @@ struct CMD_MESSAGE > ** IOP Message Transfer Data for user space > ******************************************************************************* > */ > +#define ARCMSR_API_DATA_BUFLEN 1032 > struct CMD_MESSAGE_FIELD > { > struct CMD_MESSAGE cmdmessage; > - uint8_t messagedatabuffer[1032]; > + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; > }; > /* IOP message transfer */ > #define ARCMSR_MESSAGE_FAIL 0x0001 > @@ -678,15 +679,15 @@ struct AdapterControlBlock > unsigned int uncache_size; > uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; > /* data collection buffer for read from 80331 */ > - int32_t rqbuf_firstindex; > + int32_t rqbuf_getIndex; > /* first of read buffer */ > - int32_t rqbuf_lastindex; > + int32_t rqbuf_putIndex; > /* last of read buffer */ > uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; > /* data collection buffer for write to 80331 */ > - int32_t wqbuf_firstindex; > + int32_t wqbuf_getIndex; > /* first of write buffer */ > - int32_t wqbuf_lastindex; > + int32_t wqbuf_putIndex; > /* last of write buffer */ > uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; > /* id0 ..... id15, lun0...lun7 */ > 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-21 12:14:27.000000000 +0800 > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 > @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct > buf2 = (uint32_t *)buf1; > } > while (iop_len > 0) { > - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > *pQbuffer = *buf1; > - acb->rqbuf_lastindex++; > + acb->rqbuf_putIndex++; > /* if last, index number set it to 0 */ > - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > buf1++; > iop_len--; > } > - if (buf2) > - kfree(buf2); > + kfree(buf2); > /* let IOP know data has been read */ > arcmsr_iop_message_read(acb); > return 1; > @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada > iop_data = (uint8_t __iomem *)prbuffer->data; > iop_len = readl(&prbuffer->data_len); > while (iop_len > 0) { > - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > *pQbuffer = readb(iop_data); > - acb->rqbuf_lastindex++; > - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > + acb->rqbuf_putIndex++; > + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > iop_data++; > iop_len--; > } > @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha > > spin_lock_irqsave(&acb->rqbuffer_lock, flags); > prbuffer = arcmsr_get_iop_rqbuffer(acb); > - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & > + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & > (ARCMSR_MAX_QBUFFER - 1); > if (buf_empty_len >= readl(&prbuffer->data_len)) { > if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) > @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i > 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) > + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > && (allxfer_len < 124)) { > - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > *buf1 = *pQbuffer; > - acb->wqbuf_firstindex++; > - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > + acb->wqbuf_getIndex++; > + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > buf1++; > allxfer_len++; > } > @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte > 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) > + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > && (allxfer_len < 124)) { > - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > writeb(*pQbuffer, iop_data); > - acb->wqbuf_firstindex++; > - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > + acb->wqbuf_getIndex++; > + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > iop_data++; > allxfer_len++; > } > @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han > > spin_lock_irqsave(&acb->wqbuffer_lock, flags); > acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; > - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) > + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) > arcmsr_write_ioctldata2iop(acb); > - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) > + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) > acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > } > @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( > 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; > + acb->rqbuf_getIndex = 0; > + acb->rqbuf_putIndex = 0; > arcmsr_iop_message_read(acb); > mdelay(30); > - } else if (acb->rqbuf_firstindex != > - acb->rqbuf_lastindex) { > - acb->rqbuf_firstindex = 0; > - acb->rqbuf_lastindex = 0; > + } else if (acb->rqbuf_getIndex != > + acb->rqbuf_putIndex) { > + acb->rqbuf_getIndex = 0; > + acb->rqbuf_putIndex = 0; > mdelay(30); > } else > break; > @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc > unsigned char *ver_addr; > uint8_t *pQbuffer, *ptmpQbuffer; > uint32_t allxfer_len = 0; > - ver_addr = kmalloc(1032, GFP_ATOMIC); > + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > if (!ver_addr) { > retvalue = ARCMSR_MESSAGE_FAIL; > pr_info("%s: memory not enough!\n", __func__); > @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc > } > ptmpQbuffer = ver_addr; > spin_lock_irqsave(&acb->rqbuffer_lock, flags); > - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { > + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > 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; > + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > } else { > if (((ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex) + > - acb->rqbuf_lastindex) > 1032) { > + acb->rqbuf_getIndex) + > + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > memcpy(ptmpQbuffer, > pQbuffer, ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex); > + - acb->rqbuf_getIndex); > ptmpQbuffer += > ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex; > + acb->rqbuf_getIndex; > memcpy(ptmpQbuffer, > - acb->rqbuffer, 1032 - > + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - > (ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex)); > - acb->rqbuf_firstindex = > - 1032 - (ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex); > - allxfer_len = 1032; > + - acb->rqbuf_getIndex)); > + acb->rqbuf_getIndex = > + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER > + - acb->rqbuf_getIndex); > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > } else { > memcpy(ptmpQbuffer, > pQbuffer, ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex); > + - acb->rqbuf_getIndex); > ptmpQbuffer += > ARCMSR_MAX_QBUFFER - > - acb->rqbuf_firstindex; > + acb->rqbuf_getIndex; > memcpy(ptmpQbuffer, > acb->rqbuffer, > - acb->rqbuf_lastindex); > + acb->rqbuf_putIndex); > allxfer_len = ARCMSR_MAX_QBUFFER > - - acb->rqbuf_firstindex + > - acb->rqbuf_lastindex; > - acb->rqbuf_firstindex = > - acb->rqbuf_lastindex; > + - acb->rqbuf_getIndex + > + acb->rqbuf_putIndex; > + acb->rqbuf_getIndex = > + acb->rqbuf_putIndex; > } > } > } else { > - if ((acb->rqbuf_lastindex - > - acb->rqbuf_firstindex) > 1032) { > - memcpy(ptmpQbuffer, pQbuffer, 1032); > - acb->rqbuf_firstindex += 1032; > - allxfer_len = 1032; > + if ((acb->rqbuf_putIndex - > + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > } else { > memcpy(ptmpQbuffer, pQbuffer, > - acb->rqbuf_lastindex - > - acb->rqbuf_firstindex); > - allxfer_len = acb->rqbuf_lastindex > - - acb->rqbuf_firstindex; > - acb->rqbuf_firstindex = > - acb->rqbuf_lastindex; > + acb->rqbuf_putIndex - > + acb->rqbuf_getIndex); > + allxfer_len = acb->rqbuf_putIndex > + - acb->rqbuf_getIndex; > + acb->rqbuf_getIndex = > + acb->rqbuf_putIndex; > } > } > } > @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc > } > case ARCMSR_MESSAGE_WRITE_WQBUFFER: { > unsigned char *ver_addr; > - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > uint8_t *pQbuffer, *ptmpuserbuffer; > - ver_addr = kmalloc(1032, GFP_ATOMIC); > + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > if (!ver_addr) { > retvalue = ARCMSR_MESSAGE_FAIL; > goto message_out; > @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc > 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) { > + wqbuf_putIndex = acb->wqbuf_putIndex; > + wqbuf_getIndex = acb->wqbuf_getIndex; > + if (wqbuf_putIndex != wqbuf_getIndex) { > struct SENSE_DATA *sensebuffer = > (struct SENSE_DATA *)cmd->sense_buffer; > arcmsr_write_ioctldata2iop(acb); > @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc > sensebuffer->Valid = 1; > retvalue = ARCMSR_MESSAGE_FAIL; > } else { > - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) > + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) > & (ARCMSR_MAX_QBUFFER - 1); > if (my_empty_len >= user_len) { > while (user_len > 0) { > - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; > - if ((acb->wqbuf_lastindex + user_len) > + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; > + if ((acb->wqbuf_putIndex + user_len) > > ARCMSR_MAX_QBUFFER) { > memcpy(pQbuffer, ptmpuserbuffer, > ARCMSR_MAX_QBUFFER - > - acb->wqbuf_lastindex); > + acb->wqbuf_putIndex); > ptmpuserbuffer += > (ARCMSR_MAX_QBUFFER > - - acb->wqbuf_lastindex); > + - acb->wqbuf_putIndex); > user_len -= (ARCMSR_MAX_QBUFFER > - - acb->wqbuf_lastindex); > - acb->wqbuf_lastindex = 0; > + - acb->wqbuf_putIndex); > + acb->wqbuf_putIndex = 0; > } else { > memcpy(pQbuffer, ptmpuserbuffer, > user_len); > - acb->wqbuf_lastindex += user_len; > - acb->wqbuf_lastindex %= > + acb->wqbuf_putIndex += user_len; > + acb->wqbuf_putIndex %= > ARCMSR_MAX_QBUFFER; > user_len = 0; > } > @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc > 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->rqbuf_getIndex = 0; > + acb->rqbuf_putIndex = 0; > memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > if (acb->fw_flag == FW_DEADLOCK) > @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc > 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; > + acb->wqbuf_getIndex = 0; > + acb->wqbuf_putIndex = 0; > memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > if (acb->fw_flag == FW_DEADLOCK) > @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc > 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->rqbuf_getIndex = 0; > + acb->rqbuf_putIndex = 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; > + acb->wqbuf_getIndex = 0; > + acb->wqbuf_putIndex = 0; > pQbuffer = acb->wqbuffer; > memset(pQbuffer, 0, sizeof(struct QBUFFER)); > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > > > > -- > 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 2014-08-25 10:29 ` Tomas Henzl @ 2014-08-25 12:52 ` Tomas Henzl 2014-08-26 20:27 ` Ching Huang 1 sibling, 0 replies; 10+ messages in thread From: Tomas Henzl @ 2014-08-25 12:52 UTC (permalink / raw) To: Ching Huang Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On 08/25/2014 12:29 PM, Tomas Henzl wrote: > On 08/25/2014 07:59 PM, Ching Huang wrote: >> On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: >>> 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 ? >>> >> NO. We have to check the input buffer that may have message data come >> from IOP. >>>> 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? >>> >> Yes, there copying data from a ring buffer. firstindex and lastindex are >> bad name. For readability, I rename the firstindex to getIndex, >> lastindex to putIndex. > My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' > you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. > Is this correct? And when it is copying from a ring buffer, maybe it could be made in a simpler way? What do you think about this (not even compile tested, just an idea): spin_lock_irqsave(&acb->rqbuffer_lock, flags); unsigned int tail = acb->rqbuf_firstindex; unsigned int head = acb->rqbuf_lastindex; unsigned int cnt_to_end = CIRC_CNT_TO_END(head, tail, ARCMSR_MAX_QBUFFER); allxfer_len = CIRC_CNT(head, tail, ARCMSR_MAX_QBUFFER); if (allxfer_len > 1032) allxfer_len = 1032; if (allxfer_len <= cnt_to_end) memcpy(buf, acb->rqbuffer + tail, allxfer_len); else { memcpy(buf, acb->rqbuffer + tails, cnt_to_end); memcpy(buf + cnt_to_end, acb->rqbuffer, allxfer_len - cnt_to_end); } acb->rqbuf_firstindex = (acb->rqbuf_firstindex + allxfer_len) % ARCMSR_MAX_QBUFFER; > >>> 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. >> 1032 is the API data buffer limitation. >>> 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 >> This patch is relative to branch: >> >> git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 >> >> change log: >> 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to >> rqbuf_putIndex. >> 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to >> wqbuf_putIndex. >> 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN >> 4. remove a NULL pointer checking before kfree. >> >> 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-08-21 12:14:27.000000000 +0800 >> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 >> @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ >> /* do message unit read. */ >> ptmpQbuffer = (uint8_t *)buf; >> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { >> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; >> - 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; >> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { >> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; >> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { >> + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { >> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >> } else { >> - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) >> - + acb->rqbuf_lastindex) > 1032) { >> + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >> + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { >> memcpy(ptmpQbuffer, pQbuffer, >> ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex); >> + - acb->rqbuf_getIndex); >> ptmpQbuffer += ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex; >> - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 >> + - acb->rqbuf_getIndex; >> + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN >> - (ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex)); >> - acb->rqbuf_firstindex = 1032 - >> + acb->rqbuf_getIndex)); >> + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - >> (ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex); >> - allxfer_len = 1032; >> + acb->rqbuf_getIndex); >> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >> } else { >> memcpy(ptmpQbuffer, pQbuffer, >> ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex); >> + acb->rqbuf_getIndex); >> ptmpQbuffer += ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex; >> + acb->rqbuf_getIndex; >> memcpy(ptmpQbuffer, acb->rqbuffer, >> - acb->rqbuf_lastindex); >> + acb->rqbuf_putIndex); >> allxfer_len = ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex + >> - acb->rqbuf_lastindex; >> - acb->rqbuf_firstindex = >> - acb->rqbuf_lastindex; >> + acb->rqbuf_getIndex + >> + acb->rqbuf_putIndex; >> + acb->rqbuf_getIndex = >> + acb->rqbuf_putIndex; >> } >> } >> } else { >> - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { >> - memcpy(ptmpQbuffer, pQbuffer, 1032); >> - acb->rqbuf_firstindex += 1032; >> - allxfer_len = 1032; >> + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { >> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >> } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex >> + - acb->rqbuf_getIndex); >> + allxfer_len = acb->rqbuf_putIndex - >> + acb->rqbuf_getIndex; >> + acb->rqbuf_getIndex = acb->rqbuf_putIndex; >> } >> } >> } >> @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ >> struct device *dev = container_of(kobj,struct device,kobj); >> struct Scsi_Host *host = class_to_shost(dev); >> struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; >> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; >> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; >> uint8_t *pQbuffer, *ptmpuserbuffer; >> unsigned long flags; >> >> if (!capable(CAP_SYS_ADMIN)) >> return -EACCES; >> - if (count > 1032) >> + if (count > ARCMSR_API_DATA_BUFLEN) >> return -EINVAL; >> /* 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) { >> + wqbuf_putIndex = acb->wqbuf_putIndex; >> + wqbuf_getIndex = acb->wqbuf_getIndex; >> + if (wqbuf_putIndex != wqbuf_getIndex) { >> arcmsr_write_ioctldata2iop(acb); >> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >> return 0; /*need retry*/ >> } else { >> - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) >> + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; >> memcpy(pQbuffer, ptmpuserbuffer, 1); >> - acb->wqbuf_lastindex++; >> - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >> + acb->wqbuf_putIndex++; >> + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >> ptmpuserbuffer++; >> user_len--; >> } >> @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ >> | 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; >> + acb->rqbuf_getIndex = 0; >> + acb->rqbuf_putIndex = 0; >> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); >> spin_lock_irqsave(&acb->wqbuffer_lock, flags); >> - acb->wqbuf_firstindex = 0; >> - acb->wqbuf_lastindex = 0; >> + acb->wqbuf_getIndex = 0; >> + acb->wqbuf_putIndex = 0; >> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >> pQbuffer = acb->rqbuffer; >> memset(pQbuffer, 0, sizeof (struct QBUFFER)); >> @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs >> .name = "mu_read", >> .mode = S_IRUSR , >> }, >> - .size = 1032, >> + .size = ARCMSR_API_DATA_BUFLEN, >> .read = arcmsr_sysfs_iop_message_read, >> }; >> >> @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs >> .name = "mu_write", >> .mode = S_IWUSR, >> }, >> - .size = 1032, >> + .size = ARCMSR_API_DATA_BUFLEN, >> .write = arcmsr_sysfs_iop_message_write, >> }; >> >> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h >> --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 >> +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 >> @@ -107,10 +107,11 @@ struct CMD_MESSAGE >> ** IOP Message Transfer Data for user space >> ******************************************************************************* >> */ >> +#define ARCMSR_API_DATA_BUFLEN 1032 >> struct CMD_MESSAGE_FIELD >> { >> struct CMD_MESSAGE cmdmessage; >> - uint8_t messagedatabuffer[1032]; >> + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; >> }; >> /* IOP message transfer */ >> #define ARCMSR_MESSAGE_FAIL 0x0001 >> @@ -678,15 +679,15 @@ struct AdapterControlBlock >> unsigned int uncache_size; >> uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; >> /* data collection buffer for read from 80331 */ >> - int32_t rqbuf_firstindex; >> + int32_t rqbuf_getIndex; >> /* first of read buffer */ >> - int32_t rqbuf_lastindex; >> + int32_t rqbuf_putIndex; >> /* last of read buffer */ >> uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; >> /* data collection buffer for write to 80331 */ >> - int32_t wqbuf_firstindex; >> + int32_t wqbuf_getIndex; >> /* first of write buffer */ >> - int32_t wqbuf_lastindex; >> + int32_t wqbuf_putIndex; >> /* last of write buffer */ >> uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; >> /* id0 ..... id15, lun0...lun7 */ >> 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-21 12:14:27.000000000 +0800 >> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 >> @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct >> buf2 = (uint32_t *)buf1; >> } >> while (iop_len > 0) { >> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; >> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; >> *pQbuffer = *buf1; >> - acb->rqbuf_lastindex++; >> + acb->rqbuf_putIndex++; >> /* if last, index number set it to 0 */ >> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >> buf1++; >> iop_len--; >> } >> - if (buf2) >> - kfree(buf2); >> + kfree(buf2); >> /* let IOP know data has been read */ >> arcmsr_iop_message_read(acb); >> return 1; >> @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada >> iop_data = (uint8_t __iomem *)prbuffer->data; >> iop_len = readl(&prbuffer->data_len); >> while (iop_len > 0) { >> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; >> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; >> *pQbuffer = readb(iop_data); >> - acb->rqbuf_lastindex++; >> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >> + acb->rqbuf_putIndex++; >> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >> iop_data++; >> iop_len--; >> } >> @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha >> >> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >> prbuffer = arcmsr_get_iop_rqbuffer(acb); >> - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & >> + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & >> (ARCMSR_MAX_QBUFFER - 1); >> if (buf_empty_len >= readl(&prbuffer->data_len)) { >> if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) >> @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i >> 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) >> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) >> && (allxfer_len < 124)) { >> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; >> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; >> *buf1 = *pQbuffer; >> - acb->wqbuf_firstindex++; >> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; >> + acb->wqbuf_getIndex++; >> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >> buf1++; >> allxfer_len++; >> } >> @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte >> 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) >> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) >> && (allxfer_len < 124)) { >> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; >> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; >> writeb(*pQbuffer, iop_data); >> - acb->wqbuf_firstindex++; >> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; >> + acb->wqbuf_getIndex++; >> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >> iop_data++; >> allxfer_len++; >> } >> @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han >> >> spin_lock_irqsave(&acb->wqbuffer_lock, flags); >> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; >> - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) >> + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) >> arcmsr_write_ioctldata2iop(acb); >> - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) >> + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) >> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; >> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >> } >> @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( >> 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; >> + acb->rqbuf_getIndex = 0; >> + acb->rqbuf_putIndex = 0; >> arcmsr_iop_message_read(acb); >> mdelay(30); >> - } else if (acb->rqbuf_firstindex != >> - acb->rqbuf_lastindex) { >> - acb->rqbuf_firstindex = 0; >> - acb->rqbuf_lastindex = 0; >> + } else if (acb->rqbuf_getIndex != >> + acb->rqbuf_putIndex) { >> + acb->rqbuf_getIndex = 0; >> + acb->rqbuf_putIndex = 0; >> mdelay(30); >> } else >> break; >> @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc >> unsigned char *ver_addr; >> uint8_t *pQbuffer, *ptmpQbuffer; >> uint32_t allxfer_len = 0; >> - ver_addr = kmalloc(1032, GFP_ATOMIC); >> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); >> if (!ver_addr) { >> retvalue = ARCMSR_MESSAGE_FAIL; >> pr_info("%s: memory not enough!\n", __func__); >> @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc >> } >> ptmpQbuffer = ver_addr; >> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { >> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; >> - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { >> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { >> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; >> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { >> 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; >> + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { >> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >> } else { >> if (((ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex) + >> - acb->rqbuf_lastindex) > 1032) { >> + acb->rqbuf_getIndex) + >> + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { >> memcpy(ptmpQbuffer, >> pQbuffer, ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex); >> + - acb->rqbuf_getIndex); >> ptmpQbuffer += >> ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex; >> + acb->rqbuf_getIndex; >> memcpy(ptmpQbuffer, >> - acb->rqbuffer, 1032 - >> + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - >> (ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex)); >> - acb->rqbuf_firstindex = >> - 1032 - (ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex); >> - allxfer_len = 1032; >> + - acb->rqbuf_getIndex)); >> + acb->rqbuf_getIndex = >> + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER >> + - acb->rqbuf_getIndex); >> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >> } else { >> memcpy(ptmpQbuffer, >> pQbuffer, ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex); >> + - acb->rqbuf_getIndex); >> ptmpQbuffer += >> ARCMSR_MAX_QBUFFER - >> - acb->rqbuf_firstindex; >> + acb->rqbuf_getIndex; >> memcpy(ptmpQbuffer, >> acb->rqbuffer, >> - acb->rqbuf_lastindex); >> + acb->rqbuf_putIndex); >> allxfer_len = ARCMSR_MAX_QBUFFER >> - - acb->rqbuf_firstindex + >> - acb->rqbuf_lastindex; >> - acb->rqbuf_firstindex = >> - acb->rqbuf_lastindex; >> + - acb->rqbuf_getIndex + >> + acb->rqbuf_putIndex; >> + acb->rqbuf_getIndex = >> + acb->rqbuf_putIndex; >> } >> } >> } else { >> - if ((acb->rqbuf_lastindex - >> - acb->rqbuf_firstindex) > 1032) { >> - memcpy(ptmpQbuffer, pQbuffer, 1032); >> - acb->rqbuf_firstindex += 1032; >> - allxfer_len = 1032; >> + if ((acb->rqbuf_putIndex - >> + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { >> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >> } else { >> memcpy(ptmpQbuffer, pQbuffer, >> - acb->rqbuf_lastindex - >> - acb->rqbuf_firstindex); >> - allxfer_len = acb->rqbuf_lastindex >> - - acb->rqbuf_firstindex; >> - acb->rqbuf_firstindex = >> - acb->rqbuf_lastindex; >> + acb->rqbuf_putIndex - >> + acb->rqbuf_getIndex); >> + allxfer_len = acb->rqbuf_putIndex >> + - acb->rqbuf_getIndex; >> + acb->rqbuf_getIndex = >> + acb->rqbuf_putIndex; >> } >> } >> } >> @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc >> } >> case ARCMSR_MESSAGE_WRITE_WQBUFFER: { >> unsigned char *ver_addr; >> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; >> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; >> uint8_t *pQbuffer, *ptmpuserbuffer; >> - ver_addr = kmalloc(1032, GFP_ATOMIC); >> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); >> if (!ver_addr) { >> retvalue = ARCMSR_MESSAGE_FAIL; >> goto message_out; >> @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc >> 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) { >> + wqbuf_putIndex = acb->wqbuf_putIndex; >> + wqbuf_getIndex = acb->wqbuf_getIndex; >> + if (wqbuf_putIndex != wqbuf_getIndex) { >> struct SENSE_DATA *sensebuffer = >> (struct SENSE_DATA *)cmd->sense_buffer; >> arcmsr_write_ioctldata2iop(acb); >> @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc >> sensebuffer->Valid = 1; >> retvalue = ARCMSR_MESSAGE_FAIL; >> } else { >> - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) >> + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) >> & (ARCMSR_MAX_QBUFFER - 1); >> if (my_empty_len >= user_len) { >> while (user_len > 0) { >> - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; >> - if ((acb->wqbuf_lastindex + user_len) >> + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; >> + if ((acb->wqbuf_putIndex + user_len) >> > ARCMSR_MAX_QBUFFER) { >> memcpy(pQbuffer, ptmpuserbuffer, >> ARCMSR_MAX_QBUFFER - >> - acb->wqbuf_lastindex); >> + acb->wqbuf_putIndex); >> ptmpuserbuffer += >> (ARCMSR_MAX_QBUFFER >> - - acb->wqbuf_lastindex); >> + - acb->wqbuf_putIndex); >> user_len -= (ARCMSR_MAX_QBUFFER >> - - acb->wqbuf_lastindex); >> - acb->wqbuf_lastindex = 0; >> + - acb->wqbuf_putIndex); >> + acb->wqbuf_putIndex = 0; >> } else { >> memcpy(pQbuffer, ptmpuserbuffer, >> user_len); >> - acb->wqbuf_lastindex += user_len; >> - acb->wqbuf_lastindex %= >> + acb->wqbuf_putIndex += user_len; >> + acb->wqbuf_putIndex %= >> ARCMSR_MAX_QBUFFER; >> user_len = 0; >> } >> @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc >> 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->rqbuf_getIndex = 0; >> + acb->rqbuf_putIndex = 0; >> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); >> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); >> if (acb->fw_flag == FW_DEADLOCK) >> @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc >> 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; >> + acb->wqbuf_getIndex = 0; >> + acb->wqbuf_putIndex = 0; >> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); >> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >> if (acb->fw_flag == FW_DEADLOCK) >> @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc >> 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->rqbuf_getIndex = 0; >> + acb->rqbuf_putIndex = 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; >> + acb->wqbuf_getIndex = 0; >> + acb->wqbuf_putIndex = 0; >> pQbuffer = acb->wqbuffer; >> memset(pQbuffer, 0, sizeof(struct QBUFFER)); >> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >> >> >> >> -- >> 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 > -- > 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 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 1 sibling, 1 reply; 10+ messages in thread From: Ching Huang @ 2014-08-26 20:27 UTC (permalink / raw) To: Tomas Henzl Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On Mon, 2014-08-25 at 12:29 +0200, Tomas Henzl wrote: > On 08/25/2014 07:59 PM, Ching Huang wrote: > > On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: > >> 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 ? > >> > > NO. We have to check the input buffer that may have message data come > > from IOP. > >>> 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? > >> > > Yes, there copying data from a ring buffer. firstindex and lastindex are > > bad name. For readability, I rename the firstindex to getIndex, > > lastindex to putIndex. > > My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' > you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. > Is this correct? The firstindex is a get index and lastindex is a put index of a ring buffer. At here, firstindex > lastindex, so the data remain in buffer are (ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex > > >> 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. > > 1032 is the API data buffer limitation. > >> 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 > > This patch is relative to branch: > > > > git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 > > > > change log: > > 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to > > rqbuf_putIndex. > > 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to > > wqbuf_putIndex. > > 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN > > 4. remove a NULL pointer checking before kfree. > > > > 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-08-21 12:14:27.000000000 +0800 > > +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 > > @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ > > /* do message unit read. */ > > ptmpQbuffer = (uint8_t *)buf; > > spin_lock_irqsave(&acb->rqbuffer_lock, flags); > > - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > > - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > > - 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; > > + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > > + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > > + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > > + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > > + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > > } else { > > - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) > > - + acb->rqbuf_lastindex) > 1032) { > > + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) > > + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > > memcpy(ptmpQbuffer, pQbuffer, > > ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex); > > + - acb->rqbuf_getIndex); > > ptmpQbuffer += ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex; > > - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 > > + - acb->rqbuf_getIndex; > > + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN > > - (ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex)); > > - acb->rqbuf_firstindex = 1032 - > > + acb->rqbuf_getIndex)); > > + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - > > (ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex); > > - allxfer_len = 1032; > > + acb->rqbuf_getIndex); > > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > > } else { > > memcpy(ptmpQbuffer, pQbuffer, > > ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex); > > + acb->rqbuf_getIndex); > > ptmpQbuffer += ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex; > > + acb->rqbuf_getIndex; > > memcpy(ptmpQbuffer, acb->rqbuffer, > > - acb->rqbuf_lastindex); > > + acb->rqbuf_putIndex); > > allxfer_len = ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex + > > - acb->rqbuf_lastindex; > > - acb->rqbuf_firstindex = > > - acb->rqbuf_lastindex; > > + acb->rqbuf_getIndex + > > + acb->rqbuf_putIndex; > > + acb->rqbuf_getIndex = > > + acb->rqbuf_putIndex; > > } > > } > > } else { > > - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { > > - memcpy(ptmpQbuffer, pQbuffer, 1032); > > - acb->rqbuf_firstindex += 1032; > > - allxfer_len = 1032; > > + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > > } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex > > + - acb->rqbuf_getIndex); > > + allxfer_len = acb->rqbuf_putIndex - > > + acb->rqbuf_getIndex; > > + acb->rqbuf_getIndex = acb->rqbuf_putIndex; > > } > > } > > } > > @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ > > struct device *dev = container_of(kobj,struct device,kobj); > > struct Scsi_Host *host = class_to_shost(dev); > > struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; > > - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > > + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > > uint8_t *pQbuffer, *ptmpuserbuffer; > > unsigned long flags; > > > > if (!capable(CAP_SYS_ADMIN)) > > return -EACCES; > > - if (count > 1032) > > + if (count > ARCMSR_API_DATA_BUFLEN) > > return -EINVAL; > > /* 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) { > > + wqbuf_putIndex = acb->wqbuf_putIndex; > > + wqbuf_getIndex = acb->wqbuf_getIndex; > > + if (wqbuf_putIndex != wqbuf_getIndex) { > > arcmsr_write_ioctldata2iop(acb); > > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > > return 0; /*need retry*/ > > } else { > > - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) > > + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; > > memcpy(pQbuffer, ptmpuserbuffer, 1); > > - acb->wqbuf_lastindex++; > > - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > > + acb->wqbuf_putIndex++; > > + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > > ptmpuserbuffer++; > > user_len--; > > } > > @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ > > | 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; > > + acb->rqbuf_getIndex = 0; > > + acb->rqbuf_putIndex = 0; > > spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > > spin_lock_irqsave(&acb->wqbuffer_lock, flags); > > - acb->wqbuf_firstindex = 0; > > - acb->wqbuf_lastindex = 0; > > + acb->wqbuf_getIndex = 0; > > + acb->wqbuf_putIndex = 0; > > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > > pQbuffer = acb->rqbuffer; > > memset(pQbuffer, 0, sizeof (struct QBUFFER)); > > @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs > > .name = "mu_read", > > .mode = S_IRUSR , > > }, > > - .size = 1032, > > + .size = ARCMSR_API_DATA_BUFLEN, > > .read = arcmsr_sysfs_iop_message_read, > > }; > > > > @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs > > .name = "mu_write", > > .mode = S_IWUSR, > > }, > > - .size = 1032, > > + .size = ARCMSR_API_DATA_BUFLEN, > > .write = arcmsr_sysfs_iop_message_write, > > }; > > > > diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h > > --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 > > +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 > > @@ -107,10 +107,11 @@ struct CMD_MESSAGE > > ** IOP Message Transfer Data for user space > > ******************************************************************************* > > */ > > +#define ARCMSR_API_DATA_BUFLEN 1032 > > struct CMD_MESSAGE_FIELD > > { > > struct CMD_MESSAGE cmdmessage; > > - uint8_t messagedatabuffer[1032]; > > + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; > > }; > > /* IOP message transfer */ > > #define ARCMSR_MESSAGE_FAIL 0x0001 > > @@ -678,15 +679,15 @@ struct AdapterControlBlock > > unsigned int uncache_size; > > uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; > > /* data collection buffer for read from 80331 */ > > - int32_t rqbuf_firstindex; > > + int32_t rqbuf_getIndex; > > /* first of read buffer */ > > - int32_t rqbuf_lastindex; > > + int32_t rqbuf_putIndex; > > /* last of read buffer */ > > uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; > > /* data collection buffer for write to 80331 */ > > - int32_t wqbuf_firstindex; > > + int32_t wqbuf_getIndex; > > /* first of write buffer */ > > - int32_t wqbuf_lastindex; > > + int32_t wqbuf_putIndex; > > /* last of write buffer */ > > uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; > > /* id0 ..... id15, lun0...lun7 */ > > 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-21 12:14:27.000000000 +0800 > > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 > > @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct > > buf2 = (uint32_t *)buf1; > > } > > while (iop_len > 0) { > > - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > > + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > > *pQbuffer = *buf1; > > - acb->rqbuf_lastindex++; > > + acb->rqbuf_putIndex++; > > /* if last, index number set it to 0 */ > > - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > > + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > > buf1++; > > iop_len--; > > } > > - if (buf2) > > - kfree(buf2); > > + kfree(buf2); > > /* let IOP know data has been read */ > > arcmsr_iop_message_read(acb); > > return 1; > > @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada > > iop_data = (uint8_t __iomem *)prbuffer->data; > > iop_len = readl(&prbuffer->data_len); > > while (iop_len > 0) { > > - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > > + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > > *pQbuffer = readb(iop_data); > > - acb->rqbuf_lastindex++; > > - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > > + acb->rqbuf_putIndex++; > > + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > > iop_data++; > > iop_len--; > > } > > @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha > > > > spin_lock_irqsave(&acb->rqbuffer_lock, flags); > > prbuffer = arcmsr_get_iop_rqbuffer(acb); > > - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & > > + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & > > (ARCMSR_MAX_QBUFFER - 1); > > if (buf_empty_len >= readl(&prbuffer->data_len)) { > > if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) > > @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i > > 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) > > + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > > && (allxfer_len < 124)) { > > - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > > + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > > *buf1 = *pQbuffer; > > - acb->wqbuf_firstindex++; > > - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > > + acb->wqbuf_getIndex++; > > + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > > buf1++; > > allxfer_len++; > > } > > @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte > > 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) > > + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > > && (allxfer_len < 124)) { > > - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > > + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > > writeb(*pQbuffer, iop_data); > > - acb->wqbuf_firstindex++; > > - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > > + acb->wqbuf_getIndex++; > > + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > > iop_data++; > > allxfer_len++; > > } > > @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han > > > > spin_lock_irqsave(&acb->wqbuffer_lock, flags); > > acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; > > - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) > > + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) > > arcmsr_write_ioctldata2iop(acb); > > - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) > > + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) > > acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; > > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > > } > > @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( > > 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; > > + acb->rqbuf_getIndex = 0; > > + acb->rqbuf_putIndex = 0; > > arcmsr_iop_message_read(acb); > > mdelay(30); > > - } else if (acb->rqbuf_firstindex != > > - acb->rqbuf_lastindex) { > > - acb->rqbuf_firstindex = 0; > > - acb->rqbuf_lastindex = 0; > > + } else if (acb->rqbuf_getIndex != > > + acb->rqbuf_putIndex) { > > + acb->rqbuf_getIndex = 0; > > + acb->rqbuf_putIndex = 0; > > mdelay(30); > > } else > > break; > > @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc > > unsigned char *ver_addr; > > uint8_t *pQbuffer, *ptmpQbuffer; > > uint32_t allxfer_len = 0; > > - ver_addr = kmalloc(1032, GFP_ATOMIC); > > + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > > if (!ver_addr) { > > retvalue = ARCMSR_MESSAGE_FAIL; > > pr_info("%s: memory not enough!\n", __func__); > > @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc > > } > > ptmpQbuffer = ver_addr; > > spin_lock_irqsave(&acb->rqbuffer_lock, flags); > > - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > > - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > > - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { > > + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > > + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > > + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > > 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; > > + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > > + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > > } else { > > if (((ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex) + > > - acb->rqbuf_lastindex) > 1032) { > > + acb->rqbuf_getIndex) + > > + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > > memcpy(ptmpQbuffer, > > pQbuffer, ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex); > > + - acb->rqbuf_getIndex); > > ptmpQbuffer += > > ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex; > > + acb->rqbuf_getIndex; > > memcpy(ptmpQbuffer, > > - acb->rqbuffer, 1032 - > > + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - > > (ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex)); > > - acb->rqbuf_firstindex = > > - 1032 - (ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex); > > - allxfer_len = 1032; > > + - acb->rqbuf_getIndex)); > > + acb->rqbuf_getIndex = > > + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER > > + - acb->rqbuf_getIndex); > > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > > } else { > > memcpy(ptmpQbuffer, > > pQbuffer, ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex); > > + - acb->rqbuf_getIndex); > > ptmpQbuffer += > > ARCMSR_MAX_QBUFFER - > > - acb->rqbuf_firstindex; > > + acb->rqbuf_getIndex; > > memcpy(ptmpQbuffer, > > acb->rqbuffer, > > - acb->rqbuf_lastindex); > > + acb->rqbuf_putIndex); > > allxfer_len = ARCMSR_MAX_QBUFFER > > - - acb->rqbuf_firstindex + > > - acb->rqbuf_lastindex; > > - acb->rqbuf_firstindex = > > - acb->rqbuf_lastindex; > > + - acb->rqbuf_getIndex + > > + acb->rqbuf_putIndex; > > + acb->rqbuf_getIndex = > > + acb->rqbuf_putIndex; > > } > > } > > } else { > > - if ((acb->rqbuf_lastindex - > > - acb->rqbuf_firstindex) > 1032) { > > - memcpy(ptmpQbuffer, pQbuffer, 1032); > > - acb->rqbuf_firstindex += 1032; > > - allxfer_len = 1032; > > + if ((acb->rqbuf_putIndex - > > + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > > + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > > + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > > + allxfer_len = ARCMSR_API_DATA_BUFLEN; > > } else { > > memcpy(ptmpQbuffer, pQbuffer, > > - acb->rqbuf_lastindex - > > - acb->rqbuf_firstindex); > > - allxfer_len = acb->rqbuf_lastindex > > - - acb->rqbuf_firstindex; > > - acb->rqbuf_firstindex = > > - acb->rqbuf_lastindex; > > + acb->rqbuf_putIndex - > > + acb->rqbuf_getIndex); > > + allxfer_len = acb->rqbuf_putIndex > > + - acb->rqbuf_getIndex; > > + acb->rqbuf_getIndex = > > + acb->rqbuf_putIndex; > > } > > } > > } > > @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc > > } > > case ARCMSR_MESSAGE_WRITE_WQBUFFER: { > > unsigned char *ver_addr; > > - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > > + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > > uint8_t *pQbuffer, *ptmpuserbuffer; > > - ver_addr = kmalloc(1032, GFP_ATOMIC); > > + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > > if (!ver_addr) { > > retvalue = ARCMSR_MESSAGE_FAIL; > > goto message_out; > > @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc > > 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) { > > + wqbuf_putIndex = acb->wqbuf_putIndex; > > + wqbuf_getIndex = acb->wqbuf_getIndex; > > + if (wqbuf_putIndex != wqbuf_getIndex) { > > struct SENSE_DATA *sensebuffer = > > (struct SENSE_DATA *)cmd->sense_buffer; > > arcmsr_write_ioctldata2iop(acb); > > @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc > > sensebuffer->Valid = 1; > > retvalue = ARCMSR_MESSAGE_FAIL; > > } else { > > - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) > > + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) > > & (ARCMSR_MAX_QBUFFER - 1); > > if (my_empty_len >= user_len) { > > while (user_len > 0) { > > - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; > > - if ((acb->wqbuf_lastindex + user_len) > > + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; > > + if ((acb->wqbuf_putIndex + user_len) > > > ARCMSR_MAX_QBUFFER) { > > memcpy(pQbuffer, ptmpuserbuffer, > > ARCMSR_MAX_QBUFFER - > > - acb->wqbuf_lastindex); > > + acb->wqbuf_putIndex); > > ptmpuserbuffer += > > (ARCMSR_MAX_QBUFFER > > - - acb->wqbuf_lastindex); > > + - acb->wqbuf_putIndex); > > user_len -= (ARCMSR_MAX_QBUFFER > > - - acb->wqbuf_lastindex); > > - acb->wqbuf_lastindex = 0; > > + - acb->wqbuf_putIndex); > > + acb->wqbuf_putIndex = 0; > > } else { > > memcpy(pQbuffer, ptmpuserbuffer, > > user_len); > > - acb->wqbuf_lastindex += user_len; > > - acb->wqbuf_lastindex %= > > + acb->wqbuf_putIndex += user_len; > > + acb->wqbuf_putIndex %= > > ARCMSR_MAX_QBUFFER; > > user_len = 0; > > } > > @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc > > 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->rqbuf_getIndex = 0; > > + acb->rqbuf_putIndex = 0; > > memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > > spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > > if (acb->fw_flag == FW_DEADLOCK) > > @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc > > 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; > > + acb->wqbuf_getIndex = 0; > > + acb->wqbuf_putIndex = 0; > > memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > > if (acb->fw_flag == FW_DEADLOCK) > > @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc > > 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->rqbuf_getIndex = 0; > > + acb->rqbuf_putIndex = 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; > > + acb->wqbuf_getIndex = 0; > > + acb->wqbuf_putIndex = 0; > > pQbuffer = acb->wqbuffer; > > memset(pQbuffer, 0, sizeof(struct QBUFFER)); > > spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > > > > > > > > -- > > 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 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 2014-08-26 20:27 ` Ching Huang @ 2014-08-26 13:20 ` Tomas Henzl 2014-08-27 20:19 ` Ching Huang 0 siblings, 1 reply; 10+ messages in thread From: Tomas Henzl @ 2014-08-26 13:20 UTC (permalink / raw) To: Ching Huang Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On 08/26/2014 10:27 PM, Ching Huang wrote: > On Mon, 2014-08-25 at 12:29 +0200, Tomas Henzl wrote: >> On 08/25/2014 07:59 PM, Ching Huang wrote: >>> On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: >>>> 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 ? >>>> >>> NO. We have to check the input buffer that may have message data come >>> from IOP. >>>>> 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? >>>> >>> Yes, there copying data from a ring buffer. firstindex and lastindex are >>> bad name. For readability, I rename the firstindex to getIndex, >>> lastindex to putIndex. >> My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' >> you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. >> Is this correct? > The firstindex is a get index and lastindex is a put index of a ring buffer. > At here, firstindex > lastindex, so the data remain in buffer are (ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex Yes, it's correct, I misinterpreted the from value with the amount of bytes to copy. But well it's also still overcomplicated and I believe that a copy like this could be rearranged with just few lines of code as a result - have you looked at the code I sent? Let's go with this patch as it is otherwise we will never end, repost is not needed because of this and also not because of arcmsr_Read_iop_rqbuffer_in_DWORD. I'll continue with reviewing the remaining patches. tomas > >>>> 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. >>> 1032 is the API data buffer limitation. >>>> 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 >>> This patch is relative to branch: >>> >>> git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 >>> >>> change log: >>> 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to >>> rqbuf_putIndex. >>> 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to >>> wqbuf_putIndex. >>> 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN >>> 4. remove a NULL pointer checking before kfree. >>> >>> 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-08-21 12:14:27.000000000 +0800 >>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 >>> @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ >>> /* do message unit read. */ >>> ptmpQbuffer = (uint8_t *)buf; >>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; >>> - 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; >>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; >>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { >>> + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>> } else { >>> - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) >>> - + acb->rqbuf_lastindex) > 1032) { >>> + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >>> + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { >>> memcpy(ptmpQbuffer, pQbuffer, >>> ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex); >>> + - acb->rqbuf_getIndex); >>> ptmpQbuffer += ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex; >>> - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 >>> + - acb->rqbuf_getIndex; >>> + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN >>> - (ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex)); >>> - acb->rqbuf_firstindex = 1032 - >>> + acb->rqbuf_getIndex)); >>> + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - >>> (ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex); >>> - allxfer_len = 1032; >>> + acb->rqbuf_getIndex); >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>> } else { >>> memcpy(ptmpQbuffer, pQbuffer, >>> ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex); >>> + acb->rqbuf_getIndex); >>> ptmpQbuffer += ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex; >>> + acb->rqbuf_getIndex; >>> memcpy(ptmpQbuffer, acb->rqbuffer, >>> - acb->rqbuf_lastindex); >>> + acb->rqbuf_putIndex); >>> allxfer_len = ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex + >>> - acb->rqbuf_lastindex; >>> - acb->rqbuf_firstindex = >>> - acb->rqbuf_lastindex; >>> + acb->rqbuf_getIndex + >>> + acb->rqbuf_putIndex; >>> + acb->rqbuf_getIndex = >>> + acb->rqbuf_putIndex; >>> } >>> } >>> } else { >>> - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { >>> - memcpy(ptmpQbuffer, pQbuffer, 1032); >>> - acb->rqbuf_firstindex += 1032; >>> - allxfer_len = 1032; >>> + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>> } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex >>> + - acb->rqbuf_getIndex); >>> + allxfer_len = acb->rqbuf_putIndex - >>> + acb->rqbuf_getIndex; >>> + acb->rqbuf_getIndex = acb->rqbuf_putIndex; >>> } >>> } >>> } >>> @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ >>> struct device *dev = container_of(kobj,struct device,kobj); >>> struct Scsi_Host *host = class_to_shost(dev); >>> struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; >>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; >>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; >>> uint8_t *pQbuffer, *ptmpuserbuffer; >>> unsigned long flags; >>> >>> if (!capable(CAP_SYS_ADMIN)) >>> return -EACCES; >>> - if (count > 1032) >>> + if (count > ARCMSR_API_DATA_BUFLEN) >>> return -EINVAL; >>> /* 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) { >>> + wqbuf_putIndex = acb->wqbuf_putIndex; >>> + wqbuf_getIndex = acb->wqbuf_getIndex; >>> + if (wqbuf_putIndex != wqbuf_getIndex) { >>> arcmsr_write_ioctldata2iop(acb); >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>> return 0; /*need retry*/ >>> } else { >>> - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) >>> + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; >>> memcpy(pQbuffer, ptmpuserbuffer, 1); >>> - acb->wqbuf_lastindex++; >>> - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >>> + acb->wqbuf_putIndex++; >>> + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >>> ptmpuserbuffer++; >>> user_len--; >>> } >>> @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ >>> | 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; >>> + acb->rqbuf_getIndex = 0; >>> + acb->rqbuf_putIndex = 0; >>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); >>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); >>> - acb->wqbuf_firstindex = 0; >>> - acb->wqbuf_lastindex = 0; >>> + acb->wqbuf_getIndex = 0; >>> + acb->wqbuf_putIndex = 0; >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>> pQbuffer = acb->rqbuffer; >>> memset(pQbuffer, 0, sizeof (struct QBUFFER)); >>> @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs >>> .name = "mu_read", >>> .mode = S_IRUSR , >>> }, >>> - .size = 1032, >>> + .size = ARCMSR_API_DATA_BUFLEN, >>> .read = arcmsr_sysfs_iop_message_read, >>> }; >>> >>> @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs >>> .name = "mu_write", >>> .mode = S_IWUSR, >>> }, >>> - .size = 1032, >>> + .size = ARCMSR_API_DATA_BUFLEN, >>> .write = arcmsr_sysfs_iop_message_write, >>> }; >>> >>> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h >>> --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 >>> +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 >>> @@ -107,10 +107,11 @@ struct CMD_MESSAGE >>> ** IOP Message Transfer Data for user space >>> ******************************************************************************* >>> */ >>> +#define ARCMSR_API_DATA_BUFLEN 1032 >>> struct CMD_MESSAGE_FIELD >>> { >>> struct CMD_MESSAGE cmdmessage; >>> - uint8_t messagedatabuffer[1032]; >>> + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; >>> }; >>> /* IOP message transfer */ >>> #define ARCMSR_MESSAGE_FAIL 0x0001 >>> @@ -678,15 +679,15 @@ struct AdapterControlBlock >>> unsigned int uncache_size; >>> uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; >>> /* data collection buffer for read from 80331 */ >>> - int32_t rqbuf_firstindex; >>> + int32_t rqbuf_getIndex; >>> /* first of read buffer */ >>> - int32_t rqbuf_lastindex; >>> + int32_t rqbuf_putIndex; >>> /* last of read buffer */ >>> uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; >>> /* data collection buffer for write to 80331 */ >>> - int32_t wqbuf_firstindex; >>> + int32_t wqbuf_getIndex; >>> /* first of write buffer */ >>> - int32_t wqbuf_lastindex; >>> + int32_t wqbuf_putIndex; >>> /* last of write buffer */ >>> uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; >>> /* id0 ..... id15, lun0...lun7 */ >>> 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-21 12:14:27.000000000 +0800 >>> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 >>> @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct >>> buf2 = (uint32_t *)buf1; >>> } >>> while (iop_len > 0) { >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; >>> *pQbuffer = *buf1; >>> - acb->rqbuf_lastindex++; >>> + acb->rqbuf_putIndex++; >>> /* if last, index number set it to 0 */ >>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >>> buf1++; >>> iop_len--; >>> } >>> - if (buf2) >>> - kfree(buf2); >>> + kfree(buf2); >>> /* let IOP know data has been read */ >>> arcmsr_iop_message_read(acb); >>> return 1; >>> @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada >>> iop_data = (uint8_t __iomem *)prbuffer->data; >>> iop_len = readl(&prbuffer->data_len); >>> while (iop_len > 0) { >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; >>> *pQbuffer = readb(iop_data); >>> - acb->rqbuf_lastindex++; >>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >>> + acb->rqbuf_putIndex++; >>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >>> iop_data++; >>> iop_len--; >>> } >>> @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha >>> >>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >>> prbuffer = arcmsr_get_iop_rqbuffer(acb); >>> - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & >>> + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & >>> (ARCMSR_MAX_QBUFFER - 1); >>> if (buf_empty_len >= readl(&prbuffer->data_len)) { >>> if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) >>> @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i >>> 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) >>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) >>> && (allxfer_len < 124)) { >>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; >>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; >>> *buf1 = *pQbuffer; >>> - acb->wqbuf_firstindex++; >>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; >>> + acb->wqbuf_getIndex++; >>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>> buf1++; >>> allxfer_len++; >>> } >>> @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte >>> 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) >>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) >>> && (allxfer_len < 124)) { >>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; >>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; >>> writeb(*pQbuffer, iop_data); >>> - acb->wqbuf_firstindex++; >>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; >>> + acb->wqbuf_getIndex++; >>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>> iop_data++; >>> allxfer_len++; >>> } >>> @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han >>> >>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); >>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; >>> - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) >>> + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) >>> arcmsr_write_ioctldata2iop(acb); >>> - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) >>> + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) >>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>> } >>> @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( >>> 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; >>> + acb->rqbuf_getIndex = 0; >>> + acb->rqbuf_putIndex = 0; >>> arcmsr_iop_message_read(acb); >>> mdelay(30); >>> - } else if (acb->rqbuf_firstindex != >>> - acb->rqbuf_lastindex) { >>> - acb->rqbuf_firstindex = 0; >>> - acb->rqbuf_lastindex = 0; >>> + } else if (acb->rqbuf_getIndex != >>> + acb->rqbuf_putIndex) { >>> + acb->rqbuf_getIndex = 0; >>> + acb->rqbuf_putIndex = 0; >>> mdelay(30); >>> } else >>> break; >>> @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc >>> unsigned char *ver_addr; >>> uint8_t *pQbuffer, *ptmpQbuffer; >>> uint32_t allxfer_len = 0; >>> - ver_addr = kmalloc(1032, GFP_ATOMIC); >>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); >>> if (!ver_addr) { >>> retvalue = ARCMSR_MESSAGE_FAIL; >>> pr_info("%s: memory not enough!\n", __func__); >>> @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc >>> } >>> ptmpQbuffer = ver_addr; >>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; >>> - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { >>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; >>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { >>> 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; >>> + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>> } else { >>> if (((ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex) + >>> - acb->rqbuf_lastindex) > 1032) { >>> + acb->rqbuf_getIndex) + >>> + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { >>> memcpy(ptmpQbuffer, >>> pQbuffer, ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex); >>> + - acb->rqbuf_getIndex); >>> ptmpQbuffer += >>> ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex; >>> + acb->rqbuf_getIndex; >>> memcpy(ptmpQbuffer, >>> - acb->rqbuffer, 1032 - >>> + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - >>> (ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex)); >>> - acb->rqbuf_firstindex = >>> - 1032 - (ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex); >>> - allxfer_len = 1032; >>> + - acb->rqbuf_getIndex)); >>> + acb->rqbuf_getIndex = >>> + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER >>> + - acb->rqbuf_getIndex); >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>> } else { >>> memcpy(ptmpQbuffer, >>> pQbuffer, ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex); >>> + - acb->rqbuf_getIndex); >>> ptmpQbuffer += >>> ARCMSR_MAX_QBUFFER - >>> - acb->rqbuf_firstindex; >>> + acb->rqbuf_getIndex; >>> memcpy(ptmpQbuffer, >>> acb->rqbuffer, >>> - acb->rqbuf_lastindex); >>> + acb->rqbuf_putIndex); >>> allxfer_len = ARCMSR_MAX_QBUFFER >>> - - acb->rqbuf_firstindex + >>> - acb->rqbuf_lastindex; >>> - acb->rqbuf_firstindex = >>> - acb->rqbuf_lastindex; >>> + - acb->rqbuf_getIndex + >>> + acb->rqbuf_putIndex; >>> + acb->rqbuf_getIndex = >>> + acb->rqbuf_putIndex; >>> } >>> } >>> } else { >>> - if ((acb->rqbuf_lastindex - >>> - acb->rqbuf_firstindex) > 1032) { >>> - memcpy(ptmpQbuffer, pQbuffer, 1032); >>> - acb->rqbuf_firstindex += 1032; >>> - allxfer_len = 1032; >>> + if ((acb->rqbuf_putIndex - >>> + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>> } else { >>> memcpy(ptmpQbuffer, pQbuffer, >>> - acb->rqbuf_lastindex - >>> - acb->rqbuf_firstindex); >>> - allxfer_len = acb->rqbuf_lastindex >>> - - acb->rqbuf_firstindex; >>> - acb->rqbuf_firstindex = >>> - acb->rqbuf_lastindex; >>> + acb->rqbuf_putIndex - >>> + acb->rqbuf_getIndex); >>> + allxfer_len = acb->rqbuf_putIndex >>> + - acb->rqbuf_getIndex; >>> + acb->rqbuf_getIndex = >>> + acb->rqbuf_putIndex; >>> } >>> } >>> } >>> @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc >>> } >>> case ARCMSR_MESSAGE_WRITE_WQBUFFER: { >>> unsigned char *ver_addr; >>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; >>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; >>> uint8_t *pQbuffer, *ptmpuserbuffer; >>> - ver_addr = kmalloc(1032, GFP_ATOMIC); >>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); >>> if (!ver_addr) { >>> retvalue = ARCMSR_MESSAGE_FAIL; >>> goto message_out; >>> @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc >>> 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) { >>> + wqbuf_putIndex = acb->wqbuf_putIndex; >>> + wqbuf_getIndex = acb->wqbuf_getIndex; >>> + if (wqbuf_putIndex != wqbuf_getIndex) { >>> struct SENSE_DATA *sensebuffer = >>> (struct SENSE_DATA *)cmd->sense_buffer; >>> arcmsr_write_ioctldata2iop(acb); >>> @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc >>> sensebuffer->Valid = 1; >>> retvalue = ARCMSR_MESSAGE_FAIL; >>> } else { >>> - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) >>> + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) >>> & (ARCMSR_MAX_QBUFFER - 1); >>> if (my_empty_len >= user_len) { >>> while (user_len > 0) { >>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; >>> - if ((acb->wqbuf_lastindex + user_len) >>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; >>> + if ((acb->wqbuf_putIndex + user_len) >>> > ARCMSR_MAX_QBUFFER) { >>> memcpy(pQbuffer, ptmpuserbuffer, >>> ARCMSR_MAX_QBUFFER - >>> - acb->wqbuf_lastindex); >>> + acb->wqbuf_putIndex); >>> ptmpuserbuffer += >>> (ARCMSR_MAX_QBUFFER >>> - - acb->wqbuf_lastindex); >>> + - acb->wqbuf_putIndex); >>> user_len -= (ARCMSR_MAX_QBUFFER >>> - - acb->wqbuf_lastindex); >>> - acb->wqbuf_lastindex = 0; >>> + - acb->wqbuf_putIndex); >>> + acb->wqbuf_putIndex = 0; >>> } else { >>> memcpy(pQbuffer, ptmpuserbuffer, >>> user_len); >>> - acb->wqbuf_lastindex += user_len; >>> - acb->wqbuf_lastindex %= >>> + acb->wqbuf_putIndex += user_len; >>> + acb->wqbuf_putIndex %= >>> ARCMSR_MAX_QBUFFER; >>> user_len = 0; >>> } >>> @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc >>> 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->rqbuf_getIndex = 0; >>> + acb->rqbuf_putIndex = 0; >>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); >>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); >>> if (acb->fw_flag == FW_DEADLOCK) >>> @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc >>> 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; >>> + acb->wqbuf_getIndex = 0; >>> + acb->wqbuf_putIndex = 0; >>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>> if (acb->fw_flag == FW_DEADLOCK) >>> @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc >>> 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->rqbuf_getIndex = 0; >>> + acb->rqbuf_putIndex = 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; >>> + acb->wqbuf_getIndex = 0; >>> + acb->wqbuf_putIndex = 0; >>> pQbuffer = acb->wqbuffer; >>> memset(pQbuffer, 0, sizeof(struct QBUFFER)); >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>> >>> >>> >>> -- >>> 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 > > -- > 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 2014-08-26 13:20 ` Tomas Henzl @ 2014-08-27 20:19 ` Ching Huang 2014-08-27 12:29 ` Tomas Henzl 0 siblings, 1 reply; 10+ messages in thread From: Ching Huang @ 2014-08-27 20:19 UTC (permalink / raw) To: Tomas Henzl Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On Tue, 2014-08-26 at 15:20 +0200, Tomas Henzl wrote: > On 08/26/2014 10:27 PM, Ching Huang wrote: > > On Mon, 2014-08-25 at 12:29 +0200, Tomas Henzl wrote: > >> On 08/25/2014 07:59 PM, Ching Huang wrote: > >>> On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: > >>>> 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 ? > >>>> > >>> NO. We have to check the input buffer that may have message data come > >>> from IOP. > >>>>> 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? > >>>> > >>> Yes, there copying data from a ring buffer. firstindex and lastindex are > >>> bad name. For readability, I rename the firstindex to getIndex, > >>> lastindex to putIndex. > >> My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' > >> you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. > >> Is this correct? > > The firstindex is a get index and lastindex is a put index of a ring buffer. > > At here, firstindex > lastindex, so the data remain in buffer are (ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex > > Yes, it's correct, I misinterpreted the from value with the amount of bytes to copy. > But well it's also still overcomplicated and I believe that a copy like this could be > rearranged with just few lines of code as a result - have you looked at the code I sent? > > Let's go with this patch as it is otherwise we will never end, repost is not needed because > of this and also not because of arcmsr_Read_iop_rqbuffer_in_DWORD. > > I'll continue with reviewing the remaining patches. > > tomas > I have test the code you sent. It works. I will modify the code by your idea, then send the patch. Thanks, Ching > > > >>>> 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. > >>> 1032 is the API data buffer limitation. > >>>> 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 > >>> This patch is relative to branch: > >>> > >>> git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 > >>> > >>> change log: > >>> 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to > >>> rqbuf_putIndex. > >>> 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to > >>> wqbuf_putIndex. > >>> 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN > >>> 4. remove a NULL pointer checking before kfree. > >>> > >>> 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-08-21 12:14:27.000000000 +0800 > >>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 > >>> @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ > >>> /* do message unit read. */ > >>> ptmpQbuffer = (uint8_t *)buf; > >>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); > >>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > >>> - 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; > >>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > >>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > >>> + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>> } else { > >>> - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) > >>> - + acb->rqbuf_lastindex) > 1032) { > >>> + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) > >>> + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > >>> memcpy(ptmpQbuffer, pQbuffer, > >>> ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex); > >>> + - acb->rqbuf_getIndex); > >>> ptmpQbuffer += ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex; > >>> - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 > >>> + - acb->rqbuf_getIndex; > >>> + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN > >>> - (ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex)); > >>> - acb->rqbuf_firstindex = 1032 - > >>> + acb->rqbuf_getIndex)); > >>> + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - > >>> (ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex); > >>> - allxfer_len = 1032; > >>> + acb->rqbuf_getIndex); > >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>> } else { > >>> memcpy(ptmpQbuffer, pQbuffer, > >>> ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex); > >>> + acb->rqbuf_getIndex); > >>> ptmpQbuffer += ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex; > >>> + acb->rqbuf_getIndex; > >>> memcpy(ptmpQbuffer, acb->rqbuffer, > >>> - acb->rqbuf_lastindex); > >>> + acb->rqbuf_putIndex); > >>> allxfer_len = ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex + > >>> - acb->rqbuf_lastindex; > >>> - acb->rqbuf_firstindex = > >>> - acb->rqbuf_lastindex; > >>> + acb->rqbuf_getIndex + > >>> + acb->rqbuf_putIndex; > >>> + acb->rqbuf_getIndex = > >>> + acb->rqbuf_putIndex; > >>> } > >>> } > >>> } else { > >>> - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { > >>> - memcpy(ptmpQbuffer, pQbuffer, 1032); > >>> - acb->rqbuf_firstindex += 1032; > >>> - allxfer_len = 1032; > >>> + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>> } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex > >>> + - acb->rqbuf_getIndex); > >>> + allxfer_len = acb->rqbuf_putIndex - > >>> + acb->rqbuf_getIndex; > >>> + acb->rqbuf_getIndex = acb->rqbuf_putIndex; > >>> } > >>> } > >>> } > >>> @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ > >>> struct device *dev = container_of(kobj,struct device,kobj); > >>> struct Scsi_Host *host = class_to_shost(dev); > >>> struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; > >>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > >>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > >>> uint8_t *pQbuffer, *ptmpuserbuffer; > >>> unsigned long flags; > >>> > >>> if (!capable(CAP_SYS_ADMIN)) > >>> return -EACCES; > >>> - if (count > 1032) > >>> + if (count > ARCMSR_API_DATA_BUFLEN) > >>> return -EINVAL; > >>> /* 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) { > >>> + wqbuf_putIndex = acb->wqbuf_putIndex; > >>> + wqbuf_getIndex = acb->wqbuf_getIndex; > >>> + if (wqbuf_putIndex != wqbuf_getIndex) { > >>> arcmsr_write_ioctldata2iop(acb); > >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>> return 0; /*need retry*/ > >>> } else { > >>> - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) > >>> + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; > >>> memcpy(pQbuffer, ptmpuserbuffer, 1); > >>> - acb->wqbuf_lastindex++; > >>> - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > >>> + acb->wqbuf_putIndex++; > >>> + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > >>> ptmpuserbuffer++; > >>> user_len--; > >>> } > >>> @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ > >>> | 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; > >>> + acb->rqbuf_getIndex = 0; > >>> + acb->rqbuf_putIndex = 0; > >>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > >>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); > >>> - acb->wqbuf_firstindex = 0; > >>> - acb->wqbuf_lastindex = 0; > >>> + acb->wqbuf_getIndex = 0; > >>> + acb->wqbuf_putIndex = 0; > >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>> pQbuffer = acb->rqbuffer; > >>> memset(pQbuffer, 0, sizeof (struct QBUFFER)); > >>> @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs > >>> .name = "mu_read", > >>> .mode = S_IRUSR , > >>> }, > >>> - .size = 1032, > >>> + .size = ARCMSR_API_DATA_BUFLEN, > >>> .read = arcmsr_sysfs_iop_message_read, > >>> }; > >>> > >>> @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs > >>> .name = "mu_write", > >>> .mode = S_IWUSR, > >>> }, > >>> - .size = 1032, > >>> + .size = ARCMSR_API_DATA_BUFLEN, > >>> .write = arcmsr_sysfs_iop_message_write, > >>> }; > >>> > >>> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h > >>> --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 > >>> +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 > >>> @@ -107,10 +107,11 @@ struct CMD_MESSAGE > >>> ** IOP Message Transfer Data for user space > >>> ******************************************************************************* > >>> */ > >>> +#define ARCMSR_API_DATA_BUFLEN 1032 > >>> struct CMD_MESSAGE_FIELD > >>> { > >>> struct CMD_MESSAGE cmdmessage; > >>> - uint8_t messagedatabuffer[1032]; > >>> + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; > >>> }; > >>> /* IOP message transfer */ > >>> #define ARCMSR_MESSAGE_FAIL 0x0001 > >>> @@ -678,15 +679,15 @@ struct AdapterControlBlock > >>> unsigned int uncache_size; > >>> uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; > >>> /* data collection buffer for read from 80331 */ > >>> - int32_t rqbuf_firstindex; > >>> + int32_t rqbuf_getIndex; > >>> /* first of read buffer */ > >>> - int32_t rqbuf_lastindex; > >>> + int32_t rqbuf_putIndex; > >>> /* last of read buffer */ > >>> uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; > >>> /* data collection buffer for write to 80331 */ > >>> - int32_t wqbuf_firstindex; > >>> + int32_t wqbuf_getIndex; > >>> /* first of write buffer */ > >>> - int32_t wqbuf_lastindex; > >>> + int32_t wqbuf_putIndex; > >>> /* last of write buffer */ > >>> uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; > >>> /* id0 ..... id15, lun0...lun7 */ > >>> 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-21 12:14:27.000000000 +0800 > >>> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 > >>> @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct > >>> buf2 = (uint32_t *)buf1; > >>> } > >>> while (iop_len > 0) { > >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > >>> *pQbuffer = *buf1; > >>> - acb->rqbuf_lastindex++; > >>> + acb->rqbuf_putIndex++; > >>> /* if last, index number set it to 0 */ > >>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > >>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > >>> buf1++; > >>> iop_len--; > >>> } > >>> - if (buf2) > >>> - kfree(buf2); > >>> + kfree(buf2); > >>> /* let IOP know data has been read */ > >>> arcmsr_iop_message_read(acb); > >>> return 1; > >>> @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada > >>> iop_data = (uint8_t __iomem *)prbuffer->data; > >>> iop_len = readl(&prbuffer->data_len); > >>> while (iop_len > 0) { > >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > >>> *pQbuffer = readb(iop_data); > >>> - acb->rqbuf_lastindex++; > >>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > >>> + acb->rqbuf_putIndex++; > >>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > >>> iop_data++; > >>> iop_len--; > >>> } > >>> @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha > >>> > >>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); > >>> prbuffer = arcmsr_get_iop_rqbuffer(acb); > >>> - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & > >>> + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & > >>> (ARCMSR_MAX_QBUFFER - 1); > >>> if (buf_empty_len >= readl(&prbuffer->data_len)) { > >>> if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) > >>> @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i > >>> 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) > >>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > >>> && (allxfer_len < 124)) { > >>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > >>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > >>> *buf1 = *pQbuffer; > >>> - acb->wqbuf_firstindex++; > >>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > >>> + acb->wqbuf_getIndex++; > >>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>> buf1++; > >>> allxfer_len++; > >>> } > >>> @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte > >>> 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) > >>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > >>> && (allxfer_len < 124)) { > >>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > >>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > >>> writeb(*pQbuffer, iop_data); > >>> - acb->wqbuf_firstindex++; > >>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > >>> + acb->wqbuf_getIndex++; > >>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>> iop_data++; > >>> allxfer_len++; > >>> } > >>> @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han > >>> > >>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); > >>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; > >>> - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) > >>> + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) > >>> arcmsr_write_ioctldata2iop(acb); > >>> - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) > >>> + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) > >>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; > >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>> } > >>> @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( > >>> 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; > >>> + acb->rqbuf_getIndex = 0; > >>> + acb->rqbuf_putIndex = 0; > >>> arcmsr_iop_message_read(acb); > >>> mdelay(30); > >>> - } else if (acb->rqbuf_firstindex != > >>> - acb->rqbuf_lastindex) { > >>> - acb->rqbuf_firstindex = 0; > >>> - acb->rqbuf_lastindex = 0; > >>> + } else if (acb->rqbuf_getIndex != > >>> + acb->rqbuf_putIndex) { > >>> + acb->rqbuf_getIndex = 0; > >>> + acb->rqbuf_putIndex = 0; > >>> mdelay(30); > >>> } else > >>> break; > >>> @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc > >>> unsigned char *ver_addr; > >>> uint8_t *pQbuffer, *ptmpQbuffer; > >>> uint32_t allxfer_len = 0; > >>> - ver_addr = kmalloc(1032, GFP_ATOMIC); > >>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > >>> if (!ver_addr) { > >>> retvalue = ARCMSR_MESSAGE_FAIL; > >>> pr_info("%s: memory not enough!\n", __func__); > >>> @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc > >>> } > >>> ptmpQbuffer = ver_addr; > >>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); > >>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > >>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > >>> - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { > >>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > >>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > >>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > >>> 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; > >>> + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>> } else { > >>> if (((ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex) + > >>> - acb->rqbuf_lastindex) > 1032) { > >>> + acb->rqbuf_getIndex) + > >>> + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > >>> memcpy(ptmpQbuffer, > >>> pQbuffer, ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex); > >>> + - acb->rqbuf_getIndex); > >>> ptmpQbuffer += > >>> ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex; > >>> + acb->rqbuf_getIndex; > >>> memcpy(ptmpQbuffer, > >>> - acb->rqbuffer, 1032 - > >>> + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - > >>> (ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex)); > >>> - acb->rqbuf_firstindex = > >>> - 1032 - (ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex); > >>> - allxfer_len = 1032; > >>> + - acb->rqbuf_getIndex)); > >>> + acb->rqbuf_getIndex = > >>> + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER > >>> + - acb->rqbuf_getIndex); > >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>> } else { > >>> memcpy(ptmpQbuffer, > >>> pQbuffer, ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex); > >>> + - acb->rqbuf_getIndex); > >>> ptmpQbuffer += > >>> ARCMSR_MAX_QBUFFER - > >>> - acb->rqbuf_firstindex; > >>> + acb->rqbuf_getIndex; > >>> memcpy(ptmpQbuffer, > >>> acb->rqbuffer, > >>> - acb->rqbuf_lastindex); > >>> + acb->rqbuf_putIndex); > >>> allxfer_len = ARCMSR_MAX_QBUFFER > >>> - - acb->rqbuf_firstindex + > >>> - acb->rqbuf_lastindex; > >>> - acb->rqbuf_firstindex = > >>> - acb->rqbuf_lastindex; > >>> + - acb->rqbuf_getIndex + > >>> + acb->rqbuf_putIndex; > >>> + acb->rqbuf_getIndex = > >>> + acb->rqbuf_putIndex; > >>> } > >>> } > >>> } else { > >>> - if ((acb->rqbuf_lastindex - > >>> - acb->rqbuf_firstindex) > 1032) { > >>> - memcpy(ptmpQbuffer, pQbuffer, 1032); > >>> - acb->rqbuf_firstindex += 1032; > >>> - allxfer_len = 1032; > >>> + if ((acb->rqbuf_putIndex - > >>> + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > >>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>> } else { > >>> memcpy(ptmpQbuffer, pQbuffer, > >>> - acb->rqbuf_lastindex - > >>> - acb->rqbuf_firstindex); > >>> - allxfer_len = acb->rqbuf_lastindex > >>> - - acb->rqbuf_firstindex; > >>> - acb->rqbuf_firstindex = > >>> - acb->rqbuf_lastindex; > >>> + acb->rqbuf_putIndex - > >>> + acb->rqbuf_getIndex); > >>> + allxfer_len = acb->rqbuf_putIndex > >>> + - acb->rqbuf_getIndex; > >>> + acb->rqbuf_getIndex = > >>> + acb->rqbuf_putIndex; > >>> } > >>> } > >>> } > >>> @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc > >>> } > >>> case ARCMSR_MESSAGE_WRITE_WQBUFFER: { > >>> unsigned char *ver_addr; > >>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > >>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > >>> uint8_t *pQbuffer, *ptmpuserbuffer; > >>> - ver_addr = kmalloc(1032, GFP_ATOMIC); > >>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > >>> if (!ver_addr) { > >>> retvalue = ARCMSR_MESSAGE_FAIL; > >>> goto message_out; > >>> @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc > >>> 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) { > >>> + wqbuf_putIndex = acb->wqbuf_putIndex; > >>> + wqbuf_getIndex = acb->wqbuf_getIndex; > >>> + if (wqbuf_putIndex != wqbuf_getIndex) { > >>> struct SENSE_DATA *sensebuffer = > >>> (struct SENSE_DATA *)cmd->sense_buffer; > >>> arcmsr_write_ioctldata2iop(acb); > >>> @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc > >>> sensebuffer->Valid = 1; > >>> retvalue = ARCMSR_MESSAGE_FAIL; > >>> } else { > >>> - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) > >>> + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) > >>> & (ARCMSR_MAX_QBUFFER - 1); > >>> if (my_empty_len >= user_len) { > >>> while (user_len > 0) { > >>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; > >>> - if ((acb->wqbuf_lastindex + user_len) > >>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; > >>> + if ((acb->wqbuf_putIndex + user_len) > >>> > ARCMSR_MAX_QBUFFER) { > >>> memcpy(pQbuffer, ptmpuserbuffer, > >>> ARCMSR_MAX_QBUFFER - > >>> - acb->wqbuf_lastindex); > >>> + acb->wqbuf_putIndex); > >>> ptmpuserbuffer += > >>> (ARCMSR_MAX_QBUFFER > >>> - - acb->wqbuf_lastindex); > >>> + - acb->wqbuf_putIndex); > >>> user_len -= (ARCMSR_MAX_QBUFFER > >>> - - acb->wqbuf_lastindex); > >>> - acb->wqbuf_lastindex = 0; > >>> + - acb->wqbuf_putIndex); > >>> + acb->wqbuf_putIndex = 0; > >>> } else { > >>> memcpy(pQbuffer, ptmpuserbuffer, > >>> user_len); > >>> - acb->wqbuf_lastindex += user_len; > >>> - acb->wqbuf_lastindex %= > >>> + acb->wqbuf_putIndex += user_len; > >>> + acb->wqbuf_putIndex %= > >>> ARCMSR_MAX_QBUFFER; > >>> user_len = 0; > >>> } > >>> @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc > >>> 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->rqbuf_getIndex = 0; > >>> + acb->rqbuf_putIndex = 0; > >>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > >>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > >>> if (acb->fw_flag == FW_DEADLOCK) > >>> @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc > >>> 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; > >>> + acb->wqbuf_getIndex = 0; > >>> + acb->wqbuf_putIndex = 0; > >>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>> if (acb->fw_flag == FW_DEADLOCK) > >>> @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc > >>> 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->rqbuf_getIndex = 0; > >>> + acb->rqbuf_putIndex = 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; > >>> + acb->wqbuf_getIndex = 0; > >>> + acb->wqbuf_putIndex = 0; > >>> pQbuffer = acb->wqbuffer; > >>> memset(pQbuffer, 0, sizeof(struct QBUFFER)); > >>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>> > >>> > >>> > >>> -- > >>> 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 > > > > -- > > 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 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 2014-08-27 20:19 ` Ching Huang @ 2014-08-27 12:29 ` Tomas Henzl 2014-08-28 11:40 ` Ching Huang 0 siblings, 1 reply; 10+ messages in thread From: Tomas Henzl @ 2014-08-27 12:29 UTC (permalink / raw) To: Ching Huang Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On 08/27/2014 10:19 PM, Ching Huang wrote: > On Tue, 2014-08-26 at 15:20 +0200, Tomas Henzl wrote: >> On 08/26/2014 10:27 PM, Ching Huang wrote: >>> On Mon, 2014-08-25 at 12:29 +0200, Tomas Henzl wrote: >>>> On 08/25/2014 07:59 PM, Ching Huang wrote: >>>>> On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: >>>>>> 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 ? >>>>>> >>>>> NO. We have to check the input buffer that may have message data come >>>>> from IOP. >>>>>>> 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? >>>>>> >>>>> Yes, there copying data from a ring buffer. firstindex and lastindex are >>>>> bad name. For readability, I rename the firstindex to getIndex, >>>>> lastindex to putIndex. >>>> My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' >>>> you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. >>>> Is this correct? >>> The firstindex is a get index and lastindex is a put index of a ring buffer. >>> At here, firstindex > lastindex, so the data remain in buffer are (ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex >> Yes, it's correct, I misinterpreted the from value with the amount of bytes to copy. >> But well it's also still overcomplicated and I believe that a copy like this could be >> rearranged with just few lines of code as a result - have you looked at the code I sent? >> >> Let's go with this patch as it is otherwise we will never end, repost is not needed because >> of this and also not because of arcmsr_Read_iop_rqbuffer_in_DWORD. >> >> I'll continue with reviewing the remaining patches. >> >> tomas >> > I have test the code you sent. It works. > I will modify the code by your idea, then send the patch. I think that after so many repost, and because it is not a fix, wait till we get this series in and post a new patch later. Btw. a similar copying is in arcmsr_iop_message_xfer too, and whet you want rename the fields in your ring buffer, please use the more usual names 'head+tail'. Conclusion - post nothing right now, let the changes go in in a new patch. tomash > > Thanks, > Ching >>>>>> 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. >>>>> 1032 is the API data buffer limitation. >>>>>> 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 >>>>> This patch is relative to branch: >>>>> >>>>> git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 >>>>> >>>>> change log: >>>>> 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to >>>>> rqbuf_putIndex. >>>>> 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to >>>>> wqbuf_putIndex. >>>>> 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN >>>>> 4. remove a NULL pointer checking before kfree. >>>>> >>>>> 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-08-21 12:14:27.000000000 +0800 >>>>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 >>>>> @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ >>>>> /* do message unit read. */ >>>>> ptmpQbuffer = (uint8_t *)buf; >>>>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >>>>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; >>>>> - 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; >>>>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; >>>>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { >>>>> + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>>>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>>>> } else { >>>>> - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) >>>>> - + acb->rqbuf_lastindex) > 1032) { >>>>> + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >>>>> + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { >>>>> memcpy(ptmpQbuffer, pQbuffer, >>>>> ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex); >>>>> + - acb->rqbuf_getIndex); >>>>> ptmpQbuffer += ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex; >>>>> - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 >>>>> + - acb->rqbuf_getIndex; >>>>> + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN >>>>> - (ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex)); >>>>> - acb->rqbuf_firstindex = 1032 - >>>>> + acb->rqbuf_getIndex)); >>>>> + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - >>>>> (ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex); >>>>> - allxfer_len = 1032; >>>>> + acb->rqbuf_getIndex); >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>>>> } else { >>>>> memcpy(ptmpQbuffer, pQbuffer, >>>>> ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex); >>>>> + acb->rqbuf_getIndex); >>>>> ptmpQbuffer += ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex; >>>>> + acb->rqbuf_getIndex; >>>>> memcpy(ptmpQbuffer, acb->rqbuffer, >>>>> - acb->rqbuf_lastindex); >>>>> + acb->rqbuf_putIndex); >>>>> allxfer_len = ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex + >>>>> - acb->rqbuf_lastindex; >>>>> - acb->rqbuf_firstindex = >>>>> - acb->rqbuf_lastindex; >>>>> + acb->rqbuf_getIndex + >>>>> + acb->rqbuf_putIndex; >>>>> + acb->rqbuf_getIndex = >>>>> + acb->rqbuf_putIndex; >>>>> } >>>>> } >>>>> } else { >>>>> - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { >>>>> - memcpy(ptmpQbuffer, pQbuffer, 1032); >>>>> - acb->rqbuf_firstindex += 1032; >>>>> - allxfer_len = 1032; >>>>> + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>>>> } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex >>>>> + - acb->rqbuf_getIndex); >>>>> + allxfer_len = acb->rqbuf_putIndex - >>>>> + acb->rqbuf_getIndex; >>>>> + acb->rqbuf_getIndex = acb->rqbuf_putIndex; >>>>> } >>>>> } >>>>> } >>>>> @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ >>>>> struct device *dev = container_of(kobj,struct device,kobj); >>>>> struct Scsi_Host *host = class_to_shost(dev); >>>>> struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; >>>>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; >>>>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; >>>>> uint8_t *pQbuffer, *ptmpuserbuffer; >>>>> unsigned long flags; >>>>> >>>>> if (!capable(CAP_SYS_ADMIN)) >>>>> return -EACCES; >>>>> - if (count > 1032) >>>>> + if (count > ARCMSR_API_DATA_BUFLEN) >>>>> return -EINVAL; >>>>> /* 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) { >>>>> + wqbuf_putIndex = acb->wqbuf_putIndex; >>>>> + wqbuf_getIndex = acb->wqbuf_getIndex; >>>>> + if (wqbuf_putIndex != wqbuf_getIndex) { >>>>> arcmsr_write_ioctldata2iop(acb); >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>>>> return 0; /*need retry*/ >>>>> } else { >>>>> - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) >>>>> + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; >>>>> memcpy(pQbuffer, ptmpuserbuffer, 1); >>>>> - acb->wqbuf_lastindex++; >>>>> - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >>>>> + acb->wqbuf_putIndex++; >>>>> + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >>>>> ptmpuserbuffer++; >>>>> user_len--; >>>>> } >>>>> @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ >>>>> | 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; >>>>> + acb->rqbuf_getIndex = 0; >>>>> + acb->rqbuf_putIndex = 0; >>>>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); >>>>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); >>>>> - acb->wqbuf_firstindex = 0; >>>>> - acb->wqbuf_lastindex = 0; >>>>> + acb->wqbuf_getIndex = 0; >>>>> + acb->wqbuf_putIndex = 0; >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>>>> pQbuffer = acb->rqbuffer; >>>>> memset(pQbuffer, 0, sizeof (struct QBUFFER)); >>>>> @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs >>>>> .name = "mu_read", >>>>> .mode = S_IRUSR , >>>>> }, >>>>> - .size = 1032, >>>>> + .size = ARCMSR_API_DATA_BUFLEN, >>>>> .read = arcmsr_sysfs_iop_message_read, >>>>> }; >>>>> >>>>> @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs >>>>> .name = "mu_write", >>>>> .mode = S_IWUSR, >>>>> }, >>>>> - .size = 1032, >>>>> + .size = ARCMSR_API_DATA_BUFLEN, >>>>> .write = arcmsr_sysfs_iop_message_write, >>>>> }; >>>>> >>>>> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h >>>>> --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 >>>>> +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 >>>>> @@ -107,10 +107,11 @@ struct CMD_MESSAGE >>>>> ** IOP Message Transfer Data for user space >>>>> ******************************************************************************* >>>>> */ >>>>> +#define ARCMSR_API_DATA_BUFLEN 1032 >>>>> struct CMD_MESSAGE_FIELD >>>>> { >>>>> struct CMD_MESSAGE cmdmessage; >>>>> - uint8_t messagedatabuffer[1032]; >>>>> + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; >>>>> }; >>>>> /* IOP message transfer */ >>>>> #define ARCMSR_MESSAGE_FAIL 0x0001 >>>>> @@ -678,15 +679,15 @@ struct AdapterControlBlock >>>>> unsigned int uncache_size; >>>>> uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; >>>>> /* data collection buffer for read from 80331 */ >>>>> - int32_t rqbuf_firstindex; >>>>> + int32_t rqbuf_getIndex; >>>>> /* first of read buffer */ >>>>> - int32_t rqbuf_lastindex; >>>>> + int32_t rqbuf_putIndex; >>>>> /* last of read buffer */ >>>>> uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; >>>>> /* data collection buffer for write to 80331 */ >>>>> - int32_t wqbuf_firstindex; >>>>> + int32_t wqbuf_getIndex; >>>>> /* first of write buffer */ >>>>> - int32_t wqbuf_lastindex; >>>>> + int32_t wqbuf_putIndex; >>>>> /* last of write buffer */ >>>>> uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; >>>>> /* id0 ..... id15, lun0...lun7 */ >>>>> 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-21 12:14:27.000000000 +0800 >>>>> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 >>>>> @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct >>>>> buf2 = (uint32_t *)buf1; >>>>> } >>>>> while (iop_len > 0) { >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; >>>>> *pQbuffer = *buf1; >>>>> - acb->rqbuf_lastindex++; >>>>> + acb->rqbuf_putIndex++; >>>>> /* if last, index number set it to 0 */ >>>>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >>>>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >>>>> buf1++; >>>>> iop_len--; >>>>> } >>>>> - if (buf2) >>>>> - kfree(buf2); >>>>> + kfree(buf2); >>>>> /* let IOP know data has been read */ >>>>> arcmsr_iop_message_read(acb); >>>>> return 1; >>>>> @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada >>>>> iop_data = (uint8_t __iomem *)prbuffer->data; >>>>> iop_len = readl(&prbuffer->data_len); >>>>> while (iop_len > 0) { >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; >>>>> *pQbuffer = readb(iop_data); >>>>> - acb->rqbuf_lastindex++; >>>>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; >>>>> + acb->rqbuf_putIndex++; >>>>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; >>>>> iop_data++; >>>>> iop_len--; >>>>> } >>>>> @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha >>>>> >>>>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >>>>> prbuffer = arcmsr_get_iop_rqbuffer(acb); >>>>> - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & >>>>> + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & >>>>> (ARCMSR_MAX_QBUFFER - 1); >>>>> if (buf_empty_len >= readl(&prbuffer->data_len)) { >>>>> if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) >>>>> @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i >>>>> 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) >>>>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) >>>>> && (allxfer_len < 124)) { >>>>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; >>>>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; >>>>> *buf1 = *pQbuffer; >>>>> - acb->wqbuf_firstindex++; >>>>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; >>>>> + acb->wqbuf_getIndex++; >>>>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>>>> buf1++; >>>>> allxfer_len++; >>>>> } >>>>> @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte >>>>> 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) >>>>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) >>>>> && (allxfer_len < 124)) { >>>>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; >>>>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; >>>>> writeb(*pQbuffer, iop_data); >>>>> - acb->wqbuf_firstindex++; >>>>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; >>>>> + acb->wqbuf_getIndex++; >>>>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>>>> iop_data++; >>>>> allxfer_len++; >>>>> } >>>>> @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han >>>>> >>>>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); >>>>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; >>>>> - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) >>>>> + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) >>>>> arcmsr_write_ioctldata2iop(acb); >>>>> - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) >>>>> + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) >>>>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>>>> } >>>>> @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( >>>>> 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; >>>>> + acb->rqbuf_getIndex = 0; >>>>> + acb->rqbuf_putIndex = 0; >>>>> arcmsr_iop_message_read(acb); >>>>> mdelay(30); >>>>> - } else if (acb->rqbuf_firstindex != >>>>> - acb->rqbuf_lastindex) { >>>>> - acb->rqbuf_firstindex = 0; >>>>> - acb->rqbuf_lastindex = 0; >>>>> + } else if (acb->rqbuf_getIndex != >>>>> + acb->rqbuf_putIndex) { >>>>> + acb->rqbuf_getIndex = 0; >>>>> + acb->rqbuf_putIndex = 0; >>>>> mdelay(30); >>>>> } else >>>>> break; >>>>> @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc >>>>> unsigned char *ver_addr; >>>>> uint8_t *pQbuffer, *ptmpQbuffer; >>>>> uint32_t allxfer_len = 0; >>>>> - ver_addr = kmalloc(1032, GFP_ATOMIC); >>>>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); >>>>> if (!ver_addr) { >>>>> retvalue = ARCMSR_MESSAGE_FAIL; >>>>> pr_info("%s: memory not enough!\n", __func__); >>>>> @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc >>>>> } >>>>> ptmpQbuffer = ver_addr; >>>>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); >>>>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; >>>>> - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { >>>>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; >>>>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { >>>>> 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; >>>>> + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>>>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>>>> } else { >>>>> if (((ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex) + >>>>> - acb->rqbuf_lastindex) > 1032) { >>>>> + acb->rqbuf_getIndex) + >>>>> + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { >>>>> memcpy(ptmpQbuffer, >>>>> pQbuffer, ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex); >>>>> + - acb->rqbuf_getIndex); >>>>> ptmpQbuffer += >>>>> ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex; >>>>> + acb->rqbuf_getIndex; >>>>> memcpy(ptmpQbuffer, >>>>> - acb->rqbuffer, 1032 - >>>>> + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - >>>>> (ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex)); >>>>> - acb->rqbuf_firstindex = >>>>> - 1032 - (ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex); >>>>> - allxfer_len = 1032; >>>>> + - acb->rqbuf_getIndex)); >>>>> + acb->rqbuf_getIndex = >>>>> + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER >>>>> + - acb->rqbuf_getIndex); >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>>>> } else { >>>>> memcpy(ptmpQbuffer, >>>>> pQbuffer, ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex); >>>>> + - acb->rqbuf_getIndex); >>>>> ptmpQbuffer += >>>>> ARCMSR_MAX_QBUFFER - >>>>> - acb->rqbuf_firstindex; >>>>> + acb->rqbuf_getIndex; >>>>> memcpy(ptmpQbuffer, >>>>> acb->rqbuffer, >>>>> - acb->rqbuf_lastindex); >>>>> + acb->rqbuf_putIndex); >>>>> allxfer_len = ARCMSR_MAX_QBUFFER >>>>> - - acb->rqbuf_firstindex + >>>>> - acb->rqbuf_lastindex; >>>>> - acb->rqbuf_firstindex = >>>>> - acb->rqbuf_lastindex; >>>>> + - acb->rqbuf_getIndex + >>>>> + acb->rqbuf_putIndex; >>>>> + acb->rqbuf_getIndex = >>>>> + acb->rqbuf_putIndex; >>>>> } >>>>> } >>>>> } else { >>>>> - if ((acb->rqbuf_lastindex - >>>>> - acb->rqbuf_firstindex) > 1032) { >>>>> - memcpy(ptmpQbuffer, pQbuffer, 1032); >>>>> - acb->rqbuf_firstindex += 1032; >>>>> - allxfer_len = 1032; >>>>> + if ((acb->rqbuf_putIndex - >>>>> + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; >>>>> } else { >>>>> memcpy(ptmpQbuffer, pQbuffer, >>>>> - acb->rqbuf_lastindex - >>>>> - acb->rqbuf_firstindex); >>>>> - allxfer_len = acb->rqbuf_lastindex >>>>> - - acb->rqbuf_firstindex; >>>>> - acb->rqbuf_firstindex = >>>>> - acb->rqbuf_lastindex; >>>>> + acb->rqbuf_putIndex - >>>>> + acb->rqbuf_getIndex); >>>>> + allxfer_len = acb->rqbuf_putIndex >>>>> + - acb->rqbuf_getIndex; >>>>> + acb->rqbuf_getIndex = >>>>> + acb->rqbuf_putIndex; >>>>> } >>>>> } >>>>> } >>>>> @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc >>>>> } >>>>> case ARCMSR_MESSAGE_WRITE_WQBUFFER: { >>>>> unsigned char *ver_addr; >>>>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; >>>>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; >>>>> uint8_t *pQbuffer, *ptmpuserbuffer; >>>>> - ver_addr = kmalloc(1032, GFP_ATOMIC); >>>>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); >>>>> if (!ver_addr) { >>>>> retvalue = ARCMSR_MESSAGE_FAIL; >>>>> goto message_out; >>>>> @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc >>>>> 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) { >>>>> + wqbuf_putIndex = acb->wqbuf_putIndex; >>>>> + wqbuf_getIndex = acb->wqbuf_getIndex; >>>>> + if (wqbuf_putIndex != wqbuf_getIndex) { >>>>> struct SENSE_DATA *sensebuffer = >>>>> (struct SENSE_DATA *)cmd->sense_buffer; >>>>> arcmsr_write_ioctldata2iop(acb); >>>>> @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc >>>>> sensebuffer->Valid = 1; >>>>> retvalue = ARCMSR_MESSAGE_FAIL; >>>>> } else { >>>>> - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) >>>>> + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) >>>>> & (ARCMSR_MAX_QBUFFER - 1); >>>>> if (my_empty_len >= user_len) { >>>>> while (user_len > 0) { >>>>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; >>>>> - if ((acb->wqbuf_lastindex + user_len) >>>>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; >>>>> + if ((acb->wqbuf_putIndex + user_len) >>>>> > ARCMSR_MAX_QBUFFER) { >>>>> memcpy(pQbuffer, ptmpuserbuffer, >>>>> ARCMSR_MAX_QBUFFER - >>>>> - acb->wqbuf_lastindex); >>>>> + acb->wqbuf_putIndex); >>>>> ptmpuserbuffer += >>>>> (ARCMSR_MAX_QBUFFER >>>>> - - acb->wqbuf_lastindex); >>>>> + - acb->wqbuf_putIndex); >>>>> user_len -= (ARCMSR_MAX_QBUFFER >>>>> - - acb->wqbuf_lastindex); >>>>> - acb->wqbuf_lastindex = 0; >>>>> + - acb->wqbuf_putIndex); >>>>> + acb->wqbuf_putIndex = 0; >>>>> } else { >>>>> memcpy(pQbuffer, ptmpuserbuffer, >>>>> user_len); >>>>> - acb->wqbuf_lastindex += user_len; >>>>> - acb->wqbuf_lastindex %= >>>>> + acb->wqbuf_putIndex += user_len; >>>>> + acb->wqbuf_putIndex %= >>>>> ARCMSR_MAX_QBUFFER; >>>>> user_len = 0; >>>>> } >>>>> @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc >>>>> 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->rqbuf_getIndex = 0; >>>>> + acb->rqbuf_putIndex = 0; >>>>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); >>>>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); >>>>> if (acb->fw_flag == FW_DEADLOCK) >>>>> @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc >>>>> 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; >>>>> + acb->wqbuf_getIndex = 0; >>>>> + acb->wqbuf_putIndex = 0; >>>>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>>>> if (acb->fw_flag == FW_DEADLOCK) >>>>> @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc >>>>> 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->rqbuf_getIndex = 0; >>>>> + acb->rqbuf_putIndex = 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; >>>>> + acb->wqbuf_getIndex = 0; >>>>> + acb->wqbuf_putIndex = 0; >>>>> pQbuffer = acb->wqbuffer; >>>>> memset(pQbuffer, 0, sizeof(struct QBUFFER)); >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); >>>>> >>>>> >>>>> >>>>> -- >>>>> 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 >>> -- >>> 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 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C 2014-08-27 12:29 ` Tomas Henzl @ 2014-08-28 11:40 ` Ching Huang 0 siblings, 0 replies; 10+ messages in thread From: Ching Huang @ 2014-08-28 11:40 UTC (permalink / raw) To: Tomas Henzl Cc: hch, jbottomley, dan.carpenter, agordeev, linux-scsi, linux-kernel On Wed, 2014-08-27 at 14:29 +0200, Tomas Henzl wrote: > On 08/27/2014 10:19 PM, Ching Huang wrote: > > On Tue, 2014-08-26 at 15:20 +0200, Tomas Henzl wrote: > >> On 08/26/2014 10:27 PM, Ching Huang wrote: > >>> On Mon, 2014-08-25 at 12:29 +0200, Tomas Henzl wrote: > >>>> On 08/25/2014 07:59 PM, Ching Huang wrote: > >>>>> On Fri, 2014-08-22 at 18:00 +0200, Tomas Henzl wrote: > >>>>>> 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 ? > >>>>>> > >>>>> NO. We have to check the input buffer that may have message data come > >>>>> from IOP. > >>>>>>> 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? > >>>>>> > >>>>> Yes, there copying data from a ring buffer. firstindex and lastindex are > >>>>> bad name. For readability, I rename the firstindex to getIndex, > >>>>> lastindex to putIndex. > >>>> My comment is not about names, but in this path '(ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex) > 1032)' > >>>> you copy something twice and in both cases the 'firstindex' is used and never the 'lastindex'. > >>>> Is this correct? > >>> The firstindex is a get index and lastindex is a put index of a ring buffer. > >>> At here, firstindex > lastindex, so the data remain in buffer are (ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex)+ acb->rqbuf_lastindex > >> Yes, it's correct, I misinterpreted the from value with the amount of bytes to copy. > >> But well it's also still overcomplicated and I believe that a copy like this could be > >> rearranged with just few lines of code as a result - have you looked at the code I sent? > >> > >> Let's go with this patch as it is otherwise we will never end, repost is not needed because > >> of this and also not because of arcmsr_Read_iop_rqbuffer_in_DWORD. > >> > >> I'll continue with reviewing the remaining patches. > >> > >> tomas > >> > > I have test the code you sent. It works. > > I will modify the code by your idea, then send the patch. > > I think that after so many repost, and because it is not a fix, wait till we get this series in > and post a new patch later. > Btw. a similar copying is in arcmsr_iop_message_xfer too, and whet you want rename the fields > in your ring buffer, please use the more usual names 'head+tail'. > > Conclusion - post nothing right now, let the changes go in in a new patch. > > tomash > Thanks Tomas' reminding, I have already made a modification in arcmsr_iop_message_xfer(). > > > > > Thanks, > > Ching > >>>>>> 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. > >>>>> 1032 is the API data buffer limitation. > >>>>>> 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 > >>>>> This patch is relative to branch: > >>>>> > >>>>> git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18 > >>>>> > >>>>> change log: > >>>>> 1. rename rqbuf_firstindex to rqbuf_getIndex, rqbuf_lastindex to > >>>>> rqbuf_putIndex. > >>>>> 2. rename wqbuf_firstindex to wqbuf_getIndex, wqbuf_lastindex to > >>>>> wqbuf_putIndex. > >>>>> 3. replace 1032 by define ARCMSR_API_DATA_BUFLEN > >>>>> 4. remove a NULL pointer checking before kfree. > >>>>> > >>>>> 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-08-21 12:14:27.000000000 +0800 > >>>>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-08-25 17:24:54.000000000 +0800 > >>>>> @@ -78,55 +78,55 @@ static ssize_t arcmsr_sysfs_iop_message_ > >>>>> /* do message unit read. */ > >>>>> ptmpQbuffer = (uint8_t *)buf; > >>>>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); > >>>>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > >>>>> - 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; > >>>>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > >>>>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > >>>>> + if ((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>>>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>>>> } else { > >>>>> - if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_firstindex) > >>>>> - + acb->rqbuf_lastindex) > 1032) { > >>>>> + if (((ARCMSR_MAX_QBUFFER - acb->rqbuf_getIndex) > >>>>> + + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > >>>>> memcpy(ptmpQbuffer, pQbuffer, > >>>>> ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex); > >>>>> + - acb->rqbuf_getIndex); > >>>>> ptmpQbuffer += ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex; > >>>>> - memcpy(ptmpQbuffer, acb->rqbuffer, 1032 > >>>>> + - acb->rqbuf_getIndex; > >>>>> + memcpy(ptmpQbuffer, acb->rqbuffer, ARCMSR_API_DATA_BUFLEN > >>>>> - (ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex)); > >>>>> - acb->rqbuf_firstindex = 1032 - > >>>>> + acb->rqbuf_getIndex)); > >>>>> + acb->rqbuf_getIndex = ARCMSR_API_DATA_BUFLEN - > >>>>> (ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex); > >>>>> - allxfer_len = 1032; > >>>>> + acb->rqbuf_getIndex); > >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>>>> } else { > >>>>> memcpy(ptmpQbuffer, pQbuffer, > >>>>> ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex); > >>>>> + acb->rqbuf_getIndex); > >>>>> ptmpQbuffer += ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex; > >>>>> + acb->rqbuf_getIndex; > >>>>> memcpy(ptmpQbuffer, acb->rqbuffer, > >>>>> - acb->rqbuf_lastindex); > >>>>> + acb->rqbuf_putIndex); > >>>>> allxfer_len = ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex + > >>>>> - acb->rqbuf_lastindex; > >>>>> - acb->rqbuf_firstindex = > >>>>> - acb->rqbuf_lastindex; > >>>>> + acb->rqbuf_getIndex + > >>>>> + acb->rqbuf_putIndex; > >>>>> + acb->rqbuf_getIndex = > >>>>> + acb->rqbuf_putIndex; > >>>>> } > >>>>> } > >>>>> } else { > >>>>> - if ((acb->rqbuf_lastindex - acb->rqbuf_firstindex) > 1032) { > >>>>> - memcpy(ptmpQbuffer, pQbuffer, 1032); > >>>>> - acb->rqbuf_firstindex += 1032; > >>>>> - allxfer_len = 1032; > >>>>> + if ((acb->rqbuf_putIndex - acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>>>> } 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(ptmpQbuffer, pQbuffer, acb->rqbuf_putIndex > >>>>> + - acb->rqbuf_getIndex); > >>>>> + allxfer_len = acb->rqbuf_putIndex - > >>>>> + acb->rqbuf_getIndex; > >>>>> + acb->rqbuf_getIndex = acb->rqbuf_putIndex; > >>>>> } > >>>>> } - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; - 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->rqbuf_getIndex != acb->rqbuf_putIndex) { + unsigned int tail = acb->rqbuf_getIndex; + unsigned int head = acb->rqbuf_putIndex; + unsigned int cnt_to_end = CIRC_CNT_TO_END(head, tail, ARCMSR_MAX_QBUFFER); + + allxfer_len = CIRC_CNT(head, tail, ARCMSR_MAX_QBUFFER); + if (allxfer_len > ARCMSR_API_DATA_BUFLEN) + allxfer_len = ARCMSR_API_DATA_BUFLEN; + + if (allxfer_len <= cnt_to_end) + memcpy(ptmpQbuffer, acb->rqbuffer + tail, allxfer_len); + else { + memcpy(ptmpQbuffer, acb->rqbuffer + tail, cnt_to_end); + memcpy(ptmpQbuffer + cnt_to_end, acb->rqbuffer, allxfer_len - cnt_to_end); } + acb->rqbuf_getIndex = (acb->rqbuf_getIndex + allxfer_len) % ARCMSR_MAX_QBUFFER; > >>>>> } > >>>>> @@ -150,33 +150,33 @@ static ssize_t arcmsr_sysfs_iop_message_ > >>>>> struct device *dev = container_of(kobj,struct device,kobj); > >>>>> struct Scsi_Host *host = class_to_shost(dev); > >>>>> struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; > >>>>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > >>>>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > >>>>> uint8_t *pQbuffer, *ptmpuserbuffer; > >>>>> unsigned long flags; > >>>>> > >>>>> if (!capable(CAP_SYS_ADMIN)) > >>>>> return -EACCES; > >>>>> - if (count > 1032) > >>>>> + if (count > ARCMSR_API_DATA_BUFLEN) > >>>>> return -EINVAL; > >>>>> /* 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) { > >>>>> + wqbuf_putIndex = acb->wqbuf_putIndex; > >>>>> + wqbuf_getIndex = acb->wqbuf_getIndex; > >>>>> + if (wqbuf_putIndex != wqbuf_getIndex) { > >>>>> arcmsr_write_ioctldata2iop(acb); > >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>>>> return 0; /*need retry*/ > >>>>> } else { > >>>>> - my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) > >>>>> + my_empty_len = (wqbuf_getIndex-wqbuf_putIndex - 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_putIndex]; > >>>>> memcpy(pQbuffer, ptmpuserbuffer, 1); > >>>>> - acb->wqbuf_lastindex++; > >>>>> - acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > >>>>> + acb->wqbuf_putIndex++; > >>>>> + acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > >>>>> ptmpuserbuffer++; > >>>>> user_len--; > >>>>> } > >>>>> @@ -215,12 +215,12 @@ static ssize_t arcmsr_sysfs_iop_message_ > >>>>> | 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; > >>>>> + acb->rqbuf_getIndex = 0; > >>>>> + acb->rqbuf_putIndex = 0; > >>>>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > >>>>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); > >>>>> - acb->wqbuf_firstindex = 0; > >>>>> - acb->wqbuf_lastindex = 0; > >>>>> + acb->wqbuf_getIndex = 0; > >>>>> + acb->wqbuf_putIndex = 0; > >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>>>> pQbuffer = acb->rqbuffer; > >>>>> memset(pQbuffer, 0, sizeof (struct QBUFFER)); > >>>>> @@ -234,7 +234,7 @@ static struct bin_attribute arcmsr_sysfs > >>>>> .name = "mu_read", > >>>>> .mode = S_IRUSR , > >>>>> }, > >>>>> - .size = 1032, > >>>>> + .size = ARCMSR_API_DATA_BUFLEN, > >>>>> .read = arcmsr_sysfs_iop_message_read, > >>>>> }; > >>>>> > >>>>> @@ -243,7 +243,7 @@ static struct bin_attribute arcmsr_sysfs > >>>>> .name = "mu_write", > >>>>> .mode = S_IWUSR, > >>>>> }, > >>>>> - .size = 1032, > >>>>> + .size = ARCMSR_API_DATA_BUFLEN, > >>>>> .write = arcmsr_sysfs_iop_message_write, > >>>>> }; > >>>>> > >>>>> diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h > >>>>> --- a/drivers/scsi/arcmsr/arcmsr.h 2014-08-21 12:14:27.000000000 +0800 > >>>>> +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-08-25 17:25:20.000000000 +0800 > >>>>> @@ -107,10 +107,11 @@ struct CMD_MESSAGE > >>>>> ** IOP Message Transfer Data for user space > >>>>> ******************************************************************************* > >>>>> */ > >>>>> +#define ARCMSR_API_DATA_BUFLEN 1032 > >>>>> struct CMD_MESSAGE_FIELD > >>>>> { > >>>>> struct CMD_MESSAGE cmdmessage; > >>>>> - uint8_t messagedatabuffer[1032]; > >>>>> + uint8_t messagedatabuffer[ARCMSR_API_DATA_BUFLEN]; > >>>>> }; > >>>>> /* IOP message transfer */ > >>>>> #define ARCMSR_MESSAGE_FAIL 0x0001 > >>>>> @@ -678,15 +679,15 @@ struct AdapterControlBlock > >>>>> unsigned int uncache_size; > >>>>> uint8_t rqbuffer[ARCMSR_MAX_QBUFFER]; > >>>>> /* data collection buffer for read from 80331 */ > >>>>> - int32_t rqbuf_firstindex; > >>>>> + int32_t rqbuf_getIndex; > >>>>> /* first of read buffer */ > >>>>> - int32_t rqbuf_lastindex; > >>>>> + int32_t rqbuf_putIndex; > >>>>> /* last of read buffer */ > >>>>> uint8_t wqbuffer[ARCMSR_MAX_QBUFFER]; > >>>>> /* data collection buffer for write to 80331 */ > >>>>> - int32_t wqbuf_firstindex; > >>>>> + int32_t wqbuf_getIndex; > >>>>> /* first of write buffer */ > >>>>> - int32_t wqbuf_lastindex; > >>>>> + int32_t wqbuf_putIndex; > >>>>> /* last of write buffer */ > >>>>> uint8_t devstate[ARCMSR_MAX_TARGETID][ARCMSR_MAX_TARGETLUN]; > >>>>> /* id0 ..... id15, lun0...lun7 */ > >>>>> 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-21 12:14:27.000000000 +0800 > >>>>> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-25 17:25:14.000000000 +0800 > >>>>> @@ -1724,16 +1724,15 @@ arcmsr_Read_iop_rqbuffer_in_DWORD(struct > >>>>> buf2 = (uint32_t *)buf1; > >>>>> } > >>>>> while (iop_len > 0) { > >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > >>>>> *pQbuffer = *buf1; > >>>>> - acb->rqbuf_lastindex++; > >>>>> + acb->rqbuf_putIndex++; > >>>>> /* if last, index number set it to 0 */ > >>>>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > >>>>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > >>>>> buf1++; > >>>>> iop_len--; > >>>>> } > >>>>> - if (buf2) > >>>>> - kfree(buf2); > >>>>> + kfree(buf2); > >>>>> /* let IOP know data has been read */ > >>>>> arcmsr_iop_message_read(acb); > >>>>> return 1; > >>>>> @@ -1752,10 +1751,10 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada > >>>>> iop_data = (uint8_t __iomem *)prbuffer->data; > >>>>> iop_len = readl(&prbuffer->data_len); > >>>>> while (iop_len > 0) { > >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_lastindex]; > >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_putIndex]; > >>>>> *pQbuffer = readb(iop_data); > >>>>> - acb->rqbuf_lastindex++; > >>>>> - acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; > >>>>> + acb->rqbuf_putIndex++; > >>>>> + acb->rqbuf_putIndex %= ARCMSR_MAX_QBUFFER; > >>>>> iop_data++; > >>>>> iop_len--; > >>>>> } > >>>>> @@ -1771,7 +1770,7 @@ static void arcmsr_iop2drv_data_wrote_ha > >>>>> > >>>>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); > >>>>> prbuffer = arcmsr_get_iop_rqbuffer(acb); > >>>>> - buf_empty_len = (acb->rqbuf_lastindex - acb->rqbuf_firstindex - 1) & > >>>>> + buf_empty_len = (acb->rqbuf_putIndex - acb->rqbuf_getIndex - 1) & > >>>>> (ARCMSR_MAX_QBUFFER - 1); > >>>>> if (buf_empty_len >= readl(&prbuffer->data_len)) { > >>>>> if (arcmsr_Read_iop_rqbuffer_data(acb, prbuffer) == 0) > >>>>> @@ -1798,12 +1797,12 @@ static void arcmsr_write_ioctldata2iop_i > >>>>> 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) > >>>>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > >>>>> && (allxfer_len < 124)) { > >>>>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > >>>>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > >>>>> *buf1 = *pQbuffer; > >>>>> - acb->wqbuf_firstindex++; > >>>>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > >>>>> + acb->wqbuf_getIndex++; > >>>>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>>>> buf1++; > >>>>> allxfer_len++; > >>>>> } > >>>>> @@ -1841,12 +1840,12 @@ arcmsr_write_ioctldata2iop(struct Adapte > >>>>> 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) > >>>>> + while ((acb->wqbuf_getIndex != acb->wqbuf_putIndex) > >>>>> && (allxfer_len < 124)) { > >>>>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; > >>>>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_getIndex]; > >>>>> writeb(*pQbuffer, iop_data); > >>>>> - acb->wqbuf_firstindex++; > >>>>> - acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; > >>>>> + acb->wqbuf_getIndex++; > >>>>> + acb->wqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>>>> iop_data++; > >>>>> allxfer_len++; > >>>>> } > >>>>> @@ -1861,9 +1860,9 @@ static void arcmsr_iop2drv_data_read_han > >>>>> > >>>>> spin_lock_irqsave(&acb->wqbuffer_lock, flags); > >>>>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; > >>>>> - if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) > >>>>> + if (acb->wqbuf_getIndex != acb->wqbuf_putIndex) > >>>>> arcmsr_write_ioctldata2iop(acb); > >>>>> - if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) > >>>>> + if (acb->wqbuf_getIndex == acb->wqbuf_putIndex) > >>>>> acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; > >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>>>> } > >>>>> @@ -2243,14 +2242,14 @@ void arcmsr_clear_iop2drv_rqueue_buffer( > >>>>> 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; > >>>>> + acb->rqbuf_getIndex = 0; > >>>>> + acb->rqbuf_putIndex = 0; > >>>>> arcmsr_iop_message_read(acb); > >>>>> mdelay(30); > >>>>> - } else if (acb->rqbuf_firstindex != > >>>>> - acb->rqbuf_lastindex) { > >>>>> - acb->rqbuf_firstindex = 0; > >>>>> - acb->rqbuf_lastindex = 0; > >>>>> + } else if (acb->rqbuf_getIndex != > >>>>> + acb->rqbuf_putIndex) { > >>>>> + acb->rqbuf_getIndex = 0; > >>>>> + acb->rqbuf_putIndex = 0; > >>>>> mdelay(30); > >>>>> } else > >>>>> break; > >>>>> @@ -2291,7 +2290,7 @@ static int arcmsr_iop_message_xfer(struc > >>>>> unsigned char *ver_addr; > >>>>> uint8_t *pQbuffer, *ptmpQbuffer; > >>>>> uint32_t allxfer_len = 0; > >>>>> - ver_addr = kmalloc(1032, GFP_ATOMIC); > >>>>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > >>>>> if (!ver_addr) { > >>>>> retvalue = ARCMSR_MESSAGE_FAIL; > >>>>> pr_info("%s: memory not enough!\n", __func__); > >>>>> @@ -2299,64 +2298,64 @@ static int arcmsr_iop_message_xfer(struc > >>>>> } > >>>>> ptmpQbuffer = ver_addr; > >>>>> spin_lock_irqsave(&acb->rqbuffer_lock, flags); > >>>>> - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { > >>>>> - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; > >>>>> - if (acb->rqbuf_firstindex > acb->rqbuf_lastindex) { > >>>>> + if (acb->rqbuf_getIndex != acb->rqbuf_putIndex) { > >>>>> + pQbuffer = &acb->rqbuffer[acb->rqbuf_getIndex]; > >>>>> + if (acb->rqbuf_getIndex > acb->rqbuf_putIndex) { > >>>>> 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; > >>>>> + acb->rqbuf_getIndex) >= ARCMSR_API_DATA_BUFLEN) { > >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>>>> + acb->rqbuf_getIndex %= ARCMSR_MAX_QBUFFER; > >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>>>> } else { > >>>>> if (((ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex) + > >>>>> - acb->rqbuf_lastindex) > 1032) { > >>>>> + acb->rqbuf_getIndex) + > >>>>> + acb->rqbuf_putIndex) > ARCMSR_API_DATA_BUFLEN) { > >>>>> memcpy(ptmpQbuffer, > >>>>> pQbuffer, ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex); > >>>>> + - acb->rqbuf_getIndex); > >>>>> ptmpQbuffer += > >>>>> ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex; > >>>>> + acb->rqbuf_getIndex; > >>>>> memcpy(ptmpQbuffer, > >>>>> - acb->rqbuffer, 1032 - > >>>>> + acb->rqbuffer, ARCMSR_API_DATA_BUFLEN - > >>>>> (ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex)); > >>>>> - acb->rqbuf_firstindex = > >>>>> - 1032 - (ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex); > >>>>> - allxfer_len = 1032; > >>>>> + - acb->rqbuf_getIndex)); > >>>>> + acb->rqbuf_getIndex = > >>>>> + ARCMSR_API_DATA_BUFLEN - (ARCMSR_MAX_QBUFFER > >>>>> + - acb->rqbuf_getIndex); > >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>>>> } else { > >>>>> memcpy(ptmpQbuffer, > >>>>> pQbuffer, ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex); > >>>>> + - acb->rqbuf_getIndex); > >>>>> ptmpQbuffer += > >>>>> ARCMSR_MAX_QBUFFER - > >>>>> - acb->rqbuf_firstindex; > >>>>> + acb->rqbuf_getIndex; > >>>>> memcpy(ptmpQbuffer, > >>>>> acb->rqbuffer, > >>>>> - acb->rqbuf_lastindex); > >>>>> + acb->rqbuf_putIndex); > >>>>> allxfer_len = ARCMSR_MAX_QBUFFER > >>>>> - - acb->rqbuf_firstindex + > >>>>> - acb->rqbuf_lastindex; > >>>>> - acb->rqbuf_firstindex = > >>>>> - acb->rqbuf_lastindex; > >>>>> + - acb->rqbuf_getIndex + > >>>>> + acb->rqbuf_putIndex; > >>>>> + acb->rqbuf_getIndex = > >>>>> + acb->rqbuf_putIndex; > >>>>> } > >>>>> } > >>>>> } else { > >>>>> - if ((acb->rqbuf_lastindex - > >>>>> - acb->rqbuf_firstindex) > 1032) { > >>>>> - memcpy(ptmpQbuffer, pQbuffer, 1032); > >>>>> - acb->rqbuf_firstindex += 1032; > >>>>> - allxfer_len = 1032; > >>>>> + if ((acb->rqbuf_putIndex - > >>>>> + acb->rqbuf_getIndex) > ARCMSR_API_DATA_BUFLEN) { > >>>>> + memcpy(ptmpQbuffer, pQbuffer, ARCMSR_API_DATA_BUFLEN); > >>>>> + acb->rqbuf_getIndex += ARCMSR_API_DATA_BUFLEN; > >>>>> + allxfer_len = ARCMSR_API_DATA_BUFLEN; > >>>>> } else { > >>>>> memcpy(ptmpQbuffer, pQbuffer, > >>>>> - acb->rqbuf_lastindex - > >>>>> - acb->rqbuf_firstindex); > >>>>> - allxfer_len = acb->rqbuf_lastindex > >>>>> - - acb->rqbuf_firstindex; > >>>>> - acb->rqbuf_firstindex = > >>>>> - acb->rqbuf_lastindex; > >>>>> + acb->rqbuf_putIndex - > >>>>> + acb->rqbuf_getIndex); > >>>>> + allxfer_len = acb->rqbuf_putIndex > >>>>> + - acb->rqbuf_getIndex; > >>>>> + acb->rqbuf_getIndex = > >>>>> + acb->rqbuf_putIndex; > >>>>> } > >>>>> } - if (acb->rqbuf_firstindex != acb->rqbuf_lastindex) { - pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; - 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->rqbuf_getIndex != acb->rqbuf_putIndex) { + unsigned int tail = acb->rqbuf_getIndex; + unsigned int head = acb->rqbuf_putIndex; + unsigned int cnt_to_end = CIRC_CNT_TO_END(head, tail, ARCMSR_MAX_QBUFFER); + + allxfer_len = CIRC_CNT(head, tail, ARCMSR_MAX_QBUFFER); + if (allxfer_len > ARCMSR_API_DATA_BUFLEN) + allxfer_len = ARCMSR_API_DATA_BUFLEN; + + if (allxfer_len <= cnt_to_end) + memcpy(ptmpQbuffer, acb->rqbuffer + tail, allxfer_len); + else { + memcpy(ptmpQbuffer, acb->rqbuffer + tail, cnt_to_end); + memcpy(ptmpQbuffer + cnt_to_end, acb->rqbuffer, allxfer_len - cnt_to_end); } + acb->rqbuf_getIndex = (acb->rqbuf_getIndex + allxfer_len) % ARCMSR_MAX_QBUFFER; > >>>>> } > >>>>> @@ -2382,9 +2381,9 @@ static int arcmsr_iop_message_xfer(struc > >>>>> } > >>>>> case ARCMSR_MESSAGE_WRITE_WQBUFFER: { > >>>>> unsigned char *ver_addr; > >>>>> - int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; > >>>>> + int32_t my_empty_len, user_len, wqbuf_getIndex, wqbuf_putIndex; > >>>>> uint8_t *pQbuffer, *ptmpuserbuffer; > >>>>> - ver_addr = kmalloc(1032, GFP_ATOMIC); > >>>>> + ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC); > >>>>> if (!ver_addr) { > >>>>> retvalue = ARCMSR_MESSAGE_FAIL; > >>>>> goto message_out; > >>>>> @@ -2394,9 +2393,9 @@ static int arcmsr_iop_message_xfer(struc > >>>>> 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) { > >>>>> + wqbuf_putIndex = acb->wqbuf_putIndex; > >>>>> + wqbuf_getIndex = acb->wqbuf_getIndex; > >>>>> + if (wqbuf_putIndex != wqbuf_getIndex) { > >>>>> struct SENSE_DATA *sensebuffer = > >>>>> (struct SENSE_DATA *)cmd->sense_buffer; > >>>>> arcmsr_write_ioctldata2iop(acb); > >>>>> @@ -2408,27 +2407,27 @@ static int arcmsr_iop_message_xfer(struc > >>>>> sensebuffer->Valid = 1; > >>>>> retvalue = ARCMSR_MESSAGE_FAIL; > >>>>> } else { > >>>>> - my_empty_len = (wqbuf_firstindex - wqbuf_lastindex - 1) > >>>>> + my_empty_len = (wqbuf_getIndex - wqbuf_putIndex - 1) > >>>>> & (ARCMSR_MAX_QBUFFER - 1); > >>>>> if (my_empty_len >= user_len) { > >>>>> while (user_len > 0) { > >>>>> - pQbuffer = &acb->wqbuffer[acb->wqbuf_lastindex]; > >>>>> - if ((acb->wqbuf_lastindex + user_len) > >>>>> + pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex]; > >>>>> + if ((acb->wqbuf_putIndex + user_len) > >>>>> > ARCMSR_MAX_QBUFFER) { > >>>>> memcpy(pQbuffer, ptmpuserbuffer, > >>>>> ARCMSR_MAX_QBUFFER - > >>>>> - acb->wqbuf_lastindex); > >>>>> + acb->wqbuf_putIndex); > >>>>> ptmpuserbuffer += > >>>>> (ARCMSR_MAX_QBUFFER > >>>>> - - acb->wqbuf_lastindex); > >>>>> + - acb->wqbuf_putIndex); > >>>>> user_len -= (ARCMSR_MAX_QBUFFER > >>>>> - - acb->wqbuf_lastindex); > >>>>> - acb->wqbuf_lastindex = 0; > >>>>> + - acb->wqbuf_putIndex); > >>>>> + acb->wqbuf_putIndex = 0; > >>>>> } else { > >>>>> memcpy(pQbuffer, ptmpuserbuffer, > >>>>> user_len); > >>>>> - acb->wqbuf_lastindex += user_len; > >>>>> - acb->wqbuf_lastindex %= > >>>>> + acb->wqbuf_putIndex += user_len; > >>>>> + acb->wqbuf_putIndex %= > >>>>> ARCMSR_MAX_QBUFFER; > >>>>> user_len = 0; > >>>>> } > >>>>> @@ -2468,8 +2467,8 @@ static int arcmsr_iop_message_xfer(struc > >>>>> 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->rqbuf_getIndex = 0; > >>>>> + acb->rqbuf_putIndex = 0; > >>>>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > >>>>> spin_unlock_irqrestore(&acb->rqbuffer_lock, flags); > >>>>> if (acb->fw_flag == FW_DEADLOCK) > >>>>> @@ -2485,8 +2484,8 @@ static int arcmsr_iop_message_xfer(struc > >>>>> 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; > >>>>> + acb->wqbuf_getIndex = 0; > >>>>> + acb->wqbuf_putIndex = 0; > >>>>> memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); > >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>>>> if (acb->fw_flag == FW_DEADLOCK) > >>>>> @@ -2502,16 +2501,16 @@ static int arcmsr_iop_message_xfer(struc > >>>>> 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->rqbuf_getIndex = 0; > >>>>> + acb->rqbuf_putIndex = 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; > >>>>> + acb->wqbuf_getIndex = 0; > >>>>> + acb->wqbuf_putIndex = 0; > >>>>> pQbuffer = acb->wqbuffer; > >>>>> memset(pQbuffer, 0, sizeof(struct QBUFFER)); > >>>>> spin_unlock_irqrestore(&acb->wqbuffer_lock, flags); > >>>>> > >>>>> > >>>>> > >>>>> -- > >>>>> 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 > >>> -- > >>> 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 > > > ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-08-28 3:40 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 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 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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).