[PATCH 2/2] scsi: arcmsr: update driver version to v1.50.00.04-20210414
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
[PATH 2/2] scsi: arcmsr: update driver version to v1.50.00.04-20210414
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 1/2] scsi: arcmsr: fixed the wrong cdb payload report to IOP
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);
[PATCH 0/2] scsi: arcmsr: fix SCSI command timeout on ARC-1886
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 v2 2/2] scsi: arcmsr: Confirm getting a free ccb is in spin_lock circle
From: ching Huang Confirm getting a free ccb is in spin_lock circle. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 7cfae1d..127fe50 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3162,10 +3162,12 @@ message_out: static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock *acb) { - struct list_head *head = &acb->ccb_free_list; + struct list_head *head; struct CommandControlBlock *ccb = NULL; unsigned long flags; + spin_lock_irqsave(&acb->ccblist_lock, flags); + head = &acb->ccb_free_list; if (!list_empty(head)) { ccb = list_entry(head->next, struct CommandControlBlock, list); list_del_init(&ccb->list);
[PATCH v2 1/2] scsi: arcmsr: configure the default SCSI device command timeout value
From: ching Huang Configure the default SCSI device command timeout value. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 5d054d5..0f6abd2 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -83,6 +83,7 @@ struct device_attribute; #define PCI_DEVICE_ID_ARECA_1886 0x188A #defineARCMSR_HOURS(1000 * 60 * 60 * 4) #defineARCMSR_MINUTES (1000 * 60 * 60) +#define ARCMSR_DEFAULT_TIMEOUT 90 /* ** ** diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index e4fdb47..7cfae1d 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -99,6 +99,10 @@ 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"); +static int cmd_timeout = ARCMSR_DEFAULT_TIMEOUT; +module_param(cmd_timeout, int, S_IRUGO); +MODULE_PARM_DESC(cmd_timeout, " scsi cmd timeout(0 ~ 120 sec.), default is 90"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12 @@ -140,6 +144,7 @@ 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 void arcmsr_set_iop_datetime(struct timer_list *); +static int arcmsr_slave_config(struct scsi_device *sdev); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -155,6 +160,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .eh_abort_handler = arcmsr_abort, .eh_bus_reset_handler = arcmsr_bus_reset, .bios_param = arcmsr_bios_param, + .slave_configure= arcmsr_slave_config, .change_queue_depth = arcmsr_adjust_disk_queue_depth, .can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD, .this_id= ARCMSR_SCSI_INITIATOR_ID, @@ -3256,6 +3262,16 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(arcmsr_queue_command) +static int arcmsr_slave_config(struct scsi_device *sdev) +{ + unsigned intdev_timeout; + + dev_timeout = sdev->request_queue->rq_timeout; + if ((cmd_timeout > 0) && ((cmd_timeout * HZ) > dev_timeout)) + blk_queue_rq_timeout(sdev->request_queue, cmd_timeout * HZ); + return 0; +} + static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t *rwbuffer) { int count;
[PATCH v2 0/2] scsi: arcmsr: configure the default SCSI device command timeout value
This patch is against to mkp's 5.10/scsi-fixes. 1. Configure the default SCSI device command timeout value. 2. Confirm get free ccb in spin_lock circle. ---
[PATCH 1/1] scsi: arcmsr: Configure the default SCSI device command timeout value
From: ching Huang Configure the default SCSI device command timeout value. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 5d054d5..0f6abd2 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -83,6 +83,7 @@ struct device_attribute; #define PCI_DEVICE_ID_ARECA_1886 0x188A #defineARCMSR_HOURS(1000 * 60 * 60 * 4) #defineARCMSR_MINUTES (1000 * 60 * 60) +#define ARCMSR_DEFAULT_TIMEOUT 90 /* ** ** diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 1e358d9..555f55f 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -99,6 +99,10 @@ 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"); +static int cmd_timeout = ARCMSR_DEFAULT_TIMEOUT; +module_param(cmd_timeout, int, S_IRUGO); +MODULE_PARM_DESC(cmd_timeout, " scsi cmd timeout(0 ~ 120 sec.), default is 90"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12 @@ -140,6 +144,7 @@ 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 void arcmsr_set_iop_datetime(struct timer_list *); +static int arcmsr_slave_config(struct scsi_device *sdev); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -155,6 +160,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .eh_abort_handler = arcmsr_abort, .eh_bus_reset_handler = arcmsr_bus_reset, .bios_param = arcmsr_bios_param, + .slave_configure= arcmsr_slave_config, .change_queue_depth = arcmsr_adjust_disk_queue_depth, .can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD, .this_id= ARCMSR_SCSI_INITIATOR_ID, @@ -3156,10 +3162,12 @@ message_out: static struct CommandControlBlock *arcmsr_get_freeccb(struct AdapterControlBlock *acb) { - struct list_head *head = &acb->ccb_free_list; + struct list_head *head; struct CommandControlBlock *ccb = NULL; unsigned long flags; + spin_lock_irqsave(&acb->ccblist_lock, flags); + head = &acb->ccb_free_list; if (!list_empty(head)) { ccb = list_entry(head->next, struct CommandControlBlock, list); list_del_init(&ccb->list); @@ -3256,6 +3264,16 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(arcmsr_queue_command) +static int arcmsr_slave_config(struct scsi_device *sdev) +{ + unsigned intdev_timeout; + + dev_timeout = sdev->request_queue->rq_timeout; + if ((cmd_timeout > 0) && ((cmd_timeout * HZ) > dev_timeout)) + blk_queue_rq_timeout(sdev->request_queue, cmd_timeout * HZ); + return 0; +} + static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t *rwbuffer) { int count;
[PATCH 0/1] scsi: arcmsr: configure the default SCSI device command timeout value
This patch is against to mkp's 5.10/scsi-queue. 1. Configure the default SCSI device command timeout value. ---
[PATCH v3 2/2] scsi: arcmsr: use round_up() instead of logical operation
From: ching Huang Use round_up() instead of logical operation. Reported-by: Martin K. Petersen Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 55d85c9..1e358d9 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -644,13 +644,12 @@ static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb) struct MessageUnit_F __iomem *pmuF; memset(acb->dma_coherent2, 0xff, acb->completeQ_size); - acb->message_wbuffer = (uint32_t *)unsigned long)acb->dma_coherent2 + - acb->completeQ_size + 3) >> 2) << 2); + acb->message_wbuffer = (uint32_t *)round_up((unsigned long)acb->dma_coherent2 + + acb->completeQ_size, 4); acb->message_rbuffer = ((void *)acb->message_wbuffer) + 0x100; acb->msgcode_rwbuffer = ((void *)acb->message_wbuffer) + 0x200; memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE); - host_buffer_dma = ((acb->dma_coherent_handle2 + acb->completeQ_size + - 3) >> 2) << 2; + host_buffer_dma = round_up(acb->dma_coherent_handle2 + acb->completeQ_size, 4); pmuF = acb->pmuF; /* host buffer low address, bit0:1 all buffer active */ writel(lower_32_bits(host_buffer_dma | 1), &pmuF->inbound_msgaddr0);
[PATCH v3 1/2] scsi: arcmsr: Use upper_32_bits() instead of dma_addr_hi32()
From: ching Huang Use upper_32_bits() instead of dma_addr_hi32(). Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index d13d672..55d85c9 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -653,9 +653,9 @@ static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb) 3) >> 2) << 2; pmuF = acb->pmuF; /* host buffer low address, bit0:1 all buffer active */ - writel((uint32_t)(host_buffer_dma | 1), &pmuF->inbound_msgaddr0); + writel(lower_32_bits(host_buffer_dma | 1), &pmuF->inbound_msgaddr0); /* host buffer high address */ - writel(dma_addr_hi32(host_buffer_dma), &pmuF->inbound_msgaddr1); + writel(upper_32_bits(host_buffer_dma), &pmuF->inbound_msgaddr1); /* set host buffer physical address */ writel(ARCMSR_HBFMU_DOORBELL_SYNC1, &pmuF->iobound_doorbell); } @@ -4057,11 +4057,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) writel(cdb_phyaddr, ®->msgcode_rwbuffer[2]); writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[3]); writel(acb->ccbsize, ®->msgcode_rwbuffer[4]); - dma_coherent_handle = acb->dma_coherent_handle2; - cdb_phyaddr = (uint32_t)(dma_coherent_handle & 0x); - cdb_phyaddr_hi32 = (uint32_t)((dma_coherent_handle >> 16) >> 16); - writel(cdb_phyaddr, ®->msgcode_rwbuffer[5]); - writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[6]); + writel(lower_32_bits(acb->dma_coherent_handle2), ®->msgcode_rwbuffer[5]); + writel(upper_32_bits(acb->dma_coherent_handle2), ®->msgcode_rwbuffer[6]); writel(acb->ioqueue_size, ®->msgcode_rwbuffer[7]); writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; @@ -4081,11 +4078,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) acb->msgcode_rwbuffer[2] = cdb_phyaddr; acb->msgcode_rwbuffer[3] = cdb_phyaddr_hi32; acb->msgcode_rwbuffer[4] = acb->ccbsize; - dma_coherent_handle = acb->dma_coherent_handle2; - cdb_phyaddr = (uint32_t)dma_coherent_handle; - cdb_phyaddr_hi32 = dma_addr_hi32(dma_coherent_handle); - acb->msgcode_rwbuffer[5] = cdb_phyaddr; - acb->msgcode_rwbuffer[6] = cdb_phyaddr_hi32; + acb->msgcode_rwbuffer[5] = lower_32_bits(acb->dma_coherent_handle2); + acb->msgcode_rwbuffer[6] = upper_32_bits(acb->dma_coherent_handle2); acb->msgcode_rwbuffer[7] = acb->completeQ_size; writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
[PATCH v3 0/2] scsi: arcmsr: use upper_32_bits() instead of dma_addr_hi32()
This patch is against to mkp's 5.10/scsi-staging. 1. Use upper_32_bits() instead of dma_addr_hi32(). 2. Use round_up() instead of logical operation. ---
[PATCH v2 2/2] scsi: arcmsr: use round_up() instead of logical operation
From: ching Huang Use round_up() instead of logical operation. Reported-by: Martin K. Petersen Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 55d85c9..1e358d9 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -644,13 +644,12 @@ static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb) struct MessageUnit_F __iomem *pmuF; memset(acb->dma_coherent2, 0xff, acb->completeQ_size); - acb->message_wbuffer = (uint32_t *)unsigned long)acb->dma_coherent2 + - acb->completeQ_size + 3) >> 2) << 2); + acb->message_wbuffer = (uint32_t *)round_up((unsigned long)acb->dma_coherent2 + + acb->completeQ_size, 4); acb->message_rbuffer = ((void *)acb->message_wbuffer) + 0x100; acb->msgcode_rwbuffer = ((void *)acb->message_wbuffer) + 0x200; memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE); - host_buffer_dma = ((acb->dma_coherent_handle2 + acb->completeQ_size + - 3) >> 2) << 2; + host_buffer_dma = round_up(acb->dma_coherent_handle2 + acb->completeQ_size, 4); pmuF = acb->pmuF; /* host buffer low address, bit0:1 all buffer active */ writel(lower_32_bits(host_buffer_dma | 1), &pmuF->inbound_msgaddr0);
[PATCH v2 1/2] scsi: arcmsr: fix warning: right shift count >= width of type
From: ching Huang Fix warning: right shift count >= width of type. Reported-by: kernel test robot Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index be6fb72..55d85c9 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -653,9 +653,9 @@ static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb) 3) >> 2) << 2; pmuF = acb->pmuF; /* host buffer low address, bit0:1 all buffer active */ - writel((uint32_t)(host_buffer_dma | 1), &pmuF->inbound_msgaddr0); + writel(lower_32_bits(host_buffer_dma | 1), &pmuF->inbound_msgaddr0); /* host buffer high address */ - writel((uint32_t)(host_buffer_dma >> 32), &pmuF->inbound_msgaddr1); + writel(upper_32_bits(host_buffer_dma), &pmuF->inbound_msgaddr1); /* set host buffer physical address */ writel(ARCMSR_HBFMU_DOORBELL_SYNC1, &pmuF->iobound_doorbell); } @@ -4057,11 +4057,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) writel(cdb_phyaddr, ®->msgcode_rwbuffer[2]); writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[3]); writel(acb->ccbsize, ®->msgcode_rwbuffer[4]); - dma_coherent_handle = acb->dma_coherent_handle2; - cdb_phyaddr = (uint32_t)(dma_coherent_handle & 0x); - cdb_phyaddr_hi32 = (uint32_t)((dma_coherent_handle >> 16) >> 16); - writel(cdb_phyaddr, ®->msgcode_rwbuffer[5]); - writel(cdb_phyaddr_hi32, ®->msgcode_rwbuffer[6]); + writel(lower_32_bits(acb->dma_coherent_handle2), ®->msgcode_rwbuffer[5]); + writel(upper_32_bits(acb->dma_coherent_handle2), ®->msgcode_rwbuffer[6]); writel(acb->ioqueue_size, ®->msgcode_rwbuffer[7]); writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; @@ -4081,11 +4078,8 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) acb->msgcode_rwbuffer[2] = cdb_phyaddr; acb->msgcode_rwbuffer[3] = cdb_phyaddr_hi32; acb->msgcode_rwbuffer[4] = acb->ccbsize; - dma_coherent_handle = acb->dma_coherent_handle2; - cdb_phyaddr = (uint32_t)dma_coherent_handle; - cdb_phyaddr_hi32 = (uint32_t)(dma_coherent_handle >> 32); - acb->msgcode_rwbuffer[5] = cdb_phyaddr; - acb->msgcode_rwbuffer[6] = cdb_phyaddr_hi32; + acb->msgcode_rwbuffer[5] = lower_32_bits(acb->dma_coherent_handle2); + acb->msgcode_rwbuffer[6] = upper_32_bits(acb->dma_coherent_handle2); acb->msgcode_rwbuffer[7] = acb->completeQ_size; writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
[PATCH v2 0/2] scsi: arcmsr: fix warning: right shift count >= width of type
This patch is against to mkp's 5.10/scsi-staging. 1. fix warning: right shift count >= width of type. 2. use round_up() instead of logical operation. ---
PATCH 1/1] scsi: arcmsr: fix warning: right shift count >= width of type
From: ching Huang Fix warning: right shift count >= width of type. Reported-by: kernel test robot Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index be6fb72..d13d672 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -655,7 +655,7 @@ static void arcmsr_hbaF_assign_regAddr(struct AdapterControlBlock *acb) /* host buffer low address, bit0:1 all buffer active */ writel((uint32_t)(host_buffer_dma | 1), &pmuF->inbound_msgaddr0); /* host buffer high address */ - writel((uint32_t)(host_buffer_dma >> 32), &pmuF->inbound_msgaddr1); + writel(dma_addr_hi32(host_buffer_dma), &pmuF->inbound_msgaddr1); /* set host buffer physical address */ writel(ARCMSR_HBFMU_DOORBELL_SYNC1, &pmuF->iobound_doorbell); } @@ -4083,7 +4083,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) acb->msgcode_rwbuffer[4] = acb->ccbsize; dma_coherent_handle = acb->dma_coherent_handle2; cdb_phyaddr = (uint32_t)dma_coherent_handle; - cdb_phyaddr_hi32 = (uint32_t)(dma_coherent_handle >> 32); + cdb_phyaddr_hi32 = dma_addr_hi32(dma_coherent_handle); acb->msgcode_rwbuffer[5] = cdb_phyaddr; acb->msgcode_rwbuffer[6] = cdb_phyaddr_hi32; acb->msgcode_rwbuffer[7] = acb->completeQ_size;
[PATCH 0/1] scsi: arcmsr: fix warning: right shift count >= width of type
This patch is against to mkp's 5.10/scsi-staging. 1. fix warning: right shift count >= width of type. ---
[PATCH 1/4] scsi: arcmsr: Remove unnecessary syntax
From: ching Huang (Resend for adding subject) Remove unnecessary syntax. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index fa562a0..5076480 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -317,20 +317,16 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb) static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A:{ + case ACB_ADAPTER_TYPE_A: iounmap(acb->pmuA); - } - break; - case ACB_ADAPTER_TYPE_B:{ + break; + case ACB_ADAPTER_TYPE_B: iounmap(acb->mem_base0); iounmap(acb->mem_base1); - } - - break; - case ACB_ADAPTER_TYPE_C:{ + break; + case ACB_ADAPTER_TYPE_C: iounmap(acb->pmuC); - } - break; + break; case ACB_ADAPTER_TYPE_D: iounmap(acb->mem_base0); break; @@ -552,18 +548,14 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { + case ACB_ADAPTER_TYPE_A: arcmsr_hbaA_flush_cache(acb); - } break; - - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: arcmsr_hbaB_flush_cache(acb); - } break; - case ACB_ADAPTER_TYPE_C: { + case ACB_ADAPTER_TYPE_C: arcmsr_hbaC_flush_cache(acb); - } break; case ACB_ADAPTER_TYPE_D: arcmsr_hbaD_flush_cache(acb); @@ -1213,21 +1205,15 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) { uint8_t rtnval = 0; switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { + case ACB_ADAPTER_TYPE_A: rtnval = arcmsr_hbaA_abort_allcmd(acb); - } break; - - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: rtnval = arcmsr_hbaB_abort_allcmd(acb); - } break; - - case ACB_ADAPTER_TYPE_C: { + case ACB_ADAPTER_TYPE_C: rtnval = arcmsr_hbaC_abort_allcmd(acb); - } break; - case ACB_ADAPTER_TYPE_D: rtnval = arcmsr_hbaD_abort_allcmd(acb); break; @@ -1916,18 +1902,14 @@ static void arcmsr_hbaE_stop_bgrb(struct AdapterControlBlock *pACB) static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { + case ACB_ADAPTER_TYPE_A: arcmsr_hbaA_stop_bgrb(acb); - } break; - - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: arcmsr_hbaB_stop_bgrb(acb); - } break; - case ACB_ADAPTER_TYPE_C: { + case ACB_ADAPTER_TYPE_C: arcmsr_hbaC_stop_bgrb(acb); - } break; case ACB_ADAPTER_TYPE_D: arcmsr_hbaD_stop_bgrb(acb); @@ -1951,7 +1933,6 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb) writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); } break; - case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell); @@ -2034,7 +2015,6 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) qbuffer = (struct QBUFFER __iomem *)®->message_rbuffer; } break; - case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; qbuffer = (struct QBUFFER __iomem *)reg->message_rbuffer; @@ -2069,7 +2049,6 @@ static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBloc pqbuffer = (struct QBUFFER __iomem *) ®->message_wbuffer; } break; - case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; pqbuffer = (struct QBUFFER __iomem *)reg->message_wbuffer; @@ -2699,10 +2678,8 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: return arcmsr_hbaA_handle_isr(acb); - break; case ACB_ADAPTER_TYPE_B: return arcmsr_hbaB_handle_isr(acb); - break; case ACB_ADAPTER_TYPE_C: return arcmsr_hbaC_handle_isr(acb); case ACB_ADAPTER_TYPE_D: @@ -3634,18 +3611,14 @@ stat
[PATCH 4/4] scsi: arcmsr: Update driver version to v1.50.00.02-20200819
From: ching Huang Update driver version to v1.50.00.02-20200819. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 5e32f17..5d054d5 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.10-20190116" +#define ARCMSR_DRIVER_VERSION "v1.50.00.02-20200819" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH 3/4] scsi: arcmsr: Add supporting ARC-1886 series Raid controllers
From: ching Huang Add supporting ARC-1886 series Raid controllers. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 0ae401d..5e32f17 100755 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -80,6 +80,7 @@ struct device_attribute; #ifndef PCI_DEVICE_ID_ARECA_1884 #define PCI_DEVICE_ID_ARECA_1884 0x1884 #endif +#define PCI_DEVICE_ID_ARECA_1886 0x188A #defineARCMSR_HOURS(1000 * 60 * 60 * 4) #defineARCMSR_MINUTES (1000 * 60 * 60) /* @@ -436,6 +437,21 @@ struct FIRMWARE_INFO #define ARCMSR_HBEMU_DOORBELL_SYNC 0x100 #define ARCMSR_ARC188X_RESET_ADAPTER 0x0004 #define ARCMSR_ARC1884_DiagWrite_ENABLE0x0080 + +/* +*** +**SPEC. for Areca Type F adapter +*** +*/ +#define ARCMSR_SIGNATURE_1886 0x188617D3 +// Doorbell and interrupt definition are same as Type E adapter +/* ARC-1886 doorbell sync */ +#define ARCMSR_HBFMU_DOORBELL_SYNC 0x100 +//set host rw buffer physical address at inbound message 0, 1 (low,high) +#define ARCMSR_HBFMU_DOORBELL_SYNC10x300 +#define ARCMSR_HBFMU_MESSAGE_FIRMWARE_OK 0x8000 +#define ARCMSR_HBFMU_MESSAGE_NO_VOLUME_CHANGE 0x2000 + /* *** **ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) @@ -720,6 +736,80 @@ struct MessageUnit_E{ uint32_tmsgcode_rwbuffer[256]; /*2200 23FF*/ }; +/* +* +** Messaging Unit (MU) of Type F processor(LSI) +* +*/ +struct MessageUnit_F { + uint32_tiobound_doorbell; /* 0003*/ + uint32_twrite_sequence_3xxx;/*0004 0007*/ + uint32_thost_diagnostic_3xxx; /*0008 000B*/ + uint32_tposted_outbound_doorbell; /*000C 000F*/ + uint32_tmaster_error_attribute; /*0010 0013*/ + uint32_tmaster_error_address_low; /*0014 0017*/ + uint32_tmaster_error_address_high; /*0018 001B*/ + uint32_thcb_size; /*001C 001F*/ + uint32_tinbound_doorbell; /*0020 0023*/ + uint32_tdiagnostic_rw_data; /*0024 0027*/ + uint32_tdiagnostic_rw_address_low; /*0028 002B*/ + uint32_tdiagnostic_rw_address_high; /*002C 002F*/ + uint32_thost_int_status;/*0030 0033*/ + uint32_thost_int_mask; /*0034 0037*/ + uint32_tdcr_data; /*0038 003B*/ + uint32_tdcr_address;/*003C 003F*/ + uint32_tinbound_queueport; /*0040 0043*/ + uint32_toutbound_queueport; /*0044 0047*/ + uint32_thcb_pci_address_low;/*0048 004B*/ + uint32_thcb_pci_address_high; /*004C 004F*/ + uint32_tiop_int_status; /*0050 0053*/ + uint32_tiop_int_mask; /*0054 0057*/ + uint32_tiop_inbound_queue_port; /*0058 005B*/ + uint32_tiop_outbound_queue_port;/*005C 005F*/ + uint32_tinbound_free_list_index;/*0060 0063*/ + uint32_tinbound_post_list_index;/*0064 0067*/ + uint32_treply_post_producer_index; /*0068 006B*/ + uint32_treply_post_consumer_index; /*006C 006F*/ + uint32_tinbound_doorbell_clear; /*0070 0073*/ + uint32_ti2o_message_unit_control; /*0074 0077*/ + uint32_tlast_used_message_source_address_low; /*0078 007B*/ + uint32_tlast_used_message_source_address_high; /*007C 007F*/ + uint32_tpull_mode_data_byte_count[4]; /*0080 008F*/ + uint32_tmessage_dest_address_index; /*0090 0093*/ + uint32_tdone_queue_not_empty_int_counter_timer; /*0094 0097*/ + uint32_tutility_A_int_counter_timer;/*0098 009B*/ + uint32_toutbound_doorbell; /*009C 009F*/ + uint32_toutbound_doorbell_clear;/*00A0 00A3*/ + uint32_t
[PATCH 2/4] scsi: arcmsr: Fix device hot-plug monitoring timer stop
From: ching Huang Fix device hot-plug monitoring timer stop. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 9220bcf..0ae401d 100755 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -836,8 +836,6 @@ struct AdapterControlBlock #defineFW_NORMAL 0x #defineFW_BOG 0x0001 #defineFW_DEADLOCK 0x0010 - atomic_trq_map_token; - atomic_tante_token_value; uint32_tmaxOutstanding; int vector_count; uint32_tmaxFreeCCB; diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 5076480..86f84d7 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -777,7 +777,6 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work) struct scsi_device *psdev; char diff, temp; - acb->acb_flags &= ~ACB_F_MSG_GET_CONFIG; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { struct MessageUnit_A __iomem *reg = acb->pmuA; @@ -815,7 +814,6 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work) break; } } - atomic_inc(&acb->rq_map_token); if (readl(signature) != ARCMSR_SIGNATURE_GET_CONFIG) return; for (target = 0; target < ARCMSR_MAX_TARGETID - 1; @@ -846,6 +844,7 @@ static void arcmsr_message_isr_bh_fn(struct work_struct *work) devicemap++; acb_dev_map++; } + acb->acb_flags &= ~ACB_F_MSG_GET_CONFIG; } static int @@ -898,8 +897,6 @@ out_free_irq: static void arcmsr_init_get_devmap_timer(struct AdapterControlBlock *pacb) { INIT_WORK(&pacb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn); - atomic_set(&pacb->rq_map_token, 16); - atomic_set(&pacb->ante_token_value, 16); pacb->fw_flag = FW_NORMAL; timer_setup(&pacb->eternal_timer, arcmsr_request_device_map, 0); pacb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); @@ -3925,24 +3922,10 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) static void arcmsr_request_device_map(struct timer_list *t) { struct AdapterControlBlock *acb = from_timer(acb, t, eternal_timer); - if (unlikely(atomic_read(&acb->rq_map_token) == 0) || - (acb->acb_flags & ACB_F_BUS_RESET) || - (acb->acb_flags & ACB_F_ABORT)) { - mod_timer(&acb->eternal_timer, - jiffies + msecs_to_jiffies(6 * HZ)); + if (acb->acb_flags & (ACB_F_MSG_GET_CONFIG | ACB_F_BUS_RESET | ACB_F_ABORT)) { + mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); } else { acb->fw_flag = FW_NORMAL; - if (atomic_read(&acb->ante_token_value) == - atomic_read(&acb->rq_map_token)) { - atomic_set(&acb->rq_map_token, 16); - } - atomic_set(&acb->ante_token_value, - atomic_read(&acb->rq_map_token)); - if (atomic_dec_and_test(&acb->rq_map_token)) { - mod_timer(&acb->eternal_timer, jiffies + - msecs_to_jiffies(6 * HZ)); - return; - } switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { struct MessageUnit_A __iomem *reg = acb->pmuA; @@ -4362,8 +4345,6 @@ wait_reset_done: goto wait_reset_done; } arcmsr_iop_init(acb); - atomic_set(&acb->rq_map_token, 16); - atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); @@ -4372,8 +4353,6 @@ wait_reset_done: pr_notice("arcmsr: scsi bus reset eh returns with success\n"); } else { acb->acb_flags &= ~ACB_F_BUS_RESET; - atomic_set(&acb->rq_map_token, 16); - atomic_set(&acb->ante_token_value, 16); acb->fw_flag = FW_NORMAL; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ));
[PATCH 1/4] scsi: arcmsr:
From: ching Huang Remove unnecessary syntax. Signed-off-by: ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index fa562a0..5076480 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -317,20 +317,16 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb) static void arcmsr_unmap_pciregion(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A:{ + case ACB_ADAPTER_TYPE_A: iounmap(acb->pmuA); - } - break; - case ACB_ADAPTER_TYPE_B:{ + break; + case ACB_ADAPTER_TYPE_B: iounmap(acb->mem_base0); iounmap(acb->mem_base1); - } - - break; - case ACB_ADAPTER_TYPE_C:{ + break; + case ACB_ADAPTER_TYPE_C: iounmap(acb->pmuC); - } - break; + break; case ACB_ADAPTER_TYPE_D: iounmap(acb->mem_base0); break; @@ -552,18 +548,14 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { + case ACB_ADAPTER_TYPE_A: arcmsr_hbaA_flush_cache(acb); - } break; - - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: arcmsr_hbaB_flush_cache(acb); - } break; - case ACB_ADAPTER_TYPE_C: { + case ACB_ADAPTER_TYPE_C: arcmsr_hbaC_flush_cache(acb); - } break; case ACB_ADAPTER_TYPE_D: arcmsr_hbaD_flush_cache(acb); @@ -1213,21 +1205,15 @@ static uint8_t arcmsr_abort_allcmd(struct AdapterControlBlock *acb) { uint8_t rtnval = 0; switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { + case ACB_ADAPTER_TYPE_A: rtnval = arcmsr_hbaA_abort_allcmd(acb); - } break; - - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: rtnval = arcmsr_hbaB_abort_allcmd(acb); - } break; - - case ACB_ADAPTER_TYPE_C: { + case ACB_ADAPTER_TYPE_C: rtnval = arcmsr_hbaC_abort_allcmd(acb); - } break; - case ACB_ADAPTER_TYPE_D: rtnval = arcmsr_hbaD_abort_allcmd(acb); break; @@ -1916,18 +1902,14 @@ static void arcmsr_hbaE_stop_bgrb(struct AdapterControlBlock *pACB) static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) { switch (acb->adapter_type) { - case ACB_ADAPTER_TYPE_A: { + case ACB_ADAPTER_TYPE_A: arcmsr_hbaA_stop_bgrb(acb); - } break; - - case ACB_ADAPTER_TYPE_B: { + case ACB_ADAPTER_TYPE_B: arcmsr_hbaB_stop_bgrb(acb); - } break; - case ACB_ADAPTER_TYPE_C: { + case ACB_ADAPTER_TYPE_C: arcmsr_hbaC_stop_bgrb(acb); - } break; case ACB_ADAPTER_TYPE_D: arcmsr_hbaD_stop_bgrb(acb); @@ -1951,7 +1933,6 @@ static void arcmsr_iop_message_read(struct AdapterControlBlock *acb) writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); } break; - case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell); @@ -2034,7 +2015,6 @@ struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) qbuffer = (struct QBUFFER __iomem *)®->message_rbuffer; } break; - case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; qbuffer = (struct QBUFFER __iomem *)reg->message_rbuffer; @@ -2069,7 +2049,6 @@ static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBloc pqbuffer = (struct QBUFFER __iomem *) ®->message_wbuffer; } break; - case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; pqbuffer = (struct QBUFFER __iomem *)reg->message_wbuffer; @@ -2699,10 +2678,8 @@ static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: return arcmsr_hbaA_handle_isr(acb); - break; case ACB_ADAPTER_TYPE_B: return arcmsr_hbaB_handle_isr(acb); - break; case ACB_ADAPTER_TYPE_C: return arcmsr_hbaC_handle_isr(acb); case ACB_ADAPTER_TYPE_D: @@ -3634,18 +3611,14 @@ static int arcmsr_polling_ccbd
[PATCH 0/4] scsi: arcmsr: Fix timer stop and support new adapter ARC-1886 series
This patch series are against to mkp's 5.10/scsi-queue. 1. Remove unnecessary syntax. 2. Fix device hot-plug monitoring timer stop. 3. Add supporting ARC-1886 series Raid controllers. 4. Update driver version to v1.50.00.02-20200819. ---
Re: [PATCH v2 0/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
On Tue, 2019-01-22 at 21:41 -0500, Martin K. Petersen wrote: > Ching, > > > This patch series are against to mkp's 5.1/scsi-queue. > > Applied to 5.1/scsi-queue. Thank you. > > PS. Your file permissions are odd. I always have to change your diffs > from 755 to 644 before applying. > Thanks Martin and Dan's help. The file permission problem also confused to me. I used Evolution mail of CentOS 6.x to submit the patches. The mail context format is Plain text, preformatted. I inserted the diff text file to the mail, and diff file listing as below. -rw-r--r--. 1 root root 1663 Jan 16 04:11 p1.txt Don't know why and when it's permission changed from 644 to 755.
Re: [PATCH 2/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
On Tue, 2019-01-22 at 10:48 +0300, Dan Carpenter wrote: > On Thu, Jan 17, 2019 at 05:52:28PM +0800, Ching Huang wrote: > > On Thu, 2019-01-17 at 12:16 +0300, Dan Carpenter wrote: > > > On Thu, Jan 17, 2019 at 04:47:07PM +0800, Ching Huang wrote: > > > > On Thu, 2019-01-17 at 10:59 +0300, Dan Carpenter wrote: > > > > > On Thu, Jan 17, 2019 at 11:45:03AM +0800, Ching Huang wrote: > > > > > > >From Ching Huang > > > > > > > > > > > > Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2. > > > > > > > > > > > > > > > > What does this look like from a user perspective? Does it fail every > > > > > time or does it only fail sometimes? > > > > > > > > > > What's the bug exactly? > > > > > > > > > > There is no Fixes tag... > > > > >From user's perspective, hibernate/resume are OK. > > > > But following IO may cause 'isr get an illegal ccb command' in > > > > log/messages sometime. > > > > > > > > > > > > > > You will need to resend with that information included in the commit > > > message. > > OK. I will resend this patch later. > > > > > > > > > Signed-off-by: Ching Huang > > > > > > --- > > > > > > > > > > > > diff --git a/drivers/scsi/arcmsr/arcmsr.h > > > > > > b/drivers/scsi/arcmsr/arcmsr.h > > > > > > index a94c513..b98c632 100755 > > > > > > --- a/drivers/scsi/arcmsr/arcmsr.h > > > > > > +++ b/drivers/scsi/arcmsr/arcmsr.h > > > > > > @@ -508,9 +508,9 @@ struct MessageUnit_A > > > > > > struct MessageUnit_B > > > > > > { > > > > > > uint32_tpost_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > > > > > - uint32_tdone_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > > > > > + volatile uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > > > > > > > > > There is a well known rule of thumb that when someone uses "volatile" > > > > > in the kernel it means there is a locking problem... Is this __iomem > > > > > or > > > > > something? > > > > The done_qbuffer was a command completion queue, it was an area written > > > > by IO processor and read by device driver. So, ... > > > > > > I'm not totally positive I understand this sentence. I can find a bunch > > > of places which read from this buffer, but I haven't immediately found > > > which place writes to it. Can you give me a function name that I should > > > read? > > Well, we allocate memory for struct MessageUnit_B in > > arcmsr_alloc_ccb_pool(), by assign to acb->dma_coherent_handle2. > > Then we tell IO controller its DMA address in arcmsr_iop_confirm(). > > When a command was completed, controller's firmware program will write a > > completion ccb in done_qbuffer through DMA. So, you can't see any driver > > funtion write to it. > > DMA memory doesn't need to be marked as volatile. I see. So I have removed the volatile in patch v2. > > regards, > dan carpenter >
[PATCH v2 3/3] scsi: arcmsr: Update driver version to v1.40.00.10-20190116
>From Ching Huang Update driver version to v1.40.00.10-20190116. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index a94c513..9220bcf 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.10-20181217" +#define ARCMSR_DRIVER_VERSION "v1.40.00.10-20190116" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH v2 2/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
>From Ching Huang For ACB_ADAPTER_TYPE_B controller, the read/write after hibernate and resume may got 'isr get an illegal ccb command' in log/messages sometimes. This patch fix it. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 5736434..88053b1 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1113,7 +1113,11 @@ static int arcmsr_resume(struct pci_dev *pdev) switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; - reg->post_qbuffer[0] = 0; + uint32_t i; + for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { + reg->post_qbuffer[i] = 0; + reg->done_qbuffer[i] = 0; + } reg->postq_index = 0; reg->doneq_index = 0; break;
[PATCH v2 1/3] scsi: arcmsr: Use dma_alloc_coherent to replace dma_zalloc_coherent
>From Ching Huang Due to dma_zalloc_coherent will be phase out, so use dma_alloc_coherent instead. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 9f85d5a..5736434 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -642,7 +642,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_B: { acb->ioqueue_size = roundup(sizeof(struct MessageUnit_B), 32); - dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->ioqueue_size, + dma_coherent = dma_alloc_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); @@ -656,7 +656,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) break; case ACB_ADAPTER_TYPE_D: { acb->ioqueue_size = roundup(sizeof(struct MessageUnit_D), 32); - dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->ioqueue_size, + dma_coherent = dma_alloc_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); @@ -672,7 +672,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) uint32_t completeQ_size; completeQ_size = sizeof(struct deliver_completeQ) * ARCMSR_MAX_HBE_DONEQUEUE + 128; acb->ioqueue_size = roundup(completeQ_size, 32); - dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->ioqueue_size, + dma_coherent = dma_alloc_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);
[PATCH v2 0/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
This patch series are against to mkp's 5.1/scsi-queue. 1. Due to dma_zalloc_coherent will be phase out, so use dma_alloc_coherent instead. 2. For ACB_ADAPTER_TYPE_B controller, the read/write after hibernate and resume may got 'isr get an illegal ccb command' in log/messages sometimes. This patch fix it. 3. Update driver version to v1.40.00.10-20190116 ---
Re: [PATCH 2/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
On Thu, 2019-01-17 at 12:16 +0300, Dan Carpenter wrote: > On Thu, Jan 17, 2019 at 04:47:07PM +0800, Ching Huang wrote: > > On Thu, 2019-01-17 at 10:59 +0300, Dan Carpenter wrote: > > > On Thu, Jan 17, 2019 at 11:45:03AM +0800, Ching Huang wrote: > > > > >From Ching Huang > > > > > > > > Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2. > > > > > > > > > > What does this look like from a user perspective? Does it fail every > > > time or does it only fail sometimes? > > > > > > What's the bug exactly? > > > > > > There is no Fixes tag... > > >From user's perspective, hibernate/resume are OK. > > But following IO may cause 'isr get an illegal ccb command' in > > log/messages sometime. > > > > > > You will need to resend with that information included in the commit > message. OK. I will resend this patch later. > > > > > Signed-off-by: Ching Huang > > > > --- > > > > > > > > diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h > > > > index a94c513..b98c632 100755 > > > > --- a/drivers/scsi/arcmsr/arcmsr.h > > > > +++ b/drivers/scsi/arcmsr/arcmsr.h > > > > @@ -508,9 +508,9 @@ struct MessageUnit_A > > > > struct MessageUnit_B > > > > { > > > > uint32_tpost_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > > > - uint32_tdone_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > > > + volatile uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > > > > > There is a well known rule of thumb that when someone uses "volatile" > > > in the kernel it means there is a locking problem... Is this __iomem or > > > something? > > The done_qbuffer was a command completion queue, it was an area written > > by IO processor and read by device driver. So, ... > > I'm not totally positive I understand this sentence. I can find a bunch > of places which read from this buffer, but I haven't immediately found > which place writes to it. Can you give me a function name that I should > read? Well, we allocate memory for struct MessageUnit_B in arcmsr_alloc_ccb_pool(), by assign to acb->dma_coherent_handle2. Then we tell IO controller its DMA address in arcmsr_iop_confirm(). When a command was completed, controller's firmware program will write a completion ccb in done_qbuffer through DMA. So, you can't see any driver funtion write to it. > > > > > > > > uint32_tpostq_index; > > > > - uint32_tdoneq_index; > > > > + volatile uint32_t doneq_index; > > The volatile here is not right. It's just normal memory. Right. this volatile is not necessary. > > regards, > dan carpenter
Re: [PATCH 2/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
On Thu, 2019-01-17 at 10:59 +0300, Dan Carpenter wrote: > On Thu, Jan 17, 2019 at 11:45:03AM +0800, Ching Huang wrote: > > >From Ching Huang > > > > Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2. > > > > What does this look like from a user perspective? Does it fail every > time or does it only fail sometimes? > > What's the bug exactly? > > There is no Fixes tag... >From user's perspective, hibernate/resume are OK. But following IO may cause 'isr get an illegal ccb command' in log/messages sometime. > > > Signed-off-by: Ching Huang > > --- > > > > diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h > > index a94c513..b98c632 100755 > > --- a/drivers/scsi/arcmsr/arcmsr.h > > +++ b/drivers/scsi/arcmsr/arcmsr.h > > @@ -508,9 +508,9 @@ struct MessageUnit_A > > struct MessageUnit_B > > { > > uint32_tpost_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > - uint32_tdone_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > + volatile uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; > > There is a well known rule of thumb that when someone uses "volatile" > in the kernel it means there is a locking problem... Is this __iomem or > something? The done_qbuffer was a command completion queue, it was an area written by IO processor and read by device driver. So, ... > > > uint32_tpostq_index; > > - uint32_tdoneq_index; > > + volatile uint32_t doneq_index; > > uint32_t__iomem *drv2iop_doorbell; > > uint32_t__iomem *drv2iop_doorbell_mask; > > uint32_t__iomem *iop2drv_doorbell; > > diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c > > b/drivers/scsi/arcmsr/arcmsr_hba.c > > index 5736434..88053b1 100755 > > --- a/drivers/scsi/arcmsr/arcmsr_hba.c > > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c > > @@ -1113,7 +1113,11 @@ static int arcmsr_resume(struct pci_dev *pdev) > > switch (acb->adapter_type) { > > case ACB_ADAPTER_TYPE_B: { > > struct MessageUnit_B *reg = acb->pmuB; > > - reg->post_qbuffer[0] = 0; > > + uint32_t i; > > + for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { > > + reg->post_qbuffer[i] = 0; > > + reg->done_qbuffer[i] = 0; > > + } > > Is this cause by patch 1 changing the zalloc to regular alloc?? If so > then it should be folded into that patch instead of sent separately. These fully clear delivery and completion queues are for fixing 'isr get an illegal ccb command'. It is nothing related to Zalloc or alloc. > > regards, > dan carpenter > >
[PATCH 0/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
This patch series are against to mkp's 5.1/scsi-queue. 1. Due to dma_zalloc_coherent will be phase out, so use dma_alloc_coherent to replace it. 2. Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2. 3. Update driver version to v1.40.00.10-20190116 ---
[PATCH 3/3] scsi: arcmsr: Update driver version to v1.40.00.10-20190116
>From Ching Huang Update driver version to v1.40.00.10-20190116. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index b98c632..6033bcc 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.10-20181217" +#define ARCMSR_DRIVER_VERSION "v1.40.00.10-20190116" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH 2/3] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
>From Ching Huang Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index a94c513..b98c632 100755 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -508,9 +508,9 @@ struct MessageUnit_A struct MessageUnit_B { uint32_tpost_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; - uint32_tdone_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; + volatile uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; uint32_tpostq_index; - uint32_tdoneq_index; + volatile uint32_t doneq_index; uint32_t__iomem *drv2iop_doorbell; uint32_t__iomem *drv2iop_doorbell_mask; uint32_t__iomem *iop2drv_doorbell; diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 5736434..88053b1 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1113,7 +1113,11 @@ static int arcmsr_resume(struct pci_dev *pdev) switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; - reg->post_qbuffer[0] = 0; + uint32_t i; + for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { + reg->post_qbuffer[i] = 0; + reg->done_qbuffer[i] = 0; + } reg->postq_index = 0; reg->doneq_index = 0; break;
[PATCH 1/3] scsi: arcmsr: Use dma_alloc_coherent to replace dma_zalloc_coherent
>From Ching Huang Due to dma_zalloc_coherent will be phase out, so use dma_alloc_coherent to replace it. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 9f85d5a..5736434 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -642,7 +642,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_B: { acb->ioqueue_size = roundup(sizeof(struct MessageUnit_B), 32); - dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->ioqueue_size, + dma_coherent = dma_alloc_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); @@ -656,7 +656,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) break; case ACB_ADAPTER_TYPE_D: { acb->ioqueue_size = roundup(sizeof(struct MessageUnit_D), 32); - dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->ioqueue_size, + dma_coherent = dma_alloc_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); @@ -672,7 +672,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb) uint32_t completeQ_size; completeQ_size = sizeof(struct deliver_completeQ) * ARCMSR_MAX_HBE_DONEQUEUE + 128; acb->ioqueue_size = roundup(completeQ_size, 32); - dma_coherent = dma_zalloc_coherent(&pdev->dev, acb->ioqueue_size, + dma_coherent = dma_alloc_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);
Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2
This patch series are against to mkp's 5.1/scsi-queue. 1. Due to dma_zalloc_coherent will be phase out, so use dma_alloc_coherent to replace it. 2. Fix suspend/resume of ACB_ADAPTER_TYPE_B part 2. 3. Update driver version to v1.40.00.10-20190116 ---
[PATCH 12/12] scsi: arcmsr: Update driver version to v1.40.00.10-20181217
>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 11/12] scsi: arcmsr: Fix suspend/resume of ACB_ADAPTER_TYPE_B
>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 10/12] scsi: arcmsr: Separate 'set dma mask' as a function
>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 9/12] scsi: arcmsr: Add an option of set dma_mask_64 for ACB_ADAPTER_TYPE_A
>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 8/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_D that ccb address can above 4GB
>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 7/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_C that ccb address can above 4GB
>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 6/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_B that ccb address can above 4GB
>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 5/12] scsi: arcmsr: Update for ACB_ADAPTER_TYPE_A that ccb address can above 4GB
>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 4/12] scsi: arcmsr: Update arcmsr_alloc_ccb_pool for ccb buffer address can above 4GB
>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 3/12] scsi: arcmsr: Merge arcmsr_alloc_io_queue to arcmsr_alloc_ccb_pool
>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 2/12] scsi: arcmsr: Rename arcmsr_free_mu to arcmsr_free_io_queue
>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 1/12] scsi: arcmsr: Rename acb structure member roundup_ccbsize to ioqueue_size
>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 0/12] scsi: arcmsr: update for ccb structure address can above 4GB
>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 ---
Re: [PATCH 0/3] scsi: arcmsr: Add driver parameter cmd_timeout for scsi command timeout setting
On Tue, 2018-05-08 at 14:32 +0800, Ching Huang wrote: > On Tue, 2018-05-08 at 01:41 -0400, Martin K. Petersen wrote: > > Hello Ching, > > > > > 1. Add driver parameter cmd_timeout, default value is > > > ARCMSR_DEFAULT_TIMEOUT. > > > 2. Add slave_configure callback function to set device command timeout > > > value. > > > 3. Update driver version to v1.40.00.06-20180504. > > > > I am not so keen on arcmsr overriding the timeout set by the admin or > > application. > > > > Also, instead of introducing this module parameter, why not simply ask > > the user to change rq_timeout? > > > This timeout setting only after device has been inquiry successfully. > Of course, user can set timeout value to /sys/block/sdX/device/timeout. > But user does not like to set this value once command timeout occurred. > They rather like timeout never happen. > This timeout setting apply to all devices, its better than user has to set one bye one for each device.
Re: [PATCH 0/3] scsi: arcmsr: Add driver parameter cmd_timeout for scsi command timeout setting
On Tue, 2018-05-08 at 01:41 -0400, Martin K. Petersen wrote: > Hello Ching, > > > 1. Add driver parameter cmd_timeout, default value is > > ARCMSR_DEFAULT_TIMEOUT. > > 2. Add slave_configure callback function to set device command timeout > > value. > > 3. Update driver version to v1.40.00.06-20180504. > > I am not so keen on arcmsr overriding the timeout set by the admin or > application. > > Also, instead of introducing this module parameter, why not simply ask > the user to change rq_timeout? > This timeout setting only after device has been inquiry successfully. Of course, user can set timeout value to /sys/block/sdX/device/timeout. But user does not like to set this value once command timeout occurred. They rather like timeout never happen.
[PATCH 3/3] scsi: arcmsr: Update driver version to v1.40.00.06-20180504
>From Ching Huang Update driver version to v1.40.00.06-20180504 Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 62eeef5..eb39623 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.05-20180309" +#define ARCMSR_DRIVER_VERSION "v1.40.00.06-20180504" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH 2/3] scsi: arcmsr: Add slave_configure callback function to set device command timeout value
>From Ching Huang Add slave_configure callback function to set device command timeout value Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index f6ddaec..79a4487 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -139,6 +139,7 @@ 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 void arcmsr_set_iop_datetime(struct timer_list *); +static int arcmsr_slave_config(struct scsi_device *sdev); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -154,6 +155,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = { .eh_abort_handler = arcmsr_abort, .eh_bus_reset_handler = arcmsr_bus_reset, .bios_param = arcmsr_bios_param, + .slave_configure= arcmsr_slave_config, .change_queue_depth = arcmsr_adjust_disk_queue_depth, .can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD, .this_id= ARCMSR_SCSI_INITIATOR_ID, @@ -3033,6 +3035,17 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(arcmsr_queue_command) +static int arcmsr_slave_config(struct scsi_device *sdev) +{ + unsigned intdev_timeout; + + dev_timeout = sdev->request_queue->rq_timeout; + if ((cmd_timeout > 0) && ((cmd_timeout * HZ) > dev_timeout)) + blk_queue_rq_timeout(sdev->request_queue, cmd_timeout * HZ); + arcmsr_adjust_disk_queue_depth(sdev, cmd_per_lun); + return 0; +} + static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t *rwbuffer) { int count;
[PATCH 1/3] scsi: arcmsr: Add driver parameter cmd_timeout, default value is ARCMSR_DEFAULT_TIMEOUT
>From Ching Huang Add driver parameter cmd_timeout, default value is ARCMSR_DEFAULT_TIMEOUT Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 2e51ccc..62eeef5 100755 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -82,6 +82,7 @@ struct device_attribute; #endif #defineARCMSR_HOURS(1000 * 60 * 60 * 4) #defineARCMSR_MINUTES (1000 * 60 * 60) +#define ARCMSR_DEFAULT_TIMEOUT 90 /* ** ** diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 732b5d9..f6ddaec 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -95,6 +95,10 @@ 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"); +static int cmd_timeout = ARCMSR_DEFAULT_TIMEOUT; +module_param(cmd_timeout, int, S_IRUGO); +MODULE_PARM_DESC(cmd_timeout, " scsi cmd timeout(0 ~ 120 sec.), default is 90"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12
[PATCH 0/3] scsi: arcmsr: Add driver parameter cmd_timeout for scsi command timeout setting
>From Ching Huang This patch series are against to mkp's 4.18/scsi-queue. 1. Add driver parameter cmd_timeout, default value is ARCMSR_DEFAULT_TIMEOUT. 2. Add slave_configure callback function to set device command timeout value. 3. Update driver version to v1.40.00.06-20180504. --
[PATCH 4/4] scsi: arcmsr: Change driver version to v1.40.00.05-20180309
From: Ching Huang Change driver version to v1.40.00.05-20180309 Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index 842b77a..2e51ccc 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.04-20171130" +#define ARCMSR_DRIVER_VERSION "v1.40.00.05-20180309" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH 3/4] scsi: arcmsr: Sleep to avoid CPU stuck too long for waiting adapter ready
From: Ching Huang Sleep to avoid CPU stuck too long for waiting adapter ready. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 2f52c53..732b5d9 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3807,6 +3807,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_A: { struct MessageUnit_A __iomem *reg = acb->pmuA; do { + if (!(acb->acb_flags & ACB_F_IOP_INITED)) + msleep(20); firmware_state = readl(®->outbound_msgaddr1); } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0); } @@ -3815,6 +3817,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; do { + if (!(acb->acb_flags & ACB_F_IOP_INITED)) + msleep(20); firmware_state = readl(reg->iop2drv_doorbell); } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0); writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); @@ -3823,6 +3827,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_C: { struct MessageUnit_C __iomem *reg = acb->pmuC; do { + if (!(acb->acb_flags & ACB_F_IOP_INITED)) + msleep(20); firmware_state = readl(®->outbound_msgaddr1); } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0); } @@ -3830,6 +3836,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_D: { struct MessageUnit_D *reg = acb->pmuD; do { + if (!(acb->acb_flags & ACB_F_IOP_INITED)) + msleep(20); firmware_state = readl(reg->outbound_msgaddr1); } while ((firmware_state & ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK) == 0); @@ -3838,6 +3846,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) case ACB_ADAPTER_TYPE_E: { struct MessageUnit_E __iomem *reg = acb->pmuE; do { + if (!(acb->acb_flags & ACB_F_IOP_INITED)) + msleep(20); firmware_state = readl(®->outbound_msgaddr1); } while ((firmware_state & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0); }
[PATCH 2/4] scsi: arcmsr: Handle adapter removed due to thunderbolt cable disconnection.
From: Ching Huang Handle adapter removed due to thunderbolt cable disconnection. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 75e828b..2f52c53 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -1446,12 +1446,80 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) } } +static void arcmsr_remove_scsi_devices(struct AdapterControlBlock *acb) +{ + char *acb_dev_map = (char *)acb->device_map; + int target, lun, i; + struct scsi_device *psdev; + struct CommandControlBlock *ccb; + char temp; + + for (i = 0; i < acb->maxFreeCCB; i++) { + ccb = acb->pccb_pool[i]; + if (ccb->startdone == ARCMSR_CCB_START) { + ccb->pcmd->result = DID_NO_CONNECT << 16; + arcmsr_pci_unmap_dma(ccb); + ccb->pcmd->scsi_done(ccb->pcmd); + } + } + for (target = 0; target < ARCMSR_MAX_TARGETID; target++) { + temp = *acb_dev_map; + if (temp) { + for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { + if (temp & 1) { + psdev = scsi_device_lookup(acb->host, + 0, target, lun); + if (psdev != NULL) { + scsi_remove_device(psdev); + scsi_device_put(psdev); + } + } + temp >>= 1; + } + *acb_dev_map = 0; + } + acb_dev_map++; + } +} + +static void arcmsr_free_pcidev(struct AdapterControlBlock *acb) +{ + struct pci_dev *pdev; + struct Scsi_Host *host; + + host = acb->host; + arcmsr_free_sysfs_attr(acb); + scsi_remove_host(host); + flush_work(&acb->arcmsr_do_message_isr_bh); + del_timer_sync(&acb->eternal_timer); + if (set_date_time) + del_timer_sync(&acb->refresh_timer); + pdev = acb->pdev; + arcmsr_free_irq(pdev, acb); + arcmsr_free_ccb_pool(acb); + arcmsr_free_mu(acb); + arcmsr_unmap_pciregion(acb); + pci_release_regions(pdev); + scsi_host_put(host); + pci_disable_device(pdev); +} + static void arcmsr_remove(struct pci_dev *pdev) { struct Scsi_Host *host = pci_get_drvdata(pdev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; int poll_count = 0; + uint16_t dev_id; + + pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id); + if (dev_id == 0x) { + acb->acb_flags &= ~ACB_F_IOP_INITED; + acb->acb_flags |= ACB_F_ADAPTER_REMOVED; + arcmsr_remove_scsi_devices(acb); + arcmsr_free_pcidev(acb); + return; + } arcmsr_free_sysfs_attr(acb); scsi_remove_host(host); flush_work(&acb->arcmsr_do_message_isr_bh); @@ -1499,6 +1567,8 @@ static void arcmsr_shutdown(struct pci_dev *pdev) struct Scsi_Host *host = pci_get_drvdata(pdev); struct AdapterControlBlock *acb = (struct AdapterControlBlock *)host->hostdata; + if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) + return; del_timer_sync(&acb->eternal_timer); if (set_date_time) del_timer_sync(&acb->refresh_timer); @@ -2931,6 +3001,12 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; struct CommandControlBlock *ccb; int target = cmd->device->id; + + if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) { + cmd->result = (DID_NO_CONNECT << 16); + cmd->scsi_done(cmd); + return 0; + } cmd->scsi_done = done; cmd->host_scribble = NULL; cmd->result = 0; @@ -4177,6 +4253,8 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) int retry_count = 0; int rtn = FAILED; acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; + if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) + return SUCCESS; pr_notice("arcmsr: executing bus reset eh.num_resets = %d," " num_aborts = %d \n", acb->num_resets, acb->num_aborts); acb->num_resets++; @@ -4243,6 +4321,8 @@ static int arcmsr_abort(struct scsi_cmnd *cmd) int rtn = FAILED;
[PATCH 1/4] scsi: arcmsr: Rename ACB_F_BUS_HANG_ON to ACB_F_ADAPTER_REMOVED for adapter hot-plug
From: Ching Huang Rename ACB_F_BUS_HANG_ON to ACB_F_ADAPTER_REMOVED for adapter hot-plug. Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index f375f35..842b77a 100755 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h @@ -779,12 +779,12 @@ struct AdapterControlBlock /* message clear rqbuffer */ #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 #define ACB_F_BUS_RESET0x0080 -#define ACB_F_BUS_HANG_ON 0x0800/* need hardware reset bus */ #define ACB_F_IOP_INITED 0x0100 /* iop init */ #define ACB_F_ABORT0x0200 #define ACB_F_FIRMWARE_TRAP0x0400 +#define ACB_F_ADAPTER_REMOVED 0x0800 #define ACB_F_MSG_GET_CONFIG 0x1000 struct CommandControlBlock *pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */
[PATCH 0/4] scsi: arcmsr: Support Areca thunderbolt devices hot-plug
From: Ching Huang This patch series are against to mkp's 4.17/scsi-queue. 1. Rename ACB_F_BUS_HANG_ON to ACB_F_ADAPTER_REMOVED for adapter hot-plug 2. Handle adapter removed due to thunderbolt cable disconnection. 3. Sleep to avoid CPU stuck too long for waiting adapter ready 4. Change driver version to v1.40.00.05-20180309 ---
Re: [PATCH] scsi: arcmsr: avoid do_gettimeofday
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.
Re: [PATCH 4/4] scsi: arcmsr: simplify all arcmsr_hbaX_get_config routine by call a new get_adapter_config function
On Thu, 2017-12-14 at 13:13 +0800, kbuild test robot wrote: > Hi Ching, > > Thank you for the patch! Perhaps something to improve: > > [auto build test WARNING on scsi/for-next] > [also build test WARNING on next-20171213] > [cannot apply to v4.15-rc3] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] As what I have said in [PATCH 0/4], this serial patches are apply to Martin's 4.16/scsi-queue only. Now scsi/for-next and next-20171213 are synchronized to Martin's 4.16/scsi-queue, so these patches can apply to them. But v4.15-rc3 has to do some patches like 4.16/scsi-queue done before, or this patch can not apply. > > url: > https://github.com/0day-ci/linux/commits/Ching-Huang/scsi-arcmsr-simplify-hba_get_config-routine/20171213-224803 > base: https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next > reproduce: > # apt-get install sparse > make ARCH=x86_64 allmodconfig > make C=1 CF=-D__CHECK_ENDIAN__ > > > sparse warnings: (new ones prefixed by >>) > > > vim +2971 drivers/scsi/arcmsr/arcmsr_hba.c > > 2958 > 2959static void arcmsr_get_adapter_config(struct > AdapterControlBlock *pACB, uint32_t *rwbuffer) > 2960{ > 2961int count; > 2962uint32_t *acb_firm_model = (uint32_t *)pACB->firm_model; > 2963uint32_t *acb_firm_version = (uint32_t > *)pACB->firm_version; > 2964uint32_t *acb_device_map = (uint32_t *)pACB->device_map; > 2965uint32_t *firm_model = &rwbuffer[15]; > 2966uint32_t *firm_version = &rwbuffer[17]; > 2967uint32_t *device_map = &rwbuffer[21]; > 2968 > 2969count = 2; > 2970while (count) { > > 2971*acb_firm_model = readl(firm_model); > 2972acb_firm_model++; > 2973firm_model++; > 2974count--; > 2975} > 2976count = 4; > 2977while (count) { > 2978*acb_firm_version = readl(firm_version); > 2979acb_firm_version++; > 2980firm_version++; > 2981count--; > 2982} > 2983count = 4; > 2984while (count) { > 2985*acb_device_map = readl(device_map); > 2986acb_device_map++; > 2987device_map++; > 2988count--; > 2989} > 2990pACB->signature = readl(&rwbuffer[0]); > 2991pACB->firm_request_len = readl(&rwbuffer[1]); > 2992pACB->firm_numbers_queue = readl(&rwbuffer[2]); > > 2993pACB->firm_sdram_size = readl(&rwbuffer[3]); > > 2994pACB->firm_hd_channels = readl(&rwbuffer[4]); > 2995pACB->firm_cfg_version = readl(&rwbuffer[25]); > 2996pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n", > 2997pACB->host->host_no, > 2998pACB->firm_model, > 2999pACB->firm_version); > 3000} > 3001 > 3002static bool arcmsr_hbaA_get_config(struct AdapterControlBlock > *acb) > 3003{ > 3004struct MessageUnit_A __iomem *reg = acb->pmuA; > 3005 > 3006arcmsr_wait_firmware_ready(acb); > 3007writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, > ®->inbound_msgaddr0); > 3008if (!arcmsr_hbaA_wait_msgint_ready(acb)) { > 3009printk(KERN_NOTICE "arcmsr%d: wait 'get adapter > firmware \ > 3010miscellaneous data' timeout \n", > acb->host->host_no); > 3011return false; > 3012} > > 3013arcmsr_get_adapter_config(acb, reg->message_rwbuffer); > 3014return true; > 3015} > 3016static bool arcmsr_hbaB_get_config(struct AdapterControlBlock > *acb) > 3017{ > 3018struct MessageUnit_B *reg = acb->pmuB; > 3019 > 3020arcmsr_wait_firmware_ready(acb); > 3021writel(ARCMSR_MESSAGE_START_DRIVER_MODE, > reg->drv2iop_doorbell); > 3022if (!arcmsr
[PATCH 5/4] scsi: arcmsr: simplify arcmsr_request_device_map routine
From: Ching Huang simplify arcmsr_request_device_map routine Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 95c9f08..4774559 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -122,9 +122,6 @@ static void arcmsr_stop_adapter_bgrb(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(struct timer_list *t); -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); @@ -3789,113 +3786,12 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) } } -static void arcmsr_hbaA_request_device_map(struct AdapterControlBlock *acb) -{ - struct MessageUnit_A __iomem *reg = acb->pmuA; - if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - return; - } else { - acb->fw_flag = FW_NORMAL; - if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)){ - atomic_set(&acb->rq_map_token, 16); - } - atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); - if (atomic_dec_and_test(&acb->rq_map_token)) { - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - return; - } - writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); - acb->acb_flags |= ACB_F_MSG_GET_CONFIG; - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - } - return; -} - -static void arcmsr_hbaB_request_device_map(struct AdapterControlBlock *acb) -{ - struct MessageUnit_B *reg = acb->pmuB; - if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0 ) || ((acb->acb_flags & ACB_F_ABORT) != 0 )){ - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - return; - } else { - acb->fw_flag = FW_NORMAL; - if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) { - atomic_set(&acb->rq_map_token, 16); - } - atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); - if (atomic_dec_and_test(&acb->rq_map_token)) { - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - return; - } - writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); - acb->acb_flags |= ACB_F_MSG_GET_CONFIG; - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - } - return; -} - -static void arcmsr_hbaC_request_device_map(struct AdapterControlBlock *acb) -{ - struct MessageUnit_C __iomem *reg = acb->pmuC; - if (unlikely(atomic_read(&acb->rq_map_token) == 0) || ((acb->acb_flags & ACB_F_BUS_RESET) != 0) || ((acb->acb_flags & ACB_F_ABORT) != 0)) { - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - return; - } else { - acb->fw_flag = FW_NORMAL; - if (atomic_read(&acb->ante_token_value) == atomic_read(&acb->rq_map_token)) { - atomic_set(&acb->rq_map_token, 16); - } - atomic_set(&acb->ante_token_value, atomic_read(&acb->rq_map_token)); - if (atomic_dec_and_test(&acb->rq_map_token)) { - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - return; - } - writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); - writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); - acb->acb_flags |= ACB_F_MSG_GET_CONFIG; - mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); - } - return
[PATCH 4/4] scsi: arcmsr: simplify all arcmsr_hbaX_get_config routine by call a new get_adapter_config function
From: Ching Huang simplify all arcmsr_hbaX_get_config routine by call a new get_adapter_config function Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index b7a56e8..95c9f08 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2956,75 +2956,66 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, static DEF_SCSI_QCMD(arcmsr_queue_command) -static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) +static void arcmsr_get_adapter_config(struct AdapterControlBlock *pACB, uint32_t *rwbuffer) { - struct MessageUnit_A __iomem *reg = acb->pmuA; - char *acb_firm_model = acb->firm_model; - char *acb_firm_version = acb->firm_version; - char *acb_device_map = acb->device_map; - char __iomem *iop_firm_model = (char __iomem *)(®->message_rwbuffer[15]); - char __iomem *iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); - char __iomem *iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); int count; - arcmsr_wait_firmware_ready(acb); - writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); - if (!arcmsr_hbaA_wait_msgint_ready(acb)) { - printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ - miscellaneous data' timeout \n", acb->host->host_no); - return false; - } - count = 8; - while (count){ - *acb_firm_model = readb(iop_firm_model); + uint32_t *acb_firm_model = (uint32_t *)pACB->firm_model; + uint32_t *acb_firm_version = (uint32_t *)pACB->firm_version; + uint32_t *acb_device_map = (uint32_t *)pACB->device_map; + uint32_t *firm_model = &rwbuffer[15]; + uint32_t *firm_version = &rwbuffer[17]; + uint32_t *device_map = &rwbuffer[21]; + + count = 2; + while (count) { + *acb_firm_model = readl(firm_model); acb_firm_model++; - iop_firm_model++; + firm_model++; count--; } - - count = 16; - while (count){ - *acb_firm_version = readb(iop_firm_version); + count = 4; + while (count) { + *acb_firm_version = readl(firm_version); acb_firm_version++; - iop_firm_version++; + firm_version++; count--; } - - count=16; - while(count){ - *acb_device_map = readb(iop_device_map); + count = 4; + while (count) { + *acb_device_map = readl(device_map); acb_device_map++; - iop_device_map++; + device_map++; count--; } + pACB->signature = readl(&rwbuffer[0]); + pACB->firm_request_len = readl(&rwbuffer[1]); + pACB->firm_numbers_queue = readl(&rwbuffer[2]); + pACB->firm_sdram_size = readl(&rwbuffer[3]); + pACB->firm_hd_channels = readl(&rwbuffer[4]); + pACB->firm_cfg_version = readl(&rwbuffer[25]); pr_notice("Areca RAID Controller%d: Model %s, F/W %s\n", - acb->host->host_no, - 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]); - acb->firm_sdram_size = readl(®->message_rwbuffer[3]); - acb->firm_hd_channels = readl(®->message_rwbuffer[4]); - acb->firm_cfg_version = readl(®->message_rwbuffer[25]); /*firm_cfg_version,25,100-103*/ + pACB->host->host_no, + pACB->firm_model, + pACB->firm_version); +} + +static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) +{ + struct MessageUnit_A __iomem *reg = acb->pmuA; + + arcmsr_wait_firmware_ready(acb); + writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); + if (!arcmsr_hbaA_wait_msgint_ready(acb)) { + printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ + miscellaneous data' timeout \n", acb->host->host_no); + return false; + } + arcmsr_get_adapter_config(acb, reg->message_rwbuffer); return true; } static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) { struct MessageUnit_B *reg = acb->pmuB; - char *acb_firm_model = acb->firm_model; - char *acb_firm_version = acb->firm_version; - char *acb_device_map = acb->device_map; - char __iomem *iop_firm_model; - /*firm_model,15,60-67*/ - char __iomem *iop_fi
[PATCH 3/4] scsi: arcmsr: simplify arcmsr_hbaE_get_config function
From: Ching Huang simplify arcmsr_hbaE_get_config function Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index dfaea8f..b7a56e8 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3205,16 +3205,14 @@ static bool arcmsr_hbaE_get_config(struct AdapterControlBlock *pACB) struct MessageUnit_E __iomem *reg = pACB->pmuE; char __iomem *iop_firm_model = (char __iomem *)(®->msgcode_rwbuffer[15]); char __iomem *iop_firm_version = (char __iomem *)(®->msgcode_rwbuffer[17]); - uint32_t intmask_org, Index, firmware_state = 0, read_doorbell; + uint32_t intmask_org; int count; /* disable all outbound interrupt */ intmask_org = readl(®->host_int_mask); /* disable outbound message0 int */ writel(intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE, ®->host_int_mask); /* wait firmware ready */ - do { - firmware_state = readl(®->outbound_msgaddr1); - } while ((firmware_state & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0); + arcmsr_wait_firmware_ready(pACB); mdelay(20); /* post "get config" instruction */ writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); @@ -3222,17 +3220,7 @@ static bool arcmsr_hbaE_get_config(struct AdapterControlBlock *pACB) pACB->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE; writel(pACB->out_doorbell, ®->iobound_doorbell); /* wait message ready */ - for (Index = 0; Index < 2000; Index++) { - read_doorbell = readl(®->iobound_doorbell); - if ((read_doorbell ^ pACB->in_doorbell) & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(0, ®->host_int_status); - pACB->in_doorbell = read_doorbell; - break; - } - mdelay(1); - } /*max 1 seconds*/ - - if (Index >= 2000) { + if (!arcmsr_hbaE_wait_msgint_ready(pACB)) { pr_notice("arcmsr%d: wait get adapter firmware " "miscellaneous data timeout\n", pACB->host->host_no); return false;
[PATCH 2/4] scsi: arcmsr: waiting for iop firmware ready before issue get_config command to iop
From: Ching Huang waiting for iop firmware ready before issue get_config command to iop for adapter type A and D Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 9b587ca..dfaea8f 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -2966,6 +2966,7 @@ static bool arcmsr_hbaA_get_config(struct AdapterControlBlock *acb) char __iomem *iop_firm_version = (char __iomem *)(®->message_rwbuffer[17]); char __iomem *iop_device_map = (char __iomem *)(®->message_rwbuffer[21]); int count; + arcmsr_wait_firmware_ready(acb); writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); if (!arcmsr_hbaA_wait_msgint_ready(acb)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ @@ -3149,6 +3150,7 @@ static bool arcmsr_hbaD_get_config(struct AdapterControlBlock *acb) writel(ARCMSR_ARC1214_IOP2DRV_MESSAGE_CMD_DONE, acb->pmuD->outbound_doorbell);/*clear interrupt*/ } + arcmsr_wait_firmware_ready(acb); /* post "get config" instruction */ writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, reg->inbound_msgaddr0); /* wait message ready */
[PATCH 1/4] scsi: arcmsr: simplify arcmsr_hbaC_get_config function
From: Ching Huang simplify arcmsr_hbaC_get_config function Signed-off-by: Ching Huang --- diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index e4258b6..9b587ca 100755 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c @@ -3082,7 +3082,7 @@ static bool arcmsr_hbaB_get_config(struct AdapterControlBlock *acb) static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB) { - uint32_t intmask_org, Index, firmware_state = 0; + uint32_t intmask_org; struct MessageUnit_C __iomem *reg = pACB->pmuC; char *acb_firm_model = pACB->firm_model; char *acb_firm_version = pACB->firm_version; @@ -3093,21 +3093,12 @@ static bool arcmsr_hbaC_get_config(struct AdapterControlBlock *pACB) intmask_org = readl(®->host_int_mask); /* disable outbound message0 int */ writel(intmask_org|ARCMSR_HBCMU_ALL_INTMASKENABLE, ®->host_int_mask); /* wait firmware ready */ - do { - firmware_state = readl(®->outbound_msgaddr1); - } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0); + arcmsr_wait_firmware_ready(pACB); /* post "get config" instruction */ writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); /* wait message ready */ - for (Index = 0; Index < 2000; Index++) { - if (readl(®->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, ®->outbound_doorbell_clear);/*clear interrupt*/ - break; - } - udelay(10); - } /*max 1 seconds*/ - if (Index >= 2000) { + if (!arcmsr_hbaC_wait_msgint_ready(pACB)) { printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ miscellaneous data' timeout \n", pACB->host->host_no); return false;
[PATCH 0/4] scsi: arcmsr: simplify hba_get_config routine
From: Ching Huang These patches are apply to Martin's 4.16/scsi-queue. patch 1: simplify arcmsr_hbaC_get_config function. patch 2: wait iop firmware ready before issue get_config command to iop. patch 3: simplify arcmsr_hbaE_get_config function. patch 4: simplify all arcmsr_hbaX_get_config routine by call a new get_adapter_config function ---
[PATCH 18/17] scsi: arcmsr: Fix report command result error when CHECK_CONDITION
From: Ching Huang Fix report command result error when CHECK_CONDITION. 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 2017-12-05 17:04:52.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 19:17:28.0 +0800 @@ -1205,7 +1205,7 @@ static void arcmsr_report_sense_info(str struct scsi_cmnd *pcmd = ccb->pcmd; struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; - pcmd->result = DID_OK << 16; + pcmd->result = (DID_OK << 16) | (CHECK_CONDITION << 1); if (sensebuffer) { int sense_data_length = sizeof(struct SENSE_DATA) < SCSI_SENSE_BUFFERSIZE @@ -1214,6 +1214,7 @@ static void arcmsr_report_sense_info(str memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; sensebuffer->Valid = 1; + pcmd->result |= (DRIVER_SENSE << 24); } }
[PATCH 17/17] scsi: arcmsr: Update driver version to v1.40.00.04-20171130
From: Ching Huang Update driver version to v1.40.00.04-20171130 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 2017-12-05 15:30:30.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 09:18:58.0 +0800 @@ -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.30.00.22-20151126" +#define ARCMSR_DRIVER_VERSION "v1.40.00.04-20171130" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH 16/17] scsi: arcmsr: Add driver module parameter msix_enable
From: Ching Huang Add module parameter msix_enable to has a chance to disable msix interrupt if between controller and system has msix INT compatible issue. 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 2017-12-05 16:59:58.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 17:04:52.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msix_enable = 1; +module_param(msix_enable, int, S_IRUGO); +MODULE_PARM_DESC(msix_enable, "Enable MSI-X interrupt(0 ~ 1), msix_enable=1(enable), =0(disable)"); + static int msi_enable = 1; module_param(msi_enable, int, S_IRUGO); MODULE_PARM_DESC(msi_enable, "Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); @@ -829,12 +833,15 @@ arcmsr_request_irq(struct pci_dev *pdev, unsigned long flags; int nvec, i; + if (msix_enable == 0) + goto msi_int0; nvec = pci_alloc_irq_vectors(pdev, 1, ARCMST_NUM_MSIX_VECTORS, PCI_IRQ_MSIX); if (nvec > 0) { pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { +msi_int0: if (msi_enable == 1) { nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); if (nvec == 1) {
[PATCH 15/17] scsi: arcmsr: Add driver module parameter msi_enable
From: Ching Huang Add module parameter msi_enable to has a chance to disable msi interrupt if between controller and system has msi INT compatible issue. 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 2017-12-05 11:44:36.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 16:59:58.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msi_enable = 1; +module_param(msi_enable, int, S_IRUGO); +MODULE_PARM_DESC(msi_enable, "Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); + static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; module_param(host_can_queue, int, S_IRUGO); MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default is 128"); @@ -831,11 +835,17 @@ arcmsr_request_irq(struct pci_dev *pdev, pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { - nvec = pci_alloc_irq_vectors(pdev, 1, 1, - PCI_IRQ_MSI | PCI_IRQ_LEGACY); + if (msi_enable == 1) { + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); + if (nvec == 1) { + dev_info(&pdev->dev, "msi enabled\n"); + goto msi_int1; + } + } + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); if (nvec < 1) return FAILED; - +msi_int1: flags = IRQF_SHARED; }
[PATCH 14/17] scsi: arcmsr: fix grammar error
From: Ching Huang fix grammar error. 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 2017-12-05 11:44:52.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:44:36.0 +0800 @@ -4453,7 +4453,7 @@ static int arcmsr_bus_reset(struct scsi_ if (acb->acb_flags & ACB_F_BUS_RESET) { long timeout; - pr_notice("arcmsr: there is an bus reset eh proceeding...\n"); + pr_notice("arcmsr: there is a bus reset eh proceeding...\n"); timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220 * HZ); if (timeout)
[PATCH 13/17] scsi: arcmsr: adjust some tab or white-space to make text alignment
From: Ching Huang adjust some tab or white-space to make text alignment 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 2017-12-05 15:28:50.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:29:38.0 +0800 @@ -50,35 +50,35 @@ struct device_attribute; #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 #define ARCMSR_MIN_OUTSTANDING_CMD 32 #define ARCMSR_DRIVER_VERSION "v1.30.00.22-20151126" -#define ARCMSR_SCSI_INITIATOR_ID 255 -#define ARCMSR_MAX_XFER_SECTORS 512 -#define ARCMSR_MAX_XFER_SECTORS_B 4096 -#define ARCMSR_MAX_XFER_SECTORS_C 304 -#define ARCMSR_MAX_TARGETID 17 -#define ARCMSR_MAX_TARGETLUN 8 +#define ARCMSR_SCSI_INITIATOR_ID 255 +#define ARCMSR_MAX_XFER_SECTORS512 +#define ARCMSR_MAX_XFER_SECTORS_B 4096 +#define ARCMSR_MAX_XFER_SECTORS_C 304 +#define ARCMSR_MAX_TARGETID17 +#define ARCMSR_MAX_TARGETLUN 8 #define ARCMSR_MAX_CMD_PERLUN 128 #define ARCMSR_DEFAULT_CMD_PERLUN 32 #define ARCMSR_MIN_CMD_PERLUN 1 -#define ARCMSR_MAX_QBUFFER 4096 -#define ARCMSR_DEFAULT_SG_ENTRIES 38 -#define ARCMSR_MAX_HBB_POSTQUEUE 264 +#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_HBE_DONEQUEUE 512 -#define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ -#define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#define ARCMSR_MAX_XFER_LEN0x26000 /* 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 +#define PCI_DEVICE_ID_ARECA_1880 0x1880 +#endif #ifndef PCI_DEVICE_ID_ARECA_1214 - #define PCI_DEVICE_ID_ARECA_12140x1214 +#define PCI_DEVICE_ID_ARECA_1214 0x1214 #endif #ifndef PCI_DEVICE_ID_ARECA_1203 - #define PCI_DEVICE_ID_ARECA_12030x1203 +#define PCI_DEVICE_ID_ARECA_1203 0x1203 #endif #ifndef PCI_DEVICE_ID_ARECA_1884 - #define PCI_DEVICE_ID_ARECA_18840x1884 +#define PCI_DEVICE_ID_ARECA_1884 0x1884 #endif #defineARCMSR_HOURS(1000 * 60 * 60 * 4) #defineARCMSR_MINUTES (1000 * 60 * 60) @@ -87,15 +87,15 @@ struct device_attribute; ** ** */ -#define ARC_SUCCESS 0 -#define ARC_FAILURE 1 +#define ARC_SUCCESS0 +#define ARC_FAILURE1 /* *** **split 64bits dma addressing *** */ -#define dma_addr_hi32(addr) (uint32_t) ((addr>>16)>>16) -#define dma_addr_lo32(addr) (uint32_t) (addr & 0x) +#define dma_addr_hi32(addr)(uint32_t) ((addr>>16)>>16) +#define dma_addr_lo32(addr)(uint32_t) (addr & 0x) /* *** **MESSAGE CONTROL CODE @@ -135,7 +135,7 @@ struct CMD_MESSAGE_FIELD #define FUNCTION_SAY_HELLO 0x0807 #define FUNCTION_SAY_GOODBYE 0x0808 #define FUNCTION_FLUSH_ADAPTER_CACHE 0x0809 -#define FUNCTION_GET_FIRMWARE_STATUS 0x080A +#define FUNCTION_GET_FIRMWARE_STATUS 0x080A #define FUNCTION_HARDWARE_RESET0x080B /* ARECA IO CONTROL CODE*/ #define ARCMSR_MESSAGE_READ_RQBUFFER \ @@ -166,18 +166,18 @@ struct CMD_MESSAGE_FIELD ** structure for holding DMA address data * */ -#define IS_DMA64 (sizeof(dma_addr_t) == 8) -#define IS_SG64_ADDR0x0100 /* bit24 */ +#define IS_DMA64 (sizeof(dma_addr_t) == 8) +#define IS_SG64_ADDR 0x0100 /* bit24 */ struct SG32ENTRY { - __le32 length; - __le32 address; + __le32
[PATCH 12/17] scsi: arcmsr: spin off duplicate code of timer init for message isr BH in arcmsr_probe and arcmsr_resume as a function
From: Ching Huang spin off duplicate code of timer init for message isr BH in arcmsr_probe and arcmsr_resume as a function arcmsr_init_get_devmap_timer 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 2017-12-05 11:45:34.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:45:06.0 +0800 @@ -857,6 +857,17 @@ out_free_irq: return FAILED; } +static void arcmsr_init_get_devmap_timer(struct AdapterControlBlock *pacb) +{ + INIT_WORK(&pacb->arcmsr_do_message_isr_bh, arcmsr_message_isr_bh_fn); + atomic_set(&pacb->rq_map_token, 16); + atomic_set(&pacb->ante_token_value, 16); + pacb->fw_flag = FW_NORMAL; + timer_setup(&pacb->eternal_timer, arcmsr_request_device_map, 0); + pacb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); + add_timer(&pacb->eternal_timer); +} + static void arcmsr_init_set_datetime_timer(struct AdapterControlBlock *pacb) { timer_setup(&pacb->refresh_timer, arcmsr_set_iop_datetime, 0); @@ -946,13 +957,7 @@ static int arcmsr_probe(struct pci_dev * if (arcmsr_request_irq(pdev, acb) == FAILED) goto scsi_host_remove; 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; - timer_setup(&acb->eternal_timer, arcmsr_request_device_map, 0); - acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); - add_timer(&acb->eternal_timer); + arcmsr_init_get_devmap_timer(acb); if (set_date_time) arcmsr_init_set_datetime_timer(acb); if(arcmsr_alloc_sysfs_attr(acb)) @@ -1043,13 +1048,7 @@ static int arcmsr_resume(struct pci_dev 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; - timer_setup(&acb->eternal_timer, arcmsr_request_device_map, 0); - acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); - add_timer(&acb->eternal_timer); + arcmsr_init_get_devmap_timer(acb); if (set_date_time) arcmsr_init_set_datetime_timer(acb); return 0;
[PATCH 11/17] scsi: arcmsr: fix clear doorbell queue on ACB_ADAPTER_TYPE_B controller
From: Ching Huang fix clear doorbell queue on ACB_ADAPTER_TYPE_B controller 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 2017-12-05 11:45:52.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:45:34.0 +0800 @@ -4196,10 +4196,19 @@ static void arcmsr_clear_doorbell_queue_ case ACB_ADAPTER_TYPE_B: { struct MessageUnit_B *reg = acb->pmuB; - /*clear interrupt and message state*/ - writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); + uint32_t outbound_doorbell, i; + writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell); /* let IOP know data has been read */ + for(i=0; i < 200; i++) { + msleep(20); + outbound_doorbell = readl(reg->iop2drv_doorbell); + if( outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { + writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); + writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell); + } else + break; + } } break; case ACB_ADAPTER_TYPE_C: {
[PATCH 10/17] scsi: arcmsr: add a function arcmsr_set_iop_datetime and driver option set_date_time to set date and time to firmware
From: Ching Huang add a function arcmsr_set_iop_datetime and driver option set_date_time to set date and time to firmware 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 2017-12-05 15:27:04.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:27:32.0 +0800 @@ -80,6 +80,8 @@ struct device_attribute; #ifndef PCI_DEVICE_ID_ARECA_1884 #define PCI_DEVICE_ID_ARECA_18840x1884 #endif +#defineARCMSR_HOURS(1000 * 60 * 60 * 4) +#defineARCMSR_MINUTES (1000 * 60 * 60) /* ** ** @@ -280,6 +282,7 @@ struct FIRMWARE_INFO #define ARCMSR_MESSAGE_FLUSH_CACHE0x00050008 /* (ARCMSR_INBOUND_MESG0_START_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ #define ARCMSR_MESSAGE_START_BGRB0x00060008 +#define ARCMSR_MESSAGE_SYNC_TIMER 0x00080008 #define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008 #define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008 #define ARCMSR_MESSAGE_ACTIVE_EOI_MODE 0x0018 @@ -837,6 +840,7 @@ struct AdapterControlBlock uint32_tmaxOutstanding; int vector_count; uint32_tmaxFreeCCB; + struct timer_list refresh_timer; uint32_tdoneq_index; uint32_tccbsize; uint32_tin_doorbell; diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:06.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:45:52.0 +0800 @@ -83,6 +83,10 @@ static int cmd_per_lun = ARCMSR_DEFAULT_ module_param(cmd_per_lun, int, S_IRUGO); MODULE_PARM_DESC(cmd_per_lun, " device queue depth(1 ~ 128), default is 32"); +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"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12 @@ -125,6 +129,7 @@ static const char *arcmsr_info(struct Sc 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 void arcmsr_set_iop_datetime(struct timer_list *); static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) { if (queue_depth > ARCMSR_MAX_CMD_PERLUN) @@ -852,6 +857,13 @@ out_free_irq: return FAILED; } +static void arcmsr_init_set_datetime_timer(struct AdapterControlBlock *pacb) +{ + timer_setup(&pacb->refresh_timer, arcmsr_set_iop_datetime, 0); + pacb->refresh_timer.expires = jiffies + msecs_to_jiffies(60 * 1000); + add_timer(&pacb->refresh_timer); +} + static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct Scsi_Host *host; @@ -941,11 +953,15 @@ static int arcmsr_probe(struct pci_dev * timer_setup(&acb->eternal_timer, arcmsr_request_device_map, 0); acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); add_timer(&acb->eternal_timer); + if (set_date_time) + arcmsr_init_set_datetime_timer(acb); if(arcmsr_alloc_sysfs_attr(acb)) goto out_free_sysfs; scsi_scan_host(host); return 0; out_free_sysfs: + if (set_date_time) + del_timer_sync(&acb->refresh_timer); del_timer_sync(&acb->eternal_timer); flush_work(&acb->arcmsr_do_message_isr_bh); arcmsr_stop_adapter_bgrb(acb); @@ -988,6 +1004,8 @@ 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); + if (set_date_time) + del_timer_sync(&acb->refresh_timer); flush_work(&acb->arcmsr_do_message_isr_bh); arcmsr_stop_adapter_bgrb(acb); arcmsr_flush_adapter_cache(acb); @@ -1032,6 +1050,8 @@ static int arcmsr_resume(struct pci_dev timer_setup(&acb->eternal_timer, arcmsr_request_device_map, 0); acb->eternal_timer.expires = jiffies + msecs_to_jiffies(6 * HZ); add_timer(&acb->eternal_timer); + if (set_date_time) + arcmsr_init_set_datetime_timer(acb); return 0; controller_stop: arcmsr_stop_adapter_bgrb(acb); @@ -1422,6 +1442,8 @@ static void arcmsr_remove(struct pci_dev scsi_remove_host(host); flush_work(&acb->
[PATCH 9/17] scsi: arcmsr: add ACB_F_MSG_GET_CONFIG to acb->acb_flags for for message interrupt checking before schedule work for get device map
From: Ching Huang add ACB_F_MSG_GET_CONFIG to acb->acb_flags for for message interrupt checking before schedule work for get device map 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 2017-12-05 15:26:32.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:27:04.0 +0800 @@ -782,6 +782,7 @@ struct AdapterControlBlock /* iop init */ #define ACB_F_ABORT 0x0200 #define ACB_F_FIRMWARE_TRAP 0x0400 + #define ACB_F_MSG_GET_CONFIG0x1000 struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */ struct list_headccb_free_list; diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:18.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:06.0 +0800 @@ -743,6 +743,7 @@ static void arcmsr_message_isr_bh_fn(str struct scsi_device *psdev; char diff, temp; + acb->acb_flags &= ~ACB_F_MSG_GET_CONFIG; switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: { struct MessageUnit_A __iomem *reg = acb->pmuA; @@ -2328,7 +2329,8 @@ static void arcmsr_hbaA_message_isr(stru struct MessageUnit_A __iomem *reg = acb->pmuA; /*clear interrupt and message state*/ writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, ®->outbound_intstatus); - schedule_work(&acb->arcmsr_do_message_isr_bh); + if (acb->acb_flags & ACB_F_MSG_GET_CONFIG) + schedule_work(&acb->arcmsr_do_message_isr_bh); } static void arcmsr_hbaB_message_isr(struct AdapterControlBlock *acb) { @@ -2336,7 +2338,8 @@ static void arcmsr_hbaB_message_isr(stru /*clear interrupt and message state*/ writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell); - schedule_work(&acb->arcmsr_do_message_isr_bh); + if (acb->acb_flags & ACB_F_MSG_GET_CONFIG) + schedule_work(&acb->arcmsr_do_message_isr_bh); } /* ** @@ -2352,7 +2355,8 @@ static void arcmsr_hbaC_message_isr(stru struct MessageUnit_C __iomem *reg = acb->pmuC; /*clear interrupt and message state*/ writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, ®->outbound_doorbell_clear); - schedule_work(&acb->arcmsr_do_message_isr_bh); + if (acb->acb_flags & ACB_F_MSG_GET_CONFIG) + schedule_work(&acb->arcmsr_do_message_isr_bh); } static void arcmsr_hbaD_message_isr(struct AdapterControlBlock *acb) @@ -2361,7 +2365,8 @@ static void arcmsr_hbaD_message_isr(stru writel(ARCMSR_ARC1214_IOP2DRV_MESSAGE_CMD_DONE, reg->outbound_doorbell); readl(reg->outbound_doorbell); - schedule_work(&acb->arcmsr_do_message_isr_bh); + if (acb->acb_flags & ACB_F_MSG_GET_CONFIG) + schedule_work(&acb->arcmsr_do_message_isr_bh); } static void arcmsr_hbaE_message_isr(struct AdapterControlBlock *acb) @@ -2369,7 +2374,8 @@ static void arcmsr_hbaE_message_isr(stru struct MessageUnit_E __iomem *reg = acb->pmuE; writel(0, ®->host_int_status); - schedule_work(&acb->arcmsr_do_message_isr_bh); + if (acb->acb_flags & ACB_F_MSG_GET_CONFIG) + schedule_work(&acb->arcmsr_do_message_isr_bh); } static int arcmsr_hbaA_handle_isr(struct AdapterControlBlock *acb) @@ -3826,6 +3832,7 @@ static void arcmsr_hbaA_request_device_m return; } writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); + acb->acb_flags |= ACB_F_MSG_GET_CONFIG; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); } return; @@ -3848,6 +3855,7 @@ static void arcmsr_hbaB_request_device_m return; } writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell); + acb->acb_flags |= ACB_F_MSG_GET_CONFIG; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); } return; @@ -3871,6 +3879,7 @@ static void arcmsr_hbaC_request_device_m } writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); writel(ARCMSR_HBCMU_DRV2IOP_MESSAGE_CMD_DONE, ®->inbound_doorbell); + acb->acb_flags |= ACB_F_MSG_GET_CONFIG; mod_timer(&acb->eternal_timer, jiffies + msecs_to_jiffies(6 * HZ)); } return; @@ -3900,6 +3909,7 @@ sta
[PATCH 8/17] scsi: arcmsr: add driver option cmd_per_lun to set host->cmd_per_lun value by user
From: Ching Huang add driver option cmd_per_lun to set host->cmd_per_lun value by user 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 2017-12-05 15:26:06.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:26:32.0 +0800 @@ -56,7 +56,9 @@ struct device_attribute; #define ARCMSR_MAX_XFER_SECTORS_C 304 #define ARCMSR_MAX_TARGETID 17 #define ARCMSR_MAX_TARGETLUN 8 -#define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD +#define ARCMSR_MAX_CMD_PERLUN 128 +#define ARCMSR_DEFAULT_CMD_PERLUN 32 +#define ARCMSR_MIN_CMD_PERLUN 1 #define ARCMSR_MAX_QBUFFER 4096 #define ARCMSR_DEFAULT_SG_ENTRIES 38 #define ARCMSR_MAX_HBB_POSTQUEUE 264 diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:30.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:18.0 +0800 @@ -79,6 +79,10 @@ static int host_can_queue = ARCMSR_DEFAU module_param(host_can_queue, int, S_IRUGO); MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default is 128"); +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"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12 @@ -141,7 +145,7 @@ static struct scsi_host_template arcmsr_ .this_id= ARCMSR_SCSI_INITIATOR_ID, .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, .max_sectors= ARCMSR_MAX_XFER_SECTORS_C, - .cmd_per_lun= ARCMSR_MAX_CMD_PERLUN, + .cmd_per_lun= ARCMSR_DEFAULT_CMD_PERLUN, .use_clustering = ENABLE_CLUSTERING, .shost_attrs= arcmsr_host_attrs, .no_write_same = 1, @@ -884,7 +888,9 @@ static int arcmsr_probe(struct pci_dev * if ((host_can_queue < ARCMSR_MIN_OUTSTANDING_CMD) || (host_can_queue > ARCMSR_MAX_OUTSTANDING_CMD)) host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; host->can_queue = host_can_queue; /* max simultaneous cmds */ - host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; + if ((cmd_per_lun < ARCMSR_MIN_CMD_PERLUN) || (cmd_per_lun > ARCMSR_MAX_CMD_PERLUN)) + cmd_per_lun = ARCMSR_DEFAULT_CMD_PERLUN; + host->cmd_per_lun = cmd_per_lun; host->this_id = ARCMSR_SCSI_INITIATOR_ID; host->unique_id = (bus << 8) | dev_fun; pci_set_drvdata(pdev, host);
[PATCH 7/17] scsi: arcmsr: replace constant ARCMSR_MAX_OUTSTANDING_CMD by variable acb->maxOutstanding that was determined by user
From: Ching Huang replace constant ARCMSR_MAX_OUTSTANDING_CMD by variable acb->maxOutstanding that was determined by user 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 2017-12-05 11:46:50.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:30.0 +0800 @@ -1315,7 +1315,7 @@ static void arcmsr_done4abort_postqueue( /*clear and abort all outbound posted Q*/ writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ while(((flag_ccb = readl(®->outbound_queueport)) != 0x) - && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { + && (i++ < acb->maxOutstanding)) { 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; @@ -1345,7 +1345,7 @@ static void arcmsr_done4abort_postqueue( break; case ACB_ADAPTER_TYPE_C: { struct MessageUnit_C __iomem *reg = acb->pmuC; - while ((readl(®->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { + while ((readl(®->host_int_status) & ARCMSR_HBCMU_OUTBOUND_POSTQUEUE_ISR) && (i++ < acb->maxOutstanding)) { /*need to do*/ flag_ccb = readl(®->outbound_queueport_low); ccb_cdb_phy = (flag_ccb & 0xFFF0); @@ -1421,7 +1421,7 @@ static void arcmsr_remove(struct pci_dev acb->acb_flags |= ACB_F_SCSISTOPADAPTER; acb->acb_flags &= ~ACB_F_IOP_INITED; - for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++){ + for (poll_count = 0; poll_count < acb->maxOutstanding; poll_count++){ if (!atomic_read(&acb->ccboutstandingcount)) break; arcmsr_interrupt(acb);/* FIXME: need spinlock */
[PATCH 6/17] scsi: arcmsr: add driver option host_can_queue to set host->can_queue value by user
From: Ching Huang add driver option host_can_queue to set host->can_queue value by user. It's value expands up to 1024 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 2017-12-05 15:25:06.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:25:36.0 +0800 @@ -47,6 +47,8 @@ struct device_attribute; /*The limit of outstanding scsi command that firmware can handle*/ #define ARCMSR_MAX_FREECCB_NUM 1024 #define ARCMSR_MAX_OUTSTANDING_CMD 1024 +#define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 +#define ARCMSR_MIN_OUTSTANDING_CMD 32 #define ARCMSR_DRIVER_VERSION "v1.30.00.22-20151126" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512 diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:47:04.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:46:50.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; +module_param(host_can_queue, int, S_IRUGO); +MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default is 128"); + #defineARCMSR_SLEEPTIME10 #defineARCMSR_RETRYCOUNT 12 @@ -133,7 +137,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_OUTSTANDING_CMD, + .can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD, .this_id= ARCMSR_SCSI_INITIATOR_ID, .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, .max_sectors= ARCMSR_MAX_XFER_SECTORS_C, @@ -877,7 +881,9 @@ 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_OUTSTANDING_CMD; + if ((host_can_queue < ARCMSR_MIN_OUTSTANDING_CMD) || (host_can_queue > ARCMSR_MAX_OUTSTANDING_CMD)) + host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; + host->can_queue = host_can_queue; /* 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; @@ -3234,11 +3240,11 @@ static bool arcmsr_get_firmware_spec(str default: break; } - if (acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD) - acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD; + acb->maxOutstanding = acb->firm_numbers_queue - 1; + if (acb->host->can_queue >= acb->firm_numbers_queue) + acb->host->can_queue = acb->maxOutstanding; else - acb->maxOutstanding = acb->firm_numbers_queue - 1; - acb->host->can_queue = acb->maxOutstanding; + acb->maxOutstanding = acb->host->can_queue; acb->maxFreeCCB = acb->host->can_queue; if (acb->maxFreeCCB < ARCMSR_MAX_FREECCB_NUM) acb->maxFreeCCB += 64;
[PATCH 5/17] scsi: arcmsr: replace constant ARCMSR_MAX_FREECCB_NUM by variable
From: Ching Huang replace constant ARCMSR_MAX_FREECCB_NUM by variable acb->maxFreeCCB that was got from firmware 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 2017-12-05 15:24:16.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:25:06.0 +0800 @@ -831,6 +831,7 @@ struct AdapterControlBlock atomic_tante_token_value; uint32_tmaxOutstanding; int vector_count; + uint32_tmaxFreeCCB; uint32_tdoneq_index; uint32_tccbsize; uint32_tin_doorbell; diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:47:16.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:47:04.0 +0800 @@ -688,7 +688,7 @@ static int arcmsr_alloc_ccb_pool(struct acb->host->max_sectors = max_xfer_len/512; acb->host->sg_tablesize = max_sg_entrys; roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32); - acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM; + acb->uncache_size = roundup_ccbsize * acb->maxFreeCCB; dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL); if(!dma_coherent){ printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error\n", acb->host->host_no); @@ -700,7 +700,7 @@ static int arcmsr_alloc_ccb_pool(struct acb->ccbsize = roundup_ccbsize; ccb_tmp = dma_coherent; acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle; - for(i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++){ + for(i = 0; i < acb->maxFreeCCB; i++){ cdb_phyaddr = dma_coherent_handle + offsetof(struct CommandControlBlock, arcmsr_cdb); switch (acb->adapter_type) { case ACB_ADAPTER_TYPE_A: @@ -1427,7 +1427,7 @@ static void arcmsr_remove(struct pci_dev arcmsr_abort_allcmd(acb); arcmsr_done4abort_postqueue(acb); - for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { + for (i = 0; i < acb->maxFreeCCB; i++) { struct CommandControlBlock *ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START) { ccb->startdone = ARCMSR_CCB_ABORTED; @@ -3239,6 +3239,9 @@ static bool arcmsr_get_firmware_spec(str else acb->maxOutstanding = acb->firm_numbers_queue - 1; acb->host->can_queue = acb->maxOutstanding; + acb->maxFreeCCB = acb->host->can_queue; + if (acb->maxFreeCCB < ARCMSR_MAX_FREECCB_NUM) + acb->maxFreeCCB += 64; return rtn; } @@ -4261,7 +4264,7 @@ static uint8_t arcmsr_iop_reset(struct A rtnval = arcmsr_abort_allcmd(acb); /* clear all outbound posted Q */ arcmsr_done4abort_postqueue(acb); - for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { + for (i = 0; i < acb->maxFreeCCB; i++) { ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START) { scsi_dma_unmap(ccb->pcmd); @@ -4369,7 +4372,7 @@ static int arcmsr_abort(struct scsi_cmnd } intmask_org = arcmsr_disable_outbound_ints(acb); - for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { + for (i = 0; i < acb->maxFreeCCB; i++) { struct CommandControlBlock *ccb = acb->pccb_pool[i]; if (ccb->startdone == ARCMSR_CCB_START && ccb->pcmd == cmd) { ccb->startdone = ARCMSR_CCB_ABORTED;
[PATCH 4/17] scsi: arcmsr: enable host controller command queueu up to 1024
From: Ching Huang update ARCMSR_MAX_OUTSTANDING_CMD and ARCMSR_MAX_FREECCB_NUM to 1024 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 2017-08-04 11:19:22.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-12-05 15:24:16.0 +0800 @@ -45,13 +45,8 @@ #include struct device_attribute; /*The limit of outstanding scsi command that firmware can handle*/ -#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_MAX_FREECCB_NUM 1024 +#define ARCMSR_MAX_OUTSTANDING_CMD 1024 #define ARCMSR_DRIVER_VERSION "v1.30.00.22-20151126" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS 512
[PATCH 3/17] scsi: arcmsr: add codes for ACB_ADAPTER_TYPE_E to support new adapter ARC-1884
From: Ching Huang add codes for ACB_ADAPTER_TYPE_E to support new adapter ARC-1884 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 2017-08-03 18:54:46.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-08-04 11:19:22.0 +0800 @@ -65,6 +65,7 @@ struct device_attribute; #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_ARC1214_POSTQUEUE 256 #define ARCMSR_MAX_ARC1214_DONEQUEUE 257 +#define ARCMSR_MAX_HBE_DONEQUEUE 512 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ #define ARCMSR_CDB_SG_PAGE_LENGTH 256 #define ARCMST_NUM_MSIX_VECTORS4 @@ -77,6 +78,9 @@ struct device_attribute; #ifndef PCI_DEVICE_ID_ARECA_1203 #define PCI_DEVICE_ID_ARECA_12030x1203 #endif +#ifndef PCI_DEVICE_ID_ARECA_1884 + #define PCI_DEVICE_ID_ARECA_18840x1884 +#endif /* ** ** @@ -405,6 +409,31 @@ struct FIRMWARE_INFO /*ARCMSR_HBAMU_MESSAGE_FIRMWARE_OK*/ #define ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK 0x8000 #define ARCMSR_ARC1214_OUTBOUND_LIST_INTERRUPT_CLEAR 0x0001 +/* +*** +**SPEC. for Areca Type E adapter +*** +*/ +#define ARCMSR_SIGNATURE_1884 0x188417D3 + +#define ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK 0x0002 +#define ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK 0x0004 +#define ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE 0x0008 + +#define ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK 0x0002 +#define ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK 0x0004 +#define ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE 0x0008 + +#define ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK 0x8000 + +#define ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR 0x0001 +#define ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR0x0008 +#define ARCMSR_HBEMU_ALL_INTMASKENABLE 0x0009 + +/* ARC-1884 doorbell sync */ +#define ARCMSR_HBEMU_DOORBELL_SYNC 0x100 +#define ARCMSR_ARC188X_RESET_ADAPTER 0x0004 +#define ARCMSR_ARC1884_DiagWrite_ENABLE0x0080 /* *** **ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) @@ -614,6 +643,88 @@ struct MessageUnit_D { u32 __iomem *msgcode_rwbuffer; /* 0x2200 */ }; /* +* +** Messaging Unit (MU) of Type E processor(LSI) +* +*/ +struct MessageUnit_E{ + uint32_tiobound_doorbell; /* 0003*/ + uint32_twrite_sequence_3xxx;/*0004 0007*/ + uint32_thost_diagnostic_3xxx; /*0008 000B*/ + uint32_tposted_outbound_doorbell; /*000C 000F*/ + uint32_tmaster_error_attribute; /*0010 0013*/ + uint32_tmaster_error_address_low; /*0014 0017*/ + uint32_tmaster_error_address_high; /*0018 001B*/ + uint32_thcb_size; /*001C 001F*/ + uint32_tinbound_doorbell; /*0020 0023*/ + uint32_tdiagnostic_rw_data; /*0024 0027*/ + uint32_tdiagnostic_rw_address_low; /*0028 002B*/ + uint32_tdiagnostic_rw_address_high; /*002C 002F*/ + uint32_thost_int_status;/*0030 0033*/ + uint32_thost_int_mask; /*0034 0037*/ + uint32_tdcr_data; /*0038 003B*/ + uint32_tdcr_address;/*003C 003F*/ + uint32_tinbound_queueport; /*0040 0043*/ + uint32_toutbound_queueport; /*0044 0047*/ + uint32_thcb_pci_address_low;/*0048 004B*/ + uint32_thcb_pci_address_high; /*004C 004F*/ + uint32_tiop_int_status; /*0050 0053*/ + uint32_tiop_int_mask; /*0054 0057*/ + uint32_tiop_inbound_queue_port; /*0058 005B*/ + uint32_tiop_outbound_queue_port;/*005C 005F*/ + uint32_tinbound_free_list_index;/*0060 0063*/ + uint32_tinbound_post_list_index;/*0064 0067*/ + uint32_t
[PATCH 2/17] scsi: arcmsr: simplify arcmsr_iop_init function
From: Ching Huang simplify arcmsr_iop_init 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 2017-12-05 11:47:40.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:47:28.0 +0800 @@ -3671,6 +3671,39 @@ static void arcmsr_hardware_reset(struct msleep(1000); return; } + +static bool arcmsr_reset_in_progress(struct AdapterControlBlock *acb) +{ + bool rtn = true; + + switch(acb->adapter_type) { + case ACB_ADAPTER_TYPE_A:{ + struct MessageUnit_A __iomem *reg = acb->pmuA; + rtn = ((readl(®->outbound_msgaddr1) & + ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) ? true : false; + } + break; + case ACB_ADAPTER_TYPE_B:{ + struct MessageUnit_B *reg = acb->pmuB; + rtn = ((readl(reg->iop2drv_doorbell) & + ARCMSR_MESSAGE_FIRMWARE_OK) == 0) ? true : false; + } + break; + case ACB_ADAPTER_TYPE_C:{ + struct MessageUnit_C __iomem *reg = acb->pmuC; + rtn = (readl(®->host_diagnostic) & 0x04) ? true : false; + } + break; + case ACB_ADAPTER_TYPE_D:{ + struct MessageUnit_D *reg = acb->pmuD; + rtn = ((readl(reg->sample_at_reset) & 0x80) == 0) ? + true : false; + } + break; + } + return rtn; +} + static void arcmsr_iop_init(struct AdapterControlBlock *acb) { uint32_t intmask_org; @@ -3725,197 +3758,55 @@ static uint8_t arcmsr_iop_reset(struct A static int arcmsr_bus_reset(struct scsi_cmnd *cmd) { struct AdapterControlBlock *acb; - uint32_t intmask_org, outbound_doorbell; int retry_count = 0; int rtn = FAILED; acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; - printk(KERN_ERR "arcmsr: executing bus reset eh.num_resets = %d, num_aborts = %d \n", acb->num_resets, acb->num_aborts); + pr_notice("arcmsr: executing bus reset eh.num_resets = %d," + " num_aborts = %d \n", acb->num_resets, acb->num_aborts); acb->num_resets++; - switch(acb->adapter_type){ - case ACB_ADAPTER_TYPE_A:{ - if (acb->acb_flags & ACB_F_BUS_RESET){ - long timeout; - printk(KERN_ERR "arcmsr: there is an bus reset eh proceeding...\n"); - timeout = wait_event_timeout(wait_q, (acb->acb_flags & ACB_F_BUS_RESET) == 0, 220*HZ); - if (timeout) { - return SUCCESS; - } - } - acb->acb_flags |= ACB_F_BUS_RESET; - if (!arcmsr_iop_reset(acb)) { - struct MessageUnit_A __iomem *reg; - reg = acb->pmuA; - arcmsr_hardware_reset(acb); - acb->acb_flags &= ~ACB_F_IOP_INITED; -sleep_again: - ssleep(ARCMSR_SLEEPTIME); - if ((readl(®->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) { - printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count); - if (retry_count > ARCMSR_RETRYCOUNT) { - acb->fw_flag = FW_DEADLOCK; - printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no); - return FAILED; - } - retry_count++; - goto sleep_again; - } - acb->acb_flags |= ACB_F_IOP_INITED; - /* disable all outbound interrupt */ - intmask_org = arcmsr_disable_outbound_ints(acb); - 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 interrupt
[PATCH 1/17] scsi: arcmsr: redefine ACB_ADAPTER_TYPE_A, _B, _C, _D and subsequent changes.
From: Ching Huang redefine ACB_ADAPTER_TYPE_A, _B, _C, _D and subsequent changes. 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 2017-12-05 10:45:50.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-08-03 18:54:46.0 +0800 @@ -621,10 +621,10 @@ struct MessageUnit_D { struct AdapterControlBlock { uint32_t adapter_type;/* adapter A,B. */ - #define ACB_ADAPTER_TYPE_A0x0001/* hba I IOP */ - #define ACB_ADAPTER_TYPE_B0x0002/* hbb M IOP */ - #define ACB_ADAPTER_TYPE_C0x0004/* hbc P IOP */ - #define ACB_ADAPTER_TYPE_D0x0008/* hbd A IOP */ + #define ACB_ADAPTER_TYPE_A 0x /* hba I IOP */ + #define ACB_ADAPTER_TYPE_B 0x0001 /* hbb M IOP */ + #define ACB_ADAPTER_TYPE_C 0x0002 /* hbc L IOP */ + #define ACB_ADAPTER_TYPE_D 0x0003 /* hbd M IOP */ u32 roundup_ccbsize; struct pci_dev *pdev; struct Scsi_Host * host; diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 10:45:30.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-12-05 11:47:40.0 +0800 @@ -1785,7 +1785,7 @@ arcmsr_Read_iop_rqbuffer_data(struct Ada uint8_t __iomem *iop_data; uint32_t iop_len; - if (acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) + if (acb->adapter_type > ACB_ADAPTER_TYPE_B) return arcmsr_Read_iop_rqbuffer_in_DWORD(acb, prbuffer); iop_data = (uint8_t __iomem *)prbuffer->data; iop_len = readl(&prbuffer->data_len); @@ -1871,7 +1871,7 @@ arcmsr_write_ioctldata2iop(struct Adapte uint8_t __iomem *iop_data; int32_t allxfer_len = 0; - if (acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) { + if (acb->adapter_type > ACB_ADAPTER_TYPE_B) { arcmsr_write_ioctldata2iop_in_DWORD(acb); return; }
[PATCH 0/17] scsi: arcmsr: add some driver options and support new adapter ARC-1884
From: Ching Huang Hi Martin, Due to 4.16/scsi-queue conflict with 4.15-rc1, so I resubmit these patches again. The following patches apply to Linus' 4.15-rc1 tree. Patch 1: redefine ACB_ADAPTER_TYPE_A, _B, _C, _D and subsequent changes. Patch 2: simplify arcmsr_iop_init function. Patch 3: add codes for ACB_ADAPTER_TYPE_E to support new adapter ARC-1884 Patch 4. update ARCMSR_MAX_OUTSTANDING_CMD and ARCMSR_MAX_FREECCB_NUM to 1024 Patch 5: replace constant ARCMSR_MAX_FREECCB_NUM by variable acb->maxFreeCCB that was got from firmware. Patch 6: add driver option host_can_queue to set host->can_queue value by user. It's value expands up to 1024. Patch 7: replace constant ARCMSR_MAX_OUTSTANDING_CMD by variable acb->maxOutstanding that was determined by user. Patch 8: add driver option cmd_per_lun to set host->cmd_per_lun value by user. Patch 9: add ACB_F_MSG_GET_CONFIG to acb->acb_flags for for message interrupt checking before schedule work for get device map. Patch 10: add a function arcmsr_set_iop_datetime and driver option set_date_time to set date and time to firmware. Patch 11: fix clear doorbell queue on ACB_ADAPTER_TYPE_B controller. Patch 12: spin off duplicate code of timer init for message isr BH in arcmsr_probe and arcmsr_resume as a function arcmsr_init_get_devmap_timer Patch 13: adjust some tab or white-space to make text alignment. Patch 14: fix grammar error. Patch 15: Add module parameter msi_enable to has a chance to disable msi interrupt if it does not work properly. Patch 16: Add module parameter msix_enable to has a chance to disable msix interrupt if it does not work properly. Patch 17: update driver version to v1.40.00.04-20171130 ---
Re: [PATCH v2 1/3] scsi: arcmsr: Add driver module parameter msi_enable
On Tue, 2017-11-28 at 05:58 -0800, Christoph Hellwig wrote: > On Tue, Nov 28, 2017 at 09:28:44AM +0800, Ching Huang wrote: > > From: Ching Huang > > > > Add module parameter msi_enable to has a chance to disable msi interrupt if > > between controller and system has > > msi INT compatible issue. > > If there is a system issue the system will need a quirk, and not every > driver. Yeah, but hardware compatibility is hard to clarify. This solution can make both happy.
[PATCH v2 3/3] scsi: arcmsr: Update driver version to v1.40.00.03-20171124
From: Ching Huang Update driver version to v1.40.00.03-20171124 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 2017-11-23 14:29:46.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-11-24 12:07:00.0 +0800 @@ -54,7 +54,7 @@ struct device_attribute; #endif #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 #define ARCMSR_MIN_OUTSTANDING_CMD 32 -#define ARCMSR_DRIVER_VERSION "v1.40.00.02-20171011" +#define ARCMSR_DRIVER_VERSION "v1.40.00.03-20171124" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH v2 2/3] scsi: arcmsr: Add driver module parameter msix_enable
From: Ching Huang Add module parameter msix_enable to has a chance to disable msix interrupt if between controller and system has msix INT compatible issue. 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 2017-11-24 15:16:20.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-24 15:17:46.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msix_enable = 1; +module_param(msix_enable, int, S_IRUGO); +MODULE_PARM_DESC(msix_enable, "Enable MSI-X interrupt(0 ~ 1), msix_enable=1(enable), =0(disable)"); + static int msi_enable = 1; module_param(msi_enable, int, S_IRUGO); MODULE_PARM_DESC(msi_enable, "Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); @@ -829,12 +833,15 @@ arcmsr_request_irq(struct pci_dev *pdev, unsigned long flags; int nvec, i; + if (msix_enable == 0) + goto msi_int0; nvec = pci_alloc_irq_vectors(pdev, 1, ARCMST_NUM_MSIX_VECTORS, PCI_IRQ_MSIX); if (nvec > 0) { pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { +msi_int0: if (msi_enable == 1) { nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); if (nvec == 1) {
[PATCH v2 1/3] scsi: arcmsr: Add driver module parameter msi_enable
From: Ching Huang Add module parameter msi_enable to has a chance to disable msi interrupt if between controller and system has msi INT compatible issue. 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 2017-11-23 14:29:26.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-24 15:16:20.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msi_enable = 1; +module_param(msi_enable, int, S_IRUGO); +MODULE_PARM_DESC(msi_enable, "Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); + static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; module_param(host_can_queue, int, S_IRUGO); MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default is 128"); @@ -831,11 +835,17 @@ arcmsr_request_irq(struct pci_dev *pdev, pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { - nvec = pci_alloc_irq_vectors(pdev, 1, 1, - PCI_IRQ_MSI | PCI_IRQ_LEGACY); + if (msi_enable == 1) { + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); + if (nvec == 1) { + dev_info(&pdev->dev, "msi enabled\n"); + goto msi_int1; + } + } + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); if (nvec < 1) return FAILED; - +msi_int1: flags = IRQF_SHARED; }
[PATCH v2 0/3] scsi: arcmsr: add driver module parameter - msi_enable, msix_enable
From: Ching Huang The following patches apply to james' kernel/git/jejb/scsi.git/tree/?h=misc and martin's kernel/git/mkp/scsi.git/tree/?h=4.16/scsi-queue Patch 1: Add module parameter msi_enable to has a chance to disable msi interrupt if controller has msi INT compatible issue. Patch 2: Add module parameter msix_enable to has a chance to disable msix interrupt if controller has msix INT compatible issue. Patch 3: Update driver version to v1.40.00.03-20171124 ---
Re: [PATCH 1/3] scsi: arcmsr: Add driver module parameter msi_enable
On Fri, 2017-11-24 at 04:45 +0800, Ching Huang wrote: > Hello Dan, > > On Thu, 2017-11-23 at 13:44 +0300, Dan Carpenter wrote: > > On Thu, Nov 23, 2017 at 09:27:19AM +0800, Ching Huang wrote: > > > From: Ching Huang > > > > > > Add module parameter msi_enable to has a chance to disable msi interrupt > > > if it does not work properly. > > > > > > 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.c2017-11-23 14:29:26.0 > > > +0800 > > > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c2017-11-23 16:02:28.0 > > > +0800 > > > @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 > > > MODULE_LICENSE("Dual BSD/GPL"); > > > MODULE_VERSION(ARCMSR_DRIVER_VERSION); > > > > > > +static int msi_enable = 1; > > > +module_param(msi_enable, int, S_IRUGO); > > ^^^ > > checkpatch.pl will complain that this should be 0444 > S_IRUGO value is 00444, defined in -> . > A. It will be not a issue. > > > > > +MODULE_PARM_DESC(msi_enable, " Enable MSI interrupt(0 ~ 1), > > > msi_enable=1(enable), =0(disable)"); > > ^ > > Remove the extra space > OK > > > > > + > > > static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; > > > module_param(host_can_queue, int, S_IRUGO); > > > MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), > > > default is 128"); > > > @@ -831,11 +835,15 @@ arcmsr_request_irq(struct pci_dev *pdev, > > > pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); > > > flags = 0; > > > } else { > > > - nvec = pci_alloc_irq_vectors(pdev, 1, 1, > > > - PCI_IRQ_MSI | PCI_IRQ_LEGACY); > > > + if (msi_enable == 1) > > > + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); > > > + else > > > + nvec = pci_alloc_irq_vectors(pdev, 1, 1, > > > PCI_IRQ_LEGACY); > > > if (nvec < 1) > > > return FAILED; > > > > I feel like we should try PCI_IRQ_MSI then if it fails we could fall > > back to PCI_IRQ_LEGACY. Originally, it worked like this and now it just > > fails unless you toggle the module param. It's a regression. > update as below > --- > unsigned int irq_flag; > irq_flag = PCI_IRQ_LEGACY; > if (msi_enable == 1) > irq_flag |= PCI_IRQ_MSI; > nvec = pci_alloc_irq_vectors(pdev, 1, 1, irq_flag); > > > > > > + if (msi_enable == 1) > > > + pr_info("arcmsr%d: msi enabled\n", acb->host->host_no); > > > > This printk could be improved. Use dev_info(&pdev->dev, for a start. > > I know that the other prints don't use this, but we could use it one > > time then slowly add more users until more are using dev_info() than > > pr_info() and then someone will decide to clean up the old users. > update as below > --- > if (msi_enable == 1) > dev_info(&pdev->dev, "msi enabled\n"); > > > > > regards, > > dan carpenter > > > Dan,. This new patch apply to mkp/scsi.git 4.16/scsi-queue --- diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-23 14:29:26.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-24 15:16:20.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msi_enable = 1; +module_param(msi_enable, int, S_IRUGO); +MODULE_PARM_DESC(msi_enable, "Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); + static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; module_param(host_can_queue, int, S_IRUGO); MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default is 128"); @@ -831,11 +835,17 @@ arcmsr_request_irq(struct pci_dev *pdev, pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { - nvec = pci_alloc_irq_vectors(pdev, 1, 1, - PCI_IRQ_MSI | PCI_IRQ_LEGACY); + if (msi_enable == 1) { + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); + if (nvec == 1) { + dev_info(&pdev->dev, "msi enabled\n"); + goto msi_int1; + } + } + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); if (nvec < 1) return FAILED; - +msi_int1: flags = IRQF_SHARED; }
Re: [PATCH 1/3] scsi: arcmsr: Add driver module parameter msi_enable
Hello Dan, On Thu, 2017-11-23 at 13:44 +0300, Dan Carpenter wrote: > On Thu, Nov 23, 2017 at 09:27:19AM +0800, Ching Huang wrote: > > From: Ching Huang > > > > Add module parameter msi_enable to has a chance to disable msi interrupt if > > it does not work properly. > > > > 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 2017-11-23 14:29:26.0 > > +0800 > > +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-23 16:02:28.0 > > +0800 > > @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 > > MODULE_LICENSE("Dual BSD/GPL"); > > MODULE_VERSION(ARCMSR_DRIVER_VERSION); > > > > +static int msi_enable = 1; > > +module_param(msi_enable, int, S_IRUGO); > ^^^ > checkpatch.pl will complain that this should be 0444 S_IRUGO value is 00444, defined in -> . A. It will be not a issue. > > > +MODULE_PARM_DESC(msi_enable, " Enable MSI interrupt(0 ~ 1), > > msi_enable=1(enable), =0(disable)"); > ^ > Remove the extra space OK > > > + > > static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; > > module_param(host_can_queue, int, S_IRUGO); > > MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default > > is 128"); > > @@ -831,11 +835,15 @@ arcmsr_request_irq(struct pci_dev *pdev, > > pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); > > flags = 0; > > } else { > > - nvec = pci_alloc_irq_vectors(pdev, 1, 1, > > - PCI_IRQ_MSI | PCI_IRQ_LEGACY); > > + if (msi_enable == 1) > > + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); > > + else > > + nvec = pci_alloc_irq_vectors(pdev, 1, 1, > > PCI_IRQ_LEGACY); > > if (nvec < 1) > > return FAILED; > > I feel like we should try PCI_IRQ_MSI then if it fails we could fall > back to PCI_IRQ_LEGACY. Originally, it worked like this and now it just > fails unless you toggle the module param. It's a regression. update as below --- unsigned int irq_flag; irq_flag = PCI_IRQ_LEGACY; if (msi_enable == 1) irq_flag |= PCI_IRQ_MSI; nvec = pci_alloc_irq_vectors(pdev, 1, 1, irq_flag); > > > > + if (msi_enable == 1) > > + pr_info("arcmsr%d: msi enabled\n", acb->host->host_no); > > This printk could be improved. Use dev_info(&pdev->dev, for a start. > I know that the other prints don't use this, but we could use it one > time then slowly add more users until more are using dev_info() than > pr_info() and then someone will decide to clean up the old users. update as below --- if (msi_enable == 1) dev_info(&pdev->dev, "msi enabled\n"); > > regards, > dan carpenter >
Re: [PATCH 0/3] scsi: arcmsr: add driver module parameter - msi_enable, msix_enable
On Thu, 2017-11-23 at 04:57 -0800, Christoph Hellwig wrote: > On Thu, Nov 23, 2017 at 09:22:03AM +0800, Ching Huang wrote: > > From: Ching Huang > > > > Hi all, > > > > The following patches apply to Martin's 4.16/scsi-queue. > > > > Patch 1: Add module parameter msi_enable to has a chance to disable msi > > interrupt if it does not work properly. > > > > Patch 2: Add module parameter msix_enable to has a chance to disable msix > > interrupt if it does not work properly. > > Why would it not work properly? This patch is apply to https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/tree/?h=4.16/scsi-queue
Re: [PATCH 2/3] scsi: arcmsr: Add driver module parameter msix_enable
On Thu, 2017-11-23 at 14:43 +0300, Dan Carpenter wrote: > On Thu, Nov 23, 2017 at 09:31:14AM +0800, Ching Huang wrote: > > @@ -829,12 +833,15 @@ arcmsr_request_irq(struct pci_dev *pdev, > > unsigned long flags; > > int nvec, i; > > > > + if (msix_enable == 0) > > + goto msi_int0; > > I feel like this goto is not very beautiful, but I can't actually apply > this patch? Which tree is this written against? I'm using linux-next. > This patch is apply to https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/tree/?h=4.16/scsi-queue > regards, > dan carpenter > >
[PATCH 3/3] scsi: arcmsr: Update driver version to v1.40.00.03-20171121
From: Ching Huang Update driver version to v1.40.00.03-20171121 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 2017-11-23 14:29:46.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2017-11-23 16:12:54.0 +0800 @@ -54,7 +54,7 @@ struct device_attribute; #endif #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 #define ARCMSR_MIN_OUTSTANDING_CMD 32 -#define ARCMSR_DRIVER_VERSION "v1.40.00.02-20171011" +#define ARCMSR_DRIVER_VERSION "v1.40.00.03-20171121" #define ARCMSR_SCSI_INITIATOR_ID 255 #define ARCMSR_MAX_XFER_SECTORS512 #define ARCMSR_MAX_XFER_SECTORS_B 4096
[PATCH 2/3] scsi: arcmsr: Add driver module parameter msix_enable
From: Ching Huang Add module parameter msix_enable to has a chance to disable msix interrupt if it does not work properly. 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 2017-11-23 16:02:28.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-23 16:09:24.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msix_enable = 1; +module_param(msix_enable, int, S_IRUGO); +MODULE_PARM_DESC(msix_enable, " Enable MSI-X interrupt(0 ~ 1), msix_enable=1(enable), =0(disable)"); + static int msi_enable = 1; module_param(msi_enable, int, S_IRUGO); MODULE_PARM_DESC(msi_enable, " Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); @@ -829,12 +833,15 @@ arcmsr_request_irq(struct pci_dev *pdev, unsigned long flags; int nvec, i; + if (msix_enable == 0) + goto msi_int0; nvec = pci_alloc_irq_vectors(pdev, 1, ARCMST_NUM_MSIX_VECTORS, PCI_IRQ_MSIX); if (nvec > 0) { pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { +msi_int0: if (msi_enable == 1) nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); else
[PATCH 1/3] scsi: arcmsr: Add driver module parameter msi_enable
From: Ching Huang Add module parameter msi_enable to has a chance to disable msi interrupt if it does not work properly. 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 2017-11-23 14:29:26.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2017-11-23 16:02:28.0 +0800 @@ -75,6 +75,10 @@ MODULE_DESCRIPTION("Areca ARC11xx/12xx/1 MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(ARCMSR_DRIVER_VERSION); +static int msi_enable = 1; +module_param(msi_enable, int, S_IRUGO); +MODULE_PARM_DESC(msi_enable, " Enable MSI interrupt(0 ~ 1), msi_enable=1(enable), =0(disable)"); + static int host_can_queue = ARCMSR_DEFAULT_OUTSTANDING_CMD; module_param(host_can_queue, int, S_IRUGO); MODULE_PARM_DESC(host_can_queue, " adapter queue depth(32 ~ 1024), default is 128"); @@ -831,11 +835,15 @@ arcmsr_request_irq(struct pci_dev *pdev, pr_info("arcmsr%d: msi-x enabled\n", acb->host->host_no); flags = 0; } else { - nvec = pci_alloc_irq_vectors(pdev, 1, 1, - PCI_IRQ_MSI | PCI_IRQ_LEGACY); + if (msi_enable == 1) + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); + else + nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_LEGACY); if (nvec < 1) return FAILED; + if (msi_enable == 1) + pr_info("arcmsr%d: msi enabled\n", acb->host->host_no); flags = IRQF_SHARED; }
[PATCH 0/3] scsi: arcmsr: add driver module parameter - msi_enable, msix_enable
From: Ching Huang Hi all, The following patches apply to Martin's 4.16/scsi-queue. Patch 1: Add module parameter msi_enable to has a chance to disable msi interrupt if it does not work properly. Patch 2: Add module parameter msix_enable to has a chance to disable msix interrupt if it does not work properly. Patch 3: Update driver version to v1.40.00.03-20171121 Please review. Thanks. ---