Re: [PATCH] scsi: arcmsr: avoid do_gettimeofday

2018-01-22 Thread Ching Huang
On Mon, 2018-01-22 at 00:12 +0100, Arnd Bergmann wrote:
> The arcmsr uses its own implementation of time_to_tm(), along with 
> do_gettimeofday()
> to read the current time. While the algoritm used here is fine in principle, 
> it
> suffers from two problems:
> 
> - it assigns the seconds portion of the timeval to a 32-bit unsigned integer 
> that
>   overflows in 2106 even on 64-bit architectures.
> - do_gettimeofday() returns a time_t that overflows in 2038 on all 32-bit 
> systems.
> 
> This changes the time retrieval function to ktime_get_real_seconds(), which 
> returns
> a proper 64-bit value, and replaces the open-coded time_to_tm() algorithm with
> a call to the safe time64_to_tm().
> 
> I checked way all numbers are indexed and found that months are given in range
> 0..11 while the days are in range 1..31, same as 'struct tm', but the year 
> value
> that the firmware expects starts in 2000 while 'struct tm' is based on year 
> 1900,
> so it needs a small adjustment.
> 
> Fixes: b416c099472a ("scsi: arcmsr: Add a function to set date and time to 
> firmware")
> Signed-off-by: Arnd Bergmann 
> ---
>  drivers/scsi/arcmsr/arcmsr_hba.c | 37 ++---
>  1 file changed, 10 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c 
> b/drivers/scsi/arcmsr/arcmsr_hba.c
> index 47745592cff4..75e828bd30e3 100644
> --- a/drivers/scsi/arcmsr/arcmsr_hba.c
> +++ b/drivers/scsi/arcmsr/arcmsr_hba.c
> @@ -3489,8 +3489,9 @@ static int arcmsr_polling_ccbdone(struct 
> AdapterControlBlock *acb,
>  static void arcmsr_set_iop_datetime(struct timer_list *t)
>  {
>   struct AdapterControlBlock *pacb = from_timer(pacb, t, refresh_timer);
> - unsigned int days, j, i, a, b, c, d, e, m, year, mon, day, hour, min, 
> sec, secs, next_time;
> - struct timeval tv;
> + unsigned int next_time;
> + struct tm tm;
> +
>   union {
>   struct  {
>   uint16_tsignature;
> @@ -3506,33 +3507,15 @@ static void arcmsr_set_iop_datetime(struct timer_list 
> *t)
>   } b;
>   } datetime;
>  
> - do_gettimeofday(&tv);
> - secs = (u32)(tv.tv_sec - (sys_tz.tz_minuteswest * 60));
> - days = secs / 86400;
> - secs = secs - 86400 * days;
> - j = days / 146097;
> - i = days - 146097 * j;
> - a = i + 719468;
> - b = ( 4 * a + 3 ) / 146097;
> - c = a - ( 146097 * b ) / 4;
> - d = ( 4 * c + 3 ) / 1461 ;
> - e = c - ( 1461 * d ) / 4 ;
> - m = ( 5 * e + 2 ) / 153 ;
> - year = 400 * j + 100 * b + d + m / 10 - 2000;
> - mon = m + 3 - 12 * ( m /10 );
> - day = e - ( 153 * m + 2 ) / 5 + 1;
> - hour = secs / 3600;
> - secs = secs - 3600 * hour;
> - min = secs / 60;
> - sec = secs - 60 * min;
> + time64_to_tm(ktime_get_real_seconds(), -sys_tz.tz_minuteswest * 60, 
> &tm);
>  
>   datetime.a.signature = 0x55AA;
> - datetime.a.year = year;
> - datetime.a.month = mon;
> - datetime.a.date = day;
> - datetime.a.hour = hour;
> - datetime.a.minute = min;
> - datetime.a.second = sec;
> + datetime.a.year = tm.tm_year - 100; /* base 2000 instead of 1900 */
> + datetime.a.month = tm.tm_mon;
> + datetime.a.date = tm.tm_mday;
> + datetime.a.hour = tm.tm_hour;
> + datetime.a.minute = tm.tm_min;
> + datetime.a.second = tm.tm_sec;
>  
>   switch (pacb->adapter_type) {
>   case ACB_ADAPTER_TYPE_A: {

This patch works on kernel 4.14.0, thanks Arnd.



[PATCH 0/12] scsi: arcmsr: update for ccb structure address can above 4GB

2018-12-19 Thread Ching Huang
>From Ching Huang 

This patch series are against to mkp's 4.21/scsi-queue.

1. Rename acb structure member roundup_ccbsize to ioqueue_size
2. Rename arcmsr_free_mu to arcmsr_free_io_queue
3. Merge arcmsr_alloc_io_queue to arcmsr_alloc_ccb_pool
4. Update arcmsr_alloc_ccb_pool for ccb buffer address above 4GB
5. Update codes for ACB_ADAPTER_TYPE_A in case of ccb address above 4GB
6. Update codes for ACB_ADAPTER_TYPE_B in case of ccb address above 4GB
7. Update codes for ACB_ADAPTER_TYPE_C in case of ccb address above 4GB
8. Update codes for ACB_ADAPTER_TYPE_D in case of ccb address above 4GB
9. Add an option of set dma_mask_64 for ACB_ADAPTER_TYPE_A
10.Separate 'set dma mask' as a function
11.Fix suspend/resume of ACB_ADAPTER_TYPE_B
12.Update driver version to v1.40.00.10-20181217
---



[PATCH 1/12] scsi: arcmsr: Rename acb structure member roundup_ccbsize to ioqueue_size

2018-12-19 Thread Ching Huang
>From Ching Huang 

Rename acb structure member roundup_ccbsize to ioqueue_size

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 9c397a2..256fe9a 100755
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -739,7 +739,7 @@ struct AdapterControlBlock
 #define ACB_ADAPTER_TYPE_C 0x0002  /* hbc L IOP */
 #define ACB_ADAPTER_TYPE_D 0x0003  /* hbd M IOP */
 #define ACB_ADAPTER_TYPE_E 0x0004  /* hba L IOP */
-   u32 roundup_ccbsize;
+   u32 ioqueue_size;
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 0f6751b..f3a7855 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -229,7 +229,7 @@ static void arcmsr_free_mu(struct AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_B:
case ACB_ADAPTER_TYPE_D:
case ACB_ADAPTER_TYPE_E: {
-   dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
+   dma_free_coherent(&acb->pdev->dev, acb->ioqueue_size,
acb->dma_coherent2, acb->dma_coherent_handle2);
break;
}
@@ -586,8 +586,8 @@ static bool arcmsr_alloc_io_queue(struct 
AdapterControlBlock *acb)
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_B: {
struct MessageUnit_B *reg;
-   acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 
32);
-   dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->roundup_ccbsize,
+   acb->ioqueue_size = roundup(sizeof(struct MessageUnit_B), 32);
+   dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->ioqueue_size,
&dma_coherent_handle, GFP_KERNEL);
if (!dma_coherent) {
pr_notice("arcmsr%d: DMA allocation failed\n", 
acb->host->host_no);
@@ -616,8 +616,8 @@ static bool arcmsr_alloc_io_queue(struct 
AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_D: {
struct MessageUnit_D *reg;
 
-   acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 
32);
-   dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->roundup_ccbsize,
+   acb->ioqueue_size = roundup(sizeof(struct MessageUnit_D), 32);
+   dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->ioqueue_size,
&dma_coherent_handle, GFP_KERNEL);
if (!dma_coherent) {
pr_notice("arcmsr%d: DMA allocation failed\n", 
acb->host->host_no);
@@ -658,8 +658,8 @@ static bool arcmsr_alloc_io_queue(struct 
AdapterControlBlock *acb)
case ACB_ADAPTER_TYPE_E: {
uint32_t completeQ_size;
completeQ_size = sizeof(struct deliver_completeQ) * 
ARCMSR_MAX_HBE_DONEQUEUE + 128;
-   acb->roundup_ccbsize = roundup(completeQ_size, 32);
-   dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->roundup_ccbsize,
+   acb->ioqueue_size = roundup(completeQ_size, 32);
+   dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->ioqueue_size,
&dma_coherent_handle, GFP_KERNEL);
if (!dma_coherent){
pr_notice("arcmsr%d: DMA allocation failed\n", 
acb->host->host_no);
@@ -668,7 +668,7 @@ static bool arcmsr_alloc_io_queue(struct 
AdapterControlBlock *acb)
acb->dma_coherent_handle2 = dma_coherent_handle;
acb->dma_coherent2 = dma_coherent;
acb->pCompletionQ = dma_coherent;
-   acb->completionQ_entry = acb->roundup_ccbsize / sizeof(struct 
deliver_completeQ);
+   acb->completionQ_entry = acb->ioqueue_size / sizeof(struct 
deliver_completeQ);
acb->doneq_index = 0;
}
break;
@@ -3787,7 +3787,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock 
*acb)
cdb_phyaddr_hi32 = (uint32_t)((dma_coherent_handle >> 16) >> 
16);
writel(cdb_phyaddr, ®->msgcode_rwbuffer[5]);
writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[6]);
-   writel(acb->roundup_ccbsize, ®->msgcode_rwbuffer[7]);
+   writel(acb->ioqueue_size, ®->msgcode_rwbuffer[7]);
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0);
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
writel(acb->out_doorbell, ®->iobound_doorbell);




[PATCH 2/12] scsi: arcmsr: Rename arcmsr_free_mu to arcmsr_free_io_queue

2018-12-19 Thread Ching Huang
>From Ching Huang 

Rename arcmsr_free_mu to arcmsr_free_io_queue

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f3a7855..f831c13 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -223,7 +223,7 @@ static struct pci_driver arcmsr_pci_driver = {
 
 */
 
-static void arcmsr_free_mu(struct AdapterControlBlock *acb)
+static void arcmsr_free_io_queue(struct AdapterControlBlock *acb)
 {
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_B:
@@ -990,7 +990,7 @@ scsi_host_remove:
 free_ccb_pool:
arcmsr_free_ccb_pool(acb);
 free_hbb_mu:
-   arcmsr_free_mu(acb);
+   arcmsr_free_io_queue(acb);
 unmap_pci_region:
arcmsr_unmap_pciregion(acb);
 pci_release_regs:
@@ -1500,7 +1500,7 @@ static void arcmsr_free_pcidev(struct AdapterControlBlock 
*acb)
pdev = acb->pdev;
arcmsr_free_irq(pdev, acb);
arcmsr_free_ccb_pool(acb);
-   arcmsr_free_mu(acb);
+   arcmsr_free_io_queue(acb);
arcmsr_unmap_pciregion(acb);
pci_release_regions(pdev);
scsi_host_put(host);
@@ -1558,7 +1558,7 @@ static void arcmsr_remove(struct pci_dev *pdev)
}
arcmsr_free_irq(pdev, acb);
arcmsr_free_ccb_pool(acb);
-   arcmsr_free_mu(acb);
+   arcmsr_free_io_queue(acb);
arcmsr_unmap_pciregion(acb);
pci_release_regions(pdev);
scsi_host_put(host);




[PATCH 3/12] scsi: arcmsr: Merge arcmsr_alloc_io_queue to arcmsr_alloc_ccb_pool

2018-12-19 Thread Ching Huang
>From Ching Huang 

Merge arcmsr_alloc_io_queue to arcmsr_alloc_ccb_pool

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index f831c13..e1c75ca 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -576,6 +576,58 @@ static void arcmsr_flush_adapter_cache(struct 
AdapterControlBlock *acb)
}
 }
 
+static void arcmsr_hbaB_assign_regAddr(struct AdapterControlBlock *acb)
+{
+   struct MessageUnit_B *reg = acb->pmuB;
+
+   if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
+   reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
+   reg->drv2iop_doorbell_mask = 
MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
+   reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
+   reg->iop2drv_doorbell_mask = 
MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
+   } else {
+   reg->drv2iop_doorbell= MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
+   reg->drv2iop_doorbell_mask = 
MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
+   reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
+   reg->iop2drv_doorbell_mask = 
MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
+   }
+   reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
+   reg->message_rbuffer =  MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
+   reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
+}
+
+static void arcmsr_hbaD_assign_regAddr(struct AdapterControlBlock *acb)
+{
+   struct MessageUnit_D *reg = acb->pmuD;
+
+   reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
+   reg->cpu_mem_config = 
MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
+   reg->i2o_host_interrupt_mask = 
MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
+   reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
+   reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
+   reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
+   reg->pcief0_int_enable = 
MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
+   reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
+   reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
+   reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
+   reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
+   reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
+   reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
+   reg->outbound_doorbell_enable = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
+   reg->inboundlist_base_low = 
MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
+   reg->inboundlist_base_high = 
MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
+   reg->inboundlist_write_pointer = 
MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
+   reg->outboundlist_base_low = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
+   reg->outboundlist_base_high = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
+   reg->outboundlist_copy_pointer = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER);
+   reg->outboundlist_read_pointer = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER);
+   reg->outboundlist_interrupt_cause = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE);
+   reg->outboundlist_interrupt_enable = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE);
+   reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER);
+   reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER);
+   reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
+}
+
 static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
 {
bool rtn = true;
@@ -585,7 +637,6 @@ static bool arcmsr_alloc_io_queue(struct 
AdapterControlBlock *acb)
 
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_B: {
-   struct MessageUnit_B *reg;
acb->ioqueue_size = roundup(sizeof(struct MessageUnit_B), 32);
dma_coherent = dma_zalloc_coherent(&pdev->dev, 
acb->ioqueue_size,
&dma_coherent_handle, GFP_KERNEL);
@@ -595,27 +646,11 @@ static bool arcmsr_alloc_io_queue(struct 
AdapterControlBlock *acb)
}
acb->dma_coherent_handle2 = dma_coherent_handle;
acb->dma_coherent2 = dma_coherent;
-   reg = (struct MessageUnit_B *)dma_coherent;
-   acb->pmuB = reg;
-   if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
-   reg->drv2iop_doorbell = 
MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
-   reg->drv2iop_doorbell_mask

[PATCH 4/12] scsi: arcmsr: Update arcmsr_alloc_ccb_pool for ccb buffer address can above 4GB

2018-12-19 Thread Ching Huang
>From Ching Huang 

Update arcmsr_alloc_ccb_pool for ccb buffer address can above 4GB

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 256fe9a..9041edc 100755
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -747,6 +747,7 @@ struct AdapterControlBlock
uint32_toutbound_int_enable;
uint32_tcdb_phyaddr_hi32;
uint32_treg_mu_acc_handle0;
+   uint64_tcdb_phyadd_hipart;
spinlock_t  eh_lock;
spinlock_t  ccblist_lock;
spinlock_t  postq_lock;
@@ -855,11 +856,11 @@ struct AdapterControlBlock
 ***
 */
 struct CommandControlBlock{
-   /*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
+   /*x32:sizeof struct_CCB=(64+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
struct list_headlist;   /*x32: 8byte, x64: 
16byte*/
struct scsi_cmnd*pcmd;  /*8 bytes pointer of 
linux scsi command */
struct AdapterControlBlock  *acb;   /*x32: 4byte, x64: 
8byte*/
-   uint32_tcdb_phyaddr;/*x32: 4byte, x64: 
4byte*/
+   unsigned long   cdb_phyaddr;/*x32: 4byte, x64: 
8byte*/
uint32_tarc_cdb_size;   /*x32:4byte,x64:4byte*/
uint16_tccb_flags;  /*x32: 2byte, x64: 
2byte*/
 #defineCCB_FLAG_READ   0x
@@ -875,10 +876,10 @@ struct CommandControlBlock{
uint32_tsmid;
 #if BITS_PER_LONG == 64
/*  ==512+64 bytes  */
-   uint32_treserved[4];/*16 byte*/
+   uint32_treserved[3];/*12 byte*/
 #else
/*  ==512+32 bytes  */
-   //  uint32_treserved;   /*4  byte*/
+   uint32_treserved[8];/*32  byte*/
 #endif
/*  ===   */
struct ARCMSR_CDB   arcmsr_cdb;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index e1c75ca..5353dbb 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -694,11 +694,11 @@ static int arcmsr_alloc_ccb_pool(struct 
AdapterControlBlock *acb)
dma_addr_t dma_coherent_handle;
struct CommandControlBlock *ccb_tmp;
int i = 0, j = 0;
-   dma_addr_t cdb_phyaddr;
+   unsigned long cdb_phyaddr, next_ccb_phy;
unsigned long roundup_ccbsize;
unsigned long max_xfer_len;
unsigned long max_sg_entrys;
-   uint32_t  firm_config_version;
+   uint32_t  firm_config_version, curr_phy_upper32;
 
for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
@@ -726,9 +726,10 @@ static int arcmsr_alloc_ccb_pool(struct 
AdapterControlBlock *acb)
memset(dma_coherent, 0, acb->uncache_size);
acb->ccbsize = roundup_ccbsize;
ccb_tmp = dma_coherent;
+   curr_phy_upper32 = upper_32_bits(dma_coherent_handle);
acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned 
long)dma_coherent_handle;
for(i = 0; i < acb->maxFreeCCB; i++){
-   cdb_phyaddr = dma_coherent_handle + offsetof(struct 
CommandControlBlock, arcmsr_cdb);
+   cdb_phyaddr = (unsigned long)dma_coherent_handle + 
offsetof(struct CommandControlBlock, arcmsr_cdb);
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A:
case ACB_ADAPTER_TYPE_B:
@@ -744,9 +745,16 @@ static int arcmsr_alloc_ccb_pool(struct 
AdapterControlBlock *acb)
ccb_tmp->acb = acb;
ccb_tmp->smid = (u32)i << 16;
INIT_LIST_HEAD(&ccb_tmp->list);
-   list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
+   next_ccb_phy = dma_coherent_handle + roundup_ccbsize;
+   if (upper_32_bits(next_ccb_phy) != curr_phy_upper32) {
+   acb->maxFreeCCB = i;
+   acb->host->can_queue = i;
+   break;
+   }
+   else
+   list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp 
+ roundup_ccbsize);
-   dma_coherent_handle = dma_coherent_handle + roundup_ccbsize;
+   dma_coherent_handle = next_ccb_phy;
}
acb->dma_coherent_handle2 = dma_coherent_handle;
acb->dma_coherent2 = ccb_tmp;
@@ -3701,6 +3709

[PATCH 5/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_A that ccb address can above 4GB

2018-12-19 Thread Ching Huang
>From Ching Huang 

Update for ACB_ADAPTER_TYPE_A that ccb address can above 4GB

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 5353dbb..2ff1c9a 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1382,10 +1382,12 @@ static void arcmsr_drain_donequeue(struct 
AdapterControlBlock *acb, struct Comma
 static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 {
int i = 0;
-   uint32_t flag_ccb, ccb_cdb_phy;
+   uint32_t flag_ccb;
struct ARCMSR_CDB *pARCMSR_CDB;
bool error;
struct CommandControlBlock *pCCB;
+   unsigned long ccb_cdb_phy, cdb_phy_hipart;
+
switch (acb->adapter_type) {
 
case ACB_ADAPTER_TYPE_A: {
@@ -1397,7 +1399,10 @@ static void arcmsr_done4abort_postqueue(struct 
AdapterControlBlock *acb)
writel(outbound_intstatus, ®->outbound_intstatus);/*clear 
interrupt*/
while(((flag_ccb = readl(®->outbound_queueport)) != 
0x)
&& (i++ < acb->maxOutstanding)) {
-   pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset 
+ (flag_ccb << 5));/*frame must be 32 bytes aligned*/
+   ccb_cdb_phy = (flag_ccb << 5) & 0x;
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | 
acb->cdb_phyadd_hipart;
+   pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset 
+ ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB, struct 
CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? 
true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -2333,8 +2338,13 @@ static void arcmsr_hbaA_postqueue_isr(struct 
AdapterControlBlock *acb)
struct ARCMSR_CDB *pARCMSR_CDB;
struct CommandControlBlock *pCCB;
bool error;
+   unsigned long cdb_phy_addr;
+
while ((flag_ccb = readl(®->outbound_queueport)) != 0x) {
-   pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+   cdb_phy_addr = (flag_ccb << 5) & 0x;
+   if (acb->cdb_phyadd_hipart)
+   cdb_phy_addr = cdb_phy_addr | acb->cdb_phyadd_hipart;
+   pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
cdb_phy_addr);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, 
arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : 
false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -3258,7 +3268,9 @@ static int arcmsr_hbaA_polling_ccbdone(struct 
AdapterControlBlock *acb,
uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 
0;
int rtn;
bool error;
-   polling_hba_ccb_retry:
+   unsigned long ccb_cdb_phy;
+
+polling_hba_ccb_retry:
poll_count++;
outbound_intstatus = readl(®->outbound_intstatus) & 
acb->outbound_int_enable;
writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/
@@ -3276,7 +3288,10 @@ static int arcmsr_hbaA_polling_ccbdone(struct 
AdapterControlBlock *acb,
goto polling_hba_ccb_retry;
}
}
-   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));
+   ccb_cdb_phy = (flag_ccb << 5) & 0x;
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
ccb_cdb_phy);
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {




[PATCH 6/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_B that ccb address can above 4GB

2018-12-19 Thread Ching Huang
>From Ching Huang 

Update for ACB_ADAPTER_TYPE_B that ccb address can above 4GB

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 2ff1c9a..3d2727c 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1418,7 +1418,10 @@ static void arcmsr_done4abort_postqueue(struct 
AdapterControlBlock *acb)
flag_ccb = reg->done_qbuffer[i];
if (flag_ccb != 0) {
reg->done_qbuffer[i] = 0;
-   pARCMSR_CDB = (struct ARCMSR_CDB 
*)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+   ccb_cdb_phy = (flag_ccb << 5) & 0x;
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | 
acb->cdb_phyadd_hipart;
+   pARCMSR_CDB = (struct ARCMSR_CDB 
*)(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB, struct 
CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & 
ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -2358,13 +2361,18 @@ static void arcmsr_hbaB_postqueue_isr(struct 
AdapterControlBlock *acb)
struct ARCMSR_CDB *pARCMSR_CDB;
struct CommandControlBlock *pCCB;
bool error;
+   unsigned long cdb_phy_addr;
+
index = reg->doneq_index;
while ((flag_ccb = reg->done_qbuffer[index]) != 0) {
-   reg->done_qbuffer[index] = 0;
-   pARCMSR_CDB = (struct ARCMSR_CDB 
*)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+   cdb_phy_addr = (flag_ccb << 5) & 0x;
+   if (acb->cdb_phyadd_hipart)
+   cdb_phy_addr = cdb_phy_addr | acb->cdb_phyadd_hipart;
+   pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
cdb_phy_addr);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, 
arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : 
false;
arcmsr_drain_donequeue(acb, pCCB, error);
+   reg->done_qbuffer[index] = 0;
index++;
index %= ARCMSR_MAX_HBB_POSTQUEUE;
reg->doneq_index = index;
@@ -3329,8 +3337,9 @@ static int arcmsr_hbaB_polling_ccbdone(struct 
AdapterControlBlock *acb,
uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0;
int index, rtn;
bool error;
-   polling_hbb_ccb_retry:
+   unsigned long ccb_cdb_phy;
 
+polling_hbb_ccb_retry:
poll_count++;
/* clear doorbell interrupt */
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
@@ -3356,7 +3365,10 @@ static int arcmsr_hbaB_polling_ccbdone(struct 
AdapterControlBlock *acb,
index %= ARCMSR_MAX_HBB_POSTQUEUE;
reg->doneq_index = index;
/* check if command done with no error*/
-   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));
+   ccb_cdb_phy = (flag_ccb << 5) & 0x;
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
ccb_cdb_phy);
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {




[PATCH 7/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_C that ccb address can above 4GB

2018-12-19 Thread Ching Huang
>From Ching Huang 

Update for ACB_ADAPTER_TYPE_C that ccb address can above 4GB

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 3d2727c..39f3cd0 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1438,7 +1438,9 @@ static void arcmsr_done4abort_postqueue(struct 
AdapterControlBlock *acb)
/*need to do*/
flag_ccb = readl(®->outbound_queueport_low);
ccb_cdb_phy = (flag_ccb & 0xFFF0);
-   pARCMSR_CDB = (struct  ARCMSR_CDB 
*)(acb->vir2phy_offset+ccb_cdb_phy);/*frame must be 32 bytes aligned*/
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | 
acb->cdb_phyadd_hipart;
+   pARCMSR_CDB = (struct  ARCMSR_CDB 
*)(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB, struct 
CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? 
true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -1786,12 +1788,8 @@ static void arcmsr_post_ccb(struct AdapterControlBlock 
*acb, struct CommandContr
 
arc_cdb_size = (ccb->arc_cdb_size > 0x300) ? 0x300 : 
ccb->arc_cdb_size;
ccb_post_stamp = (cdb_phyaddr | ((arc_cdb_size - 1) >> 6) | 1);
-   if (acb->cdb_phyaddr_hi32) {
-   writel(acb->cdb_phyaddr_hi32, 
&phbcmu->inbound_queueport_high);
-   writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
-   } else {
-   writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
-   }
+   writel(upper_32_bits(ccb->cdb_phyaddr), 
&phbcmu->inbound_queueport_high);
+   writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
}
break;
case ACB_ADAPTER_TYPE_D: {
@@ -2384,7 +2382,8 @@ static void arcmsr_hbaC_postqueue_isr(struct 
AdapterControlBlock *acb)
struct MessageUnit_C __iomem *phbcmu;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *ccb;
-   uint32_t flag_ccb, ccb_cdb_phy, throttling = 0;
+   uint32_t flag_ccb, throttling = 0;
+   unsigned long ccb_cdb_phy;
int error;
 
phbcmu = acb->pmuC;
@@ -2394,6 +2393,8 @@ static void arcmsr_hbaC_postqueue_isr(struct 
AdapterControlBlock *acb)
while ((flag_ccb = readl(&phbcmu->outbound_queueport_low)) !=
0x) {
ccb_cdb_phy = (flag_ccb & 0xFFF0);
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset
+ ccb_cdb_phy);
ccb = container_of(arcmsr_cdb, struct CommandControlBlock,
@@ -3401,12 +3402,14 @@ static int arcmsr_hbaC_polling_ccbdone(struct 
AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
 {
struct MessageUnit_C __iomem *reg = acb->pmuC;
-   uint32_t flag_ccb, ccb_cdb_phy;
+   uint32_t flag_ccb;
struct ARCMSR_CDB *arcmsr_cdb;
bool error;
struct CommandControlBlock *pCCB;
uint32_t poll_ccb_done = 0, poll_count = 0;
int rtn;
+   unsigned long ccb_cdb_phy;
+
 polling_hbc_ccb_retry:
poll_count++;
while (1) {
@@ -3425,7 +3428,9 @@ polling_hbc_ccb_retry:
}
flag_ccb = readl(®->outbound_queueport_low);
ccb_cdb_phy = (flag_ccb & 0xFFF0);
-   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
ccb_cdb_phy);/*frame must be 32 bytes aligned*/
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
ccb_cdb_phy);
pCCB = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
poll_ccb_done |= (pCCB == poll_ccb) ? 1 : 0;
/* check ifcommand done with no error*/
@@ -3801,7 +3806,6 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock 
*acb)
}
break;
case ACB_ADAPTER_TYPE_C: {
-   if (cdb_phyaddr_hi32 != 0) {
struct MessageUnit_C __iomem *reg = acb->pmuC;
 
printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x\n",
@@ -3816,7 +3820,6 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock 
*acb)
return 1;
}
}
-   }
break;
case ACB_ADAPTER_TYPE_D: {
uint32_t __iomem *rwbuffer;




[PATCH 8/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_D that ccb address can above 4GB

2018-12-19 Thread Ching Huang
>From Ching Huang 

Update for ACB_ADAPTER_TYPE_D that ccb address can above 4GB

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 39f3cd0..8cc2134 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1468,9 +1468,13 @@ static void arcmsr_done4abort_postqueue(struct 
AdapterControlBlock *acb)
((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
spin_unlock_irqrestore(&acb->doneq_lock, flags);
+   cdb_phy_hipart = pmu->done_qbuffer[doneq_index &
+   0xFFF].addressHigh;
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFF0);
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | 
acb->cdb_phyadd_hipart;
pARCMSR_CDB = (struct  ARCMSR_CDB *)
(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB,
@@ -1802,8 +1806,8 @@ static void arcmsr_post_ccb(struct AdapterControlBlock 
*acb, struct CommandContr
spin_lock_irqsave(&acb->postq_lock, flags);
postq_index = pmu->postq_index;
pinbound_srb = (struct InBound_SRB 
*)&(pmu->post_qbuffer[postq_index & 0xFF]);
-   pinbound_srb->addressHigh = dma_addr_hi32(cdb_phyaddr);
-   pinbound_srb->addressLow = dma_addr_lo32(cdb_phyaddr);
+   pinbound_srb->addressHigh = upper_32_bits(ccb->cdb_phyaddr);
+   pinbound_srb->addressLow = cdb_phyaddr;
pinbound_srb->length = ccb->arc_cdb_size >> 2;
arcmsr_cdb->msgContext = dma_addr_lo32(cdb_phyaddr);
toggle = postq_index & 0x4000;
@@ -2415,12 +2419,12 @@ static void arcmsr_hbaC_postqueue_isr(struct 
AdapterControlBlock *acb)
 static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
 {
u32 outbound_write_pointer, doneq_index, index_stripped, toggle;
-   uint32_t addressLow, ccb_cdb_phy;
+   uint32_t addressLow;
int error;
struct MessageUnit_D  *pmu;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *ccb;
-   unsigned long flags;
+   unsigned long flags, ccb_cdb_phy, cdb_phy_hipart;
 
spin_lock_irqsave(&acb->doneq_lock, flags);
pmu = acb->pmuD;
@@ -2434,9 +2438,13 @@ static void arcmsr_hbaD_postqueue_isr(struct 
AdapterControlBlock *acb)
pmu->doneq_index = index_stripped ? (index_stripped | 
toggle) :
((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
+   cdb_phy_hipart = pmu->done_qbuffer[doneq_index &
+   0xFFF].addressHigh;
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFF0);
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | 
acb->cdb_phyadd_hipart;
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset
+ ccb_cdb_phy);
ccb = container_of(arcmsr_cdb,
@@ -3464,9 +3472,9 @@ static int arcmsr_hbaD_polling_ccbdone(struct 
AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
 {
bool error;
-   uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
+   uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb;
int rtn, doneq_index, index_stripped, outbound_write_pointer, toggle;
-   unsigned long flags;
+   unsigned long flags, ccb_cdb_phy, cdb_phy_hipart;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *pCCB;
struct MessageUnit_D *pmu = acb->pmuD;
@@ -3498,8 +3506,12 @@ polling_hbaD_ccb_retry:
((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
spin_unlock_irqrestore(&acb->doneq_lock, flags);
+   cdb_phy_hipart = pmu->done_qbuffer[doneq_index &
+   0xFFF].addressHigh;
flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (flag_ccb & 0xFFF0);
+   if (acb->cdb_phyadd_hipart)
+   ccb_cdb_phy = ccb_cdb_phy | acb->c

[PATCH 9/12] scsi: arcmsr: Add an option of set dma_mask_64 for ACB_ADAPTER_TYPE_A

2018-12-19 Thread Ching Huang
>From Ching Huang 

Add an option of set dma_mask_64 for ACB_ADAPTER_TYPE_A

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 8cc2134..45f1374 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -91,6 +91,10 @@ static int cmd_per_lun = ARCMSR_DEFAULT_CMD_PERLUN;
 module_param(cmd_per_lun, int, S_IRUGO);
 MODULE_PARM_DESC(cmd_per_lun, " device queue depth(1 ~ 128), default is 32");
 
+static int dma_mask_64 = 0;
+module_param(dma_mask_64, int, S_IRUGO);
+MODULE_PARM_DESC(dma_mask_64, " set DMA mask to 64 bits(0 ~ 1), 
dma_mask_64=1(64 bits), =0(32 bits)");
+
 static int set_date_time = 0;
 module_param(set_date_time, int, S_IRUGO);
 MODULE_PARM_DESC(set_date_time, " send date, time to iop(0 ~ 1), 
set_date_time=1(enable), default(=0) is disable");




[PATCH 10/12] scsi: arcmsr: Separate 'set dma mask' as a function

2018-12-19 Thread Ching Huang
>From Ching Huang 

Separate 'set dma mask' as a function

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 45f1374..30dff6c 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -927,6 +927,31 @@ static void arcmsr_init_set_datetime_timer(struct 
AdapterControlBlock *pacb)
add_timer(&pacb->refresh_timer);
 }
 
+static int arcmsr_set_dma_mask(struct AdapterControlBlock *acb)
+{
+   struct pci_dev *pcidev = acb->pdev;
+
+   if (IS_DMA64) {
+   if (((acb->adapter_type == ACB_ADAPTER_TYPE_A) && !dma_mask_64) 
||
+   dma_set_mask(&pcidev->dev, DMA_BIT_MASK(64)))
+   gotodma32;
+   if (dma_set_coherent_mask(&pcidev->dev, DMA_BIT_MASK(64)) ||
+   dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(64))) {
+   printk("arcmsr: set DMA 64 mask failed\n");
+   return -ENXIO;
+   }
+   } else {
+dma32:
+   if (dma_set_mask(&pcidev->dev, DMA_BIT_MASK(32)) ||
+   dma_set_coherent_mask(&pcidev->dev, DMA_BIT_MASK(32)) ||
+   dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32))) {
+   printk("arcmsr: set DMA 32-bit mask failed\n");
+   return -ENXIO;
+   }
+   }
+   return 0;
+}
+
 static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
struct Scsi_Host *host;
@@ -941,22 +966,15 @@ static int arcmsr_probe(struct pci_dev *pdev, const 
struct pci_device_id *id)
if(!host){
goto pci_disable_dev;
}
-   error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
-   if(error){
-   error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-   if(error){
-   printk(KERN_WARNING
-  "scsi%d: No suitable DMA mask available\n",
-  host->host_no);
-   goto scsi_host_release;
-   }
-   }
init_waitqueue_head(&wait_q);
bus = pdev->bus->number;
dev_fun = pdev->devfn;
acb = (struct AdapterControlBlock *) host->hostdata;
memset(acb,0,sizeof(struct AdapterControlBlock));
acb->pdev = pdev;
+   acb->adapter_type = id->driver_data;
+   if (arcmsr_set_dma_mask(acb))
+   goto scsi_host_release;
acb->host = host;
host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
@@ -986,7 +1004,6 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct 
pci_device_id *id)
ACB_F_MESSAGE_WQBUFFER_READED);
acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
INIT_LIST_HEAD(&acb->ccb_free_list);
-   acb->adapter_type = id->driver_data;
error = arcmsr_remap_pciregion(acb);
if(!error){
goto pci_release_regs;
@@ -1077,7 +1094,6 @@ static int arcmsr_suspend(struct pci_dev *pdev, 
pm_message_t state)
 
 static int arcmsr_resume(struct pci_dev *pdev)
 {
-   int error;
struct Scsi_Host *host = pci_get_drvdata(pdev);
struct AdapterControlBlock *acb =
(struct AdapterControlBlock *)host->hostdata;
@@ -1089,15 +1105,8 @@ static int arcmsr_resume(struct pci_dev *pdev)
pr_warn("%s: pci_enable_device error\n", __func__);
return -ENODEV;
}
-   error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
-   if (error) {
-   error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
-   if (error) {
-   pr_warn("scsi%d: No suitable DMA mask available\n",
-  host->host_no);
-   goto controller_unregister;
-   }
-   }
+   if (arcmsr_set_dma_mask(acb))
+   goto controller_unregister;
pci_set_master(pdev);
if (arcmsr_request_irq(pdev, acb) == FAILED)
goto controller_stop;




[PATCH 11/12] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B

2018-12-19 Thread Ching Huang
>From Ching Huang 

Fix suspend/resume of ACB_ADAPTER_TYPE_B

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 30dff6c..9f85d5a 100755
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1110,12 +1110,21 @@ static int arcmsr_resume(struct pci_dev *pdev)
pci_set_master(pdev);
if (arcmsr_request_irq(pdev, acb) == FAILED)
goto controller_stop;
-   if (acb->adapter_type == ACB_ADAPTER_TYPE_E) {
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_B: {
+   struct MessageUnit_B *reg = acb->pmuB;
+   reg->post_qbuffer[0] = 0;
+   reg->postq_index = 0;
+   reg->doneq_index = 0;
+   break;
+   }
+   case ACB_ADAPTER_TYPE_E:
writel(0, &acb->pmuE->host_int_status);
writel(ARCMSR_HBEMU_DOORBELL_SYNC, 
&acb->pmuE->iobound_doorbell);
acb->in_doorbell = 0;
acb->out_doorbell = 0;
acb->doneq_index = 0;
+   break;
}
arcmsr_iop_init(acb);
arcmsr_init_get_devmap_timer(acb);




[PATCH 12/12] scsi: arcmsr: Update driver version to v1.40.00.10-20181217

2018-12-19 Thread Ching Huang
>From Ching Huang 

Update driver version to v1.40.00.10-20181217

Signed-off-by: Ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 9041edc..a94c513 100755
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -49,7 +49,7 @@ struct device_attribute;
 #define ARCMSR_MAX_OUTSTANDING_CMD 1024
 #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128
 #define ARCMSR_MIN_OUTSTANDING_CMD 32
-#define ARCMSR_DRIVER_VERSION  "v1.40.00.09-20180709"
+#define ARCMSR_DRIVER_VERSION  "v1.40.00.10-20181217"
 #define ARCMSR_SCSI_INITIATOR_ID   255
 #define ARCMSR_MAX_XFER_SECTORS512
 #define ARCMSR_MAX_XFER_SECTORS_B  4096




[PATCH 0/2] scsi: arcmsr: fix SCSI command timeout on ARC-1886

2021-04-15 Thread ching Huang
This patch is against to mkp's 5.13/scsi-staging.

This patch fixed the wrong cdb payload report to IOP, that cause scsi command
timeout when scatter-gather count is large than some number.
---




[PATCH 1/2] scsi: arcmsr: fixed the wrong cdb payload report to IOP

2021-04-15 Thread ching Huang
From: ching Huang 

This patch fixed the wrong cdb payload report to IOP.

Signed-off-by: ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 4b79661..930972c 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -1923,8 +1923,12 @@ static void arcmsr_post_ccb(struct AdapterControlBlock 
*acb, struct CommandContr
 
if (ccb->arc_cdb_size <= 0x300)
arc_cdb_size = (ccb->arc_cdb_size - 1) >> 6 | 1;
-   else
-   arc_cdb_size = (((ccb->arc_cdb_size + 0xff) >> 8) + 2) 
<< 1 | 1;
+   else {
+   arc_cdb_size = ((ccb->arc_cdb_size + 0xff) >> 8) + 2;
+   if (arc_cdb_size > 0xF)
+   arc_cdb_size = 0xF;
+   arc_cdb_size = (arc_cdb_size << 1) | 1;
+   }
ccb_post_stamp = (ccb->smid | arc_cdb_size);
writel(0, &pmu->inbound_queueport_high);
writel(ccb_post_stamp, &pmu->inbound_queueport_low);



[PATH 2/2] scsi: arcmsr: update driver version to v1.50.00.04-20210414

2021-04-15 Thread ching Huang
From: ching Huang 

Update driver version to v1.50.00.04-20210414.

Signed-off-by: ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 0f6abd2..eb0ef73 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -49,7 +49,7 @@ struct device_attribute;
 #define ARCMSR_MAX_OUTSTANDING_CMD 1024
 #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128
 #define ARCMSR_MIN_OUTSTANDING_CMD 32
-#define ARCMSR_DRIVER_VERSION  "v1.50.00.02-20200819"
+#define ARCMSR_DRIVER_VERSION  "v1.50.00.04-20210414"
 #define ARCMSR_SCSI_INITIATOR_ID   255
 #define ARCMSR_MAX_XFER_SECTORS512
 #define ARCMSR_MAX_XFER_SECTORS_B  4096



[PATCH 2/2] scsi: arcmsr: update driver version to v1.50.00.04-20210414

2021-04-15 Thread ching Huang
From: ching Huang 

Update driver version to v1.50.00.04-20210414.

Signed-off-by: ching Huang 
---

diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 0f6abd2..eb0ef73 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -49,7 +49,7 @@ struct device_attribute;
 #define ARCMSR_MAX_OUTSTANDING_CMD 1024
 #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128
 #define ARCMSR_MIN_OUTSTANDING_CMD 32
-#define ARCMSR_DRIVER_VERSION  "v1.50.00.02-20200819"
+#define ARCMSR_DRIVER_VERSION  "v1.50.00.04-20210414"
 #define ARCMSR_SCSI_INITIATOR_ID   255
 #define ARCMSR_MAX_XFER_SECTORS512
 #define ARCMSR_MAX_XFER_SECTORS_B  4096



[PATCH v1.3 0/18] arcmsr: bugfix, new features and support new adapters

2014-08-01 Thread Ching Huang
Hi Christoph,

This patches are made against the 
git://git.infradead.org/users/hch/scsi-queue.git/tree/drivers/scsi/arcmsr/

This patches series address following issues.

1. Bugfix for command timeout, abort and ioctl error.

2. Add new feature of support MSI-X interrupt and system hibernation.

3. Support new adapters ARC12x4 series.

4. Simplify and unify code for readability and consistency.

Regards,
Ching

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 1/18] arcmsr: Revised interrupt service routine relate function to fix bug

2014-08-01 Thread Ching Huang

This patch rewrite the interrupt service routine relate function to fix command 
timeout when controller has very 
heavy loading.

Signed-off-by: Ching
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-07-30 10:33:02.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-04-28 16:02:46.0 +0800
@@ -51,7 +51,7 @@ struct device_attribute;
 #else
#define ARCMSR_MAX_FREECCB_NUM  320
 #endif
-#define ARCMSR_DRIVER_VERSION   "Driver Version 1.20.00.15 
2010/08/05"
+#define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140428"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
 #define ARCMSR_MAX_XFER_SECTORS
512
 #define ARCMSR_MAX_XFER_SECTORS_B  
4096
diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2014-07-30 10:32:28.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:02:44.0 +0800
@@ -1441,14 +1441,15 @@ static void arcmsr_hba_doorbell_isr(stru
uint32_t outbound_doorbell;
struct MessageUnit_A __iomem *reg = acb->pmuA;
outbound_doorbell = readl(®->outbound_doorbell);
-   writel(outbound_doorbell, ®->outbound_doorbell);
-   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
-   arcmsr_iop2drv_data_wrote_handle(acb);
-   }
-
-   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
-   arcmsr_iop2drv_data_read_handle(acb);
-   }
+   do {
+   writel(outbound_doorbell, ®->outbound_doorbell);
+   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK)
+   arcmsr_iop2drv_data_wrote_handle(acb);
+   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK)
+   arcmsr_iop2drv_data_read_handle(acb);
+   outbound_doorbell = readl(®->outbound_doorbell);
+   } while (outbound_doorbell & (ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK
+   | ARCMSR_OUTBOUND_IOP331_DATA_READ_OK));
 }
 static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *pACB)
 {
@@ -1462,17 +1463,19 @@ static void arcmsr_hbc_doorbell_isr(stru
***
*/
outbound_doorbell = readl(®->outbound_doorbell);
-   writel(outbound_doorbell, ®->outbound_doorbell_clear);/*clear 
interrupt*/
-   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
-   arcmsr_iop2drv_data_wrote_handle(pACB);
-   }
-   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
-   arcmsr_iop2drv_data_read_handle(pACB);
-   }
-   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
-   arcmsr_hbc_message_isr(pACB);/* messenger of "driver to iop 
commands" */
-   }
-   return;
+   do {
+   writel(outbound_doorbell, ®->outbound_doorbell_clear);
+   readl(®->outbound_doorbell_clear);
+   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK)
+   arcmsr_iop2drv_data_wrote_handle(pACB);
+   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK)
+   arcmsr_iop2drv_data_read_handle(pACB);
+   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE)
+   arcmsr_hbc_message_isr(pACB);
+   outbound_doorbell = readl(®->outbound_doorbell);
+   } while (outbound_doorbell & (ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK
+   | ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK
+   | ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE));
 }
 static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 {
@@ -1521,21 +1524,22 @@ static void arcmsr_hbc_postqueue_isr(str
/* areca cdb command done */
/* Use correct offset and size for syncing */
 
-   while (readl(&phbcmu->host_int_status) &
-   ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR){
-   /* check if command done with no error*/
-   flag_ccb = readl(&phbcmu->outbound_queueport_low);
-   ccb_cdb_phy = (flag_ccb & 0xFFF0);/*frame must be 32 bytes aligned*/
-   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
-   ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
-   error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
-   /* check if command done with no error */
-   arcmsr_drain_donequeue(acb, ccb, error);
-   if (throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
-   writel(ARCMSR_HBCMU_DRV2IOP_POSTQUEUE_THROTTLING, 
&phbcmu->inbound_doorbell);
-   break;
-   }
-   throttling++;
+   while ((flag_ccb = readl(&phbcmu->outbound_queueport_low)) != 
0x

[PATCH v1.3 2/18] arcmsr: Add code to support MSI-X, MSI interrupt

2014-08-01 Thread Ching Huang

This patch adds code to support MSI, MSI-X interrupt.

Signed-off-by: Ching
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-04-28 16:02:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:36.0 +0800
@@ -64,6 +64,7 @@ struct device_attribute;
 #define ARCMSR_MAX_HBB_POSTQUEUE   
264
 #define ARCMSR_MAX_XFER_LEN
0x26000 /* 152K */
 #define ARCMSR_CDB_SG_PAGE_LENGTH  
256 
+#define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
@@ -508,6 +509,7 @@ struct AdapterControlBlock
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
+   struct msix_entry   entries[ARCMST_NUM_MSIX_VECTORS];
/* Offset is used in making arc cdb physical to virtual calculations */
uint32_toutbound_int_enable;
uint32_tcdb_phyaddr_hi32;
@@ -544,6 +546,8 @@ struct AdapterControlBlock
/* iop init */
#define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400
+   #define ACB_F_MSI_ENABLED   0x1000
+   #define ACB_F_MSIX_ENABLED  0x2000
struct CommandControlBlock *
pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */
struct list_headccb_free_list;
@@ -594,6 +598,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
 ***
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-01 11:02:44.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:03:00.0 +0800
@@ -603,6 +603,60 @@ static void arcmsr_message_isr_bh_fn(str
}
 }
 
+static int
+arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
+{
+   int i, j, r;
+   struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
+
+   if (!pci_find_capability(pdev, PCI_CAP_ID_MSIX))
+   goto msi_int;
+   for (i = 0; i < ARCMST_NUM_MSIX_VECTORS; i++)
+   entries[i].entry = i;
+   r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS);
+   if (r < 0)
+   goto msi_int;
+   acb->msix_vector_count = r;
+   for (i = 0; i < r; i++) {
+   if (request_irq(entries[i].vector,
+   arcmsr_do_interrupt, 0, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, pdev->irq);
+   for (j = 0 ; j < i ; j++)
+   free_irq(entries[j].vector, acb);
+   pci_disable_msix(pdev);
+   goto msi_int;
+   }
+   acb->entries[i] = entries[i];
+   }
+   acb->acb_flags |= ACB_F_MSIX_ENABLED;
+   pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
+   return ARC_SUCCESS;
+msi_int:
+   if (!pci_find_capability(pdev, PCI_CAP_ID_MSI))
+   goto legacy_int;
+   if (pci_enable_msi_range(pdev, 1, 1) < 0)
+   goto legacy_int;
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, pdev->irq);
+   pci_disable_msi(pdev);
+   goto legacy_int;
+   }
+   acb->acb_flags |= ACB_F_MSI_ENABLED;
+   pr_info("arcmsr%d: msi enabled\n", acb->host->host_no);
+   return ARC_SUCCESS;
+legacy_int:
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq = %d failed!\n",
+   acb->host->host_no, pdev->irq);
+   return ARC_FAILURE;
+   }
+   return ARC_SUCCESS;
+}
+
 static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
struct Scsi_Host *host;
@@ -667,16 +721,13 @@ static int arcmsr_probe(struct pci_dev *
if(error){
goto free_hbb_mu;
}
-   arcmsr_iop_init(acb);
error = scsi_add_host(host, &pdev->dev);
if(error){
goto RAID_controller_stop;
}
-   error = request_irq(pdev->irq, arcmsr_do_interrup

[PATCH v1.3 3/18] arcmsr: Add code to support system hibernation

2014-08-01 Thread Ching Huang

This patch adds code to support system hibernation.

Signed-off-by: Ching
---

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-01 11:03:00.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:04:28.0 +0800
@@ -89,11 +89,15 @@ static int arcmsr_bios_param(struct scsi
 static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int arcmsr_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
+static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state);
+static int arcmsr_resume(struct pci_dev *pdev);
 static void arcmsr_remove(struct pci_dev *pdev);
 static void arcmsr_shutdown(struct pci_dev *pdev);
 static void arcmsr_iop_init(struct AdapterControlBlock *acb);
 static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb);
 static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb);
+static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
+   u32 intmask_org);
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb);
 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
@@ -167,6 +171,8 @@ static struct pci_driver arcmsr_pci_driv
.id_table   = arcmsr_device_id_table,
.probe  = arcmsr_probe,
.remove = arcmsr_remove,
+   .suspend= arcmsr_suspend,
+   .resume = arcmsr_resume,
.shutdown   = arcmsr_shutdown,
 };
 /*
@@ -776,6 +782,77 @@ static void arcmsr_free_irq(struct pci_d
free_irq(pdev->irq, acb);
 }
 
+static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+   uint32_t intmask_org;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host->hostdata;
+
+   intmask_org = arcmsr_disable_outbound_ints(acb);
+   arcmsr_free_irq(pdev, acb);
+   del_timer_sync(&acb->eternal_timer);
+   flush_scheduled_work();
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+   arcmsr_enable_outbound_ints(acb, intmask_org);
+   pci_set_drvdata(pdev, host);
+   pci_save_state(pdev);
+   pci_disable_device(pdev);
+   pci_set_power_state(pdev, pci_choose_state(pdev, state));
+   return 0;
+}
+
+static int arcmsr_resume(struct pci_dev *pdev)
+{
+   int error;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host->hostdata;
+
+   pci_set_power_state(pdev, PCI_D0);
+   pci_enable_wake(pdev, PCI_D0, 0);
+   pci_restore_state(pdev);
+   if (pci_enable_device(pdev)) {
+   pr_warn("%s: pci_enable_device error\n", __func__);
+   return -ENODEV;
+   }
+   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (error) {
+   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+   if (error) {
+   pr_warn("scsi%d: No suitable DMA mask available\n",
+  host->host_no);
+   goto controller_unregister;
+   }
+   }
+   pci_set_master(pdev);
+   if (arcmsr_request_irq(pdev, acb) == ARC_FAILURE)
+   goto controller_stop;
+   arcmsr_iop_init(acb);
+   INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
+   atomic_set(&acb->rq_map_token, 16);
+   atomic_set(&acb->ante_token_value, 16);
+   acb->fw_flag = FW_NORMAL;
+   init_timer(&acb->eternal_timer);
+   acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ);
+   acb->eternal_timer.data = (unsigned long) acb;
+   acb->eternal_timer.function = &arcmsr_request_device_map;
+   add_timer(&acb->eternal_timer);
+   return 0;
+controller_stop:
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+controller_unregister:
+   scsi_remove_host(host);
+   arcmsr_free_ccb_pool(acb);
+   arcmsr_unmap_pciregion(acb);
+   pci_release_regions(pdev);
+   scsi_host_put(host);
+   pci_disable_device(pdev);
+   return -ENODEV;
+}
+
 static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
 {
struct MessageUnit_A __iomem *reg = acb->pmuA;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 4/18] arcmsr: limit max. number of SCSI command request

2014-08-01 Thread Ching Huang

This patch limits the max. number of SCSI command request to avoid command 
overflow.

Signed-off-by: Ching
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:06.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:22:36.0 +0800
@@ -45,11 +45,12 @@
 #include 
 struct device_attribute;
 /*The limit of outstanding scsi command that firmware can handle*/
