[PATCH v1.3 2/18] arcmsr: Add code to support MSI-X, MSI interrupt
This patch adds code to support MSI, MSI-X interrupt. Signed-off-by: Chingching2...@areca.com.tw --- diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h --- a/drivers/scsi/arcmsr/arcmsr.h 2014-04-28 16:02:46.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-05-06 15:24:36.0 +0800 @@ -64,6 +64,7 @@ struct device_attribute; #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ #define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#define ARCMST_NUM_MSIX_VECTORS4 #ifndef PCI_DEVICE_ID_ARECA_1880 #define PCI_DEVICE_ID_ARECA_1880 0x1880 #endif @@ -508,6 +509,7 @@ struct AdapterControlBlock struct pci_dev *pdev; struct Scsi_Host * host; unsigned long vir2phy_offset; + struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; /* Offset is used in making arc cdb physical to virtual calculations */ uint32_toutbound_int_enable; uint32_tcdb_phyaddr_hi32; @@ -544,6 +546,8 @@ struct AdapterControlBlock /* iop init */ #define ACB_F_ABORT 0x0200 #define ACB_F_FIRMWARE_TRAP 0x0400 + #define ACB_F_MSI_ENABLED 0x1000 + #define ACB_F_MSIX_ENABLED 0x2000 struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */ struct list_headccb_free_list; @@ -594,6 +598,7 @@ struct AdapterControlBlock #define FW_DEADLOCK 0x0010 atomic_trq_map_token; atomic_tante_token_value; + int msix_vector_count; };/* HW_DEVICE_EXTENSION */ /* *** diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-01 11:02:44.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-01 11:03:00.0 +0800 @@ -603,6 +603,60 @@ static void arcmsr_message_isr_bh_fn(str } } +static int +arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb) +{ + int i, j, r; + struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; + + if (!pci_find_capability(pdev, PCI_CAP_ID_MSIX)) + goto msi_int; + for (i = 0; i ARCMST_NUM_MSIX_VECTORS; i++) + entries[i].entry = i; + r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS); + if (r 0) + goto msi_int; + acb-msix_vector_count = r; + for (i = 0; i r; i++) { + if (request_irq(entries[i].vector, + arcmsr_do_interrupt, 0, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq =%d failed!\n, + acb-host-host_no, pdev-irq); + for (j = 0 ; j i ; j++) + free_irq(entries[j].vector, acb); + pci_disable_msix(pdev); + goto msi_int; + } + acb-entries[i] = entries[i]; + } + acb-acb_flags |= ACB_F_MSIX_ENABLED; + pr_info(arcmsr%d: msi-x enabled\n, acb-host-host_no); + return ARC_SUCCESS; +msi_int: + if (!pci_find_capability(pdev, PCI_CAP_ID_MSI)) + goto legacy_int; + if (pci_enable_msi_range(pdev, 1, 1) 0) + goto legacy_int; + if (request_irq(pdev-irq, arcmsr_do_interrupt, + IRQF_SHARED, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq =%d failed!\n, + acb-host-host_no, pdev-irq); + pci_disable_msi(pdev); + goto legacy_int; + } + acb-acb_flags |= ACB_F_MSI_ENABLED; + pr_info(arcmsr%d: msi enabled\n, acb-host-host_no); + return ARC_SUCCESS; +legacy_int: + if (request_irq(pdev-irq, arcmsr_do_interrupt, + IRQF_SHARED, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq = %d failed!\n, + acb-host-host_no, pdev-irq); + return ARC_FAILURE; + } + return ARC_SUCCESS; +} + static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct Scsi_Host *host; @@ -667,16 +721,13 @@ static int arcmsr_probe(struct pci_dev * if(error){ goto free_hbb_mu; } - arcmsr_iop_init(acb); error = scsi_add_host(host, pdev-dev); if(error){ goto RAID_controller_stop; } - error = request_irq(pdev-irq, arcmsr_do_interrupt, IRQF_SHARED,
Re: [PATCH v1.3 2/18] arcmsr: Add code to support MSI-X, MSI interrupt
On Fri, Aug 01, 2014 at 04:33:09PM +0800, Ching Huang wrote: This patch adds code to support MSI, MSI-X interrupt. Signed-off-by: Chingching2...@areca.com.tw --- diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h --- a/drivers/scsi/arcmsr/arcmsr.h2014-04-28 16:02:46.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h2014-05-06 15:24:36.0 +0800 @@ -64,6 +64,7 @@ struct device_attribute; #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ #define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#define ARCMST_NUM_MSIX_VECTORS 4 #ifndef PCI_DEVICE_ID_ARECA_1880 #define PCI_DEVICE_ID_ARECA_1880 0x1880 #endif @@ -508,6 +509,7 @@ struct AdapterControlBlock struct pci_dev *pdev; struct Scsi_Host * host; unsigned long vir2phy_offset; + struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; /* Offset is used in making arc cdb physical to virtual calculations */ uint32_toutbound_int_enable; uint32_tcdb_phyaddr_hi32; @@ -544,6 +546,8 @@ struct AdapterControlBlock /* iop init */ #define ACB_F_ABORT 0x0200 #define ACB_F_FIRMWARE_TRAP 0x0400 + #define ACB_F_MSI_ENABLED 0x1000 + #define ACB_F_MSIX_ENABLED 0x2000 struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */ struct list_headccb_free_list; @@ -594,6 +598,7 @@ struct AdapterControlBlock #define FW_DEADLOCK 0x0010 atomic_trq_map_token; atomic_tante_token_value; + int msix_vector_count; };/* HW_DEVICE_EXTENSION */ /* *** diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c2014-08-01 11:02:44.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c2014-08-01 11:03:00.0 +0800 @@ -603,6 +603,60 @@ static void arcmsr_message_isr_bh_fn(str } } +static int +arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb) +{ + int i, j, r; + struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; + + if (!pci_find_capability(pdev, PCI_CAP_ID_MSIX)) + goto msi_int; It is not on top of my head, but checking the capability is discouraged. pci_enable_msix_range() will fail if MSI-X is not supported. Hence, it is redundant. + for (i = 0; i ARCMST_NUM_MSIX_VECTORS; i++) + entries[i].entry = i; + r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS); + if (r 0) + goto msi_int; + acb-msix_vector_count = r; Not sure how msix_vector_count is used throughout the rest of the code, but placing this assignment after successful initialization of MSI-X is generally safer and clearer. + for (i = 0; i r; i++) { + if (request_irq(entries[i].vector, + arcmsr_do_interrupt, 0, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq =%d failed!\n, + acb-host-host_no, pdev-irq); Nah, pdev-irq is wrong here. Should be entries[i].vector. + for (j = 0 ; j i ; j++) + free_irq(entries[j].vector, acb); + pci_disable_msix(pdev); + goto msi_int; + } + acb-entries[i] = entries[i]; + } + acb-acb_flags |= ACB_F_MSIX_ENABLED; + pr_info(arcmsr%d: msi-x enabled\n, acb-host-host_no); + return ARC_SUCCESS; +msi_int: + if (!pci_find_capability(pdev, PCI_CAP_ID_MSI)) + goto legacy_int; The same as with MSI-X (above). + if (pci_enable_msi_range(pdev, 1, 1) 0) + goto legacy_int; pci_enable_msi_exact() or pci_enable_msi() is better choice here. + if (request_irq(pdev-irq, arcmsr_do_interrupt, + IRQF_SHARED, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq =%d failed!\n, + acb-host-host_no, pdev-irq); + pci_disable_msi(pdev); + goto legacy_int; + } + acb-acb_flags |= ACB_F_MSI_ENABLED; + pr_info(arcmsr%d: msi enabled\n, acb-host-host_no); + return ARC_SUCCESS; +legacy_int: + if (request_irq(pdev-irq, arcmsr_do_interrupt, + IRQF_SHARED, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq = %d failed!\n, + acb-host-host_no, pdev-irq); +
Re: [PATCH v1.3 2/18] arcmsr: Add code to support MSI-X, MSI interrupt
Hi Alexander, Thanks for your advice. This patch was revised according to your comment. Signed-off-by: Chingching2...@areca.com.tw --- diff -uprN a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h --- a/drivers/scsi/arcmsr/arcmsr.h 2014-04-28 16:02:46.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr.h 2014-05-06 15:24:36.0 +0800 @@ -64,6 +64,7 @@ struct device_attribute; #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ #define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#define ARCMST_NUM_MSIX_VECTORS4 #ifndef PCI_DEVICE_ID_ARECA_1880 #define PCI_DEVICE_ID_ARECA_1880 0x1880 #endif @@ -508,6 +509,7 @@ struct AdapterControlBlock struct pci_dev *pdev; struct Scsi_Host * host; unsigned long vir2phy_offset; + struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; /* Offset is used in making arc cdb physical to virtual calculations */ uint32_toutbound_int_enable; uint32_tcdb_phyaddr_hi32; @@ -544,6 +546,8 @@ struct AdapterControlBlock /* iop init */ #define ACB_F_ABORT 0x0200 #define ACB_F_FIRMWARE_TRAP 0x0400 + #define ACB_F_MSI_ENABLED 0x1000 + #define ACB_F_MSIX_ENABLED 0x2000 struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; /* used for memory free */ struct list_headccb_free_list; @@ -594,6 +598,7 @@ struct AdapterControlBlock #define FW_DEADLOCK 0x0010 atomic_trq_map_token; atomic_tante_token_value; + int msix_vector_count; };/* HW_DEVICE_EXTENSION */ /* *** diff -uprN a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c --- a/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-01 11:02:44.0 +0800 +++ b/drivers/scsi/arcmsr/arcmsr_hba.c 2014-08-01 17:54:46.0 +0800 @@ -603,6 +603,56 @@ static void arcmsr_message_isr_bh_fn(str } } +static int +arcmsr_request_irq(struct pci_dev *pdev, struct AdapterControlBlock *acb) +{ + int i, j, r; + struct msix_entry entries[ARCMST_NUM_MSIX_VECTORS]; + + for (i = 0; i ARCMST_NUM_MSIX_VECTORS; i++) + entries[i].entry = i; + r = pci_enable_msix_range(pdev, entries, 1, ARCMST_NUM_MSIX_VECTORS); + if (r 0) + goto msi_int; + acb-msix_vector_count = r; + for (i = 0; i r; i++) { + if (request_irq(entries[i].vector, + arcmsr_do_interrupt, 0, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq =%d failed!\n, + acb-host-host_no, entries[i].vector); + for (j = 0 ; j i ; j++) + free_irq(entries[j].vector, acb); + pci_disable_msix(pdev); + goto msi_int; + } + acb-entries[i] = entries[i]; + } + acb-acb_flags |= ACB_F_MSIX_ENABLED; + pr_info(arcmsr%d: msi-x enabled\n, acb-host-host_no); + return SUCCESS; +msi_int: + if (pci_enable_msi_exact(pdev, 1) 0) + goto legacy_int; + if (request_irq(pdev-irq, arcmsr_do_interrupt, + IRQF_SHARED, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq =%d failed!\n, + acb-host-host_no, pdev-irq); + pci_disable_msi(pdev); + goto legacy_int; + } + acb-acb_flags |= ACB_F_MSI_ENABLED; + pr_info(arcmsr%d: msi enabled\n, acb-host-host_no); + return SUCCESS; +legacy_int: + if (request_irq(pdev-irq, arcmsr_do_interrupt, + IRQF_SHARED, arcmsr, acb)) { + pr_warn(arcmsr%d: request_irq = %d failed!\n, + acb-host-host_no, pdev-irq); + return FAILED; + } + return SUCCESS; +} + static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct Scsi_Host *host; @@ -667,16 +717,13 @@ static int arcmsr_probe(struct pci_dev * if(error){ goto free_hbb_mu; } - arcmsr_iop_init(acb); error = scsi_add_host(host, pdev-dev); if(error){ goto RAID_controller_stop; } - error = request_irq(pdev-irq, arcmsr_do_interrupt, IRQF_SHARED, arcmsr, acb); - if(error){ + if (arcmsr_request_irq(pdev, acb) == FAILED) goto scsi_host_remove; - } - host-irq =
Re: [PATCH v1.3 2/18] arcmsr: Add code to support MSI-X, MSI interrupt
On Fri, Aug 01, 2014 at 06:38:48PM +0800, Ching Huang wrote: Hi Alexander, Thanks for your advice. This patch was revised according to your comment. Signed-off-by: Chingching2...@areca.com.tw This patch is something that can't be applied at all. There is no changelog. Apply the patch with `cat email.txt | git am` and review the changelog using the `git log` command. https://www.google.com/search?q=how+to+send+a+v2+patch Also the Signed-off-by line is wrong. It should have your full name. There needs to be a space between the name and the email address. regards, dan carpenter -- To unsubscribe from this list: send the line unsubscribe linux-scsi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html