[PATCH 3/5] SCSI: Support MSI and MSI-X
From: Nick Cheng Support MSI or MSI-X for whole series of RAID controllers. Meanwhole correct the register access as iowrite32/ioread32 Signed-off-by: Nick Cheng< nick.ch...@areca.com.tw > --- diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr.h linux-development//drivers/scsi/arcmsr/arcmsr.h --- linux-vanilla//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:16:18.114629695 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:17:44.826628853 +0800 @@ -63,7 +63,8 @@ struct device_attribute; #define ARCMSR_DEFAULT_SG_ENTRIES 38 #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ -#define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#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; diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c linux-development//drivers/scsi/arcmsr/arcmsr_hba.c --- linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:16:18.214629692 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:17:44.834628853 +0800 @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -82,7 +81,7 @@ MODULE_VERSION(ARCMSR_DRIVER_VERSION); wait_queue_head_t wait_q; static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); -static int arcmsr_iop_confirm(struct AdapterControlBlock *acb); +static void arcmsr_iop_confirm(struct AdapterControlBlock *acb); static int arcmsr_abort(struct scsi_cmnd *); static int arcmsr_bus_reset(struct scsi_cmnd *); static int arcmsr_bios_param(struct scsi_device *sdev, @@ -97,6 +96,8 @@ static void arcmsr_shutdown(struct pci_d static void arcmsr_iop_init(struct AdapterControlBlock *acb); static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, + u32 intmask_org); static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb); static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb); @@ -227,8 +228,8 @@ static bool arcmsr_remap_pciregion(struc printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no); return false; } - if (readl(>pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, >pmuC->outbound_doorbell_clear);/*clear interrupt*/ + if (ioread32(>pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, >pmuC->outbound_doorbell_clear);/*clear interrupt*/ return true; } break; @@ -357,9 +358,9 @@ static uint8_t arcmsr_hbaC_wait_msgint_r int i; for (i = 0; i < 2000; i++) { - if (readl(>outbound_doorbell) + if (ioread32(>outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, >outbound_doorbell_clear); /*clear interrupt*/ return true; } @@ -404,9 +405,11 @@ static void arcmsr_hbaB_flush_cache(stru static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB) { struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC; - int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ -
[PATCH 3/5] SCSI: Support MSI and MSI-X
From: Nick Cheng Support MSI or MSI-X for whole series of RAID controllers. Meanwhole correct the register access as iowrite32/ioread32 Signed-off-by: Nick Cheng< nick.ch...@areca.com.tw > diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr.h linux-development//drivers/scsi/arcmsr/arcmsr.h --- linux-vanilla//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:16:18.114629695 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:17:44.826628853 +0800 @@ -63,7 +63,8 @@ struct device_attribute; #define ARCMSR_DEFAULT_SG_ENTRIES 38 #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ -#define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#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; diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c linux-development//drivers/scsi/arcmsr/arcmsr_hba.c --- linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:16:18.214629692 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:17:44.834628853 +0800 @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -82,7 +81,7 @@ MODULE_VERSION(ARCMSR_DRIVER_VERSION); wait_queue_head_t wait_q; static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); -static int arcmsr_iop_confirm(struct AdapterControlBlock *acb); +static void arcmsr_iop_confirm(struct AdapterControlBlock *acb); static int arcmsr_abort(struct scsi_cmnd *); static int arcmsr_bus_reset(struct scsi_cmnd *); static int arcmsr_bios_param(struct scsi_device *sdev, @@ -97,6 +96,8 @@ static void arcmsr_shutdown(struct pci_d static void arcmsr_iop_init(struct AdapterControlBlock *acb); static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, + u32 intmask_org); static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb); static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb); @@ -227,8 +228,8 @@ static bool arcmsr_remap_pciregion(struc printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", acb->host->host_no); return false; } - if (readl(>pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, >pmuC->outbound_doorbell_clear);/*clear interrupt*/ + if (ioread32(>pmuC->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, >pmuC->outbound_doorbell_clear);/*clear interrupt*/ return true; } break; @@ -357,9 +358,9 @@ static uint8_t arcmsr_hbaC_wait_msgint_r int i; for (i = 0; i < 2000; i++) { - if (readl(>outbound_doorbell) + if (ioread32(>outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, >outbound_doorbell_clear); /*clear interrupt*/ return true; } @@ -404,9 +405,11 @@ static void arcmsr_hbaB_flush_cache(stru static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB) { struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB->pmuC; - int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */ -
[PATCH 3/5] SCSI: Support MSI and MSI-X
From: Nick Cheng nick.ch...@areca.com.tw Support MSI or MSI-X for whole series of RAID controllers. Meanwhole correct the register access as iowrite32/ioread32 Signed-off-by: Nick Cheng nick.ch...@areca.com.tw diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr.h linux-development//drivers/scsi/arcmsr/arcmsr.h --- linux-vanilla//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:16:18.114629695 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:17:44.826628853 +0800 @@ -63,7 +63,8 @@ struct device_attribute; #define ARCMSR_DEFAULT_SG_ENTRIES 38 #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ -#define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#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; diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c linux-development//drivers/scsi/arcmsr/arcmsr_hba.c --- linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:16:18.214629692 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:17:44.834628853 +0800 @@ -61,7 +61,6 @@ #include linux/aer.h #include asm/dma.h #include asm/io.h -#include asm/system.h #include asm/uaccess.h #include scsi/scsi_host.h #include scsi/scsi.h @@ -82,7 +81,7 @@ MODULE_VERSION(ARCMSR_DRIVER_VERSION); wait_queue_head_t wait_q; static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); -static int arcmsr_iop_confirm(struct AdapterControlBlock *acb); +static void arcmsr_iop_confirm(struct AdapterControlBlock *acb); static int arcmsr_abort(struct scsi_cmnd *); static int arcmsr_bus_reset(struct scsi_cmnd *); static int arcmsr_bios_param(struct scsi_device *sdev, @@ -97,6 +96,8 @@ static void arcmsr_shutdown(struct pci_d static void arcmsr_iop_init(struct AdapterControlBlock *acb); static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, + u32 intmask_org); static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb); static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb); @@ -227,8 +228,8 @@ static bool arcmsr_remap_pciregion(struc printk(KERN_NOTICE arcmsr%d: memory mapping region fail \n, acb-host-host_no); return false; } - if (readl(acb-pmuC-outbound_doorbell) ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, acb-pmuC-outbound_doorbell_clear);/*clear interrupt*/ + if (ioread32(acb-pmuC-outbound_doorbell) ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, acb-pmuC-outbound_doorbell_clear);/*clear interrupt*/ return true; } break; @@ -357,9 +358,9 @@ static uint8_t arcmsr_hbaC_wait_msgint_r int i; for (i = 0; i 2000; i++) { - if (readl(phbcmu-outbound_doorbell) + if (ioread32(phbcmu-outbound_doorbell) ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, phbcmu-outbound_doorbell_clear); /*clear interrupt*/ return true; } @@ -404,9 +405,11 @@ static void arcmsr_hbaB_flush_cache(stru static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB) { struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB-pmuC; -
[PATCH 3/5] SCSI: Support MSI and MSI-X
From: Nick Cheng nick.ch...@areca.com.tw Support MSI or MSI-X for whole series of RAID controllers. Meanwhole correct the register access as iowrite32/ioread32 Signed-off-by: Nick Cheng nick.ch...@areca.com.tw --- diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr.h linux-development//drivers/scsi/arcmsr/arcmsr.h --- linux-vanilla//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:16:18.114629695 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr.h 2012-10-03 19:17:44.826628853 +0800 @@ -63,7 +63,8 @@ struct device_attribute; #define ARCMSR_DEFAULT_SG_ENTRIES 38 #define ARCMSR_MAX_HBB_POSTQUEUE 264 #define ARCMSR_MAX_XFER_LEN 0x26000 /* 152K */ -#define ARCMSR_CDB_SG_PAGE_LENGTH 256 +#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; diff -uprN -X linux-vanilla/Documentation/dontdiff linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c linux-development//drivers/scsi/arcmsr/arcmsr_hba.c --- linux-vanilla//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:16:18.214629692 +0800 +++ linux-development//drivers/scsi/arcmsr/arcmsr_hba.c 2012-10-03 19:17:44.834628853 +0800 @@ -61,7 +61,6 @@ #include linux/aer.h #include asm/dma.h #include asm/io.h -#include asm/system.h #include asm/uaccess.h #include scsi/scsi_host.h #include scsi/scsi.h @@ -82,7 +81,7 @@ MODULE_VERSION(ARCMSR_DRIVER_VERSION); wait_queue_head_t wait_q; static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); -static int arcmsr_iop_confirm(struct AdapterControlBlock *acb); +static void arcmsr_iop_confirm(struct AdapterControlBlock *acb); static int arcmsr_abort(struct scsi_cmnd *); static int arcmsr_bus_reset(struct scsi_cmnd *); static int arcmsr_bios_param(struct scsi_device *sdev, @@ -97,6 +96,8 @@ static void arcmsr_shutdown(struct pci_d static void arcmsr_iop_init(struct AdapterControlBlock *acb); static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); +static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, + u32 intmask_org); static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); static void arcmsr_hbaA_flush_cache(struct AdapterControlBlock *acb); static void arcmsr_hbaB_flush_cache(struct AdapterControlBlock *acb); @@ -227,8 +228,8 @@ static bool arcmsr_remap_pciregion(struc printk(KERN_NOTICE arcmsr%d: memory mapping region fail \n, acb-host-host_no); return false; } - if (readl(acb-pmuC-outbound_doorbell) ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, acb-pmuC-outbound_doorbell_clear);/*clear interrupt*/ + if (ioread32(acb-pmuC-outbound_doorbell) ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, acb-pmuC-outbound_doorbell_clear);/*clear interrupt*/ return true; } break; @@ -357,9 +358,9 @@ static uint8_t arcmsr_hbaC_wait_msgint_r int i; for (i = 0; i 2000; i++) { - if (readl(phbcmu-outbound_doorbell) + if (ioread32(phbcmu-outbound_doorbell) ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) { - writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, + iowrite32(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, phbcmu-outbound_doorbell_clear); /*clear interrupt*/ return true; } @@ -404,9 +405,11 @@ static void arcmsr_hbaB_flush_cache(stru static void arcmsr_hbaC_flush_cache(struct AdapterControlBlock *pACB) { struct MessageUnit_C *reg = (struct MessageUnit_C *)pACB-pmuC; -