-#define ARCMSR_MAX_OUTSTANDING_CMD 
256
 #ifdef CONFIG_XEN
#define ARCMSR_MAX_FREECCB_NUM  160
+#define ARCMSR_MAX_OUTSTANDING_CMD 155
 #else
#define ARCMSR_MAX_FREECCB_NUM  320
+#define ARCMSR_MAX_OUTSTANDING_CMD 255
 #endif
 #define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140428"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
@@ -598,6 +599,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   uint32_tmaxOutstanding;
int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
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-01 11:04:28.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:05:44.0 +0800
@@ -134,7 +134,7 @@ static struct scsi_host_template arcmsr_
.eh_bus_reset_handler   = arcmsr_bus_reset,
.bios_param = arcmsr_bios_param,
.change_queue_depth = arcmsr_adjust_disk_queue_depth,
-   .can_queue  = ARCMSR_MAX_FREECCB_NUM,
+   .can_queue  = ARCMSR_MAX_OUTSTANDING_CMD,
.this_id= ARCMSR_SCSI_INITIATOR_ID,
.sg_tablesize   = ARCMSR_DEFAULT_SG_ENTRIES, 
.max_sectors= ARCMSR_MAX_XFER_SECTORS_C, 
@@ -697,7 +697,7 @@ static int arcmsr_probe(struct pci_dev *
host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
host->max_cmd_len = 16; /*this is issue of 
64bit LBA ,over 2T byte*/
-   host->can_queue = ARCMSR_MAX_FREECCB_NUM;   /* max simultaneous 
cmds */ 
+   host->can_queue = ARCMSR_MAX_OUTSTANDING_CMD;   /* max simultaneous 
cmds */ 
host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;  
host->this_id = ARCMSR_SCSI_INITIATOR_ID;
host->unique_id = (bus << 8) | dev_fun;
@@ -2220,8 +2220,7 @@ static int arcmsr_queue_command_lck(stru
arcmsr_handle_virtual_command(acb, cmd);
return 0;
}
-   if (atomic_read(&acb->ccboutstandingcount) >=
-   ARCMSR_MAX_OUTSTANDING_CMD)
+   if (atomic_read(&acb->ccboutstandingcount) >= acb->maxOutstanding)
return SCSI_MLQUEUE_HOST_BUSY;
ccb = arcmsr_get_freeccb(acb);
if (!ccb)
@@ -2432,12 +2431,26 @@ static bool arcmsr_get_hbc_config(struct
 }
 static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 {
-   if (acb->adapter_type == ACB_ADAPTER_TYPE_A)
-   return arcmsr_get_hba_config(acb);
-   else if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
-   return arcmsr_get_hbb_config(acb);
+   bool rtn = false;
+
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_A:
+   rtn = arcmsr_get_hba_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_B:
+   rtn = arcmsr_get_hbb_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_C:
+   rtn = arcmsr_get_hbc_config(acb);
+   break;
+   default:
+   break;
+   }
+   if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
+   acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD;
else
-   return arcmsr_get_hbc_config(acb);
+   acb->maxOutstanding = acb->firm_numbers_queue - 1;
+   return rtn;
 }
 
 static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 5/18] arcmsr: bugfix - return status of abort command

2014-08-01 Thread Ching Huang

This patch fixes the wrong return status of abort command.

Singed-off-by: Ching
---

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-01 11:05:44.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:06:34.0 +0800
@@ -2482,7 +2482,7 @@ static int arcmsr_polling_hba_ccbdone(st
}
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
-   poll_ccb_done = (ccb == poll_ccb) ? 1:0;
+   poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == 
poll_ccb)) {
printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun 
= %d ccb = '0x%p'"
@@ -2546,7 +2546,7 @@ static int arcmsr_polling_hbb_ccbdone(st
/* check if command done with no error*/
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
-   poll_ccb_done = (ccb == poll_ccb) ? 1:0;
+   poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == 
poll_ccb)) {
printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun 
= %d ccb = '0x%p'"
@@ -2602,7 +2602,7 @@ polling_hbc_ccb_retry:
ccb_cdb_phy = (flag_ccb & 0xFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
ccb_cdb_phy);/*frame must be 32 bytes aligned*/
pCCB = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
-   poll_ccb_done = (pCCB == poll_ccb) ? 1 : 0;
+   poll_ccb_done |= (pCCB == poll_ccb) ? 1 : 0;
/* check ifcommand done with no error*/
if ((pCCB->acb != acb) || (pCCB->startdone != 
ARCMSR_CCB_START)) {
if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
@@ -3204,6 +3204,8 @@ static int arcmsr_abort(struct scsi_cmnd
(struct AdapterControlBlock *)cmd->device->host->hostdata;
int i = 0;
int rtn = FAILED;
+   uint32_t intmask_org;
+
printk(KERN_NOTICE
"arcmsr%d: abort device command of scsi id = %d lun = %d \n",
acb->host->host_no, cmd->device->id, (u32)cmd->device->lun);
@@ -3215,9 +3217,12 @@ static int arcmsr_abort(struct scsi_cmnd
** we need to handle it as soon as possible and exit

*/
-   if (!atomic_read(&acb->ccboutstandingcount))
+   if (!atomic_read(&acb->ccboutstandingcount)) {
+   acb->acb_flags &= ~ACB_F_ABORT;
return rtn;
+   }
 
+   intmask_org = arcmsr_disable_outbound_ints(acb);
for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
struct CommandControlBlock *ccb = acb->pccb_pool[i];
if (ccb->startdone == ARCMSR_CCB_START && ccb->pcmd == cmd) {
@@ -3227,6 +3232,7 @@ static int arcmsr_abort(struct scsi_cmnd
}
}
acb->acb_flags &= ~ACB_F_ABORT;
+   arcmsr_enable_outbound_ints(acb, intmask_org);
return rtn;
 }
 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 6/18] arcmsr: precise checking adapter ID

2014-08-01 Thread Ching Huang

This patch rewrites the arcmsr_define_adapter_type function to precisely check 
Areca adapter's ID.
This can prevent an unknown adapter being used as a default adapter type by 
driver.

Signed-off-by: Ching
---

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-01 11:06:34.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:07:44.0 +0800
@@ -295,24 +295,43 @@ static int arcmsr_bios_param(struct scsi
return 0;
 }
 
-static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
+static bool arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
 {
struct pci_dev *pdev = acb->pdev;
u16 dev_id;
+
pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id);
acb->dev_id = dev_id;
switch (dev_id) {
-   case 0x1880: {
+   case 0x1880:
acb->adapter_type = ACB_ADAPTER_TYPE_C;
-   }
break;
-   case 0x1201: {
+   case 0x1200:
+   case 0x1201:
+   case 0x1202:
acb->adapter_type = ACB_ADAPTER_TYPE_B;
-   }
break;
-
-   default: acb->adapter_type = ACB_ADAPTER_TYPE_A;
+   case 0x1110:
+   case 0x1120:
+   case 0x1130:
+   case 0x1160:
+   case 0x1170:
+   case 0x1210:
+   case 0x1220:
+   case 0x1230:
+   case 0x1260:
+   case 0x1270:
+   case 0x1280:
+   case 0x1380:
+   case 0x1381:
+   case 0x1680:
+   acb->adapter_type = ACB_ADAPTER_TYPE_A;
+   break;
+   default:
+   pr_notice("Unknown device ID = 0x%x\n", dev_id);
+   return false;
}
+   return true;
 }
 
 static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
@@ -714,7 +733,9 @@ static int arcmsr_probe(struct pci_dev *
ACB_F_MESSAGE_WQBUFFER_READED);
acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
INIT_LIST_HEAD(&acb->ccb_free_list);
-   arcmsr_define_adapter_type(acb);
+   error = arcmsr_define_adapter_type(acb);
+   if (!error)
+   goto pci_release_regs;
error = arcmsr_remap_pciregion(acb);
if(!error){
goto pci_release_regs;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 1/2] arcmsr: simplify ioctl data read/write

2014-09-24 Thread Ching Huang
From: Ching Huang 

This patch is relative to:
http://git.infradead.org/users/hch/scsi-queue.git/tree/drivers-for-3.18:/drivers/scsi/arcmsr

change in v5:
1. rename firstindex to getIndex, lastindex to putIndex for readability
2. define ARCMSR_API_DATA_BUFLEN as 1032
3. simplify ioctl data read by marcro CIRC_CNT_TO_END and CIRC_CNT

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_attr.c 
b/drivers/scsi/arcmsr/arcmsr_attr.c
--- a/drivers/scsi/arcmsr/arcmsr_attr.c 2014-09-17 10:39:01.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-09-19 11:04:10.109098000 +0800
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -68,7 +69,7 @@ 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;
-   uint8_t *pQbuffer,*ptmpQbuffer;
+   uint8_t *ptmpQbuffer;
int32_t allxfer_len = 0;
unsigned long flags;
 
@@ -78,57 +79,22 @@ 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;
-   } 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_l

Re: [PATCH v5 1/2] arcmsr: simplify ioctl data read/write

2014-09-25 Thread Ching Huang
On Wed, 2014-09-24 at 17:48 +0200, Tomas Henzl wrote:
> On 09/24/2014 11:33 AM, Ching Huang wrote:
> > From: Ching Huang 
> >
> > This patch is relative to:
> > http://git.infradead.org/users/hch/scsi-queue.git/tree/drivers-for-3.18:/drivers/scsi/arcmsr
> >
> > change in v5:
> > 1. rename firstindex to getIndex, lastindex to putIndex for readability
> > 2. define ARCMSR_API_DATA_BUFLEN as 1032
> > 3. simplify ioctl data read by marcro CIRC_CNT_TO_END and CIRC_CNT
> >
> > Signed-off-by: Ching Huang 
> > ---
> >
> ...
> > +   pQbuffer = &acb->wqbuffer[acb->wqbuf_putIndex];
> > +   cnt2end = ARCMSR_MAX_QBUFFER - acb->wqbuf_putIndex;
> > +   if (user_len > cnt2end) {
> > +   memcpy(pQbuffer, ptmpuserbuffer, cnt2end);
> > +   ptmpuserbuffer += cnt2end;
> > +   user_len -= cnt2end;
> > +   acb->wqbuf_putIndex = 0;
> > +   pQbuffer = acb->wqbuffer;
> > }
> > +   memcpy(pQbuffer, ptmpuserbuffer, user_len);
> > +   acb->wqbuf_putIndex += user_len;
> > +   acb->wqbuf_putIndex %= ARCMSR_MAX_QBUFFER;
> > +   if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) {
> This test^ is most likely useless, it looks like you set the
> ACB_F_MESSAGE_WQBUFFER_CLEARED every time you have added some data to the 
> buffer
> and clear it when the buffer gets empty. I think you could get rid of
> the ACB_F_MESSAGE_WQBUFFER_CLEARED completely. Also the 
> ACB_F_MESSAGE_RQBUFFER_CLEARED doesn't
> seems to be ever evaluated.
> I'm not sure with the ACB_F_MESSAGE_WQBUFFER_READED, but that one probably is 
> also
> a candidate for removal.
You are right. ACB_F_MESSAGE_WQBUFFER_CLEARED, ACB_F_MESSAGE_RQBUFFER_CLEARED, 
ACB_F_MESSAGE_WQBUFFER_READED
are seem useless.
> ...
> > @@ -678,15 +679,15 @@ struct AdapterControlBlock
> > unsigned intuncache_size;
> > uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
> > /* data collection buffer for read from 80331 */
> > -   int32_t rqbuf_firstindex;
> > +   int32_t rqbuf_getIndex;
> What is the reason for using an exact size int32 (instead of a plain int) 
> here?
There is not special reason have to int32, int is OK.
> > /* 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 */
> 
> The comments I've added are not directly related to this patch,
> but you may still address them in a new patch
> so -
> Reviewed-by: Tomas Henzl 
> 
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 1/2] arcmsr: simplify ioctl data read/write

2014-09-25 Thread Ching Huang
On Thu, 2014-09-25 at 19:01 +0200, Christoph Hellwig wrote:
> Thanks, applied to drivers-for-3.18.
Thanks for all of your review, especially Tomas.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 16/17] arcmsr: support new adapter ARC12x4 series

2014-09-10 Thread Ching Huang
On Wed, 2014-09-10 at 11:58 +0200, Tomas Henzl wrote:
> On 09/09/2014 06:30 PM, Christoph Hellwig wrote:
> > Ching,
> >
> > do you have a chance to address Thomas second concern below?  As
> > far as I can tell (Thomas, please correct me) that's the last
> > outstanding concern, and I'd really like to merge the arcmsr updates
> > for the Linux 3.18 merge window.
> 
> Correct, still awaiting a response.

Christoph, Tomas,

Sorry for the late reply.

I think I misunderstand Tomas' meaning.
The spin lock in arcmsr_hbaD_polling_ccbdone() is necessary to protect 
doneq_index and have to be modified as following.

static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
{
bool error;
uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
int rtn, doneq_index, index_stripped, outbound_write_pointer, toggle;
unsigned long flags;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *pCCB;
struct MessageUnit_D *pmu = acb->pmuD;

polling_hbaD_ccb_retry:
poll_count++;
while (1) {
spin_lock_irqsave(&acb->doneq_lock, flags);
outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) {
spin_unlock_irqrestore(&acb->doneq_lock, flags);
if (poll_ccb_done) {
rtn = SUCCESS;
break;
} else {
msleep(25);
if (poll_count > 40) {
rtn = FAILED;
break;
}
goto polling_hbaD_ccb_retry;
}
}
toggle = doneq_index & 0x4000;
index_stripped = (doneq_index & 0xFFF) + 1;
index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
((index_stripped + 1) | (toggle ^ 0x4000));
spin_unlock_irqrestore(&acb->doneq_lock, flags);
doneq_index = pmu->doneq_index;
flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (flag_ccb & 0xFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +
ccb_cdb_phy);
pCCB = container_of(arcmsr_cdb, struct CommandControlBlock,
arcmsr_cdb);
poll_ccb_done |= (pCCB == poll_ccb) ? 1 : 0;
if ((pCCB->acb != acb) ||
(pCCB->startdone != ARCMSR_CCB_START)) {
if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
pr_notice("arcmsr%d: scsi id = %d "
"lun = %d ccb = '0x%p' poll command "
"abort successfully\n"
, acb->host->host_no
, pCCB->pcmd->device->id
, (u32)pCCB->pcmd->device->lun
, pCCB);
pCCB->pcmd->result = DID_ABORT << 16;
arcmsr_ccb_complete(pCCB);
continue;
}
pr_notice("arcmsr%d: polling an illegal "
"ccb command done ccb = '0x%p' "
"ccboutstandingcount = %d\n"
, acb->host->host_no
, pCCB
, atomic_read(&acb->ccboutstandingcount));
continue;
}
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1)
? true : false;
arcmsr_report_ccb_state(acb, pCCB, error);
}
return rtn;
}


> 
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 16/17] arcmsr: support new adapter ARC12x4 series

2014-09-11 Thread Ching Huang
On Thu, 2014-09-11 at 16:21 +0200, Tomas Henzl wrote:
> On 09/11/2014 05:59 AM, Ching Huang wrote:
> > On Wed, 2014-09-10 at 11:58 +0200, Tomas Henzl wrote:
> >> On 09/09/2014 06:30 PM, Christoph Hellwig wrote:
> >>> Ching,
> >>>
> >>> do you have a chance to address Thomas second concern below?  As
> >>> far as I can tell (Thomas, please correct me) that's the last
> >>> outstanding concern, and I'd really like to merge the arcmsr updates
> >>> for the Linux 3.18 merge window.
> >> Correct, still awaiting a response.
> > Christoph, Tomas,
> >
> > Sorry for the late reply.
> >
> > I think I misunderstand Tomas' meaning.
> > The spin lock in arcmsr_hbaD_polling_ccbdone() is necessary to protect 
> > doneq_index and have to be modified as following.
> 
> OK, so you are going to repost 16/17 ? If so, please describe all changes 
> you'll do, in that new post.
> 
By previous review, I will post two patches.
One for 13/17 and another for 16/17.
These patches are relative to 
http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr
> >
> > static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
> > struct CommandControlBlock *poll_ccb)
> > {
> > bool error;
> > uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
> > int rtn, doneq_index, index_stripped, outbound_write_pointer, toggle;
> > unsigned long flags;
> > struct ARCMSR_CDB *arcmsr_cdb;
> > struct CommandControlBlock *pCCB;
> > struct MessageUnit_D *pmu = acb->pmuD;
> >
> > polling_hbaD_ccb_retry:
> > poll_count++;
> > while (1) {
> > spin_lock_irqsave(&acb->doneq_lock, flags);
> > outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
> > doneq_index = pmu->doneq_index;
> > if ((outbound_write_pointer & 0xFFF) == (doneq_index & 0xFFF)) {
> > spin_unlock_irqrestore(&acb->doneq_lock, flags);
> > if (poll_ccb_done) {
> > rtn = SUCCESS;
> > break;
> > } else {
> > msleep(25);
> > if (poll_count > 40) {
> > rtn = FAILED;
> > break;
> > }
> > goto polling_hbaD_ccb_retry;
> > }
> > }
> > toggle = doneq_index & 0x4000;
> > index_stripped = (doneq_index & 0xFFF) + 1;
> > index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
> > pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
> > ((index_stripped + 1) | (toggle ^ 0x4000));
> > spin_unlock_irqrestore(&acb->doneq_lock, flags);
> > doneq_index = pmu->doneq_index;
> > flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
> > ccb_cdb_phy = (flag_ccb & 0xFFF0);
> > arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +
> > ccb_cdb_phy);
> > pCCB = container_of(arcmsr_cdb, struct CommandControlBlock,
> > arcmsr_cdb);
> > poll_ccb_done |= (pCCB == poll_ccb) ? 1 : 0;
> > if ((pCCB->acb != acb) ||
> > (pCCB->startdone != ARCMSR_CCB_START)) {
> > if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
> > pr_notice("arcmsr%d: scsi id = %d "
> > "lun = %d ccb = '0x%p' poll command "
> > "abort successfully\n"
> > , acb->host->host_no
> > , pCCB->pcmd->device->id
> > , (u32)pCCB->pcmd->device->lun
> > , pCCB);
> > pCCB->pcmd->result = DID_ABORT << 16;
> > arcmsr_ccb_complete(pCCB);
> > continue;
> > }
> > pr_notice("arcmsr%d: polling an illegal "
> > "ccb command done c

[PATCH v4 1/2] arcmsr: simplify ioctl data read/write

2014-09-12 Thread Ching Huang
From: Ching Huang 

This patch is to modify previous patch 13/17 and it is relative to
http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr

change in v4:
1. for readability, rename firstindex to getIndex, rename lastindex to putIndex
2. define ARCMSR_API_DATA_BUFLEN as 1032
3. simplify ioctl data read by macro CIRC_CNT_TO_END and CIRC_CNT

Signed-off-by: Ching Huang 
---

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.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-09-12 15:18:46.659125000 +0800
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -68,7 +69,7 @@ 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;
-   uint8_t *pQbuffer,*ptmpQbuffer;
+   uint8_t *ptmpQbuffer;
int32_t allxfer_len = 0;
unsigned long flags;
 
@@ -78,57 +79,22 @@ 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;
-   } 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_

[PATCH v4 2/2] arcmsr: simplify of updating doneq_index and postq_index

2014-09-12 Thread Ching Huang
From: Ching Huang 

This patch is to modify previous patch 16/17 and it is relative to
http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr

change in v4:
1. clean up of duplicate variable declaration in switch.
2. simplify of updating doneq_index and postq_index
3. fix spin_lock area in arcmsr_hbaD_polling_ccbdone

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2014-09-12 12:43:16.956653000 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-09-12 15:00:23.516069000 +0800
@@ -1121,7 +1121,7 @@ static void arcmsr_drain_donequeue(struc
 static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 {
int i = 0;
-   uint32_t flag_ccb;
+   uint32_t flag_ccb, ccb_cdb_phy;
struct ARCMSR_CDB *pARCMSR_CDB;
bool error;
struct CommandControlBlock *pCCB;
@@ -1165,10 +1165,6 @@ static void arcmsr_done4abort_postqueue(
break;
case ACB_ADAPTER_TYPE_C: {
struct MessageUnit_C __iomem *reg = acb->pmuC;
-   struct  ARCMSR_CDB *pARCMSR_CDB;
-   uint32_t flag_ccb, ccb_cdb_phy;
-   bool error;
-   struct CommandControlBlock *pCCB;
while ((readl(®->host_int_status) & 
ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
/*need to do*/
flag_ccb = readl(®->outbound_queueport_low);
@@ -1182,10 +1178,8 @@ static void arcmsr_done4abort_postqueue(
break;
case ACB_ADAPTER_TYPE_D: {
struct MessageUnit_D  *pmu = acb->pmuD;
-   uint32_t ccb_cdb_phy, outbound_write_pointer;
-   uint32_t doneq_index, index_stripped, addressLow, residual;
-   bool error;
-   struct CommandControlBlock *pCCB;
+   uint32_t outbound_write_pointer;
+   uint32_t doneq_index, index_stripped, addressLow, residual, 
toggle;
 
outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
doneq_index = pmu->doneq_index;
@@ -1193,23 +1187,11 @@ static void arcmsr_done4abort_postqueue(
for (i = 0; i < residual; i++) {
while ((doneq_index & 0xFFF) !=
(outbound_write_pointer & 0xFFF)) {
-   if (doneq_index & 0x4000) {
-   index_stripped = doneq_index & 0xFFF;
-   index_stripped += 1;
-   index_stripped %=
-   ARCMSR_MAX_ARC1214_DONEQUEUE;
-   pmu->doneq_index = index_stripped ?
-   (index_stripped | 0x4000) :
-   (index_stripped + 1);
-   } else {
-   index_stripped = doneq_index;
-   index_stripped += 1;
-   index_stripped %=
-   ARCMSR_MAX_ARC1214_DONEQUEUE;
-   pmu->doneq_index = index_stripped ?
-   index_stripped :
-   ((index_stripped | 0x4000) + 1);
-   }
+   toggle = doneq_index & 0x4000;
+   index_stripped = (doneq_index & 0xFFF) + 1;
+   index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+   pmu->doneq_index = index_stripped ? 
(index_stripped | toggle) :
+   ((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
@@ -1461,7 +1443,7 @@ static void arcmsr_post_ccb(struct Adapt
case ACB_ADAPTER_TYPE_D: {
struct MessageUnit_D  *pmu = acb->pmuD;
u16 index_stripped;
-   u16 postq_index;
+   u16 postq_index, toggle;
unsigned long flags;
struct InBound_SRB *pinbound_srb;
 
@@ -1472,19 +1454,11 @@ static void arcmsr_post_ccb(struct Adapt
pinbound_srb->addressLow = dma_addr_lo32(cdb_phyaddr);
pinbound_srb->length = ccb->arc_cdb_size >> 2;
arcmsr_cdb->msgContext = dma_addr_lo32(cdb_phyaddr);
-   if (postq_index & 0x4000) {
-   index_stripped = postq_index & 0xFF;
-  

Re: [PATCH v4 1/2] arcmsr: simplify ioctl data read/write

2014-09-14 Thread Ching Huang
On Fri, 2014-09-12 at 15:34 +0200, Tomas Henzl wrote:
> On 09/12/2014 09:29 AM, Ching Huang wrote:
> > From: Ching Huang 
> >
> > This patch is to modify previous patch 13/17 and it is relative to
> > http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr
> >
> > change in v4:
> > 1. for readability, rename firstindex to getIndex, rename lastindex to 
> > putIndex
> For some reason, the names head+tail areusual for a circular buffer.
> But let us ignore the names, I don't care.
> > 2. define ARCMSR_API_DATA_BUFLEN as 1032
> > 3. simplify ioctl data read by macro CIRC_CNT_TO_END and CIRC_CNT
> It's definitely better when you post renames and other non-functional changes 
> in separate
> patches, it's easier for the reviewer. 
> >
> > Signed-off-by: Ching Huang 
> > ---
> >
> > 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.0 
> > +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-09-12 15:18:46.659125000 
> > +0800
> > @@ -50,6 +50,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include 
> >  #include 
> > @@ -68,7 +69,7 @@ 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;
> > -   uint8_t *pQbuffer,*ptmpQbuffer;
> > +   uint8_t *ptmpQbuffer;
> > int32_t allxfer_len = 0;
> > unsigned long flags;
> >  
> > @@ -78,57 +79,22 @@ 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;
> > -   } 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;
> > -   }
> > -  

Re: [PATCH v4 2/2] arcmsr: simplify of updating doneq_index and postq_index

2014-09-14 Thread Ching Huang
On Fri, 2014-09-12 at 16:05 +0200, Tomas Henzl wrote:
> On 09/12/2014 10:22 AM, Ching Huang wrote:
> > From: Ching Huang 
> >
> > This patch is to modify previous patch 16/17 and it is relative to
> > http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr
> >
> > change in v4:
> > 1. clean up of duplicate variable declaration in switch.
> > 2. simplify of updating doneq_index and postq_index
> > 3. fix spin_lock area in arcmsr_hbaD_polling_ccbdone
> 
> The intention of the doneq_lock is to protect the pmu->doneq_index and the 
> associated buffer,
> right? Why is the spinlock not used on other places accessing the doneq_index
> like arcmsr_done4abort_postqueue or arcmsr_hbaD_postqueue_isr ?
In fact, in original code arcmsr_hbaD_postqueue_isr has spinlock with a larger 
area.
As to arcmsr_done4abort_postqueue, it should be protected as below.

@@ -1182,35 +1178,25 @@ static void arcmsr_done4abort_postqueue(
break;
case ACB_ADAPTER_TYPE_D: {
struct MessageUnit_D  *pmu = acb->pmuD;
-   uint32_t ccb_cdb_phy, outbound_write_pointer;
-   uint32_t doneq_index, index_stripped, addressLow, residual;
-   bool error;
-   struct CommandControlBlock *pCCB;
+   uint32_t outbound_write_pointer;
+   uint32_t doneq_index, index_stripped, addressLow, residual, 
toggle;
+   unsigned long flags;
 
-   outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
-   doneq_index = pmu->doneq_index;
residual = atomic_read(&acb->ccboutstandingcount);
for (i = 0; i < residual; i++) {
-   while ((doneq_index & 0xFFF) !=
+   spin_lock_irqsave(&acb->doneq_lock, flags);
+   outbound_write_pointer =
+   pmu->done_qbuffer[0].addressLow + 1;
+   doneq_index = pmu->doneq_index;
+   if ((doneq_index & 0xFFF) !=
(outbound_write_pointer & 0xFFF)) {
-   if (doneq_index & 0x4000) {
-   index_stripped = doneq_index & 0xFFF;
-   index_stripped += 1;
-   index_stripped %=
-   ARCMSR_MAX_ARC1214_DONEQUEUE;
-   pmu->doneq_index = index_stripped ?
-   (index_stripped | 0x4000) :
-   (index_stripped + 1);
-   } else {
-   index_stripped = doneq_index;
-   index_stripped += 1;
-   index_stripped %=
-   ARCMSR_MAX_ARC1214_DONEQUEUE;
-   pmu->doneq_index = index_stripped ?
-   index_stripped :
-   ((index_stripped | 0x4000) + 1);
-   }
+   toggle = doneq_index & 0x4000;
+   index_stripped = (doneq_index & 0xFFF) + 1;
+   index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+   pmu->doneq_index = index_stripped ? 
(index_stripped | toggle) :
+   ((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
+   spin_unlock_irqrestore(&acb->doneq_lock, flags);
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFF0);
@@ -1224,11 +1210,10 @@ static void arcmsr_done4abort_postqueue(
arcmsr_drain_donequeue(acb, pCCB, error);
writel(doneq_index,
pmu->outboundlist_read_pointer);
+   } else {
+   spin_unlock_irqrestore(&acb->doneq_lock, flags);
+   mdelay(10);
}
-   mdelay(10);
-   outbound_write_pointer =
-   pmu->done_qbuffer[0].addressLow + 1;
-   doneq_index = pmu->doneq_index;
}
pmu->postq_index = 0;
pmu->doneq_index = 0x40FF;


> And in arcmsr_hbaD_polling_ccbdone the code looks so:
> 
>   

Re: [PATCH v4 1/2] arcmsr: simplify ioctl data read/write

2014-09-15 Thread Ching Huang
On Mon, 2014-09-15 at 12:25 +0200, Tomas Henzl wrote:
> On 09/15/2014 04:56 AM, Ching Huang wrote:
> > On Fri, 2014-09-12 at 15:34 +0200, Tomas Henzl wrote:
> >> On 09/12/2014 09:29 AM, Ching Huang wrote:
> >>> From: Ching Huang 
> >>>
> >>> This patch is to modify previous patch 13/17 and it is relative to
> >>> http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr
> >>>
> >>> change in v4:
> >>> 1. for readability, rename firstindex to getIndex, rename lastindex to 
> >>> putIndex
> >> For some reason, the names head+tail areusual for a circular buffer.
> >> But let us ignore the names, I don't care.
> >>> 2. define ARCMSR_API_DATA_BUFLEN as 1032
> >>> 3. simplify ioctl data read by macro CIRC_CNT_TO_END and CIRC_CNT
> >> It's definitely better when you post renames and other non-functional 
> >> changes in separate
> >> patches, it's easier for the reviewer. 
> >>> Signed-off-by: Ching Huang 
> >>> ---
> >>>
> >>> 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.0 
> >>> +0800
> >>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c   2014-09-12 15:18:46.659125000 
> >>> +0800
> >>> @@ -50,6 +50,7 @@
> >>>  #include 
> >>>  #include 
> >>>  #include 
> >>> +#include 
> >>>  
> >>>  #include 
> >>>  #include 
> >>> @@ -68,7 +69,7 @@ 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;
> >>> - uint8_t *pQbuffer,*ptmpQbuffer;
> >>> + uint8_t *ptmpQbuffer;
> >>>   int32_t allxfer_len = 0;
> >>>   unsigned long flags;
> >>>  
> >>> @@ -78,57 +79,22 @@ 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;
> >>> - } 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 -
> >>> - 

[PATCH v5 2/2] arcmsr: simplify of updating doneq_index and postq_index

2014-09-15 Thread Ching Huang
From: Ching Huang 

This patch is to modify previous patch 16/17 and it is relative to
http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr

change since v4:
1. add spin_lock in arcmsr_done4abort_postqueue for protect doneq_index.
2. fix spinlock area in arcmsr_hbaD_polling_ccbdone.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2014-09-12 12:43:16.956653000 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-09-15 18:53:44.483743000 +0800
@@ -1121,7 +1121,7 @@ static void arcmsr_drain_donequeue(struc
 static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
 {
int i = 0;
-   uint32_t flag_ccb;
+   uint32_t flag_ccb, ccb_cdb_phy;
struct ARCMSR_CDB *pARCMSR_CDB;
bool error;
struct CommandControlBlock *pCCB;
@@ -1165,10 +1165,6 @@ static void arcmsr_done4abort_postqueue(
break;
case ACB_ADAPTER_TYPE_C: {
struct MessageUnit_C __iomem *reg = acb->pmuC;
-   struct  ARCMSR_CDB *pARCMSR_CDB;
-   uint32_t flag_ccb, ccb_cdb_phy;
-   bool error;
-   struct CommandControlBlock *pCCB;
while ((readl(®->host_int_status) & 
ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
/*need to do*/
flag_ccb = readl(®->outbound_queueport_low);
@@ -1182,35 +1178,25 @@ static void arcmsr_done4abort_postqueue(
break;
case ACB_ADAPTER_TYPE_D: {
struct MessageUnit_D  *pmu = acb->pmuD;
-   uint32_t ccb_cdb_phy, outbound_write_pointer;
-   uint32_t doneq_index, index_stripped, addressLow, residual;
-   bool error;
-   struct CommandControlBlock *pCCB;
+   uint32_t outbound_write_pointer;
+   uint32_t doneq_index, index_stripped, addressLow, residual, 
toggle;
+   unsigned long flags;
 
-   outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
-   doneq_index = pmu->doneq_index;
residual = atomic_read(&acb->ccboutstandingcount);
for (i = 0; i < residual; i++) {
-   while ((doneq_index & 0xFFF) !=
+   spin_lock_irqsave(&acb->doneq_lock, flags);
+   outbound_write_pointer =
+   pmu->done_qbuffer[0].addressLow + 1;
+   doneq_index = pmu->doneq_index;
+   if ((doneq_index & 0xFFF) !=
(outbound_write_pointer & 0xFFF)) {
-   if (doneq_index & 0x4000) {
-   index_stripped = doneq_index & 0xFFF;
-   index_stripped += 1;
-   index_stripped %=
-   ARCMSR_MAX_ARC1214_DONEQUEUE;
-   pmu->doneq_index = index_stripped ?
-   (index_stripped | 0x4000) :
-   (index_stripped + 1);
-   } else {
-   index_stripped = doneq_index;
-   index_stripped += 1;
-   index_stripped %=
-   ARCMSR_MAX_ARC1214_DONEQUEUE;
-   pmu->doneq_index = index_stripped ?
-   index_stripped :
-   ((index_stripped | 0x4000) + 1);
-   }
+   toggle = doneq_index & 0x4000;
+   index_stripped = (doneq_index & 0xFFF) + 1;
+   index_stripped %= ARCMSR_MAX_ARC1214_DONEQUEUE;
+   pmu->doneq_index = index_stripped ? 
(index_stripped | toggle) :
+   ((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
+   spin_unlock_irqrestore(&acb->doneq_lock, flags);
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFF0);
@@ -1224,11 +1210,10 @@ static void arcmsr_done4abort_postqueue(
arcmsr_drain_donequeue(acb, pCCB, error);
writel(doneq_index,
pmu->outboundlist_read_poin

Re: [PATCH v4 1/2] arcmsr: simplify ioctl data read/write

2014-09-15 Thread Ching Huang
On Mon, 2014-09-15 at 13:50 +0200, Tomas Henzl wrote:
> On 09/15/2014 12:36 PM, Ching Huang wrote:
> > On Mon, 2014-09-15 at 12:25 +0200, Tomas Henzl wrote:
> >> On 09/15/2014 04:56 AM, Ching Huang wrote:
> >>> On Fri, 2014-09-12 at 15:34 +0200, Tomas Henzl wrote:
> >>>> On 09/12/2014 09:29 AM, Ching Huang wrote:
> >>>>> From: Ching Huang 
> >>>>>
> >>>>> This patch is to modify previous patch 13/17 and it is relative to
> >>>>> http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr
> >>>>>
> >>>>> change in v4:
> >>>>> 1. for readability, rename firstindex to getIndex, rename lastindex to 
> >>>>> putIndex
> >>>> For some reason, the names head+tail areusual for a circular buffer.
> >>>> But let us ignore the names, I don't care.
> >>>>> 2. define ARCMSR_API_DATA_BUFLEN as 1032
> >>>>> 3. simplify ioctl data read by macro CIRC_CNT_TO_END and CIRC_CNT
> >>>> It's definitely better when you post renames and other non-functional 
> >>>> changes in separate
> >>>> patches, it's easier for the reviewer. 
> >>>>> Signed-off-by: Ching Huang 
> >>>>> ---
> >>>>>
> >>>>> 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.0 
> >>>>> +0800
> >>>>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-09-12 15:18:46.659125000 
> >>>>> +0800
> >>>>> @@ -50,6 +50,7 @@
> >>>>>  #include 
> >>>>>  #include 
> >>>>>  #include 
> >>>>> +#include 
> >>>>>  
> >>>>>  #include 
> >>>>>  #include 
> >>>>> @@ -68,7 +69,7 @@ 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;
> >>>>> -   uint8_t *pQbuffer,*ptmpQbuffer;
> >>>>> +   uint8_t *ptmpQbuffer;
> >>>>> int32_t allxfer_len = 0;
> >>>>> unsigned long flags;
> >>>>>  
> >>>>> @@ -78,57 +79,22 @@ 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;
> >>>>> -   } 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, 
> >>>>

Re: [PATCH v3 16/17] arcmsr: support new adapter ARC12x4 series

2014-09-15 Thread Ching Huang
On Mon, 2014-09-15 at 10:05 -0700, Christoph Hellwig wrote:
> On Mon, Sep 15, 2014 at 03:23:36PM +0200, Tomas Henzl wrote:
> > Christoph,
> > 
> > you may add my 'reviewed-by' to the arcmsr series
> > http://git.infradead.org/users/hch/scsi-queue.git/tree/arcmsr-for-3.18:/drivers/scsi/arcmsr
> > with the '[PATCH v5 2/2] arcmsr: simplify of updating doneq_index and 
> > postq_index'
> > ( https://lkml.org/lkml/2014/9/15/177 ) on top of the series
> > that last patch fixes the 16/17 from your git.
> > I hope the series is an iteration in the right direction.
> > Skip the the '[PATCH v4 1/2] arcmsr: simplify ioctl data read/write', Ching 
> > will repost it later.
> 
> Thanks a lot Tomas for all the review, and thanks Ching for the patches
> and updates.  I'll merge the branch and the additional patch today.
> 

Christoph,

The [PATCH v5 2/2] was depend on [PATCH v4 1/2].
If you skip patch 1/2, then patch 2/2 may cause line number mismatch.
How should I do? Please advise.



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C

2014-08-25 Thread Ching Huang
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 
> >
> > 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 
> > ---
> >
> > 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.0 
> > +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-04-29 17:10:42.0 
> > +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 -
> > +  

Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C

2014-08-26 Thread Ching Huang
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 
> >>>
> >>> 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 
> >>> ---
> >>>
> >>> 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.0 
> >>> +0800
> >>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c   2014-04-29 17:10:42.0 
> >>> +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 
> >> sh

Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C

2014-08-27 Thread Ching Huang
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 
> >>>>>
> >>>>> 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 
> >>>>> ---
> >>>>>
> >>>>> 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.0 
> >>>>> +0800
> >>>>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-04-29 17:10:42.0 
> >>>>> +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,
> >>

Re: [PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C

2014-08-27 Thread Ching Huang
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 
> >>>>>>>
> >>>>>>> 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 
> >>>>>>> ---
> >>>>>>>
> >>>>>>> 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.0 +0800
> >>>>>>> +++ b/drivers/scsi/arcmsr/arcmsr_attr.c   2014-04-29 
> >>>>>>> 17:10:42.0 +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);
> >>>>>>> + ptmpQb

Re: [PATCH v3 16/17] arcmsr: support new adapter ARC12x4 series

2014-08-28 Thread Ching Huang
On Wed, 2014-08-27 at 16:00 +0200, Tomas Henzl wrote:
> On 08/19/2014 09:25 AM, Ching Huang wrote:
> > From: Ching Huang 
> >
> > Add code for supporting Areca new Raid adapter ARC12x4 series.
> >
> > Signed-off-by: Ching Huang 
> > ---
> 
> Hi Ching,
> please look at the comments below -
> 
> >  }
> > @@ -1039,7 +1147,60 @@ static void arcmsr_done4abort_postqueue(
> > error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? 
> > true : false;
> > arcmsr_drain_donequeue(acb, pCCB, error);
> > }
> > -   }
> > +   }
> > +   break;
> > +   case ACB_ADAPTER_TYPE_D: {
> > +   struct MessageUnit_D  *pmu = acb->pmuD;
> > +   uint32_t ccb_cdb_phy, outbound_write_pointer;
> > +   uint32_t doneq_index, index_stripped, addressLow, residual;
> > +   bool error;
> > +   struct CommandControlBlock *pCCB;
> 
> I have noticed this^ in this driver already before. Sometimes it makes sense
> when a variable is declared in a 'case' block but often it is just
> a waste of space. In this function this is the third 'bool error' declared.
> Is there a reason for this style (this function is not the worst case) ?
Yea, there is many variable are duplicate declaration, I will clean it up.
> 
> > +   outbound_write_pointer = pmu->done_qbuffer[0].addressLow + 1;
> > +   doneq_index = pmu->doneq_index;
> > +   residual = atomic_read(&acb->ccboutstandingcount);
> > +   for (i = 0; i < residual; i++) {
> > +   while ((doneq_index & 0xFFF) !=
> > +   (outbound_write_pointer & 0xFFF)) {
> > +   if (doneq_index & 0x4000) {
> > +   index_stripped = doneq_index & 0xFFF;
> > +   index_stripped += 1;
> > +   index_stripped %=
> > +   ARCMSR_MAX_ARC1214_DONEQUEUE;
> > +   pmu->doneq_index = index_stripped ?
> > +   (index_stripped | 0x4000) :
> > +   (index_stripped + 1);
> > +   } else {
> > +   index_stripped = doneq_index;
> > +   index_stripped += 1;
> > +   index_stripped %=
> > +   ARCMSR_MAX_ARC1214_DONEQUEUE;
> > +   pmu->doneq_index = index_stripped ?
> > +   index_stripped :
> > +   ((index_stripped | 0x4000) + 1);
> > +   }
> > +   doneq_index = pmu->doneq_index;
> > +   addressLow = pmu->done_qbuffer[doneq_index &
> > +   0xFFF].addressLow;
> > +   ccb_cdb_phy = (addressLow & 0xFFF0);
> > +   pARCMSR_CDB = (struct  ARCMSR_CDB *)
> > +   (acb->vir2phy_offset + ccb_cdb_phy);
> > +   pCCB = container_of(pARCMSR_CDB,
> > +   struct CommandControlBlock, arcmsr_cdb);
> > +   error = (addressLow &
> > +   ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ?
> > +   true : false;
> > +   arcmsr_drain_donequeue(acb, pCCB, error);
> > +   writel(doneq_index, 
> > pmu->outboundlist_read_pointer);
> > +   }
> > +   mdelay(10);
> > +   outbound_write_pointer =
> > +   pmu->done_qbuffer[0].addressLow + 1;
> > +   doneq_index = pmu->doneq_index;
> > +   }
> > +   pmu->postq_index = 0;
> > +   pmu->doneq_index = 0x40FF;
> > +   }
> > +   break;
> > }
> >  }
> ...
> 
> >
> >  
> > @@ -1256,6 +1424,38 @@ static void arcmsr_post_ccb(struct Adapt
> > writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
> > }
> > }
> > +   break;
> > +   case ACB_ADAPTER_TYPE_D: {
> > +   struct MessageU

[PATCH v3 0/17] arcmsr: change note since v13 or v2

2014-08-18 Thread Ching Huang

Change note:
1,5,7~17/17 since v1.3 are not change.
2,3,4/17 since v2 are not change.

6/17 since v2:
1. pre-define adapter_type value in private data of pci_device_id.
2. remove the arcmsr_define_adapter_type function.

Ching Huang 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/17] arcmsr: Revised interrupt service routine relate function to fix bug

2014-08-18 Thread Ching Huang
From: Ching Huang 

This patch rewrite the interrupt service routine relate function to fix command 
timeout when controller has very heavy loading.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-07-30 10:33:02.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-04-28 16:02:46.0 +0800
@@ -51,7 +51,7 @@ struct device_attribute;
 #else
#define ARCMSR_MAX_FREECCB_NUM  320
 #endif
-#define ARCMSR_DRIVER_VERSION   "Driver Version 1.20.00.15 
2010/08/05"
+#define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140428"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
 #define ARCMSR_MAX_XFER_SECTORS
512
 #define ARCMSR_MAX_XFER_SECTORS_B  
4096
diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2014-07-30 10:32:28.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 11:02:44.0 +0800
@@ -1441,14 +1441,15 @@ static void arcmsr_hba_doorbell_isr(stru
uint32_t outbound_doorbell;
struct MessageUnit_A __iomem *reg = acb->pmuA;
outbound_doorbell = readl(®->outbound_doorbell);
-   writel(outbound_doorbell, ®->outbound_doorbell);
-   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) {
-   arcmsr_iop2drv_data_wrote_handle(acb);
-   }
-
-   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) {
-   arcmsr_iop2drv_data_read_handle(acb);
-   }
+   do {
+   writel(outbound_doorbell, ®->outbound_doorbell);
+   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK)
+   arcmsr_iop2drv_data_wrote_handle(acb);
+   if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK)
+   arcmsr_iop2drv_data_read_handle(acb);
+   outbound_doorbell = readl(®->outbound_doorbell);
+   } while (outbound_doorbell & (ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK
+   | ARCMSR_OUTBOUND_IOP331_DATA_READ_OK));
 }
 static void arcmsr_hbc_doorbell_isr(struct AdapterControlBlock *pACB)
 {
@@ -1462,17 +1463,19 @@ static void arcmsr_hbc_doorbell_isr(stru
***
*/
outbound_doorbell = readl(®->outbound_doorbell);
-   writel(outbound_doorbell, ®->outbound_doorbell_clear);/*clear 
interrupt*/
-   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
-   arcmsr_iop2drv_data_wrote_handle(pACB);
-   }
-   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK) {
-   arcmsr_iop2drv_data_read_handle(pACB);
-   }
-   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
-   arcmsr_hbc_message_isr(pACB);/* messenger of "driver to iop 
commands" */
-   }
-   return;
+   do {
+   writel(outbound_doorbell, ®->outbound_doorbell_clear);
+   readl(®->outbound_doorbell_clear);
+   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK)
+   arcmsr_iop2drv_data_wrote_handle(pACB);
+   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK)
+   arcmsr_iop2drv_data_read_handle(pACB);
+   if (outbound_doorbell & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE)
+   arcmsr_hbc_message_isr(pACB);
+   outbound_doorbell = readl(®->outbound_doorbell);
+   } while (outbound_doorbell & (ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK
+   | ARCMSR_HBCMU_IOP2DRV_DATA_READ_OK
+   | ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE));
 }
 static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 {
@@ -1521,21 +1524,22 @@ static void arcmsr_hbc_postqueue_isr(str
/* areca cdb command done */
/* Use correct offset and size for syncing */
 
-   while (readl(&phbcmu->host_int_status) &
-   ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR){
-   /* check if command done with no error*/
-   flag_ccb = readl(&phbcmu->outbound_queueport_low);
-   ccb_cdb_phy = (flag_ccb & 0xFFF0);/*frame must be 32 bytes aligned*/
-   arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
-   ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
-   error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
-   /* check if command done with no error */
-   arcmsr_drain_donequeue(acb, ccb, error);
-   if (throttling == ARCMSR_HBC_ISR_THROTTLING_LEVEL) {
-   writel(ARCMSR_HBCMU_DRV2IOP_POSTQUEUE

[PATCH v3 2/17] arcmsr: Add code to support MSI-X, MSI interrupt

2014-08-18 Thread Ching Huang
From: Ching Huang 

This patch adds code to support MSI, MSI-X interrupt.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-04-28 16:02:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:36.0 +0800
@@ -64,6 +64,7 @@ struct device_attribute;
 #define ARCMSR_MAX_HBB_POSTQUEUE   
264
 #define ARCMSR_MAX_XFER_LEN
0x26000 /* 152K */
 #define ARCMSR_CDB_SG_PAGE_LENGTH  
256 
+#define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
@@ -508,6 +509,7 @@ struct AdapterControlBlock
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
+   struct msix_entry   entries[ARCMST_NUM_MSIX_VECTORS];
/* Offset is used in making arc cdb physical to virtual calculations */
uint32_toutbound_int_enable;
uint32_tcdb_phyaddr_hi32;
@@ -544,6 +546,8 @@ struct AdapterControlBlock
/* iop init */
#define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400
+   #define ACB_F_MSI_ENABLED   0x1000
+   #define ACB_F_MSIX_ENABLED  0x2000
struct CommandControlBlock *
pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */
struct list_headccb_free_list;
@@ -594,6 +598,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
 ***
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-01 11:02:44.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 17:54:46.0 +0800
@@ -603,6 +603,56 @@ static void arcmsr_message_isr_bh_fn(str
}
 }
 
+static int
+arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
+{
+   int i, j, r;
+   struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
+
+   for (i = 0; i < ARCMST_NUM_MSIX_VECTORS; i++)
+   entries[i].entry = i;
+   r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS);
+   if (r < 0)
+   goto msi_int;
+   acb->msix_vector_count = r;
+   for (i = 0; i < r; i++) {
+   if (request_irq(entries[i].vector,
+   arcmsr_do_interrupt, 0, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, entries[i].vector);
+   for (j = 0 ; j < i ; j++)
+   free_irq(entries[j].vector, acb);
+   pci_disable_msix(pdev);
+   goto msi_int;
+   }
+   acb->entries[i] = entries[i];
+   }
+   acb->acb_flags |= ACB_F_MSIX_ENABLED;
+   pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
+   return SUCCESS;
+msi_int:
+   if (pci_enable_msi_exact(pdev, 1) < 0)
+   goto legacy_int;
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, pdev->irq);
+   pci_disable_msi(pdev);
+   goto legacy_int;
+   }
+   acb->acb_flags |= ACB_F_MSI_ENABLED;
+   pr_info("arcmsr%d: msi enabled\n", acb->host->host_no);
+   return SUCCESS;
+legacy_int:
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq = %d failed!\n",
+   acb->host->host_no, pdev->irq);
+   return FAILED;
+   }
+   return SUCCESS;
+}
+
 static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
struct Scsi_Host *host;
@@ -667,16 +717,13 @@ static int arcmsr_probe(struct pci_dev *
if(error){
goto free_hbb_mu;
}
-   arcmsr_iop_init(acb);
error = scsi_add_host(host, &pdev->dev);
if(error){
goto RAID_controller_stop;
}
-   error = request_irq(pdev->irq, a

[PATCH v3 3/17] arcmsr: Add code to support hibernation

2014-08-18 Thread Ching Huang
From: Ching Huang 

This patch adds code to support system hibernation.

Signed-off-by: Ching Huang 
---

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-01 17:54:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:03:48.0 +0800
@@ -89,11 +89,15 @@ static int arcmsr_bios_param(struct scsi
 static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int arcmsr_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
+static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state);
+static int arcmsr_resume(struct pci_dev *pdev);
 static void arcmsr_remove(struct pci_dev *pdev);
 static void arcmsr_shutdown(struct pci_dev *pdev);
 static void arcmsr_iop_init(struct AdapterControlBlock *acb);
 static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb);
 static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb);
+static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
+   u32 intmask_org);
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb);
 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
@@ -167,6 +171,8 @@ static struct pci_driver arcmsr_pci_driv
.id_table   = arcmsr_device_id_table,
.probe  = arcmsr_probe,
.remove = arcmsr_remove,
+   .suspend= arcmsr_suspend,
+   .resume = arcmsr_resume,
.shutdown   = arcmsr_shutdown,
 };
 /*
@@ -772,6 +778,76 @@ static void arcmsr_free_irq(struct pci_d
free_irq(pdev->irq, acb);
 }
 
+static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+   uint32_t intmask_org;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host->hostdata;
+
+   intmask_org = arcmsr_disable_outbound_ints(acb);
+   arcmsr_free_irq(pdev, acb);
+   del_timer_sync(&acb->eternal_timer);
+   flush_work(&acb->arcmsr_do_message_isr_bh);
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+   pci_set_drvdata(pdev, host);
+   pci_save_state(pdev);
+   pci_disable_device(pdev);
+   pci_set_power_state(pdev, pci_choose_state(pdev, state));
+   return 0;
+}
+
+static int arcmsr_resume(struct pci_dev *pdev)
+{
+   int error;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host->hostdata;
+
+   pci_set_power_state(pdev, PCI_D0);
+   pci_enable_wake(pdev, PCI_D0, 0);
+   pci_restore_state(pdev);
+   if (pci_enable_device(pdev)) {
+   pr_warn("%s: pci_enable_device error\n", __func__);
+   return -ENODEV;
+   }
+   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (error) {
+   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+   if (error) {
+   pr_warn("scsi%d: No suitable DMA mask available\n",
+  host->host_no);
+   goto controller_unregister;
+   }
+   }
+   pci_set_master(pdev);
+   if (arcmsr_request_irq(pdev, acb) == FAILED)
+   goto controller_stop;
+   arcmsr_iop_init(acb);
+   INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
+   atomic_set(&acb->rq_map_token, 16);
+   atomic_set(&acb->ante_token_value, 16);
+   acb->fw_flag = FW_NORMAL;
+   init_timer(&acb->eternal_timer);
+   acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ);
+   acb->eternal_timer.data = (unsigned long) acb;
+   acb->eternal_timer.function = &arcmsr_request_device_map;
+   add_timer(&acb->eternal_timer);
+   return 0;
+controller_stop:
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+controller_unregister:
+   scsi_remove_host(host);
+   arcmsr_free_ccb_pool(acb);
+   arcmsr_unmap_pciregion(acb);
+   pci_release_regions(pdev);
+   scsi_host_put(host);
+   pci_disable_device(pdev);
+   return -ENODEV;
+}
+
 static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
 {
struct MessageUnit_A __iomem *reg = acb->pmuA;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v4 4/17] arcmsr: limit max. number of SCSI command request

2014-08-18 Thread Ching Huang
From: Ching Huang 

This patch limits the max. number of SCSI commmand request to avoid command 
overflow.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:06.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:22:36.0 +0800
@@ -45,11 +45,12 @@
 #include 
 struct device_attribute;
 /*The limit of outstanding scsi command that firmware can handle*/
-#define ARCMSR_MAX_OUTSTANDING_CMD 
256
 #ifdef CONFIG_XEN
#define ARCMSR_MAX_FREECCB_NUM  160
+#define ARCMSR_MAX_OUTSTANDING_CMD 155
 #else
#define ARCMSR_MAX_FREECCB_NUM  320
+#define ARCMSR_MAX_OUTSTANDING_CMD 255
 #endif
 #define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140428"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
@@ -598,6 +599,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   uint32_tmaxOutstanding;
int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
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-08 19:03:48.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:35:46.0 +0800
@@ -134,7 +134,7 @@ static struct scsi_host_template arcmsr_
.eh_bus_reset_handler   = arcmsr_bus_reset,
.bios_param = arcmsr_bios_param,
.change_queue_depth = arcmsr_adjust_disk_queue_depth,
-   .can_queue  = ARCMSR_MAX_FREECCB_NUM,
+   .can_queue  = ARCMSR_MAX_OUTSTANDING_CMD,
.this_id= ARCMSR_SCSI_INITIATOR_ID,
.sg_tablesize   = ARCMSR_DEFAULT_SG_ENTRIES, 
.max_sectors= ARCMSR_MAX_XFER_SECTORS_C, 
@@ -693,7 +693,7 @@ static int arcmsr_probe(struct pci_dev *
host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
host->max_cmd_len = 16; /*this is issue of 
64bit LBA ,over 2T byte*/
-   host->can_queue = ARCMSR_MAX_FREECCB_NUM;   /* max simultaneous 
cmds */ 
+   host->can_queue = ARCMSR_MAX_OUTSTANDING_CMD;   /* max simultaneous 
cmds */ 
host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;  
host->this_id = ARCMSR_SCSI_INITIATOR_ID;
host->unique_id = (bus << 8) | dev_fun;
@@ -2215,9 +2215,6 @@ static int arcmsr_queue_command_lck(stru
arcmsr_handle_virtual_command(acb, cmd);
return 0;
}
-   if (atomic_read(&acb->ccboutstandingcount) >=
-   ARCMSR_MAX_OUTSTANDING_CMD)
-   return SCSI_MLQUEUE_HOST_BUSY;
ccb = arcmsr_get_freeccb(acb);
if (!ccb)
return SCSI_MLQUEUE_HOST_BUSY;
@@ -2427,12 +2424,27 @@ static bool arcmsr_get_hbc_config(struct
 }
 static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 {
-   if (acb->adapter_type == ACB_ADAPTER_TYPE_A)
-   return arcmsr_get_hba_config(acb);
-   else if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
-   return arcmsr_get_hbb_config(acb);
+   bool rtn = false;
+
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_A:
+   rtn = arcmsr_get_hba_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_B:
+   rtn = arcmsr_get_hbb_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_C:
+   rtn = arcmsr_get_hbc_config(acb);
+   break;
+   default:
+   break;
+   }
+   if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
+   acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD;
else
-   return arcmsr_get_hbc_config(acb);
+   acb->maxOutstanding = acb->firm_numbers_queue - 1;
+   acb->host->can_queue = acb->maxOutstanding;
+   return rtn;
 }
 
 static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Ignore the [PATCH v4 4/17]

2014-08-18 Thread Ching Huang
Please ignore the patch [PATCH v4 4/17], I will resend the patch [PATCH v3 
4/17].

Regards,
Ching Huang 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 4/17] arcmsr: limit max. number of SCSI command request

2014-08-18 Thread Ching Huang
From: Ching Huang 

This patch limits the max. number of SCSI command request to avoid command 
overflow.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:06.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:22:36.0 +0800
@@ -45,11 +45,12 @@
 #include 
 struct device_attribute;
 /*The limit of outstanding scsi command that firmware can handle*/
-#define ARCMSR_MAX_OUTSTANDING_CMD 
256
 #ifdef CONFIG_XEN
#define ARCMSR_MAX_FREECCB_NUM  160
+#define ARCMSR_MAX_OUTSTANDING_CMD 155
 #else
#define ARCMSR_MAX_FREECCB_NUM  320
+#define ARCMSR_MAX_OUTSTANDING_CMD 255
 #endif
 #define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140428"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
@@ -598,6 +599,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   uint32_tmaxOutstanding;
int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
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-08 19:03:48.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:35:46.0 +0800
@@ -134,7 +134,7 @@ static struct scsi_host_template arcmsr_
.eh_bus_reset_handler   = arcmsr_bus_reset,
.bios_param = arcmsr_bios_param,
.change_queue_depth = arcmsr_adjust_disk_queue_depth,
-   .can_queue  = ARCMSR_MAX_FREECCB_NUM,
+   .can_queue  = ARCMSR_MAX_OUTSTANDING_CMD,
.this_id= ARCMSR_SCSI_INITIATOR_ID,
.sg_tablesize   = ARCMSR_DEFAULT_SG_ENTRIES, 
.max_sectors= ARCMSR_MAX_XFER_SECTORS_C, 
@@ -693,7 +693,7 @@ static int arcmsr_probe(struct pci_dev *
host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
host->max_cmd_len = 16; /*this is issue of 
64bit LBA ,over 2T byte*/
-   host->can_queue = ARCMSR_MAX_FREECCB_NUM;   /* max simultaneous 
cmds */ 
+   host->can_queue = ARCMSR_MAX_OUTSTANDING_CMD;   /* max simultaneous 
cmds */ 
host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;  
host->this_id = ARCMSR_SCSI_INITIATOR_ID;
host->unique_id = (bus << 8) | dev_fun;
@@ -2215,9 +2215,6 @@ static int arcmsr_queue_command_lck(stru
arcmsr_handle_virtual_command(acb, cmd);
return 0;
}
-   if (atomic_read(&acb->ccboutstandingcount) >=
-   ARCMSR_MAX_OUTSTANDING_CMD)
-   return SCSI_MLQUEUE_HOST_BUSY;
ccb = arcmsr_get_freeccb(acb);
if (!ccb)
return SCSI_MLQUEUE_HOST_BUSY;
@@ -2427,12 +2424,27 @@ static bool arcmsr_get_hbc_config(struct
 }
 static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 {
-   if (acb->adapter_type == ACB_ADAPTER_TYPE_A)
-   return arcmsr_get_hba_config(acb);
-   else if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
-   return arcmsr_get_hbb_config(acb);
+   bool rtn = false;
+
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_A:
+   rtn = arcmsr_get_hba_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_B:
+   rtn = arcmsr_get_hbb_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_C:
+   rtn = arcmsr_get_hbc_config(acb);
+   break;
+   default:
+   break;
+   }
+   if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
+   acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD;
else
-   return arcmsr_get_hbc_config(acb);
+   acb->maxOutstanding = acb->firm_numbers_queue - 1;
+   acb->host->can_queue = acb->maxOutstanding;
+   return rtn;
 }
 
 static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 5/17] arcmsr: bugfix - return status of abort command

2014-08-18 Thread Ching Huang
From: Ching Huang 

This patch fixed the wrong return status of abort command.

Signed-off-by: Ching Huang 
---

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-08 19:35:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:36:00.0 +0800
@@ -2476,7 +2476,7 @@ static int arcmsr_polling_hba_ccbdone(st
}
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
-   poll_ccb_done = (ccb == poll_ccb) ? 1:0;
+   poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == 
poll_ccb)) {
printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun 
= %d ccb = '0x%p'"
@@ -2540,7 +2540,7 @@ static int arcmsr_polling_hbb_ccbdone(st
/* check if command done with no error*/
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
(flag_ccb << 5));
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
-   poll_ccb_done = (ccb == poll_ccb) ? 1:0;
+   poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == 
poll_ccb)) {
printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun 
= %d ccb = '0x%p'"
@@ -2596,7 +2596,7 @@ polling_hbc_ccb_retry:
ccb_cdb_phy = (flag_ccb & 0xFFF0);
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + 
ccb_cdb_phy);/*frame must be 32 bytes aligned*/
pCCB = container_of(arcmsr_cdb, struct CommandControlBlock, 
arcmsr_cdb);
-   poll_ccb_done = (pCCB == poll_ccb) ? 1 : 0;
+   poll_ccb_done |= (pCCB == poll_ccb) ? 1 : 0;
/* check ifcommand done with no error*/
if ((pCCB->acb != acb) || (pCCB->startdone != 
ARCMSR_CCB_START)) {
if (pCCB->startdone == ARCMSR_CCB_ABORTED) {
@@ -3198,6 +3198,8 @@ static int arcmsr_abort(struct scsi_cmnd
(struct AdapterControlBlock *)cmd->device->host->hostdata;
int i = 0;
int rtn = FAILED;
+   uint32_t intmask_org;
+
printk(KERN_NOTICE
"arcmsr%d: abort device command of scsi id = %d lun = %d \n",
acb->host->host_no, cmd->device->id, (u32)cmd->device->lun);
@@ -3209,9 +3211,12 @@ static int arcmsr_abort(struct scsi_cmnd
** we need to handle it as soon as possible and exit

*/
-   if (!atomic_read(&acb->ccboutstandingcount))
+   if (!atomic_read(&acb->ccboutstandingcount)) {
+   acb->acb_flags &= ~ACB_F_ABORT;
return rtn;
+   }
 
+   intmask_org = arcmsr_disable_outbound_ints(acb);
for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) {
struct CommandControlBlock *ccb = acb->pccb_pool[i];
if (ccb->startdone == ARCMSR_CCB_START && ccb->pcmd == cmd) {
@@ -3221,6 +3226,7 @@ static int arcmsr_abort(struct scsi_cmnd
}
}
acb->acb_flags &= ~ACB_F_ABORT;
+   arcmsr_enable_outbound_ints(acb, intmask_org);
return rtn;
 }
 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 6/17] arcmsr: precise checking adapter ID

2014-08-18 Thread Ching Huang
From: Ching Huang 

change since v2:
1. This patch pre-define the adapter->type in private data of struct 
pci_device_id.
2. Remove arcmsr_define_adapter_type function.

Signed-off-by: Ching Huang 
---

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-08 19:36:00.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:36:38.0 +0800
@@ -144,25 +144,25 @@ static struct scsi_host_template arcmsr_
.no_write_same  = 1,
 };
 static struct pci_device_id arcmsr_device_id_table[] = {
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1200)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1201)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1260)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1270)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1280)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1380)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1381)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1680)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1681)},
-   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880)},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1200), 
.driver_data = ACB_ADAPTER_TYPE_B,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1201), 
.driver_data = ACB_ADAPTER_TYPE_B,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202), 
.driver_data = ACB_ADAPTER_TYPE_B,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1260), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1270), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1280), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1380), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1381), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1680), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1681), 
.driver_data = ACB_ADAPTER_TYPE_A,},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880), 
.driver_data = ACB_ADAPTER_TYPE_C,},
{0, 0}, /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, arcmsr_device_id_table);
@@ -295,26 +295,6 @@ static int arcmsr_bios_param(struct scsi
return 0;
 }
 
-static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
-{
-   struct pci_dev *pdev = acb->pdev;
-   u16 dev_id;
-   pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id);
-   acb->dev_id = dev_id;
-   switch (dev_id) {
-   case 0x1880: {
-   acb->adapter_type = ACB_ADAPTER_TYPE_C;
-   }
-   break;
-   case 0x1201: {
-   acb->adapter_type = ACB_ADAPTER_TYPE_B;
-   }
-   break;
-
-   default: acb->adapter_type = ACB_ADAPTER_TYPE_A;
-   }
-}
-
 static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
struct MessageUnit_A __iomem *reg = acb->pmuA;
@@ -710,7 +690,7 @@ static int arcmsr_probe(struct pci_dev *
ACB_F_MESSAGE_WQBUFFER_READED);
acb->acb_flags &= ~ACB_F_SCSISTO

[PATCH v3 7/17] arcmsr: revise message_isr_bh_fn to remove duplicate code

2014-08-19 Thread Ching Huang
From: Ching Huang 

Revise message_isr_bh_fn to remove the duplicate code for each adapter type.

Signed-off-by: Ching Huang 
---

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:36:38.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:39:06.0 +0800
@@ -472,120 +472,65 @@ static int arcmsr_alloc_ccb_pool(struct 
 
 static void arcmsr_message_isr_bh_fn(struct work_struct *work) 
 {
-   struct AdapterControlBlock *acb = container_of(work,struct 
AdapterControlBlock, arcmsr_do_message_isr_bh);
-   switch (acb->adapter_type) {
-   case ACB_ADAPTER_TYPE_A: {
+   struct AdapterControlBlock *acb = container_of(work,
+   struct AdapterControlBlock, arcmsr_do_message_isr_bh);
+   char *acb_dev_map = (char *)acb->device_map;
+   uint32_t __iomem *signature = NULL;
+   char __iomem *devicemap = NULL;
+   int target, lun;
+   struct scsi_device *psdev;
+   char diff, temp;
 
-   struct MessageUnit_A __iomem *reg  = acb->pmuA;
-   char *acb_dev_map = (char *)acb->device_map;
-   uint32_t __iomem *signature = (uint32_t __iomem*) 
(®->message_rwbuffer[0]);
-   char __iomem *devicemap = (char __iomem*) 
(®->message_rwbuffer[21]);
-   int target, lun;
-   struct scsi_device *psdev;
-   char diff;
-
-   atomic_inc(&acb->rq_map_token);
-   if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) {
-   for(target = 0; target < ARCMSR_MAX_TARGETID 
-1; target++) {
-   diff = (*acb_dev_map)^readb(devicemap);
-   if (diff != 0) {
-   char temp;
-   *acb_dev_map = readb(devicemap);
-   temp =*acb_dev_map;
-   for(lun = 0; lun < 
ARCMSR_MAX_TARGETLUN; lun++) {
-   if((temp & 0x01)==1 && 
(diff & 0x01) == 1) {
-   
scsi_add_device(acb->host, 0, target, lun);
-   }else if((temp & 0x01) 
== 0 && (diff & 0x01) == 1) {
-   psdev = 
scsi_device_lookup(acb->host, 0, target, lun);
-   if (psdev != 
NULL ) {
-   
scsi_remove_device(psdev);
-   
scsi_device_put(psdev);
-   }
-   }
-   temp >>= 1;
-   diff >>= 1;
-   }
-   }
-   devicemap++;
-   acb_dev_map++;
-   }
-   }
-   break;
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_A: {
+   struct MessageUnit_A __iomem *reg  = acb->pmuA;
+   signature = (uint32_t __iomem *)(®->message_rwbuffer[0]);
+   devicemap = (char __iomem *)(®->message_rwbuffer[21]);
+   break;
}
-
-   case ACB_ADAPTER_TYPE_B: {
-   struct MessageUnit_B *reg  = acb->pmuB;
-   char *acb_dev_map = (char *)acb->device_map;
-   uint32_t __iomem *signature = (uint32_t 
__iomem*)(®->message_rwbuffer[0]);
-   char __iomem *devicemap = (char 
__iomem*)(®->message_rwbuffer[21]);
-   int target, lun;
-   struct scsi_device *psdev;
-   char diff;
-
-   atomic_inc(&acb->rq_map_token);
-   if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) {
-   for(target = 0; target < ARCMSR_MAX_TARGETID 
-1; target++) {
-   diff = (*acb_dev_map)^readb(devicemap);
-   if (diff != 0) {
-   char temp;
-   *acb_dev_map = readb(devicemap);
- 

[PATCH v3 8/17] arcmsr: remove calling arcmsr_hbb_enable_driver_mode

2014-08-19 Thread Ching Huang
From: Ching Huang 

Remove calling arcmsr_hbb_enable_driver_mode by in-line code.

Signed-off-by: Ching Huang 
---

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:39:06.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:39:48.0 +0800
@@ -833,17 +833,6 @@ static uint8_t arcmsr_abort_allcmd(struc
return rtnval;
 }
 
-static bool arcmsr_hbb_enable_driver_mode(struct AdapterControlBlock *pacb)
-{
-   struct MessageUnit_B *reg = pacb->pmuB;
-   writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
-   if (!arcmsr_hbb_wait_msgint_ready(pacb)) {
-   printk(KERN_ERR "arcmsr%d: can't set driver mode. \n", 
pacb->host->host_no);
-   return false;
-   }
-   return true;
-}
-
 static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb)
 {
struct scsi_cmnd *pcmd = ccb->pcmd;
@@ -2640,7 +2629,12 @@ static int arcmsr_iop_confirm(struct Ada
timeout \n",acb->host->host_no);
return 1;
}
-   arcmsr_hbb_enable_driver_mode(acb);
+   writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
+   if (!arcmsr_hbb_wait_msgint_ready(acb)) {
+   pr_err("arcmsr%d: can't set driver mode.\n",
+   acb->host->host_no);
+   return 1;
+   }
}
break;
case ACB_ADAPTER_TYPE_C: {


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 9/17] arcmsr: modify printing adapter model number and F/W messages

2014-08-19 Thread Ching Huang
From: Ching Huang 

Adjust printing order of adapter model name and firmware version.

Signed-off-by: Ching Huang 
---

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:39:48.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:40:00.0 +0800
@@ -2182,10 +2182,10 @@ static bool arcmsr_get_hba_config(struct
iop_device_map++;
count--;
}
-   printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", 
+   pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
acb->host->host_no,
-   acb->firm_version,
-   acb->firm_model);
+   acb->firm_model,
+   acb->firm_version);
acb->signature = readl(®->message_rwbuffer[0]);
acb->firm_request_len = readl(®->message_rwbuffer[1]);
acb->firm_numbers_queue = readl(®->message_rwbuffer[2]);
@@ -2258,10 +2258,10 @@ static bool arcmsr_get_hbb_config(struct
count--;
}

-   printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+   pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
acb->host->host_no,
-   acb->firm_version,
-   acb->firm_model);
+   acb->firm_model,
+   acb->firm_version);
 
acb->signature = readl(®->message_rwbuffer[1]);
/*firm_signature,1,00-03*/
@@ -2324,10 +2324,10 @@ static bool arcmsr_get_hbc_config(struct
iop_firm_version++;
count--;
}
-   printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+   pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
pACB->host->host_no,
-   pACB->firm_version,
-   pACB->firm_model);
+   pACB->firm_model,
+   pACB->firm_version);
pACB->firm_request_len = readl(®->msgcode_rwbuffer[1]);   
/*firm_request_len,1,04-07*/
pACB->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]); 
/*firm_numbers_queue,2,08-11*/
pACB->firm_sdram_size = readl(®->msgcode_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 10/17] arcmsr: clear outbound doorbell buffer completely

2014-08-19 Thread Ching Huang
From: Ching Huang 

Clear outbound doorbell buffer completely for adapter type C.
This is to prevent getting bad data input from IOP before ioctl command 
beginning.

Signed-off-by: Ching Huang 
---

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:00.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:40:12.0 +0800
@@ -2845,11 +2845,23 @@ static void arcmsr_clear_doorbell_queue_
break;
case ACB_ADAPTER_TYPE_C: {
struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
-   uint32_t outbound_doorbell;
+   uint32_t outbound_doorbell, i;
/* empty doorbell Qbuffer if door bell ringed */
outbound_doorbell = readl(®->outbound_doorbell);
writel(outbound_doorbell, ®->outbound_doorbell_clear);
writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, 
®->inbound_doorbell);
+   for (i = 0; i < 200; i++) {
+   msleep(20);
+   outbound_doorbell = readl(®->outbound_doorbell);
+   if (outbound_doorbell &
+   ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
+   writel(outbound_doorbell,
+   ®->outbound_doorbell_clear);
+   writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK,
+   ®->inbound_doorbell);
+   } else
+   break;
+   }
}
}
 }
@@ -3077,9 +3089,7 @@ sleep:
arcmsr_get_firmware_spec(acb);
arcmsr_start_adapter_bgrb(acb);
/* clear Qbuffer if door bell ringed */
-   outbound_doorbell = 
readl(®->outbound_doorbell);
-   writel(outbound_doorbell, 
®->outbound_doorbell_clear); /*clear interrupt */
-   writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, 
®->inbound_doorbell);
+   arcmsr_clear_doorbell_queue_buffer(acb);
/* enable outbound Post Queue,outbound doorbell 
Interrupt */
arcmsr_enable_outbound_ints(acb, intmask_org);
atomic_set(&acb->rq_map_token, 16);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 11/17] arcmsr: rename function and variable

2014-08-19 Thread Ching Huang
From: Ching Huang 

Rename some variable and function name for readability and consistency.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:27:14.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:27:38.0 +0800
@@ -359,7 +359,7 @@ struct ARCMSR_CDB
 #define ARCMSR_CDB_FLAG_ORDEREDQ   0x10
 
uint8_t msgPages;
-   uint32_tContext;
+   uint32_tmsgContext;
uint32_tDataLength;
uint8_t Cdb[16];
uint8_t DeviceStatus;
@@ -562,7 +562,7 @@ struct AdapterControlBlock
/* dma_coherent used for memory free */
dma_addr_t  dma_coherent_handle;
/* dma_coherent_handle used for memory free */
-   dma_addr_t  dma_coherent_handle_hbb_mu;
+   dma_addr_t  dma_coherent_handle2;
unsigned intuncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
@@ -613,7 +613,7 @@ struct CommandControlBlock{
struct list_headlist;   /*x32: 
8byte, x64: 16byte*/
struct scsi_cmnd*pcmd;  /*8 
bytes pointer of linux scsi command */
struct AdapterControlBlock  *acb;   /*x32: 
4byte, x64: 8byte*/
-   uint32_tcdb_phyaddr_pattern;/*x32: 
4byte, x64: 4byte*/
+   uint32_tcdb_phyaddr;/*x32: 
4byte, x64: 4byte*/
uint32_tarc_cdb_size;   
/*x32:4byte,x64:4byte*/
uint16_tccb_flags;  /*x32: 
2byte, x64: 2byte*/
#define CCB_FLAG_READ   0x
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:12.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:40:26.0 +0800
@@ -99,16 +99,16 @@ static u32 arcmsr_disable_outbound_ints(
 static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
u32 intmask_org);
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
-static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb);
-static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
+static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb);
+static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb);
 static void arcmsr_request_device_map(unsigned long pacb);
-static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb);
-static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb);
-static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_hbaA_request_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_hbaB_request_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_hbaC_request_device_map(struct AdapterControlBlock *acb);
 static void arcmsr_message_isr_bh_fn(struct work_struct *work);
 static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb);
 static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
-static void arcmsr_hbc_message_isr(struct AdapterControlBlock *pACB);
+static void arcmsr_hbaC_message_isr(struct AdapterControlBlock *pACB);
 static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
@@ -180,7 +180,7 @@ static struct pci_driver arcmsr_pci_driv
 
 */
 
-static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb)
+static void arcmsr_free_mu(struct AdapterControlBlock *acb)
 {
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A:
@@ -189,7 +189,7 @@ static void arcmsr_free_hbb_mu(struct Ad
case ACB_ADAPTER_TYPE_B:{
dma_free_coherent(&acb->pdev->dev,
sizeof(struct MessageUnit_B),
-   acb->pmuB, acb->dma_coherent_handle_hbb_mu);
+   acb->pmuB, acb->dma_coherent_handle2);
}
}
 }
@@ -295,7 +295,7 @@ static int arcmsr_bios_param(struct scsi
return 0;
 }
 
-static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
+static uint8_t arcm

[PATCH v3 12/17] arcmsr: revise allocation of second dma_coherent_handle for type B

2014-08-19 Thread Ching Huang
From: Ching Huang 

This modification is for consistency with upcoming adapter type D.
Both adapter type B and D have similar H/W and S/W structure.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:27:38.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:28:38.0 +0800
@@ -507,6 +507,7 @@ struct AdapterControlBlock
#define ACB_ADAPTER_TYPE_B0x0002/* hbb M IOP */
#define ACB_ADAPTER_TYPE_C0x0004/* hbc P IOP */
#define ACB_ADAPTER_TYPE_D0x0008/* hbd A IOP */
+   u32 roundup_ccbsize;
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
@@ -563,6 +564,7 @@ struct AdapterControlBlock
dma_addr_t  dma_coherent_handle;
/* dma_coherent_handle used for memory free */
dma_addr_t  dma_coherent_handle2;
+   void*dma_coherent2;
unsigned intuncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
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:26.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:40:38.0 +0800
@@ -183,13 +183,10 @@ static struct pci_driver arcmsr_pci_driv
 static void arcmsr_free_mu(struct AdapterControlBlock *acb)
 {
switch (acb->adapter_type) {
-   case ACB_ADAPTER_TYPE_A:
-   case ACB_ADAPTER_TYPE_C:
-   break;
case ACB_ADAPTER_TYPE_B:{
-   dma_free_coherent(&acb->pdev->dev,
-   sizeof(struct MessageUnit_B),
-   acb->pmuB, acb->dma_coherent_handle2);
+   dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
+   acb->dma_coherent2, acb->dma_coherent_handle2);
+   break;
}
}
 }
@@ -2210,12 +2207,15 @@ static bool arcmsr_hbaB_get_config(struc
char __iomem *iop_device_map;
/*firm_version,21,84-99*/
int count;
-   dma_coherent = dma_alloc_coherent(&pdev->dev, sizeof(struct 
MessageUnit_B), &dma_coherent_handle, GFP_KERNEL);
+
+   acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
+   dma_coherent = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize, 
&dma_coherent_handle, GFP_KERNEL);
if (!dma_coherent){
printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error for 
hbb mu\n", acb->host->host_no);
return false;
}
acb->dma_coherent_handle2 = dma_coherent_handle;
+   acb->dma_coherent2 = dma_coherent;
reg = (struct MessageUnit_B *)dma_coherent;
acb->pmuB = reg;
reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
@@ -2562,6 +2562,7 @@ static int arcmsr_polling_ccbdone(struct
 static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 {
uint32_t cdb_phyaddr, cdb_phyaddr_hi32;
+   dma_addr_t dma_coherent_handle;
 
/*

@@ -2569,8 +2570,16 @@ static int arcmsr_iop_confirm(struct Ada
** if freeccb.HighPart is not zero

*/
-   cdb_phyaddr = lower_32_bits(acb->dma_coherent_handle);
-   cdb_phyaddr_hi32 = upper_32_bits(acb->dma_coherent_handle);
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_B:
+   dma_coherent_handle = acb->dma_coherent_handle2;
+   break;
+   default:
+   dma_coherent_handle = acb->dma_coherent_handle;
+   break;
+   }
+   cdb_phyaddr = lower_32_bits(dma_coherent_handle);
+   cdb_phyaddr_hi32 = upper_32_bits(dma_coherent_handle);
acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32;
/*
***
@@ -2598,7 +2607,6 @@ static int arcmsr_iop_confirm(struct Ada
break;
 
case ACB_ADAPTER_TYPE_B: {
-   unsigned long post_queue_phyaddr;
uint32_t __iomem *rwbuffer;
 
struct MessageUnit_B *reg = acb->pmuB;
@@ -2610,16 +2618,15 @@ static int arcmsr_iop_confirm(struct Ada
acb->host->host_no);
return 1;
}
-   post

[PATCH v3 13/17] arcmsr: fix ioctl data read/write error for adapter type C

2014-08-19 Thread Ching Huang
From: Ching Huang 

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

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.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-04-29 17:10:42.0 +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;

[PATCH v3 14/17] arcmsr: fix sparse warning and error

2014-08-19 Thread Ching Huang
From: Ching Huang 

Fix sparse utility checking error and warning.

Signed-off-by: Ching Huang 
---

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:48.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:41:02.0 +0800
@@ -78,7 +78,7 @@ MODULE_VERSION(ARCMSR_DRIVER_VERSION);
 #defineARCMSR_SLEEPTIME10
 #defineARCMSR_RETRYCOUNT   12
 
-wait_queue_head_t wait_q;
+static wait_queue_head_t wait_q;
 static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
struct scsi_cmnd *cmd);
 static int arcmsr_iop_confirm(struct AdapterControlBlock *acb);
@@ -332,7 +332,7 @@ static uint8_t arcmsr_hbaB_wait_msgint_r
 
 static uint8_t arcmsr_hbaC_wait_msgint_ready(struct AdapterControlBlock *pACB)
 {
-   struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC;
+   struct MessageUnit_C __iomem *phbcmu = pACB->pmuC;
int i;
 
for (i = 0; i < 2000; i++) {
@@ -382,7 +382,7 @@ static void arcmsr_hbaB_flush_cache(stru
 
 static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB)
 {
-   struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+   struct MessageUnit_C __iomem *reg = pACB->pmuC;
int retry_count = 30;/* enlarge wait flush adapter cache time: 10 
minute */
writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0);
writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);
@@ -800,7 +800,7 @@ static uint8_t arcmsr_hbaB_abort_allcmd(
 }
 static uint8_t arcmsr_hbaC_abort_allcmd(struct AdapterControlBlock *pACB)
 {
-   struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+   struct MessageUnit_C __iomem *reg = pACB->pmuC;
writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0);
writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);
if (!arcmsr_hbaC_wait_msgint_ready(pACB)) {
@@ -888,7 +888,7 @@ static u32 arcmsr_disable_outbound_ints(
}
break;
case ACB_ADAPTER_TYPE_C:{
-   struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+   struct MessageUnit_C __iomem *reg = acb->pmuC;
/* disable all outbound interrupt */
orig_mask = readl(®->host_int_mask); /* disable outbound 
message0 int */
writel(orig_mask|ARCMSR_HBCMU_ALL_INTMASKENABLE, 
®->host_int_mask);
@@ -1012,8 +1012,9 @@ static void arcmsr_done4abort_postqueue(
/*clear all outbound posted Q*/
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, 
reg->iop2drv_doorbell); /* clear doorbell interrupt */
for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
-   if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) {
-   writel(0, ®->done_qbuffer[i]);
+   flag_ccb = reg->done_qbuffer[i];
+   if (flag_ccb != 0) {
+   reg->done_qbuffer[i] = 0;
pARCMSR_CDB = (struct ARCMSR_CDB 
*)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
pCCB = container_of(pARCMSR_CDB, struct 
CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & 
ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
@@ -1026,7 +1027,7 @@ static void arcmsr_done4abort_postqueue(
}
break;
case ACB_ADAPTER_TYPE_C: {
-   struct MessageUnit_C *reg = acb->pmuC;
+   struct MessageUnit_C __iomem *reg = acb->pmuC;
struct  ARCMSR_CDB *pARCMSR_CDB;
uint32_t flag_ccb, ccb_cdb_phy;
bool error;
@@ -1144,7 +1145,7 @@ static void arcmsr_enable_outbound_ints(
}
break;
case ACB_ADAPTER_TYPE_C: {
-   struct MessageUnit_C *reg = acb->pmuC;
+   struct MessageUnit_C __iomem *reg = acb->pmuC;
mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | 
ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK|ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
writel(intmask_org & mask, ®->host_int_mask);
acb->outbound_int_enable = ~(intmask_org & mask) & 0x000f;
@@ -1231,12 +1232,12 @@ static void arcmsr_post_ccb(struct Adapt
uint32_t ending_index, index = reg->postq_index;
 
ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE);
-   writel(0, ®->post_qbuffer[ending_index]);
+   reg->post_qbuffer[ending_index] = 0;
if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
-   writel(cdb_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\

[PATCH v3 15/17] arcmsr: modify some character string

2014-08-19 Thread Ching Huang
From: Ching Huang 

Revise comment and some character strings.

Signed-off-by: Ching Huang 
---

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:41:02.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 18:41:12.0 +0800
@@ -2,11 +2,10 @@
 ***
 **O.S   : Linux
 **   FILE NAME  : arcmsr_hba.c
-**BY: Nick Cheng
-**   Description: SCSI RAID Device Driver for
-**ARECA RAID Host adapter
+**BY: Nick Cheng, C.L. Huang
+**   Description: SCSI RAID Device Driver for Areca RAID Controller
 ***
-** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved
+** Copyright (C) 2002 - 2014, Areca Technology Corporation All rights reserved
 **
 ** Web site: www.areca.com.tw
 **   E-mail: supp...@areca.com.tw
@@ -70,8 +69,8 @@
 #include 
 #include 
 #include "arcmsr.h"
-MODULE_AUTHOR("Nick Cheng ");
-MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus 
Adapter");
+MODULE_AUTHOR("Nick Cheng, C.L. Huang ");
+MODULE_DESCRIPTION("Areca ARC11xx/12xx/16xx/188x SAS/SATA RAID Controller 
Driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(ARCMSR_DRIVER_VERSION);
 
@@ -126,8 +125,7 @@ static int arcmsr_adjust_disk_queue_dept
 
 static struct scsi_host_template arcmsr_scsi_host_template = {
.module = THIS_MODULE,
-   .name   = "ARCMSR ARECA SATA/SAS RAID Controller"
-   ARCMSR_DRIVER_VERSION,
+   .name   = "Areca SAS/SATA RAID driver",
.info   = arcmsr_info,
.queuecommand   = arcmsr_queue_command,
.eh_abort_handler   = arcmsr_abort,
@@ -3355,14 +3353,14 @@ static const char *arcmsr_info(struct Sc
case PCI_DEVICE_ID_ARECA_1680:
case PCI_DEVICE_ID_ARECA_1681:
case PCI_DEVICE_ID_ARECA_1880:
-   type = "SAS";
+   type = "SAS/SATA";
break;
default:
-   type = "X-TYPE";
+   type = "unknown";
+   raid6 = 0;
break;
}
-   sprintf(buf, "Areca %s Host Adapter RAID Controller%s\n %s",
-   type, raid6 ? "( RAID6 capable)" : "",
-   ARCMSR_DRIVER_VERSION);
+   sprintf(buf, "Areca %s RAID Controller %s\narcmsr version %s\n",
+   type, raid6 ? "(RAID6 capable)" : "", ARCMSR_DRIVER_VERSION);
return buf;
 }


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 16/17] arcmsr: support new adapter ARC12x4 series

2014-08-19 Thread Ching Huang
From: Ching Huang 

Add code for supporting Areca new Raid adapter ARC12x4 series.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:29:54.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:06:04.0 +0800
@@ -63,12 +63,17 @@ struct device_attribute;
 #define ARCMSR_MAX_QBUFFER 
4096
 #define ARCMSR_DEFAULT_SG_ENTRIES  
38
 #define ARCMSR_MAX_HBB_POSTQUEUE   
264
+#define ARCMSR_MAX_ARC1214_POSTQUEUE   256
+#define ARCMSR_MAX_ARC1214_DONEQUEUE   257
 #define ARCMSR_MAX_XFER_LEN
0x26000 /* 152K */
 #define ARCMSR_CDB_SG_PAGE_LENGTH  
256 
 #define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
+#ifndef PCI_DEVICE_ID_ARECA_1214
+   #define PCI_DEVICE_ID_ARECA_12140x1214
+#endif
 /*
 
**
 **
@@ -339,6 +344,56 @@ struct FIRMWARE_INFO
 #define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK   0x8000
 /*
 ***
+**SPEC. for Areca Type D adapter
+***
+*/
+#define ARCMSR_ARC1214_CHIP_ID 0x4
+#define ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION0x8
+#define ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK  0x00034
+#define ARCMSR_ARC1214_SAMPLE_RESET0x00100
+#define ARCMSR_ARC1214_RESET_REQUEST   0x00108
+#define ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS   0x00200
+#define ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE0x0020C
+#define ARCMSR_ARC1214_INBOUND_MESSAGE00x00400
+#define ARCMSR_ARC1214_INBOUND_MESSAGE10x00404
+#define ARCMSR_ARC1214_OUTBOUND_MESSAGE0   0x00420
+#define ARCMSR_ARC1214_OUTBOUND_MESSAGE1   0x00424
+#define ARCMSR_ARC1214_INBOUND_DOORBELL0x00460
+#define ARCMSR_ARC1214_OUTBOUND_DOORBELL   0x00480
+#define ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE0x00484
+#define ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW   0x01000
+#define ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH  0x01004
+#define ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER  0x01018
+#define ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW  0x01060
+#define ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH 0x01064
+#define ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER  0x0106C
+#define ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER  0x01070
+#define ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE0x01088
+#define ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE   0x0108C
+#define ARCMSR_ARC1214_MESSAGE_WBUFFER 0x02000
+#define ARCMSR_ARC1214_MESSAGE_RBUFFER 0x02100
+#define ARCMSR_ARC1214_MESSAGE_RWBUFFER0x02200
+/* Host Interrupt Mask */
+#define ARCMSR_ARC1214_ALL_INT_ENABLE  0x1010
+#define ARCMSR_ARC1214_ALL_INT_DISABLE 0x
+/* Host Interrupt Status */
+#define ARCMSR_ARC1214_OUTBOUND_DOORBELL_ISR   0x1000
+#define ARCMSR_ARC1214_OUTBOUND_POSTQUEUE_ISR  0x0010
+/* DoorBell*/
+#define ARCMSR_ARC1214_DRV2IOP_DATA_IN_READY   0x0001
+#define ARCMSR_ARC1214_DRV2IOP_DATA_OUT_READ   0x0002
+/*inbound message 0 ready*/
+#define ARCMSR_ARC1214_IOP2DRV_DATA_WRITE_OK   0x0001
+/*outbound DATA WRITE isr door bell clear*/
+#define ARCMSR_ARC1214_IOP2DRV_DATA_READ_OK0x0002
+/*outbound message 0 ready*/
+#define ARCMSR_ARC1214_IOP2DRV_MESSAGE_CMD_DONE0x0200
+/*outbound message cmd isr door bell clear*/
+/*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/
+#define ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK 0x8000
+#define ARCMSR_ARC1214_OUTBOUND_LIST_INTERRUPT_CLEAR   0x0001
+/*
+***
 **ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
 ***
 */
@@ -496,6 +551,55 @@ struct MessageUnit_C{
uint32_tmsgcode_rwbuffer[256];  /*2200 23FF*/
 };
 /*
+*
+** Messaging Unit (MU) of Type D processor
+*
+*/
+struct InBound_SRB {
+   uint32_t addressLow; /* pointer to SRB block */
+   uint32_t addressHigh;
+   uint32_t length

[PATCH v3 17/17] arcmsr: modify calling scsi_scan_host after all initialization done

2014-08-19 Thread Ching Huang
From: Ching Huang 

Modify calling scsi_scan_host until all initialization done.
And fix error path of free allocation resource.

Signed-off-by: Ching Huang 
---

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:38:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-14 17:43:04.0 +0800
@@ -112,6 +112,7 @@ static void arcmsr_hbaD_message_isr(stru
 static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
+static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
  int queue_depth, int reason)
 {
@@ -730,12 +731,11 @@ static int arcmsr_probe(struct pci_dev *
}
error = scsi_add_host(host, &pdev->dev);
if(error){
-   goto RAID_controller_stop;
+   goto free_ccb_pool;
}
if (arcmsr_request_irq(pdev, acb) == FAILED)
goto scsi_host_remove;
arcmsr_iop_init(acb);
-   scsi_scan_host(host);
INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
atomic_set(&acb->rq_map_token, 16);
atomic_set(&acb->ante_token_value, 16);
@@ -747,13 +747,17 @@ static int arcmsr_probe(struct pci_dev *
add_timer(&acb->eternal_timer);
if(arcmsr_alloc_sysfs_attr(acb))
goto out_free_sysfs;
+   scsi_scan_host(host);
return 0;
 out_free_sysfs:
-scsi_host_remove:
-   scsi_remove_host(host);
-RAID_controller_stop:
+   del_timer_sync(&acb->eternal_timer);
+   flush_work(&acb->arcmsr_do_message_isr_bh);
arcmsr_stop_adapter_bgrb(acb);
arcmsr_flush_adapter_cache(acb);
+   arcmsr_free_irq(pdev, acb);
+scsi_host_remove:
+   scsi_remove_host(host);
+free_ccb_pool:
arcmsr_free_ccb_pool(acb);
 free_hbb_mu:
arcmsr_free_mu(acb);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 0/17] arcmsr: change note since v13 or v2

2014-08-20 Thread Ching Huang
Hi Christoph,

Thanks for your effort to fix up errors and apply the patches of arcmsr
to a branch. It is great.

Regards,
Ching Huang
On Tue, 2014-08-19 at 08:02 -0700, Christoph Hellwig wrote:
> Hi Ching,
> 
> I've fixed up various checkpatch errors and fixed up some descriptions
> and applied the patches to a branch.  This includes patch 4, so please
> send a fix for this and any other patches relative to the branch.
> 
> Please find the branch at
> 
>   git://git.infradead.org/users/hch/scsi-queue.git arcmsr-for-3.18
> 
> Can the others help reviewing these patches and make sure we can get
> them into 3.18?
> 
> Thanks,
>   Christoph


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 3/17] arcmsr: Add code to support system hibernation

2014-08-08 Thread Ching Huang
From: Ching Huang 

This patch adds code to support system hibernation.

Changes in v2 of 3/17:
* merge patch 18/18 to this patch

Signed-off-by: Ching Huang 
---

Thanks to Tomas's advice.

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-01 17:54:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:03:48.0 +0800
@@ -89,11 +89,15 @@ static int arcmsr_bios_param(struct scsi
 static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int arcmsr_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
+static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state);
+static int arcmsr_resume(struct pci_dev *pdev);
 static void arcmsr_remove(struct pci_dev *pdev);
 static void arcmsr_shutdown(struct pci_dev *pdev);
 static void arcmsr_iop_init(struct AdapterControlBlock *acb);
 static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb);
 static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb);
+static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
+   u32 intmask_org);
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb);
 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
@@ -167,6 +171,8 @@ static struct pci_driver arcmsr_pci_driv
.id_table   = arcmsr_device_id_table,
.probe  = arcmsr_probe,
.remove = arcmsr_remove,
+   .suspend= arcmsr_suspend,
+   .resume = arcmsr_resume,
.shutdown   = arcmsr_shutdown,
 };
 /*
@@ -772,6 +778,76 @@ static void arcmsr_free_irq(struct pci_d
free_irq(pdev->irq, acb);
 }
 
+static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+   uint32_t intmask_org;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host->hostdata;
+
+   intmask_org = arcmsr_disable_outbound_ints(acb);
+   arcmsr_free_irq(pdev, acb);
+   del_timer_sync(&acb->eternal_timer);
+   flush_work(&acb->arcmsr_do_message_isr_bh);
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+   pci_set_drvdata(pdev, host);
+   pci_save_state(pdev);
+   pci_disable_device(pdev);
+   pci_set_power_state(pdev, pci_choose_state(pdev, state));
+   return 0;
+}
+
+static int arcmsr_resume(struct pci_dev *pdev)
+{
+   int error;
+   struct Scsi_Host *host = pci_get_drvdata(pdev);
+   struct AdapterControlBlock *acb =
+   (struct AdapterControlBlock *)host->hostdata;
+
+   pci_set_power_state(pdev, PCI_D0);
+   pci_enable_wake(pdev, PCI_D0, 0);
+   pci_restore_state(pdev);
+   if (pci_enable_device(pdev)) {
+   pr_warn("%s: pci_enable_device error\n", __func__);
+   return -ENODEV;
+   }
+   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+   if (error) {
+   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+   if (error) {
+   pr_warn("scsi%d: No suitable DMA mask available\n",
+  host->host_no);
+   goto controller_unregister;
+   }
+   }
+   pci_set_master(pdev);
+   if (arcmsr_request_irq(pdev, acb) == FAILED)
+   goto controller_stop;
+   arcmsr_iop_init(acb);
+   INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
+   atomic_set(&acb->rq_map_token, 16);
+   atomic_set(&acb->ante_token_value, 16);
+   acb->fw_flag = FW_NORMAL;
+   init_timer(&acb->eternal_timer);
+   acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ);
+   acb->eternal_timer.data = (unsigned long) acb;
+   acb->eternal_timer.function = &arcmsr_request_device_map;
+   add_timer(&acb->eternal_timer);
+   return 0;
+controller_stop:
+   arcmsr_stop_adapter_bgrb(acb);
+   arcmsr_flush_adapter_cache(acb);
+controller_unregister:
+   scsi_remove_host(host);
+   arcmsr_free_ccb_pool(acb);
+   arcmsr_unmap_pciregion(acb);
+   pci_release_regions(pdev);
+   scsi_host_put(host);
+   pci_disable_device(pdev);
+   return -ENODEV;
+}
+
 static uint8_t arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
 {
struct MessageUnit_A __iomem *reg = acb->pmuA;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 4/17] arcmsr: limit max. number of SCSI command request

2014-08-08 Thread Ching Huang
From: Ching Huang 

This patch limits the max. number of SCSI command request to avoid command 
overflow.

Changes in v2 4/17:
* set the correct host->can_queue value after read adapter's limitation.

Signed-off-by: Ching Huang 
---

Thanks to Tomas's advice.

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:06.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:22:36.0 +0800
@@ -45,11 +45,12 @@
 #include 
 struct device_attribute;
 /*The limit of outstanding scsi command that firmware can handle*/
-#define ARCMSR_MAX_OUTSTANDING_CMD 
256
 #ifdef CONFIG_XEN
#define ARCMSR_MAX_FREECCB_NUM  160
+#define ARCMSR_MAX_OUTSTANDING_CMD 155
 #else
#define ARCMSR_MAX_FREECCB_NUM  320
+#define ARCMSR_MAX_OUTSTANDING_CMD 255
 #endif
 #define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140428"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
@@ -598,6 +599,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   uint32_tmaxOutstanding;
int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
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-08 19:03:48.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:35:46.0 +0800
@@ -134,7 +134,7 @@ static struct scsi_host_template arcmsr_
.eh_bus_reset_handler   = arcmsr_bus_reset,
.bios_param = arcmsr_bios_param,
.change_queue_depth = arcmsr_adjust_disk_queue_depth,
-   .can_queue  = ARCMSR_MAX_FREECCB_NUM,
+   .can_queue  = ARCMSR_MAX_OUTSTANDING_CMD,
.this_id= ARCMSR_SCSI_INITIATOR_ID,
.sg_tablesize   = ARCMSR_DEFAULT_SG_ENTRIES, 
.max_sectors= ARCMSR_MAX_XFER_SECTORS_C, 
@@ -693,7 +693,7 @@ static int arcmsr_probe(struct pci_dev *
host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
host->max_cmd_len = 16; /*this is issue of 
64bit LBA ,over 2T byte*/
-   host->can_queue = ARCMSR_MAX_FREECCB_NUM;   /* max simultaneous 
cmds */ 
+   host->can_queue = ARCMSR_MAX_OUTSTANDING_CMD;   /* max simultaneous 
cmds */ 
host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN;  
host->this_id = ARCMSR_SCSI_INITIATOR_ID;
host->unique_id = (bus << 8) | dev_fun;
@@ -2215,9 +2215,6 @@ static int arcmsr_queue_command_lck(stru
arcmsr_handle_virtual_command(acb, cmd);
return 0;
}
-   if (atomic_read(&acb->ccboutstandingcount) >=
-   ARCMSR_MAX_OUTSTANDING_CMD)
-   return SCSI_MLQUEUE_HOST_BUSY;
ccb = arcmsr_get_freeccb(acb);
if (!ccb)
return SCSI_MLQUEUE_HOST_BUSY;
@@ -2427,12 +2424,27 @@ static bool arcmsr_get_hbc_config(struct
 }
 static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 {
-   if (acb->adapter_type == ACB_ADAPTER_TYPE_A)
-   return arcmsr_get_hba_config(acb);
-   else if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
-   return arcmsr_get_hbb_config(acb);
+   bool rtn = false;
+
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_A:
+   rtn = arcmsr_get_hba_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_B:
+   rtn = arcmsr_get_hbb_config(acb);
+   break;
+   case ACB_ADAPTER_TYPE_C:
+   rtn = arcmsr_get_hbc_config(acb);
+   break;
+   default:
+   break;
+   }
+   if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
+   acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD;
else
-   return arcmsr_get_hbc_config(acb);
+   acb->maxOutstanding = acb->firm_numbers_queue - 1;
+   acb->host->can_queue = acb->maxOutstanding;
+   return rtn;
 }
 
 static int arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 3/17] arcmsr: Add code to support system hibernation

2014-08-11 Thread Ching Huang
Yes. 18/18 is obsolete.
Thanks to Tomas's advice.

Ching
On Fri, 2014-08-08 at 16:23 +0200, Tomas Henzl wrote:
> On 08/08/2014 02:05 PM, Ching Huang wrote:
> > From: Ching Huang 
> >
> > This patch adds code to support system hibernation.
> >
> > Changes in v2 of 3/17:
> > * merge patch 18/18 to this patch, so 18/18 is obsolete.
> 
> Thanks, and please mark the the 18/18 as obsolete - add a comment there 
> 
> In my previous response were other comments too, you haven't probably 
> noticed them. I could be wrong with my comments, but if you want a review
> you should explain why the code is ok as it is.
> 
> >
> > Signed-off-by: Ching Huang 
> > ---
> >
> > Thanks to Tomas's advice.
> >
> > 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-01 17:54:46.0 
> > +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-08 19:03:48.0 
> > +0800
> > @@ -89,11 +89,15 @@ static int arcmsr_bios_param(struct scsi
> >  static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd 
> > *cmd);
> >  static int arcmsr_probe(struct pci_dev *pdev,
> > const struct pci_device_id *id);
> > +static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state);
> > +static int arcmsr_resume(struct pci_dev *pdev);
> >  static void arcmsr_remove(struct pci_dev *pdev);
> >  static void arcmsr_shutdown(struct pci_dev *pdev);
> >  static void arcmsr_iop_init(struct AdapterControlBlock *acb);
> >  static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb);
> >  static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb);
> > +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
> > +   u32 intmask_org);
> >  static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
> >  static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb);
> >  static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
> > @@ -167,6 +171,8 @@ static struct pci_driver arcmsr_pci_driv
> > .id_table   = arcmsr_device_id_table,
> > .probe  = arcmsr_probe,
> > .remove = arcmsr_remove,
> > +   .suspend= arcmsr_suspend,
> > +   .resume = arcmsr_resume,
> > .shutdown   = arcmsr_shutdown,
> >  };
> >  /*
> > @@ -772,6 +778,76 @@ static void arcmsr_free_irq(struct pci_d
> > free_irq(pdev->irq, acb);
> >  }
> >  
> > +static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)
> > +{
> > +   uint32_t intmask_org;
> > +   struct Scsi_Host *host = pci_get_drvdata(pdev);
> > +   struct AdapterControlBlock *acb =
> > +   (struct AdapterControlBlock *)host->hostdata;
> > +
> > +   intmask_org = arcmsr_disable_outbound_ints(acb);
> > +   arcmsr_free_irq(pdev, acb);
> > +   del_timer_sync(&acb->eternal_timer);
> > +   flush_work(&acb->arcmsr_do_message_isr_bh);
> > +   arcmsr_stop_adapter_bgrb(acb);
> > +   arcmsr_flush_adapter_cache(acb);
> > +   pci_set_drvdata(pdev, host);
> > +   pci_save_state(pdev);
> > +   pci_disable_device(pdev);
> > +   pci_set_power_state(pdev, pci_choose_state(pdev, state));
> > +   return 0;
> > +}
> > +
> > +static int arcmsr_resume(struct pci_dev *pdev)
> > +{
> > +   int error;
> > +   struct Scsi_Host *host = pci_get_drvdata(pdev);
> > +   struct AdapterControlBlock *acb =
> > +   (struct AdapterControlBlock *)host->hostdata;
> > +
> > +   pci_set_power_state(pdev, PCI_D0);
> > +   pci_enable_wake(pdev, PCI_D0, 0);
> > +   pci_restore_state(pdev);
> > +   if (pci_enable_device(pdev)) {
> > +   pr_warn("%s: pci_enable_device error\n", __func__);
> > +   return -ENODEV;
> > +   }
> > +   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
> > +   if (error) {
> > +   error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
> > +   if (error) {
> > +   pr_warn("scsi%d: No suitable DMA mask available\n",
> > +  host->host_no);
> > +   goto controller_unregister;
> > +   }
> > +   }
> > +   pci_set_master(pdev);
> > +   if (arcmsr_request_irq(pdev, acb) == FAILED)
> > +   goto controller_stop;
> > +   arcmsr_iop_init(acb);

Re: [PATCH v1.3 2/18] arcmsr: Add code to support MSI-X, MSI interrupt

2014-08-01 Thread Ching Huang
Hi Alexander,

Thanks for your advice.
This patch was revised according to your comment.

Signed-off-by: Ching
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-04-28 16:02:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:36.0 +0800
@@ -64,6 +64,7 @@ struct device_attribute;
 #define ARCMSR_MAX_HBB_POSTQUEUE   
264
 #define ARCMSR_MAX_XFER_LEN
0x26000 /* 152K */
 #define ARCMSR_CDB_SG_PAGE_LENGTH  
256 
+#define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
@@ -508,6 +509,7 @@ struct AdapterControlBlock
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
+   struct msix_entry   entries[ARCMST_NUM_MSIX_VECTORS];
/* Offset is used in making arc cdb physical to virtual calculations */
uint32_toutbound_int_enable;
uint32_tcdb_phyaddr_hi32;
@@ -544,6 +546,8 @@ struct AdapterControlBlock
/* iop init */
#define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400
+   #define ACB_F_MSI_ENABLED   0x1000
+   #define ACB_F_MSIX_ENABLED  0x2000
struct CommandControlBlock *
pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */
struct list_headccb_free_list;
@@ -594,6 +598,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
 ***
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-01 11:02:44.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 17:54:46.0 +0800
@@ -603,6 +603,56 @@ static void arcmsr_message_isr_bh_fn(str
}
 }
 
+static int
+arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
+{
+   int i, j, r;
+   struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
+
+   for (i = 0; i < ARCMST_NUM_MSIX_VECTORS; i++)
+   entries[i].entry = i;
+   r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS);
+   if (r < 0)
+   goto msi_int;
+   acb->msix_vector_count = r;
+   for (i = 0; i < r; i++) {
+   if (request_irq(entries[i].vector,
+   arcmsr_do_interrupt, 0, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, entries[i].vector);
+   for (j = 0 ; j < i ; j++)
+   free_irq(entries[j].vector, acb);
+   pci_disable_msix(pdev);
+   goto msi_int;
+   }
+   acb->entries[i] = entries[i];
+   }
+   acb->acb_flags |= ACB_F_MSIX_ENABLED;
+   pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
+   return SUCCESS;
+msi_int:
+   if (pci_enable_msi_exact(pdev, 1) < 0)
+   goto legacy_int;
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, pdev->irq);
+   pci_disable_msi(pdev);
+   goto legacy_int;
+   }
+   acb->acb_flags |= ACB_F_MSI_ENABLED;
+   pr_info("arcmsr%d: msi enabled\n", acb->host->host_no);
+   return SUCCESS;
+legacy_int:
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq = %d failed!\n",
+   acb->host->host_no, pdev->irq);
+   return FAILED;
+   }
+   return SUCCESS;
+}
+
 static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
struct Scsi_Host *host;
@@ -667,16 +717,13 @@ static int arcmsr_probe(struct pci_dev *
if(error){
goto free_hbb_mu;
}
-   arcmsr_iop_init(acb);
error = scsi_add_host(host, &pdev->dev);
if(error){
goto RAID_controller_stop;
}
-   error = request_irq(pdev->irq, arcmsr_do_interrupt, IRQF_SHARED, 
"arcmsr", acb);
-   if(error){
+   if (arcmsr_request_irq(pdev, acb) == FAILED)
goto scsi_host_remove;
-   }

[PATCH v2 2/18] arcmsr: Add code to support MSI-X, MSI interrupt

2014-08-03 Thread Ching Huang

From: Ching Huang 

Changes in v2 of 2/18:
* remove the checking of capability of MSI-X, MSI.
* correct the wrong IRQ vector of request_irq failed.
* replace pci_enable_msi_range() by pci_enable_msi_exact().

Signed-off-by: Ching Huang 
---

Thanks for Dan's advice.

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-04-28 16:02:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:24:36.0 +0800
@@ -64,6 +64,7 @@ struct device_attribute;
 #define ARCMSR_MAX_HBB_POSTQUEUE   
264
 #define ARCMSR_MAX_XFER_LEN
0x26000 /* 152K */
 #define ARCMSR_CDB_SG_PAGE_LENGTH  
256 
+#define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
@@ -508,6 +509,7 @@ struct AdapterControlBlock
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
+   struct msix_entry   entries[ARCMST_NUM_MSIX_VECTORS];
/* Offset is used in making arc cdb physical to virtual calculations */
uint32_toutbound_int_enable;
uint32_tcdb_phyaddr_hi32;
@@ -544,6 +546,8 @@ struct AdapterControlBlock
/* iop init */
#define ACB_F_ABORT 0x0200
#define ACB_F_FIRMWARE_TRAP 0x0400
+   #define ACB_F_MSI_ENABLED   0x1000
+   #define ACB_F_MSIX_ENABLED  0x2000
struct CommandControlBlock *
pccb_pool[ARCMSR_MAX_FREECCB_NUM];
/* used for memory free */
struct list_headccb_free_list;
@@ -594,6 +598,7 @@ struct AdapterControlBlock
#define FW_DEADLOCK 0x0010
atomic_trq_map_token;
atomic_tante_token_value;
+   int msix_vector_count;
 };/* HW_DEVICE_EXTENSION */
 /*
 ***
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-01 11:02:44.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-01 17:54:46.0 +0800
@@ -603,6 +603,56 @@ static void arcmsr_message_isr_bh_fn(str
}
 }
 
+static int
+arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb)
+{
+   int i, j, r;
+   struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS];
+
+   for (i = 0; i < ARCMST_NUM_MSIX_VECTORS; i++)
+   entries[i].entry = i;
+   r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS);
+   if (r < 0)
+   goto msi_int;
+   acb->msix_vector_count = r;
+   for (i = 0; i < r; i++) {
+   if (request_irq(entries[i].vector,
+   arcmsr_do_interrupt, 0, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, entries[i].vector);
+   for (j = 0 ; j < i ; j++)
+   free_irq(entries[j].vector, acb);
+   pci_disable_msix(pdev);
+   goto msi_int;
+   }
+   acb->entries[i] = entries[i];
+   }
+   acb->acb_flags |= ACB_F_MSIX_ENABLED;
+   pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no);
+   return SUCCESS;
+msi_int:
+   if (pci_enable_msi_exact(pdev, 1) < 0)
+   goto legacy_int;
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq =%d failed!\n",
+   acb->host->host_no, pdev->irq);
+   pci_disable_msi(pdev);
+   goto legacy_int;
+   }
+   acb->acb_flags |= ACB_F_MSI_ENABLED;
+   pr_info("arcmsr%d: msi enabled\n", acb->host->host_no);
+   return SUCCESS;
+legacy_int:
+   if (request_irq(pdev->irq, arcmsr_do_interrupt,
+   IRQF_SHARED, "arcmsr", acb)) {
+   pr_warn("arcmsr%d: request_irq = %d failed!\n",
+   acb->host->host_no, pdev->irq);
+   return FAILED;
+   }
+   return SUCCESS;
+}
+
 static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
struct Scsi_Host *host;
@@ -667,16 +717,13 @@ static int arcmsr_probe(struct pci_dev *
if(error){
goto free_hbb_mu;
}
-   arcmsr_iop_init(acb);

Re: [PATCH v1.3 4/18] arcmsr: limit max. number of SCSI command request

2014-08-03 Thread Ching Huang
On Fri, 2014-08-01 at 05:35 -0700, Christoph Hellwig wrote:
> > @@ -2220,8 +2220,7 @@ static int arcmsr_queue_command_lck(stru
> > arcmsr_handle_virtual_command(acb, cmd);
> > return 0;
> > }
> > -   if (atomic_read(&acb->ccboutstandingcount) >=
> > -   ARCMSR_MAX_OUTSTANDING_CMD)
> > +   if (atomic_read(&acb->ccboutstandingcount) >= acb->maxOutstanding)
> > return SCSI_MLQUEUE_HOST_BUSY;
> 
> The scsi midlayer already takes care of this check for you.
> 

Hello Christoph,

We have 4 types of Adapter that some adpaters have command queue less
than ARCMSR_MAX_OUTSTANDING_CMD.
So we have to check outstanding command number here.

Thanks for your comment.
Ching

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 6/18] arcmsr: precise checking adapter ID

2014-08-04 Thread Ching Huang
From: Ching Huang 

This patch rewrites the arcmsr_define_adapter_type function to precisely check 
Areca adapter's ID.
This can prevent an unknown adapter being used as a default adapter type by 
driver.

Signed-off-by: Ching Huang 
---

Thanks for Christoph advice.


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-01 18:02:08.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:43:16.0 +0800
@@ -295,24 +295,43 @@ static int arcmsr_bios_param(struct scsi
return 0;
 }
 
-static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
+static int arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
 {
struct pci_dev *pdev = acb->pdev;
u16 dev_id;
-   pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id);
+
+   dev_id = pdev->device;
acb->dev_id = dev_id;
switch (dev_id) {
-   case 0x1880: {
+   case 0x1880:
acb->adapter_type = ACB_ADAPTER_TYPE_C;
-   }
break;
-   case 0x1201: {
+   case 0x1200:
+   case 0x1201:
+   case 0x1202:
acb->adapter_type = ACB_ADAPTER_TYPE_B;
-   }
break;
-
-   default: acb->adapter_type = ACB_ADAPTER_TYPE_A;
+   case 0x1110:
+   case 0x1120:
+   case 0x1130:
+   case 0x1160:
+   case 0x1170:
+   case 0x1210:
+   case 0x1220:
+   case 0x1230:
+   case 0x1260:
+   case 0x1270:
+   case 0x1280:
+   case 0x1380:
+   case 0x1381:
+   case 0x1680:
+   acb->adapter_type = ACB_ADAPTER_TYPE_A;
+   break;
+   default:
+   pr_notice("Unknown device ID = 0x%x\n", dev_id);
+   return false;
}
+   return true;
 }
 
 static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
@@ -710,7 +729,9 @@ static int arcmsr_probe(struct pci_dev *
ACB_F_MESSAGE_WQBUFFER_READED);
acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
INIT_LIST_HEAD(&acb->ccb_free_list);
-   arcmsr_define_adapter_type(acb);
+   error = arcmsr_define_adapter_type(acb);
+   if (!error)
+   goto pci_release_regs;
error = arcmsr_remap_pciregion(acb);
if(!error){
goto pci_release_regs;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 7/18] arcmsr: revise messages_isr_bh_fn to remove duplicate code

2014-08-04 Thread Ching Huang
From: Ching Huang 

Revise message_isr_bh_fn to remove the duplicate code for each adapter type.

Signed-off-by: Ching Huang 
---

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-04 16:43:16.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:43:06.0 +0800
@@ -511,120 +511,65 @@ static int arcmsr_alloc_ccb_pool(struct 
 
 static void arcmsr_message_isr_bh_fn(struct work_struct *work) 
 {
-   struct AdapterControlBlock *acb = container_of(work,struct 
AdapterControlBlock, arcmsr_do_message_isr_bh);
-   switch (acb->adapter_type) {
-   case ACB_ADAPTER_TYPE_A: {
+   struct AdapterControlBlock *acb = container_of(work,
+   struct AdapterControlBlock, arcmsr_do_message_isr_bh);
+   char *acb_dev_map = (char *)acb->device_map;
+   uint32_t __iomem *signature = NULL;
+   char __iomem *devicemap = NULL;
+   int target, lun;
+   struct scsi_device *psdev;
+   char diff, temp;
 
-   struct MessageUnit_A __iomem *reg  = acb->pmuA;
-   char *acb_dev_map = (char *)acb->device_map;
-   uint32_t __iomem *signature = (uint32_t __iomem*) 
(®->message_rwbuffer[0]);
-   char __iomem *devicemap = (char __iomem*) 
(®->message_rwbuffer[21]);
-   int target, lun;
-   struct scsi_device *psdev;
-   char diff;
-
-   atomic_inc(&acb->rq_map_token);
-   if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) {
-   for(target = 0; target < ARCMSR_MAX_TARGETID 
-1; target++) {
-   diff = (*acb_dev_map)^readb(devicemap);
-   if (diff != 0) {
-   char temp;
-   *acb_dev_map = readb(devicemap);
-   temp =*acb_dev_map;
-   for(lun = 0; lun < 
ARCMSR_MAX_TARGETLUN; lun++) {
-   if((temp & 0x01)==1 && 
(diff & 0x01) == 1) {
-   
scsi_add_device(acb->host, 0, target, lun);
-   }else if((temp & 0x01) 
== 0 && (diff & 0x01) == 1) {
-   psdev = 
scsi_device_lookup(acb->host, 0, target, lun);
-   if (psdev != 
NULL ) {
-   
scsi_remove_device(psdev);
-   
scsi_device_put(psdev);
-   }
-   }
-   temp >>= 1;
-   diff >>= 1;
-   }
-   }
-   devicemap++;
-   acb_dev_map++;
-   }
-   }
-   break;
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_A: {
+   struct MessageUnit_A __iomem *reg  = acb->pmuA;
+   signature = (uint32_t __iomem *)(®->message_rwbuffer[0]);
+   devicemap = (char __iomem *)(®->message_rwbuffer[21]);
+   break;
}
-
-   case ACB_ADAPTER_TYPE_B: {
-   struct MessageUnit_B *reg  = acb->pmuB;
-   char *acb_dev_map = (char *)acb->device_map;
-   uint32_t __iomem *signature = (uint32_t 
__iomem*)(®->message_rwbuffer[0]);
-   char __iomem *devicemap = (char 
__iomem*)(®->message_rwbuffer[21]);
-   int target, lun;
-   struct scsi_device *psdev;
-   char diff;
-
-   atomic_inc(&acb->rq_map_token);
-   if (readl(signature) == ARCMSR_SIGNATURE_GET_CONFIG) {
-   for(target = 0; target < ARCMSR_MAX_TARGETID 
-1; target++) {
-   diff = (*acb_dev_map)^readb(devicemap);
-   if (diff != 0) {
-   char temp;
-   *acb_dev_map = readb(devicemap);
- 

[PATCH v1.3 8/18] arcmsr: remove calling arcmsr_hbb_enable_driver_mode

2014-08-04 Thread Ching Huang
From: Ching Huang 

Remove calling arcmsr_hbb_enable_driver_mode by in-line code.

Signed-off-by: Ching Huang 
---

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-04 16:43:06.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:44:44.0 +0800
@@ -875,17 +875,6 @@ static uint8_t arcmsr_abort_allcmd(struc
return rtnval;
 }
 
-static bool arcmsr_hbb_enable_driver_mode(struct AdapterControlBlock *pacb)
-{
-   struct MessageUnit_B *reg = pacb->pmuB;
-   writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
-   if (!arcmsr_hbb_wait_msgint_ready(pacb)) {
-   printk(KERN_ERR "arcmsr%d: can't set driver mode. \n", 
pacb->host->host_no);
-   return false;
-   }
-   return true;
-}
-
 static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb)
 {
struct scsi_cmnd *pcmd = ccb->pcmd;
@@ -2683,7 +2672,12 @@ static int arcmsr_iop_confirm(struct Ada
timeout \n",acb->host->host_no);
return 1;
}
-   arcmsr_hbb_enable_driver_mode(acb);
+   writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
+   if (!arcmsr_hbb_wait_msgint_ready(acb)) {
+   pr_err("arcmsr%d: can't set driver mode.\n",
+   acb->host->host_no);
+   return 1;
+   }
}
break;
case ACB_ADAPTER_TYPE_C: {



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 9/18] arcmsr: modify printing adapter model number and F/W messages

2014-08-04 Thread Ching Huang
From: Ching Huang 

Adjust printing order of adapter model name and firmware version.

Signed-off-by: Ching Huang 
---

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-04 16:44:44.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:44:50.0 +0800
@@ -2226,10 +2226,10 @@ static bool arcmsr_get_hba_config(struct
iop_device_map++;
count--;
}
-   printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n", 
+   pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
acb->host->host_no,
-   acb->firm_version,
-   acb->firm_model);
+   acb->firm_model,
+   acb->firm_version);
acb->signature = readl(®->message_rwbuffer[0]);
acb->firm_request_len = readl(®->message_rwbuffer[1]);
acb->firm_numbers_queue = readl(®->message_rwbuffer[2]);
@@ -2302,10 +2302,10 @@ static bool arcmsr_get_hbb_config(struct
count--;
}

-   printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+   pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
acb->host->host_no,
-   acb->firm_version,
-   acb->firm_model);
+   acb->firm_model,
+   acb->firm_version);
 
acb->signature = readl(®->message_rwbuffer[1]);
/*firm_signature,1,00-03*/
@@ -2368,10 +2368,10 @@ static bool arcmsr_get_hbc_config(struct
iop_firm_version++;
count--;
}
-   printk(KERN_NOTICE "Areca RAID Controller%d: F/W %s & Model %s\n",
+   pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",
pACB->host->host_no,
-   pACB->firm_version,
-   pACB->firm_model);
+   pACB->firm_model,
+   pACB->firm_version);
pACB->firm_request_len = readl(®->msgcode_rwbuffer[1]);   
/*firm_request_len,1,04-07*/
pACB->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]); 
/*firm_numbers_queue,2,08-11*/
pACB->firm_sdram_size = readl(®->msgcode_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 10/18] arcmsr: clear outbound doorbell buffer completely

2014-08-04 Thread Ching Huang
From: Ching Huang 

Clear outbound doorbell buffer completely for adapter type C.
This is to prevent getting bad data input from IOP before ioctl command 
beginning.

Signed-off-by: Ching Huang 
---

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-04 16:44:50.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:45:00.0 +0800
@@ -2888,11 +2888,23 @@ static void arcmsr_clear_doorbell_queue_
break;
case ACB_ADAPTER_TYPE_C: {
struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
-   uint32_t outbound_doorbell;
+   uint32_t outbound_doorbell, i;
/* empty doorbell Qbuffer if door bell ringed */
outbound_doorbell = readl(®->outbound_doorbell);
writel(outbound_doorbell, ®->outbound_doorbell_clear);
writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, 
®->inbound_doorbell);
+   for (i = 0; i < 200; i++) {
+   msleep(20);
+   outbound_doorbell = readl(®->outbound_doorbell);
+   if (outbound_doorbell &
+   ARCMSR_HBCMU_IOP2DRV_DATA_WRITE_OK) {
+   writel(outbound_doorbell,
+   ®->outbound_doorbell_clear);
+   writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK,
+   ®->inbound_doorbell);
+   } else
+   break;
+   }
}
}
 }
@@ -3120,9 +3132,7 @@ sleep:
arcmsr_get_firmware_spec(acb);
arcmsr_start_adapter_bgrb(acb);
/* clear Qbuffer if door bell ringed */
-   outbound_doorbell = 
readl(®->outbound_doorbell);
-   writel(outbound_doorbell, 
®->outbound_doorbell_clear); /*clear interrupt */
-   writel(ARCMSR_HBCMU_DRV2IOP_DATA_READ_OK, 
®->inbound_doorbell);
+   arcmsr_clear_doorbell_queue_buffer(acb);
/* enable outbound Post Queue,outbound doorbell 
Interrupt */
arcmsr_enable_outbound_ints(acb, intmask_org);
atomic_set(&acb->rq_map_token, 16);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 11/18] arcmsr: rename function and variable

2014-08-04 Thread Ching Huang
From: Ching Huang 

Rename some variable and function name for readability and consistency.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:27:14.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:27:38.0 +0800
@@ -359,7 +359,7 @@ struct ARCMSR_CDB
 #define ARCMSR_CDB_FLAG_ORDEREDQ   0x10
 
uint8_t msgPages;
-   uint32_tContext;
+   uint32_tmsgContext;
uint32_tDataLength;
uint8_t Cdb[16];
uint8_t DeviceStatus;
@@ -562,7 +562,7 @@ struct AdapterControlBlock
/* dma_coherent used for memory free */
dma_addr_t  dma_coherent_handle;
/* dma_coherent_handle used for memory free */
-   dma_addr_t  dma_coherent_handle_hbb_mu;
+   dma_addr_t  dma_coherent_handle2;
unsigned intuncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
@@ -613,7 +613,7 @@ struct CommandControlBlock{
struct list_headlist;   /*x32: 
8byte, x64: 16byte*/
struct scsi_cmnd*pcmd;  /*8 
bytes pointer of linux scsi command */
struct AdapterControlBlock  *acb;   /*x32: 
4byte, x64: 8byte*/
-   uint32_tcdb_phyaddr_pattern;/*x32: 
4byte, x64: 4byte*/
+   uint32_tcdb_phyaddr;/*x32: 
4byte, x64: 4byte*/
uint32_tarc_cdb_size;   
/*x32:4byte,x64:4byte*/
uint16_tccb_flags;  /*x32: 
2byte, x64: 2byte*/
#define CCB_FLAG_READ   0x
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-04 16:45:00.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:45:18.0 +0800
@@ -99,16 +99,16 @@ static u32 arcmsr_disable_outbound_ints(
 static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb,
u32 intmask_org);
 static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb);
-static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb);
-static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb);
+static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb);
+static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb);
 static void arcmsr_request_device_map(unsigned long pacb);
-static void arcmsr_request_hba_device_map(struct AdapterControlBlock *acb);
-static void arcmsr_request_hbb_device_map(struct AdapterControlBlock *acb);
-static void arcmsr_request_hbc_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_hbaA_request_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_hbaB_request_device_map(struct AdapterControlBlock *acb);
+static void arcmsr_hbaC_request_device_map(struct AdapterControlBlock *acb);
 static void arcmsr_message_isr_bh_fn(struct work_struct *work);
 static bool arcmsr_get_firmware_spec(struct AdapterControlBlock *acb);
 static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb);
-static void arcmsr_hbc_message_isr(struct AdapterControlBlock *pACB);
+static void arcmsr_hbaC_message_isr(struct AdapterControlBlock *pACB);
 static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
@@ -180,7 +180,7 @@ static struct pci_driver arcmsr_pci_driv
 
 */
 
-static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb)
+static void arcmsr_free_mu(struct AdapterControlBlock *acb)
 {
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A:
@@ -189,7 +189,7 @@ static void arcmsr_free_hbb_mu(struct Ad
case ACB_ADAPTER_TYPE_B:{
dma_free_coherent(&acb->pdev->dev,
sizeof(struct MessageUnit_B),
-   acb->pmuB, acb->dma_coherent_handle_hbb_mu);
+   acb->pmuB, acb->dma_coherent_handle2);
}
}
 }
@@ -334,7 +334,7 @@ static int arcmsr_define_adapter_type(st
return true;
 }
 
-static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
+static uint8_t arcm

[PATCH v1.3 12/18] arcmsr: revise allocation of second dma_coherent_handle for type B adapter

2014-08-04 Thread Ching Huang
From: Ching Huang 

This modification is for consistency with up-coming adapter type D.
They have similar H/W and S/W structure.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:27:38.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:28:38.0 +0800
@@ -507,6 +507,7 @@ struct AdapterControlBlock
#define ACB_ADAPTER_TYPE_B0x0002/* hbb M IOP */
#define ACB_ADAPTER_TYPE_C0x0004/* hbc P IOP */
#define ACB_ADAPTER_TYPE_D0x0008/* hbd A IOP */
+   u32 roundup_ccbsize;
struct pci_dev *pdev;
struct Scsi_Host *  host;
unsigned long   vir2phy_offset;
@@ -563,6 +564,7 @@ struct AdapterControlBlock
dma_addr_t  dma_coherent_handle;
/* dma_coherent_handle used for memory free */
dma_addr_t  dma_coherent_handle2;
+   void*dma_coherent2;
unsigned intuncache_size;
uint8_t rqbuffer[ARCMSR_MAX_QBUFFER];
/* data collection buffer for read from 80331 */
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-04 16:45:18.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:45:26.0 +0800
@@ -183,13 +183,10 @@ static struct pci_driver arcmsr_pci_driv
 static void arcmsr_free_mu(struct AdapterControlBlock *acb)
 {
switch (acb->adapter_type) {
-   case ACB_ADAPTER_TYPE_A:
-   case ACB_ADAPTER_TYPE_C:
-   break;
case ACB_ADAPTER_TYPE_B:{
-   dma_free_coherent(&acb->pdev->dev,
-   sizeof(struct MessageUnit_B),
-   acb->pmuB, acb->dma_coherent_handle2);
+   dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
+   acb->dma_coherent2, acb->dma_coherent_handle2);
+   break;
}
}
 }
@@ -2254,12 +2251,15 @@ static bool arcmsr_hbaB_get_config(struc
char __iomem *iop_device_map;
/*firm_version,21,84-99*/
int count;
-   dma_coherent = dma_alloc_coherent(&pdev->dev, sizeof(struct 
MessageUnit_B), &dma_coherent_handle, GFP_KERNEL);
+
+   acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
+   dma_coherent = dma_alloc_coherent(&pdev->dev, acb->roundup_ccbsize, 
&dma_coherent_handle, GFP_KERNEL);
if (!dma_coherent){
printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error for 
hbb mu\n", acb->host->host_no);
return false;
}
acb->dma_coherent_handle2 = dma_coherent_handle;
+   acb->dma_coherent2 = dma_coherent;
reg = (struct MessageUnit_B *)dma_coherent;
acb->pmuB = reg;
reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
@@ -2605,6 +2605,7 @@ static int arcmsr_polling_ccbdone(struct
 static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 {
uint32_t cdb_phyaddr, cdb_phyaddr_hi32;
+   dma_addr_t dma_coherent_handle;
 
/*

@@ -2612,8 +2613,16 @@ static int arcmsr_iop_confirm(struct Ada
** if freeccb.HighPart is not zero

*/
-   cdb_phyaddr = lower_32_bits(acb->dma_coherent_handle);
-   cdb_phyaddr_hi32 = upper_32_bits(acb->dma_coherent_handle);
+   switch (acb->adapter_type) {
+   case ACB_ADAPTER_TYPE_B:
+   dma_coherent_handle = acb->dma_coherent_handle2;
+   break;
+   default:
+   dma_coherent_handle = acb->dma_coherent_handle;
+   break;
+   }
+   cdb_phyaddr = lower_32_bits(dma_coherent_handle);
+   cdb_phyaddr_hi32 = upper_32_bits(dma_coherent_handle);
acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32;
/*
***
@@ -2641,7 +2650,6 @@ static int arcmsr_iop_confirm(struct Ada
break;
 
case ACB_ADAPTER_TYPE_B: {
-   unsigned long post_queue_phyaddr;
uint32_t __iomem *rwbuffer;
 
struct MessageUnit_B *reg = acb->pmuB;
@@ -2653,16 +2661,15 @@ static int arcmsr_iop_confirm(struct Ada
acb->host->host_no);
return 1;
}
-   post_queue_phyaddr = a

[PATCH v1.3 13/18] arcmsr: fix ioctl data read/write error for adapter type C

2014-08-04 Thread Ching Huang
From: Ching Huang 

Rewrite ioctl entry and its relate functions.
This patch fix ioctl data read/write error and change data I/O access from byte 
to Dword.

Signed-off-by: Ching Huang 
---

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.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c 2014-04-29 17:10:42.0 +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;

[PATCH v1.3 14/18] arcmsr: fix sparse waring and error

2014-08-04 Thread Ching Huang
From: Ching Huang 

Fix sparse utility checking error and warning.

Signed-off-by: Ching Huang 
---

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-04 16:46:30.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:45:46.0 +0800
@@ -78,7 +78,7 @@ MODULE_VERSION(ARCMSR_DRIVER_VERSION);
 #defineARCMSR_SLEEPTIME10
 #defineARCMSR_RETRYCOUNT   12
 
-wait_queue_head_t wait_q;
+static wait_queue_head_t wait_q;
 static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
struct scsi_cmnd *cmd);
 static int arcmsr_iop_confirm(struct AdapterControlBlock *acb);
@@ -371,7 +371,7 @@ static uint8_t arcmsr_hbaB_wait_msgint_r
 
 static uint8_t arcmsr_hbaC_wait_msgint_ready(struct AdapterControlBlock *pACB)
 {
-   struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC;
+   struct MessageUnit_C __iomem *phbcmu = pACB->pmuC;
int i;
 
for (i = 0; i < 2000; i++) {
@@ -421,7 +421,7 @@ static void arcmsr_hbaB_flush_cache(stru
 
 static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB)
 {
-   struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+   struct MessageUnit_C __iomem *reg = pACB->pmuC;
int retry_count = 30;/* enlarge wait flush adapter cache time: 10 
minute */
writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0);
writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);
@@ -842,7 +842,7 @@ static uint8_t arcmsr_hbaB_abort_allcmd(
 }
 static uint8_t arcmsr_hbaC_abort_allcmd(struct AdapterControlBlock *pACB)
 {
-   struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC;
+   struct MessageUnit_C __iomem *reg = pACB->pmuC;
writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0);
writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell);
if (!arcmsr_hbaC_wait_msgint_ready(pACB)) {
@@ -930,7 +930,7 @@ static u32 arcmsr_disable_outbound_ints(
}
break;
case ACB_ADAPTER_TYPE_C:{
-   struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
+   struct MessageUnit_C __iomem *reg = acb->pmuC;
/* disable all outbound interrupt */
orig_mask = readl(®->host_int_mask); /* disable outbound 
message0 int */
writel(orig_mask|ARCMSR_HBCMU_ALL_INTMASKENABLE, 
®->host_int_mask);
@@ -1054,8 +1054,9 @@ static void arcmsr_done4abort_postqueue(
/*clear all outbound posted Q*/
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, 
reg->iop2drv_doorbell); /* clear doorbell interrupt */
for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
-   if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) {
-   writel(0, ®->done_qbuffer[i]);
+   flag_ccb = reg->done_qbuffer[i];
+   if (flag_ccb != 0) {
+   reg->done_qbuffer[i] = 0;
pARCMSR_CDB = (struct ARCMSR_CDB 
*)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
pCCB = container_of(pARCMSR_CDB, struct 
CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & 
ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
@@ -1068,7 +1069,7 @@ static void arcmsr_done4abort_postqueue(
}
break;
case ACB_ADAPTER_TYPE_C: {
-   struct MessageUnit_C *reg = acb->pmuC;
+   struct MessageUnit_C __iomem *reg = acb->pmuC;
struct  ARCMSR_CDB *pARCMSR_CDB;
uint32_t flag_ccb, ccb_cdb_phy;
bool error;
@@ -1186,7 +1187,7 @@ static void arcmsr_enable_outbound_ints(
}
break;
case ACB_ADAPTER_TYPE_C: {
-   struct MessageUnit_C *reg = acb->pmuC;
+   struct MessageUnit_C __iomem *reg = acb->pmuC;
mask = ~(ARCMSR_HBCMU_UTILITY_A_ISR_MASK | 
ARCMSR_HBCMU_OUTBOUND_DOORBELL_ISR_MASK|ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR_MASK);
writel(intmask_org & mask, ®->host_int_mask);
acb->outbound_int_enable = ~(intmask_org & mask) & 0x000f;
@@ -1273,12 +1274,12 @@ static void arcmsr_post_ccb(struct Adapt
uint32_t ending_index, index = reg->postq_index;
 
ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE);
-   writel(0, ®->post_qbuffer[ending_index]);
+   reg->post_qbuffer[ending_index] = 0;
if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) {
-   writel(cdb_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\

[PATCH v1.3 15/18] arcmsr: modify some character string

2014-08-04 Thread Ching Huang
From: Ching Huang 

Revise comment and some character strings.

Signed-off-by: Ching Huang 
---

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-04 16:45:46.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:46:46.0 +0800
@@ -2,11 +2,10 @@
 ***
 **O.S   : Linux
 **   FILE NAME  : arcmsr_hba.c
-**BY: Nick Cheng
-**   Description: SCSI RAID Device Driver for
-**ARECA RAID Host adapter
+**BY: Nick Cheng, C.L. Huang
+**   Description: SCSI RAID Device Driver for Areca RAID Controller
 ***
-** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved
+** Copyright (C) 2002 - 2014, Areca Technology Corporation All rights reserved
 **
 ** Web site: www.areca.com.tw
 **   E-mail: supp...@areca.com.tw
@@ -70,8 +69,8 @@
 #include 
 #include 
 #include "arcmsr.h"
-MODULE_AUTHOR("Nick Cheng ");
-MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus 
Adapter");
+MODULE_AUTHOR("Nick Cheng, C.L. Huang ");
+MODULE_DESCRIPTION("Areca ARC11xx/12xx/16xx/188x SAS/SATA RAID Controller 
Driver");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(ARCMSR_DRIVER_VERSION);
 
@@ -126,8 +125,7 @@ static int arcmsr_adjust_disk_queue_dept
 
 static struct scsi_host_template arcmsr_scsi_host_template = {
.module = THIS_MODULE,
-   .name   = "ARCMSR ARECA SATA/SAS RAID Controller"
-   ARCMSR_DRIVER_VERSION,
+   .name   = "Areca SAS/SATA RAID driver",
.info   = arcmsr_info,
.queuecommand   = arcmsr_queue_command,
.eh_abort_handler   = arcmsr_abort,
@@ -3398,14 +3396,14 @@ static const char *arcmsr_info(struct Sc
case PCI_DEVICE_ID_ARECA_1680:
case PCI_DEVICE_ID_ARECA_1681:
case PCI_DEVICE_ID_ARECA_1880:
-   type = "SAS";
+   type = "SAS/SATA";
break;
default:
-   type = "X-TYPE";
+   type = "unknown";
+   raid6 = 0;
break;
}
-   sprintf(buf, "Areca %s Host Adapter RAID Controller%s\n %s",
-   type, raid6 ? "( RAID6 capable)" : "",
-   ARCMSR_DRIVER_VERSION);
+   sprintf(buf, "Areca %s RAID Controller %s\narcmsr version %s\n",
+   type, raid6 ? "(RAID6 capable)" : "", ARCMSR_DRIVER_VERSION);
return buf;
 }


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 16/18] arcmsr: support new adapter ARC12x4 series

2014-08-04 Thread Ching Huang
From: Ching Huang 

Add code for supporting Areca new Raid adapter ARC12x4 series.

Signed-off-by: Ching Huang 
---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:29:54.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2014-05-06 15:06:04.0 +0800
@@ -63,12 +63,17 @@ struct device_attribute;
 #define ARCMSR_MAX_QBUFFER 
4096
 #define ARCMSR_DEFAULT_SG_ENTRIES  
38
 #define ARCMSR_MAX_HBB_POSTQUEUE   
264
+#define ARCMSR_MAX_ARC1214_POSTQUEUE   256
+#define ARCMSR_MAX_ARC1214_DONEQUEUE   257
 #define ARCMSR_MAX_XFER_LEN
0x26000 /* 152K */
 #define ARCMSR_CDB_SG_PAGE_LENGTH  
256 
 #define ARCMST_NUM_MSIX_VECTORS4
 #ifndef PCI_DEVICE_ID_ARECA_1880
 #define PCI_DEVICE_ID_ARECA_1880 0x1880
  #endif
+#ifndef PCI_DEVICE_ID_ARECA_1214
+   #define PCI_DEVICE_ID_ARECA_12140x1214
+#endif
 /*
 
**
 **
@@ -339,6 +344,56 @@ struct FIRMWARE_INFO
 #define ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK   0x8000
 /*
 ***
+**SPEC. for Areca Type D adapter
+***
+*/
+#define ARCMSR_ARC1214_CHIP_ID 0x4
+#define ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION0x8
+#define ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK  0x00034
+#define ARCMSR_ARC1214_SAMPLE_RESET0x00100
+#define ARCMSR_ARC1214_RESET_REQUEST   0x00108
+#define ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS   0x00200
+#define ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE0x0020C
+#define ARCMSR_ARC1214_INBOUND_MESSAGE00x00400
+#define ARCMSR_ARC1214_INBOUND_MESSAGE10x00404
+#define ARCMSR_ARC1214_OUTBOUND_MESSAGE0   0x00420
+#define ARCMSR_ARC1214_OUTBOUND_MESSAGE1   0x00424
+#define ARCMSR_ARC1214_INBOUND_DOORBELL0x00460
+#define ARCMSR_ARC1214_OUTBOUND_DOORBELL   0x00480
+#define ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE0x00484
+#define ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW   0x01000
+#define ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH  0x01004
+#define ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER  0x01018
+#define ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW  0x01060
+#define ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH 0x01064
+#define ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER  0x0106C
+#define ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER  0x01070
+#define ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE0x01088
+#define ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE   0x0108C
+#define ARCMSR_ARC1214_MESSAGE_WBUFFER 0x02000
+#define ARCMSR_ARC1214_MESSAGE_RBUFFER 0x02100
+#define ARCMSR_ARC1214_MESSAGE_RWBUFFER0x02200
+/* Host Interrupt Mask */
+#define ARCMSR_ARC1214_ALL_INT_ENABLE  0x1010
+#define ARCMSR_ARC1214_ALL_INT_DISABLE 0x
+/* Host Interrupt Status */
+#define ARCMSR_ARC1214_OUTBOUND_DOORBELL_ISR   0x1000
+#define ARCMSR_ARC1214_OUTBOUND_POSTQUEUE_ISR  0x0010
+/* DoorBell*/
+#define ARCMSR_ARC1214_DRV2IOP_DATA_IN_READY   0x0001
+#define ARCMSR_ARC1214_DRV2IOP_DATA_OUT_READ   0x0002
+/*inbound message 0 ready*/
+#define ARCMSR_ARC1214_IOP2DRV_DATA_WRITE_OK   0x0001
+/*outbound DATA WRITE isr door bell clear*/
+#define ARCMSR_ARC1214_IOP2DRV_DATA_READ_OK0x0002
+/*outbound message 0 ready*/
+#define ARCMSR_ARC1214_IOP2DRV_MESSAGE_CMD_DONE0x0200
+/*outbound message cmd isr door bell clear*/
+/*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/
+#define ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK 0x8000
+#define ARCMSR_ARC1214_OUTBOUND_LIST_INTERRUPT_CLEAR   0x0001
+/*
+***
 **ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504)
 ***
 */
@@ -496,6 +551,55 @@ struct MessageUnit_C{
uint32_tmsgcode_rwbuffer[256];  /*2200 23FF*/
 };
 /*
+*
+** Messaging Unit (MU) of Type D processor
+*
+*/
+struct InBound_SRB {
+   uint32_t addressLow; /* pointer to SRB block */
+   uint32_t addressHigh;
+   uint32_t length

[PATCH v1.3 17/18] arcmsr: modify calling scsi_scan_host after all initialization done

2014-08-04 Thread Ching Huang
From: Ching Huang 

Modify calling scsi_scan_host until all initialization done.
And fix error path of free allocated resource.

Signed-off-by: Ching Huang 
---

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-04 16:46:52.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:47:02.0 +0800
@@ -112,6 +112,7 @@ static void arcmsr_hbaD_message_isr(stru
 static void arcmsr_hardware_reset(struct AdapterControlBlock *acb);
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
+static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev,
  int queue_depth, int reason)
 {
@@ -774,12 +775,11 @@ static int arcmsr_probe(struct pci_dev *
}
error = scsi_add_host(host, &pdev->dev);
if(error){
-   goto RAID_controller_stop;
+   goto free_ccb_pool;
}
if (arcmsr_request_irq(pdev, acb) == FAILED)
goto scsi_host_remove;
arcmsr_iop_init(acb);
-   scsi_scan_host(host);
INIT_WORK(&acb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn);
atomic_set(&acb->rq_map_token, 16);
atomic_set(&acb->ante_token_value, 16);
@@ -791,13 +791,17 @@ static int arcmsr_probe(struct pci_dev *
add_timer(&acb->eternal_timer);
if(arcmsr_alloc_sysfs_attr(acb))
goto out_free_sysfs;
+   scsi_scan_host(host);
return 0;
 out_free_sysfs:
-scsi_host_remove:
-   scsi_remove_host(host);
-RAID_controller_stop:
+   del_timer_sync(&acb->eternal_timer);
+   flush_work(&acb->arcmsr_do_message_isr_bh);
arcmsr_stop_adapter_bgrb(acb);
arcmsr_flush_adapter_cache(acb);
+   arcmsr_free_irq(pdev, acb);
+scsi_host_remove:
+   scsi_remove_host(host);
+free_ccb_pool:
arcmsr_free_ccb_pool(acb);
 free_hbb_mu:
arcmsr_free_mu(acb);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v1.3 18/18] arcmsr: replace flush_scheduled_work() by flush_work()

2014-08-04 Thread Ching Huang
From: Ching Huang 

To prevent flushing entire workqueue, replace flush_scheduled_work() by 
flush_work().

Signed-off-by: Ching Huang 
---

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-04 16:47:02.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2014-08-04 16:47:12.0 +0800
@@ -841,7 +841,7 @@ static int arcmsr_suspend(struct pci_dev
intmask_org = arcmsr_disable_outbound_ints(acb);
arcmsr_free_irq(pdev, acb);
del_timer_sync(&acb->eternal_timer);
-   flush_scheduled_work();
+   flush_work(&acb->arcmsr_do_message_isr_bh);
arcmsr_stop_adapter_bgrb(acb);
arcmsr_flush_adapter_cache(acb);
arcmsr_enable_outbound_ints(acb, intmask_org);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 1/5] arcmsr: fixed getting wrong configuration data

2015-11-30 Thread Ching Huang
On Mon, 2015-11-30 at 19:17 -0500, Martin K. Petersen wrote:
> >>>>> "Ching" == Ching Huang  writes:
> 
> Hello Ching,
> 
> I applied both your series to 4.5/scsi-queue.
> 
> In the future please run checkpatch before submitting. Warnings are OK
> but in this case there were several things flagged as errors that I had
> to fix up by hand.
> 
> Also make sure you tag with "Signed-off-by:". Your signoff was mistyped
> in all the patches.
> 
> Thank you!
> Martin
> 
Thanks Martin's effort and advice.
I will pay attention on future submitting.

Best Regards,
Ching

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 0/2] arcmsr: support areca new adapter ARC1203

2015-11-24 Thread Ching Huang
On Tue, 2015-11-24 at 16:07 +0100, Hannes Reinecke wrote:
> On 11/24/2015 09:00 AM, Ching Huang wrote:
> > From: Ching Huang 
> > 
> > Patch 1 fixes getting wrong configuration data.
> > 
> > Pacth 2 adds codes to support new adapter ARC1203.
> > 
Patch 3 changes driver version number.
> Please split off the driver version update into a separate patch and
> add it as the last patch in the series.
> Otherwise it'll be hard to keep track of which patch belongs to
> which version.
> Thanks.
> 
> Cheers,
> 
> Hannes
> 
OK. So I have patch 3 as above.
I will resend v2 all 3 patches later. 

Thanks, 
Ching
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/3] arcmsr: support areca new adapter ARC1203

2015-11-24 Thread Ching Huang
From: Ching Huang 

Patch 1 fixes getting wrong configuration data.

Pacth 2 adds codes to support new adapter ARC1203.

Patch 3 changes driver version number.

--


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/3] arcmsr: fixed getting wrong configuration data

2015-11-24 Thread Ching Huang
From: Ching Huang 

Fixed getting wrong configuration data of adapter type B and type D.

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-23 16:25:22.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0 +0800
@@ -2694,15 +2694,15 @@ static bool arcmsr_hbaB_get_config(struc
acb->firm_model,
acb->firm_version);
 
-   acb->signature = readl(®->message_rwbuffer[1]);
+   acb->signature = readl(®->message_rwbuffer[0]);
/*firm_signature,1,00-03*/
-   acb->firm_request_len = readl(®->message_rwbuffer[2]);
+   acb->firm_request_len = readl(®->message_rwbuffer[1]);
/*firm_request_len,1,04-07*/
-   acb->firm_numbers_queue = readl(®->message_rwbuffer[3]);
+   acb->firm_numbers_queue = readl(®->message_rwbuffer[2]);
/*firm_numbers_queue,2,08-11*/
-   acb->firm_sdram_size = readl(®->message_rwbuffer[4]);
+   acb->firm_sdram_size = readl(®->message_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/
-   acb->firm_hd_channels = readl(®->message_rwbuffer[5]);
+   acb->firm_hd_channels = readl(®->message_rwbuffer[4]);
/*firm_ide_channels,4,16-19*/
acb->firm_cfg_version = readl(®->message_rwbuffer[25]);  
/*firm_cfg_version,25,100-103*/
/*firm_ide_channels,4,16-19*/
@@ -2880,15 +2880,15 @@ static bool arcmsr_hbaD_get_config(struc
iop_device_map++;
count--;
}
-   acb->signature = readl(®->msgcode_rwbuffer[1]);
+   acb->signature = readl(®->msgcode_rwbuffer[0]);
/*firm_signature,1,00-03*/
-   acb->firm_request_len = readl(®->msgcode_rwbuffer[2]);
+   acb->firm_request_len = readl(®->msgcode_rwbuffer[1]);
/*firm_request_len,1,04-07*/
-   acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[3]);
+   acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]);
/*firm_numbers_queue,2,08-11*/
-   acb->firm_sdram_size = readl(®->msgcode_rwbuffer[4]);
+   acb->firm_sdram_size = readl(®->msgcode_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/
-   acb->firm_hd_channels = readl(®->msgcode_rwbuffer[5]);
+   acb->firm_hd_channels = readl(®->msgcode_rwbuffer[4]);
/*firm_hd_channels,4,16-19*/
acb->firm_cfg_version = readl(®->msgcode_rwbuffer[25]);
pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 2/3] arcmsr: adds code for support areca new adapter ARC1203

2015-11-24 Thread Ching Huang
From: Ching Huang 

Support areca new PCIe to SATA RAID adapter ARC1203

Signed-of-by: Ching Huang

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:16.28647 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:13.33447 +0800
@@ -74,6 +74,9 @@ struct device_attribute;
 #ifndef PCI_DEVICE_ID_ARECA_1214
#define PCI_DEVICE_ID_ARECA_12140x1214
 #endif
+#ifndef PCI_DEVICE_ID_ARECA_1203
+   #define PCI_DEVICE_ID_ARECA_12030x1203
+#endif
 /*
 
**
 **
@@ -245,6 +248,12 @@ struct FIRMWARE_INFO
 /* window of "instruction flags" from iop to driver */
 #define ARCMSR_IOP2DRV_DOORBELL   0x00020408
 #define ARCMSR_IOP2DRV_DOORBELL_MASK  0x0002040C
+/* window of "instruction flags" from iop to driver */
+#define ARCMSR_IOP2DRV_DOORBELL_1203  0x00021870
+#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203 0x00021874
+/* window of "instruction flags" from driver to iop */
+#define ARCMSR_DRV2IOP_DOORBELL_1203  0x00021878
+#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203 0x0002187C
 /* ARECA FLAG LANGUAGE */
 /* ioctl transfer */
 #define ARCMSR_IOP2DRV_DATA_WRITE_OK  0x0001
diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 18:58:40.640226000 +0800
@@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
+static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int 
queue_depth)
 {
if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
@@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_devic
.driver_data = ACB_ADAPTER_TYPE_B},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202),
.driver_data = ACB_ADAPTER_TYPE_B},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203),
+   .driver_data = ACB_ADAPTER_TYPE_B},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210),
.driver_data = ACB_ADAPTER_TYPE_A},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214),
@@ -2621,7 +2624,7 @@ static bool arcmsr_hbaA_get_config(struc
 }
 static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
 {
-   struct MessageUnit_B *reg = acb->pmuB;
+   struct MessageUnit_B *reg;
struct pci_dev *pdev = acb->pdev;
void *dma_coherent;
dma_addr_t dma_coherent_handle;
@@ -2649,10 +2652,17 @@ static bool arcmsr_hbaB_get_config(struc
acb->dma_coherent2 = dma_coherent;
reg = (struct MessageUnit_B *)dma_coherent;
acb->pmuB = reg;
-   reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
-   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
-   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
-   reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
+   if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
+   reg->drv2iop_doorbell = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_1203);
+   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
+   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_1203);
+   reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
+   } else {
+   reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
+   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
+   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
+   reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
+   }
reg->message_wbuffer = (uint32_t __iomem *)((unsigned 
long)acb->mem_base1 + ARCMSR_MESSAGE_WBUFFER);
reg->message_rbuffer

[PATCH v2 3/3] arcmsr: changes driver version number

2015-11-24 Thread Ching Huang
From: Ching Huang 

Changes driver version number.

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:13.33447 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2015-10-19 15:57:08.0 +0800
@@ -52,7 +52,7 @@ struct device_attribute;
#define ARCMSR_MAX_FREECCB_NUM  320
 #define ARCMSR_MAX_OUTSTANDING_CMD 255
 #endif
-#define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140919"
+#define ARCMSR_DRIVER_VERSION  "v1.30.00.21-20151019"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
 #define ARCMSR_MAX_XFER_SECTORS
512
 #define ARCMSR_MAX_XFER_SECTORS_B  
4096


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 2/3] arcmsr: adds code for support areca new adapter ARC1203

2015-11-25 Thread Ching Huang
On Wed, 2015-11-25 at 08:18 +0100, Hannes Reinecke wrote:
> On 11/25/2015 04:25 AM, Ching Huang wrote:
> > From: Ching Huang 
> > 
> > Support areca new PCIe to SATA RAID adapter ARC1203
> > 
> > Signed-of-by: Ching Huang
> > 
> > ---
> > 
> > diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
> > --- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:16.28647 +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:13.33447 +0800
> > @@ -74,6 +74,9 @@ struct device_attribute;
> >  #ifndef PCI_DEVICE_ID_ARECA_1214
> > #define PCI_DEVICE_ID_ARECA_12140x1214
> >  #endif
> > +#ifndef PCI_DEVICE_ID_ARECA_1203
> > +   #define PCI_DEVICE_ID_ARECA_12030x1203
> > +#endif
> >  /*
> >  
> > **
> >  **
> > @@ -245,6 +248,12 @@ struct FIRMWARE_INFO
> >  /* window of "instruction flags" from iop to driver */
> >  #define ARCMSR_IOP2DRV_DOORBELL   0x00020408
> >  #define ARCMSR_IOP2DRV_DOORBELL_MASK  0x0002040C
> > +/* window of "instruction flags" from iop to driver */
> > +#define ARCMSR_IOP2DRV_DOORBELL_1203  0x00021870
> > +#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203 0x00021874
> > +/* window of "instruction flags" from driver to iop */
> > +#define ARCMSR_DRV2IOP_DOORBELL_1203  0x00021878
> > +#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203 0x0002187C
> >  /* ARECA FLAG LANGUAGE */
> >  /* ioctl transfer */
> >  #define ARCMSR_IOP2DRV_DATA_WRITE_OK  0x0001
> > diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c 
> > b/drivers/scsi/arcmsr/arcmsr_hba.c
> > --- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0 
> > +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 18:58:40.640226000 
> > +0800
> > @@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct
> >  static const char *arcmsr_info(struct Scsi_Host *);
> >  static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
> >  static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock 
> > *);
> > +static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb);
> >  static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int 
> > queue_depth)
> >  {
> > if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
> > @@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_devic
> > .driver_data = ACB_ADAPTER_TYPE_B},
> > {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202),
> > .driver_data = ACB_ADAPTER_TYPE_B},
> > +   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203),
> > +   .driver_data = ACB_ADAPTER_TYPE_B},
> > {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210),
> > .driver_data = ACB_ADAPTER_TYPE_A},
> > {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214),
> > @@ -2621,7 +2624,7 @@ static bool arcmsr_hbaA_get_config(struc
> >  }
> >  static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
> >  {
> > -   struct MessageUnit_B *reg = acb->pmuB;
> > +   struct MessageUnit_B *reg;
> > struct pci_dev *pdev = acb->pdev;
> > void *dma_coherent;
> > dma_addr_t dma_coherent_handle;
> > @@ -2649,10 +2652,17 @@ static bool arcmsr_hbaB_get_config(struc
> > acb->dma_coherent2 = dma_coherent;
> > reg = (struct MessageUnit_B *)dma_coherent;
> > acb->pmuB = reg;
> > -   reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned 
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
> > -   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned 
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
> > -   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned 
> > long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
> > -   reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned 
> > long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
> > +   if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
> > +   reg->drv2iop_doorbell = (uint32_t __iomem *)((unsigned 
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_1203);
> > +   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned 
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
> > +   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned 
> > long)acb-&g

Re: [PATCH v2 2/3] arcmsr: adds code for support areca new adapter ARC1203

2015-11-25 Thread Ching Huang
On Wed, 2015-11-25 at 09:43 +0100, Johannes Thumshirn wrote:
> On Wed, 2015-11-25 at 11:25 +0800, Ching Huang wrote:
> > From: Ching Huang 
> > 
> > Support areca new PCIe to SATA RAID adapter ARC1203
> > 
> > Signed-of-by: Ching Huang
> > 
> > ---
> > 
> > diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
> > --- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:16.28647 +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:13.33447 +0800
> > @@ -74,6 +74,9 @@ struct device_attribute;
> >  #ifndef PCI_DEVICE_ID_ARECA_1214
> > #define PCI_DEVICE_ID_ARECA_12140x1214
> >  #endif
> > +#ifndef PCI_DEVICE_ID_ARECA_1203
> > +   #define PCI_DEVICE_ID_ARECA_12030x1203
> > +#endif
> >  /*
> >  
> > 
> > **
> >  **
> > @@ -245,6 +248,12 @@ struct FIRMWARE_INFO
> >  /* window of "instruction flags" from iop to driver */
> >  #define ARCMSR_IOP2DRV_DOORBELL   0x00020408
> >  #define ARCMSR_IOP2DRV_DOORBELL_MASK  0x0002040C
> > +/* window of "instruction flags" from iop to driver */
> > +#define ARCMSR_IOP2DRV_DOORBELL_1203  0x00021870
> > +#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203 0x00021874
> > +/* window of "instruction flags" from driver to iop */
> > +#define ARCMSR_DRV2IOP_DOORBELL_1203  0x00021878
> > +#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203 0x0002187C
> >  /* ARECA FLAG LANGUAGE */
> >  /* ioctl transfer */
> >  #define ARCMSR_IOP2DRV_DATA_WRITE_OK  0x0001
> > diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c
> > b/drivers/scsi/arcmsr/arcmsr_hba.c
> > --- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0
> > +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 18:58:40.640226000
> > +0800
> > @@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct
> >  static const char *arcmsr_info(struct Scsi_Host *);
> >  static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
> >  static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock 
> > *);
> > +static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb);
> >  static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int
> > queue_depth)
> >  {
> > if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
> > @@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_devic
> > .driver_data = ACB_ADAPTER_TYPE_B},
> > {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202),
> > .driver_data = ACB_ADAPTER_TYPE_B},
> > +   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203),
> > +   .driver_data = ACB_ADAPTER_TYPE_B},
> > {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210),
> > .driver_data = ACB_ADAPTER_TYPE_A},
> > {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214),
> > @@ -2621,7 +2624,7 @@ static bool arcmsr_hbaA_get_config(struc
> >  }
> >  static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
> >  {
> > -   struct MessageUnit_B *reg = acb->pmuB;
> > +   struct MessageUnit_B *reg;
> > struct pci_dev *pdev = acb->pdev;
> > void *dma_coherent;
> > dma_addr_t dma_coherent_handle;
> > @@ -2649,10 +2652,17 @@ static bool arcmsr_hbaB_get_config(struc
> > acb->dma_coherent2 = dma_coherent;
> > reg = (struct MessageUnit_B *)dma_coherent;
> > acb->pmuB = reg;
> > -   reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned long)acb-
> > >mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
> > -   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
> > -   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned long)acb-
> > >mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
> > -   reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned
> > long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
> > +   if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
> > +   reg->drv2iop_doorbell = (uint32_t __iomem *)((unsigned
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_1203);
> > +   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned
> > long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
> > +   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned
> > l

[PATCH v3 0/5] arcmsr: support areca new adapter ARC1203

2015-11-25 Thread Ching Huang
From: Ching Huang 

Patch 1 fixes getting wrong configuration data.

Patch 2 fixes not release allocated resource if get configuration data
failed.

Patch 3 modifies codes for more readable.

Pacth 4 adds codes to support new adapter ARC1203.

Patch 5 changes driver version number.

--

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 1/5] arcmsr: fixed getting wrong configuration data

2015-11-25 Thread Ching Huang
From: Ching Huang 

Fixed getting wrong configuration data of adapter type B and type D.

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-23 16:25:22.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0 +0800
@@ -2694,15 +2694,15 @@ static bool arcmsr_hbaB_get_config(struc
acb->firm_model,
acb->firm_version);
 
-   acb->signature = readl(®->message_rwbuffer[1]);
+   acb->signature = readl(®->message_rwbuffer[0]);
/*firm_signature,1,00-03*/
-   acb->firm_request_len = readl(®->message_rwbuffer[2]);
+   acb->firm_request_len = readl(®->message_rwbuffer[1]);
/*firm_request_len,1,04-07*/
-   acb->firm_numbers_queue = readl(®->message_rwbuffer[3]);
+   acb->firm_numbers_queue = readl(®->message_rwbuffer[2]);
/*firm_numbers_queue,2,08-11*/
-   acb->firm_sdram_size = readl(®->message_rwbuffer[4]);
+   acb->firm_sdram_size = readl(®->message_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/
-   acb->firm_hd_channels = readl(®->message_rwbuffer[5]);
+   acb->firm_hd_channels = readl(®->message_rwbuffer[4]);
/*firm_ide_channels,4,16-19*/
acb->firm_cfg_version = readl(®->message_rwbuffer[25]);  
/*firm_cfg_version,25,100-103*/
/*firm_ide_channels,4,16-19*/
@@ -2880,15 +2880,15 @@ static bool arcmsr_hbaD_get_config(struc
iop_device_map++;
count--;
}
-   acb->signature = readl(®->msgcode_rwbuffer[1]);
+   acb->signature = readl(®->msgcode_rwbuffer[0]);
/*firm_signature,1,00-03*/
-   acb->firm_request_len = readl(®->msgcode_rwbuffer[2]);
+   acb->firm_request_len = readl(®->msgcode_rwbuffer[1]);
/*firm_request_len,1,04-07*/
-   acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[3]);
+   acb->firm_numbers_queue = readl(®->msgcode_rwbuffer[2]);
/*firm_numbers_queue,2,08-11*/
-   acb->firm_sdram_size = readl(®->msgcode_rwbuffer[4]);
+   acb->firm_sdram_size = readl(®->msgcode_rwbuffer[3]);
/*firm_sdram_size,3,12-15*/
-   acb->firm_hd_channels = readl(®->msgcode_rwbuffer[5]);
+   acb->firm_hd_channels = readl(®->msgcode_rwbuffer[4]);
/*firm_hd_channels,4,16-19*/
acb->firm_cfg_version = readl(®->msgcode_rwbuffer[25]);
pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n",


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 2/5] arcmsr: fixes not release allocated resource

2015-11-25 Thread Ching Huang
From: Ching Huang 

Releasing allocated resource if get configuration data failed.

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 19:04:44.59097 +0800
@@ -2664,7 +2664,7 @@ static bool arcmsr_hbaB_get_config(struc
if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
miscellaneous data' timeout \n", acb->host->host_no);
-   return false;
+   goto err_free_dma;
}
count = 8;
while (count){
@@ -2707,6 +2707,10 @@ static bool arcmsr_hbaB_get_config(struc
acb->firm_cfg_version = readl(®->message_rwbuffer[25]);  
/*firm_cfg_version,25,100-103*/
/*firm_ide_channels,4,16-19*/
return true;
+err_free_dma:
+   dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
+   acb->dma_coherent2, acb->dma_coherent_handle2);
+   return false;
 }
 
 static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB)


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 3/5] arcmsr: modifies codes for more readable

2015-11-25 Thread Ching Huang
From: Ching Huang 

Modifies codes for more readable

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 10:52:16.28647 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 19:10:21.30996 +0800
@@ -288,6 +288,9 @@ struct FIRMWARE_INFO
 #define ARCMSR_MESSAGE_RBUFFER   0xff00
 /* iop message_rwbuffer for message command */
 #define ARCMSR_MESSAGE_RWBUFFER  0xfa00
+
+#define MEM_BASE0(x)   (u32 __iomem *)((unsigned long)acb->mem_base0 + x)
+#define MEM_BASE1(x)   (u32 __iomem *)((unsigned long)acb->mem_base1 + x)
 /* 
 
 **SPEC. for Areca HBC adapter
diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 19:04:44.59097 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 19:11:27.679958000 +0800
@@ -2649,13 +2649,13 @@ static bool arcmsr_hbaB_get_config(struc
acb->dma_coherent2 = dma_coherent;
reg = (struct MessageUnit_B *)dma_coherent;
acb->pmuB = reg;
-   reg->drv2iop_doorbell= (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL);
-   reg->drv2iop_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_DRV2IOP_DOORBELL_MASK);
-   reg->iop2drv_doorbell = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL);
-   reg->iop2drv_doorbell_mask = (uint32_t __iomem *)((unsigned 
long)acb->mem_base0 + ARCMSR_IOP2DRV_DOORBELL_MASK);
-   reg->message_wbuffer = (uint32_t __iomem *)((unsigned 
long)acb->mem_base1 + ARCMSR_MESSAGE_WBUFFER);
-   reg->message_rbuffer =  (uint32_t __iomem *)((unsigned 
long)acb->mem_base1 + ARCMSR_MESSAGE_RBUFFER);
-   reg->message_rwbuffer = (uint32_t __iomem *)((unsigned 
long)acb->mem_base1 + ARCMSR_MESSAGE_RWBUFFER);
+   reg->drv2iop_doorbell= MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
+   reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
+   reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
+   reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
+   reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
+   reg->message_rbuffer =  MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
+   reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]);  
/*firm_model,15,60-67*/
iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]);
/*firm_version,17,68-83*/
iop_device_map = (char __iomem *)(®->message_rwbuffer[21]);  
/*firm_version,21,84-99*/


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v3 4/5] arcmsr: adds code for support areca new adapter ARC1203

2015-11-25 Thread Ching Huang
From: Ching Huang 

Support areca new PCIe to SATA RAID adapter ARC1203

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 19:10:21.30996 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 18:25:42.926038000 +0800
@@ -74,6 +74,9 @@ struct device_attribute;
 #ifndef PCI_DEVICE_ID_ARECA_1214
#define PCI_DEVICE_ID_ARECA_12140x1214
 #endif
+#ifndef PCI_DEVICE_ID_ARECA_1203
+   #define PCI_DEVICE_ID_ARECA_12030x1203
+#endif
 /*
 
**
 **
@@ -245,6 +248,12 @@ struct FIRMWARE_INFO
 /* window of "instruction flags" from iop to driver */
 #define ARCMSR_IOP2DRV_DOORBELL   0x00020408
 #define ARCMSR_IOP2DRV_DOORBELL_MASK  0x0002040C
+/* window of "instruction flags" from iop to driver */
+#define ARCMSR_IOP2DRV_DOORBELL_1203  0x00021870
+#define ARCMSR_IOP2DRV_DOORBELL_MASK_1203 0x00021874
+/* window of "instruction flags" from driver to iop */
+#define ARCMSR_DRV2IOP_DOORBELL_1203  0x00021878
+#define ARCMSR_DRV2IOP_DOORBELL_MASK_1203 0x0002187C
 /* ARECA FLAG LANGUAGE */
 /* ioctl transfer */
 #define ARCMSR_IOP2DRV_DATA_WRITE_OK  0x0001
diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 19:11:27.679958000 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 18:30:52.239029000 +0800
@@ -114,6 +114,7 @@ static void arcmsr_hardware_reset(struct
 static const char *arcmsr_info(struct Scsi_Host *);
 static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb);
 static void arcmsr_free_irq(struct pci_dev *, struct AdapterControlBlock *);
+static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb);
 static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int 
queue_depth)
 {
if (queue_depth > ARCMSR_MAX_CMD_PERLUN)
@@ -157,6 +158,8 @@ static struct pci_device_id arcmsr_devic
.driver_data = ACB_ADAPTER_TYPE_B},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202),
.driver_data = ACB_ADAPTER_TYPE_B},
+   {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1203),
+   .driver_data = ACB_ADAPTER_TYPE_B},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210),
.driver_data = ACB_ADAPTER_TYPE_A},
{PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1214),
@@ -2621,7 +2624,7 @@ static bool arcmsr_hbaA_get_config(struc
 }
 static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb)
 {
-   struct MessageUnit_B *reg = acb->pmuB;
+   struct MessageUnit_B *reg;
struct pci_dev *pdev = acb->pdev;
void *dma_coherent;
dma_addr_t dma_coherent_handle;
@@ -2649,10 +2652,17 @@ static bool arcmsr_hbaB_get_config(struc
acb->dma_coherent2 = dma_coherent;
reg = (struct MessageUnit_B *)dma_coherent;
acb->pmuB = reg;
-   reg->drv2iop_doorbell= MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
-   reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
-   reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
-   reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
+   if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
+   reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
+   reg->drv2iop_doorbell_mask = 
MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
+   reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
+   reg->iop2drv_doorbell_mask = 
MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
+   } else {
+   reg->drv2iop_doorbell= MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
+   reg->drv2iop_doorbell_mask = 
MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
+   reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
+   reg->iop2drv_doorbell_mask = 
MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
+   }
reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
reg->message_rbuffer =  MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
@@ -2660,6 +2670,12 @@ static bool arcmsr_hbaB_get_config(struc
iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]);
/*firm_version,17,68-83*/
iop_device_map = (char __iomem *)(®->message_rwbuffer[21]);  
/*firm_version,21,84-99*/
 
+   arcmsr_wait_firmware_ready(acb);
+   writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell);
+   if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
+   printk(KERN_ERR "arcmsr%d

[PATCH v3 5/5] arcmsr: changes driver version number

2015-11-25 Thread Ching Huang
From: Ching Huang 

Changes driver version number.

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
--- a/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 18:25:42.926038000 +0800
+++ b/drivers/scsi/arcmsr/arcmsr.h  2015-11-25 18:04:27.400075000 +0800
@@ -52,7 +52,7 @@ struct device_attribute;
#define ARCMSR_MAX_FREECCB_NUM  320
 #define ARCMSR_MAX_OUTSTANDING_CMD 255
 #endif
-#define ARCMSR_DRIVER_VERSION  "v1.30.00.04-20140919"
+#define ARCMSR_DRIVER_VERSION  "v1.30.00.21-20151019"
 #define ARCMSR_SCSI_INITIATOR_ID   
255
 #define ARCMSR_MAX_XFER_SECTORS
512
 #define ARCMSR_MAX_XFER_SECTORS_B  
4096


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3 2/5] arcmsr: fixes not release allocated resource

2015-11-25 Thread Ching Huang
On Wed, 2015-11-25 at 14:55 +0100, Tomas Henzl wrote:
> On 25.11.2015 12:41, Ching Huang wrote:
> > From: Ching Huang 
> >
> > Releasing allocated resource if get configuration data failed.
> >
> > Signed-of-by: Ching Huang 
> >
> > ---
> >
> > diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c 
> > b/drivers/scsi/arcmsr/arcmsr_hba.c
> > --- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-24 11:35:26.0 
> > +0800
> > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 19:04:44.59097 
> > +0800
> > @@ -2664,7 +2664,7 @@ static bool arcmsr_hbaB_get_config(struc
> > if (!arcmsr_hbaB_wait_msgint_ready(acb)) {
> > printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \
> > miscellaneous data' timeout \n", acb->host->host_no);
> > -   return false;
> > +   goto err_free_dma;
> > }
> > count = 8;
> > while (count){
> > @@ -2707,6 +2707,10 @@ static bool arcmsr_hbaB_get_config(struc
> > acb->firm_cfg_version = readl(®->message_rwbuffer[25]);  
> > /*firm_cfg_version,25,100-103*/
> > /*firm_ide_channels,4,16-19*/
> > return true;
> > +err_free_dma:
> > +   dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
> > +   acb->dma_coherent2, acb->dma_coherent_handle2);
> > +   return false;
> >  }
> >  
> 
> The resource should be released here, that is okay. 
> 
> How works the resource management when the eh_bus_reset_handler
> is called ? It looks to me that you allocate a new 
> acb->dma_coherent2 without releasing it before.
> Btw. is it needed in that handler to re-read the firmware-spec?
> 
> Tomas
> 
You are right. In eh_bus_reset_handler, there may re-allocate a new dma 
resource if call get_config again.
I will initiate a new patches for this bug after current 5 patches.
Thanks Tomas.
> >  static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB)
> >
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 0/3] arcmsr: fix bug of reallocate dma resource

2015-11-26 Thread Ching Huang
From: Ching Huang 

This patch is relative to previous version v1.30.00.21-20151016.
This patch series are to fix reallocate dma resource if get_firmware_spec was 
called again when eh_bus_reset_handler occurred.

Patch 1 modifies codes for more readable.

Patch 2 split allocate dma resource and io register assignment from get_config 
to new function arcmsr_alloc_io_queue.

Patch 3 change driver version to v1.30.00.22-20151126.

--


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] arcmsr: modify codes for more readable

2015-11-26 Thread Ching Huang
From: Ching Huang 

modify codes for more readable

Signed-of-by: Ching Huang 

---

diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
--- a/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-25 18:08:52.0 +0800
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c  2015-11-26 15:52:54.0 +0800
@@ -2814,53 +2814,32 @@ static bool arcmsr_hbaD_get_config(struc
acb->dma_coherent2 = dma_coherent2;
reg = (struct MessageUnit_D *)dma_coherent2;
acb->pmuD = reg;
-   reg->chip_id = acb->mem_base0 + ARCMSR_ARC1214_CHIP_ID;
-   reg->cpu_mem_config = acb->mem_base0 +
-   ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION;
-   reg->i2o_host_interrupt_mask = acb->mem_base0 +
-   ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK;
-   reg->sample_at_reset = acb->mem_base0 + ARCMSR_ARC1214_SAMPLE_RESET;
-   reg->reset_request = acb->mem_base0 + ARCMSR_ARC1214_RESET_REQUEST;
-   reg->host_int_status = acb->mem_base0 +
-   ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS;
-   reg->pcief0_int_enable = acb->mem_base0 +
-   ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE;
-   reg->inbound_msgaddr0 = acb->mem_base0 +
-   ARCMSR_ARC1214_INBOUND_MESSAGE0;
-   reg->inbound_msgaddr1 = acb->mem_base0 +
-   ARCMSR_ARC1214_INBOUND_MESSAGE1;
-   reg->outbound_msgaddr0 = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_MESSAGE0;
-   reg->outbound_msgaddr1 = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_MESSAGE1;
-   reg->inbound_doorbell = acb->mem_base0 +
-   ARCMSR_ARC1214_INBOUND_DOORBELL;
-   reg->outbound_doorbell = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_DOORBELL;
-   reg->outbound_doorbell_enable = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE;
-   reg->inboundlist_base_low = acb->mem_base0 +
-   ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW;
-   reg->inboundlist_base_high = acb->mem_base0 +
-   ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH;
-   reg->inboundlist_write_pointer = acb->mem_base0 +
-   ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER;
-   reg->outboundlist_base_low = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW;
-   reg->outboundlist_base_high = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH;
-   reg->outboundlist_copy_pointer = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER;
-   reg->outboundlist_read_pointer = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER;
-   reg->outboundlist_interrupt_cause = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE;
-   reg->outboundlist_interrupt_enable = acb->mem_base0 +
-   ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE;
-   reg->message_wbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_WBUFFER;
-   reg->message_rbuffer = acb->mem_base0 + ARCMSR_ARC1214_MESSAGE_RBUFFER;
-   reg->msgcode_rwbuffer = acb->mem_base0 +
-   ARCMSR_ARC1214_MESSAGE_RWBUFFER;
+   reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
+   reg->cpu_mem_config = 
MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
+   reg->i2o_host_interrupt_mask = 
MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
+   reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
+   reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
+   reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
+   reg->pcief0_int_enable = 
MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
+   reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
+   reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
+   reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
+   reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
+   reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
+   reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
+   reg->outbound_doorbell_enable = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
+   reg->inboundlist_base_low = 
MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
+   reg->inboundlist_base_high = 
MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
+   reg->inboundlist_write_pointer = 
MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
+   reg->outboundlist_base_low = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
+   reg->outboundlist_base_high = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
+   reg->outboundlist_copy_pointer = 
MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LI

  1   2   3   >