From b37f230efb40659d20fa40e47e9c4c80bc251a63 Mon Sep 17 00:00:00 2001 From: Johnny Hughes Date: Mar 03 2017 00:35:51 +0000 Subject: include plus patches in git --- diff --git a/SOURCES/addmissing.patch b/SOURCES/addmissing.patch new file mode 100644 index 0000000..95ad87a --- /dev/null +++ b/SOURCES/addmissing.patch @@ -0,0 +1,27 @@ +diff -up linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/ptrace.h.addmissing linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/ptrace.h +--- linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/ptrace.h.addmissing 2015-10-29 16:56:51.000000000 -0400 ++++ linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/ptrace.h 2015-11-21 23:33:16.430036291 -0500 +@@ -109,6 +109,23 @@ static inline int user_mode_vm(struct pt + #endif + } + ++/* ++ * This is the fastest way to check whether regs come from user space. ++ * It is unsafe if regs might come from vm86 mode, though -- in vm86 ++ * mode, all bits of CS and SS are completely under the user's control. ++ * The CPU considers vm86 mode to be CPL 3 regardless of CS and SS. ++ * ++ * Do NOT use this function unless you have already ruled out the ++ * possibility that regs came from vm86 mode. ++ * ++ * We check for RPL != 0 instead of RPL == 3 because we don't use rings ++ * 1 or 2 and this is more efficient. ++ */ ++static inline int user_mode_ignore_vm86(struct pt_regs *regs) ++{ ++ return (regs->cs & SEGMENT_RPL_MASK) != 0; ++} ++ + static inline int v8086_mode(struct pt_regs *regs) + { + #ifdef CONFIG_X86_32 diff --git a/SOURCES/centos-linux-3.10-0001-scsi-megaraid_sas-Add-new-pci-device-Ids-for-SAS3.5-.patch b/SOURCES/centos-linux-3.10-0001-scsi-megaraid_sas-Add-new-pci-device-Ids-for-SAS3.5-.patch new file mode 100644 index 0000000..2a5bafe --- /dev/null +++ b/SOURCES/centos-linux-3.10-0001-scsi-megaraid_sas-Add-new-pci-device-Ids-for-SAS3.5-.patch @@ -0,0 +1,200 @@ +From 748b88ff6deca4fda640b16ca021857b33aa5ca6 Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:43 -0500 +Subject: [PATCH 01/11] scsi: megaraid_sas: Add new pci device Ids for SAS3.5 + Generic Megaraid Controllers + +This patch contains new pci device ids for SAS3.5 Generic Megaraid Controllers + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 12 +++++++++--- + drivers/scsi/megaraid/megaraid_sas_base.c | 14 +++++++++++++- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 30 ++++++++++++++++++++++------- + 3 files changed, 45 insertions(+), 11 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index ba52d14..e5ac6b1 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -56,6 +56,11 @@ + #define PCI_DEVICE_ID_LSI_INTRUDER_24 0x00cf + #define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052 + #define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053 ++#define PCI_DEVICE_ID_LSI_VENTURA 0x0014 ++#define PCI_DEVICE_ID_LSI_HARPOON 0x0016 ++#define PCI_DEVICE_ID_LSI_TOMCAT 0x0017 ++#define PCI_DEVICE_ID_LSI_VENTURA_4PORT 0x001B ++#define PCI_DEVICE_ID_LSI_CRUSADER_4PORT 0x001C + + /* + * Intel HBA SSDIDs +@@ -100,7 +105,7 @@ + */ + + /* +- * MFI stands for MegaRAID SAS FW Interface. This is just a moniker for ++ * MFI stands for MegaRAID SAS FW Interface. This is just a moniker for + * protocol between the software and firmware. Commands are issued using + * "message frames" + */ +@@ -1435,7 +1440,7 @@ enum FW_BOOT_CONTEXT { + * register set for both 1068 and 1078 controllers + * structure extended for 1078 registers + */ +- ++ + struct megasas_register_set { + u32 doorbell; /*0000h*/ + u32 fusion_seq_offset; /*0004h*/ +@@ -1478,7 +1483,7 @@ struct megasas_register_set { + + u32 inbound_high_queue_port ; /*00C4h*/ + +- u32 reserved_5; /*00C8h*/ ++ u32 inbound_single_queue_port; /*00C8h*/ + u32 res_6[11]; /*CCh*/ + u32 host_diag; + u32 seq_offset; +@@ -2143,6 +2148,7 @@ struct megasas_instance { + u8 is_rdpq; + bool dev_handle; + bool fw_sync_cache_support; ++ bool is_ventura; + }; + struct MR_LD_VF_MAP { + u32 size; +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index ac01648..a73e6f6 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -155,6 +155,12 @@ static struct pci_device_id megasas_pci_table[] = { + /* Intruder 24 port*/ + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)}, + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)}, ++ /* VENTURA */ ++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA)}, ++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_HARPOON)}, ++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)}, ++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)}, ++ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER_4PORT)}, + {} + }; + +@@ -5765,6 +5771,12 @@ static int megasas_probe_one(struct pci_dev *pdev, + instance->pdev = pdev; + + switch (instance->pdev->device) { ++ case PCI_DEVICE_ID_LSI_VENTURA: ++ case PCI_DEVICE_ID_LSI_HARPOON: ++ case PCI_DEVICE_ID_LSI_TOMCAT: ++ case PCI_DEVICE_ID_LSI_VENTURA_4PORT: ++ case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: ++ instance->is_ventura = true; + case PCI_DEVICE_ID_LSI_FUSION: + case PCI_DEVICE_ID_LSI_PLASMA: + case PCI_DEVICE_ID_LSI_INVADER: +@@ -5789,7 +5801,7 @@ static int megasas_probe_one(struct pci_dev *pdev, + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) + fusion->adapter_type = THUNDERBOLT_SERIES; +- else ++ else if (!instance->is_ventura) + fusion->adapter_type = INVADER_SERIES; + } + break; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 7ecd0b4..5ad8a07 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -189,15 +189,29 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, + */ + static void + megasas_fire_cmd_fusion(struct megasas_instance *instance, +- union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) ++ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit) + { ++ struct megasas_register_set __iomem *regs = instance->reg_set; ++ unsigned long flags; ++ ++ if (is_32bit) ++ writel(le32_to_cpu(req_desc->u.low), ++ &(regs)->inbound_single_queue_port); ++ else if (instance->is_ventura) { ++ spin_lock_irqsave(&instance->hba_lock, flags); ++ writel(le32_to_cpu(req_desc->u.low), ++ &(regs)->inbound_low_queue_port); ++ writel(le32_to_cpu(req_desc->u.high), ++ &(regs)->inbound_high_queue_port); ++ mmiowb(); ++ spin_unlock_irqrestore(&instance->hba_lock, flags); ++ } else { + #if defined(writeq) && defined(CONFIG_64BIT) + u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | + le32_to_cpu(req_desc->u.low)); + + writeq(req_data, &instance->reg_set->inbound_low_queue_port); + #else +- unsigned long flags; + + spin_lock_irqsave(&instance->hba_lock, flags); + writel(le32_to_cpu(req_desc->u.low), +@@ -207,6 +221,7 @@ megasas_fire_cmd_fusion(struct megasas_instance *instance, + mmiowb(); + spin_unlock_irqrestore(&instance->hba_lock, flags); + #endif ++ } + } + + /** +@@ -850,7 +865,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) + break; + } + +- megasas_fire_cmd_fusion(instance, &req_desc); ++ megasas_fire_cmd_fusion(instance, &req_desc, false); + + wait_and_poll(instance, cmd, MFI_POLL_TIMEOUT_SECS); + +@@ -2224,7 +2239,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + */ + atomic_inc(&instance->fw_outstanding); + +- megasas_fire_cmd_fusion(instance, req_desc); ++ megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + + return 0; + } +@@ -2592,7 +2607,7 @@ megasas_issue_dcmd_fusion(struct megasas_instance *instance, + return DCMD_NOT_FIRED; + } + +- megasas_fire_cmd_fusion(instance, req_desc); ++ megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + return DCMD_SUCCESS; + } + +@@ -2884,7 +2899,8 @@ void megasas_refire_mgmt_cmd(struct megasas_instance *instance) + cpu_to_le32(MR_DCMD_SYSTEM_PD_MAP_GET_INFO))) + && !(cmd_mfi->flags & DRV_DCMD_SKIP_REFIRE); + if (refire_cmd) +- megasas_fire_cmd_fusion(instance, req_desc); ++ megasas_fire_cmd_fusion(instance, req_desc, ++ instance->is_ventura); + else + megasas_return_cmd(instance, cmd_mfi); + } +@@ -3063,7 +3079,7 @@ megasas_issue_tm(struct megasas_instance *instance, u16 device_handle, + mr_request->tmReqFlags.isTMForLD = 1; + + init_completion(&cmd_fusion->done); +- megasas_fire_cmd_fusion(instance, req_desc); ++ megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + + timeleft = wait_for_completion_timeout(&cmd_fusion->done, 50 * HZ); + +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0001-scsi-mpt3sas-Fix-for-improper-info-displayed-in-var-.patch b/SOURCES/centos-linux-3.10-0001-scsi-mpt3sas-Fix-for-improper-info-displayed-in-var-.patch new file mode 100644 index 0000000..089f8f8 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0001-scsi-mpt3sas-Fix-for-improper-info-displayed-in-var-.patch @@ -0,0 +1,59 @@ +From 5c528134dc5242845930c8eb33abd97bb0ef5bc2 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:32 +0530 +Subject: [PATCH 01/11] scsi: mpt3sas: Fix for improper info displayed in var + log, while blocking or unblocking the device. + +Return value and Device_handle Arguments passed in correct order + to match with its format string. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 1911152..9c61476 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -2888,7 +2888,7 @@ _scsih_internal_device_block(struct scsi_device *sdev, + if (r == -EINVAL) + sdev_printk(KERN_WARNING, sdev, + "device_block failed with return(%d) for handle(0x%04x)\n", +- sas_device_priv_data->sas_target->handle, r); ++ r, sas_device_priv_data->sas_target->handle); + } + + /** +@@ -2918,20 +2918,20 @@ _scsih_internal_device_unblock(struct scsi_device *sdev, + sdev_printk(KERN_WARNING, sdev, + "device_unblock failed with return(%d) for handle(0x%04x) " + "performing a block followed by an unblock\n", +- sas_device_priv_data->sas_target->handle, r); ++ r, sas_device_priv_data->sas_target->handle); + sas_device_priv_data->block = 1; + r = scsi_internal_device_block(sdev); + if (r) + sdev_printk(KERN_WARNING, sdev, "retried device_block " + "failed with return(%d) for handle(0x%04x)\n", +- sas_device_priv_data->sas_target->handle, r); ++ r, sas_device_priv_data->sas_target->handle); + + sas_device_priv_data->block = 0; + r = scsi_internal_device_unblock(sdev, SDEV_RUNNING); + if (r) + sdev_printk(KERN_WARNING, sdev, "retried device_unblock" + " failed with return(%d) for handle(0x%04x)\n", +- sas_device_priv_data->sas_target->handle, r); ++ r, sas_device_priv_data->sas_target->handle); + } + } + +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0002-scsi-megaraid_sas-128-MSIX-Support.patch b/SOURCES/centos-linux-3.10-0002-scsi-megaraid_sas-128-MSIX-Support.patch new file mode 100644 index 0000000..8fdd89c --- /dev/null +++ b/SOURCES/centos-linux-3.10-0002-scsi-megaraid_sas-128-MSIX-Support.patch @@ -0,0 +1,103 @@ +From 13ac44ddfb8f0cfc407bb91713384e9961f6e762 Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:44 -0500 +Subject: [PATCH 02/11] scsi: megaraid_sas: 128 MSIX Support + +SAS3.5 Generic Megaraid based Controllers will have the support for 128 MSI-X vectors, +resulting in the need to support 128 reply queues + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 1 + + drivers/scsi/megaraid/megaraid_sas_base.c | 24 +++++++++++++++++------- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 ++-- + 3 files changed, 20 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index e5ac6b1..ccef47b 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -2149,6 +2149,7 @@ struct megasas_instance { + bool dev_handle; + bool fw_sync_cache_support; + bool is_ventura; ++ bool msix_combined; + }; + struct MR_LD_VF_MAP { + u32 size; +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index a73e6f6..c78d7ee 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -5119,13 +5119,7 @@ static int megasas_init_fw(struct megasas_instance *instance) + goto fail_ready_state; + } + +- /* +- * MSI-X host index 0 is common for all adapter. +- * It is used for all MPT based Adapters. +- */ +- instance->reply_post_host_index_addr[0] = +- (u32 __iomem *)((u8 __iomem *)instance->reg_set + +- MPI2_REPLY_POST_HOST_INDEX_OFFSET); ++ + + /* Check if MSI-X is supported while in ready state */ + msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & +@@ -5143,6 +5137,9 @@ static int megasas_init_fw(struct megasas_instance *instance) + instance->msix_vectors = ((scratch_pad_2 + & MR_MAX_REPLY_QUEUES_EXT_OFFSET) + >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1; ++ if (instance->msix_vectors > 16) ++ instance->msix_combined = true; ++ + if (rdpq_enable) + instance->is_rdpq = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? + 1 : 0; +@@ -5176,6 +5173,19 @@ static int megasas_init_fw(struct megasas_instance *instance) + else + instance->msix_vectors = 0; + } ++ /* ++ * MSI-X host index 0 is common for all adapter. ++ * It is used for all MPT based Adapters. ++ */ ++ if (instance->msix_combined) { ++ instance->reply_post_host_index_addr[0] = ++ (u32 *)((u8 *)instance->reg_set + ++ MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET); ++ } else { ++ instance->reply_post_host_index_addr[0] = ++ (u32 *)((u8 *)instance->reg_set + ++ MPI2_REPLY_POST_HOST_INDEX_OFFSET); ++ } + + dev_info(&instance->pdev->dev, + "firmware supports msix\t: (%d)", fw_msix_count); +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 5ad8a07..c64b85a 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -2391,7 +2391,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + * pending to be completed + */ + if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) { +- if (fusion->adapter_type == INVADER_SERIES) ++ if (instance->msix_combined) + writel(((MSIxIndex & 0x7) << 24) | + fusion->last_reply_idx[MSIxIndex], + instance->reply_post_host_index_addr[MSIxIndex/8]); +@@ -2407,7 +2407,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + return IRQ_NONE; + + wmb(); +- if (fusion->adapter_type == INVADER_SERIES) ++ if (instance->msix_combined) + writel(((MSIxIndex & 0x7) << 24) | + fusion->last_reply_idx[MSIxIndex], + instance->reply_post_host_index_addr[MSIxIndex/8]); +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0002-scsi-mpt3sas-Fix-for-incorrect-numbers-for-MSIX-vect.patch b/SOURCES/centos-linux-3.10-0002-scsi-mpt3sas-Fix-for-incorrect-numbers-for-MSIX-vect.patch new file mode 100644 index 0000000..f008615 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0002-scsi-mpt3sas-Fix-for-incorrect-numbers-for-MSIX-vect.patch @@ -0,0 +1,68 @@ +From 79caef2412a36c3ed223be7e35395b41e99c6c4c Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:33 +0530 +Subject: [PATCH 02/11] scsi: mpt3sas: Fix for incorrect numbers for MSIX + vectors enabled when non RDPQ card is enumerated first. + +No. of MSIX vectors supported = min (Total no. of CPU cores, +MSIX vectors supported by card) + +when RDPQ is disabled "max_msix_vectors" module parameter which was +declared as global was set to '8' and hence if there are more than one card +in system among which if RDPQ disabled card is enumerated first then only 8 +MSIX vectors was getting enabled for all the cards(including RDPQ enabled +card,which can support more than 8 MSIX vectors). + +Used local variable instead of global variable ,if RDPQ is disabled this +local variable is set to '8' else it is set to "max_msix_vectors" (by +default this is set to -1, whose value can be set by user during driver +load time).So now regardless of whether RDPQ disabled card is enumerated +first or RDPQ enabled card is enumerated first , MSIX vectors enabled +depends on the cards capability. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index c77c31c..2319db8 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1960,7 +1960,7 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) + { + struct msix_entry *entries, *a; + int r; +- int i; ++ int i, local_max_msix_vectors; + u8 try_msix = 0; + + if (msix_disable == -1 || msix_disable == 0) +@@ -1980,13 +1980,15 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) + ioc->cpu_count, max_msix_vectors); + + if (!ioc->rdpq_array_enable && max_msix_vectors == -1) +- max_msix_vectors = 8; ++ local_max_msix_vectors = 8; ++ else ++ local_max_msix_vectors = max_msix_vectors; + +- if (max_msix_vectors > 0) { +- ioc->reply_queue_count = min_t(int, max_msix_vectors, ++ if (local_max_msix_vectors > 0) { ++ ioc->reply_queue_count = min_t(int, local_max_msix_vectors, + ioc->reply_queue_count); + ioc->msix_vector_count = ioc->reply_queue_count; +- } else if (max_msix_vectors == 0) ++ } else if (local_max_msix_vectors == 0) + goto try_ioapic; + + if (ioc->msix_vector_count < ioc->cpu_count) +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0003-scsi-megaraid_sas-EEDP-Escape-Mode-Support-for-SAS3..patch b/SOURCES/centos-linux-3.10-0003-scsi-megaraid_sas-EEDP-Escape-Mode-Support-for-SAS3..patch new file mode 100644 index 0000000..b1e5687 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0003-scsi-megaraid_sas-EEDP-Escape-Mode-Support-for-SAS3..patch @@ -0,0 +1,51 @@ +From b004a9938ed1a8bb2007d0442512c6802c3a6bd1 Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:45 -0500 +Subject: [PATCH 03/11] scsi: megaraid_sas: EEDP Escape Mode Support for SAS3.5 + Generic Megaraid Controllers + +An UNMAP command on a PI formatted device will leave the Logical Block Application +Tag and Logical Block Reference Tag as all F's (for those LBAs that are unmapped). +To avoid IO errors if those LBAs are subsequently read before they are written with +valid tag fields, the MPI SCSI IO requests need to set the EEDPFlags element EEDP +Escape Mode field, Bits [7:6] appropriately. A value of 2 should be set to disable +all PI checks if the Logical Block Application Tag is 0xFFFF for PI types 1 and 2. +A value of 3 should be set to disable all PI checks if the Logical Block Application +Tag is 0xFFFF and the Logical Block Reference Tag is 0xFFFFFFFF for PI type 3. + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 + + drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 ++ + 2 files changed, 3 insertions(+) + +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index c64b85a..27c6a1f 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -1589,6 +1589,7 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, + MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | + MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP | + MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG | ++ MPI25_SCSIIO_EEDPFLAGS_DO_NOT_DISABLE_MODE | + MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD); + } else { + io_request->EEDPFlags = cpu_to_le16( +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index 80eaee2..3cd3d0a 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -175,6 +175,8 @@ enum REGION_TYPE { + #define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200) + #define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100) + #define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004) ++/* EEDP escape mode */ ++#define MPI25_SCSIIO_EEDPFLAGS_DO_NOT_DISABLE_MODE (0x0040) + #define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO */ + #define MPI2_FUNCTION_SCSI_TASK_MGMT (0x01) + #define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x03) +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0003-scsi-mpt3sas-Implement-device_remove_in_progress-che.patch b/SOURCES/centos-linux-3.10-0003-scsi-mpt3sas-Implement-device_remove_in_progress-che.patch new file mode 100644 index 0000000..cc90027 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0003-scsi-mpt3sas-Implement-device_remove_in_progress-che.patch @@ -0,0 +1,271 @@ +From a372b29ab979095c323d33ab922062015d459ddd Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:34 +0530 +Subject: [PATCH 03/11] scsi: mpt3sas: Implement device_remove_in_progress + check in IOCTL path + +When device missing event arrives, device_remove_in_progress bit will be +set and hence driver has to stop sending IOCTL commands.Now the check has +been added in IOCTL path to test device_remove_in_progress bit is set, if +so then IOCTL will be failed printing failure message. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 19 +++++++++++++++ + drivers/scsi/mpt3sas/mpt3sas_base.h | 5 ++++ + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 46 ++++++++++++++++++++++++++++++------ + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 24 ++++++++++++++++++- + 4 files changed, 86 insertions(+), 8 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index 2319db8..ac87e12 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -5368,6 +5368,21 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) + goto out_free_resources; + } + ++ /* allocate memory for pending OS device add list */ ++ ioc->pend_os_device_add_sz = (ioc->facts.MaxDevHandle / 8); ++ if (ioc->facts.MaxDevHandle % 8) ++ ioc->pend_os_device_add_sz++; ++ ioc->pend_os_device_add = kzalloc(ioc->pend_os_device_add_sz, ++ GFP_KERNEL); ++ if (!ioc->pend_os_device_add) ++ goto out_free_resources; ++ ++ ioc->device_remove_in_progress_sz = ioc->pend_os_device_add_sz; ++ ioc->device_remove_in_progress = ++ kzalloc(ioc->device_remove_in_progress_sz, GFP_KERNEL); ++ if (!ioc->device_remove_in_progress) ++ goto out_free_resources; ++ + ioc->fwfault_debug = mpt3sas_fwfault_debug; + + /* base internal command bits */ +@@ -5450,6 +5465,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) + kfree(ioc->reply_post_host_index); + kfree(ioc->pd_handles); + kfree(ioc->blocking_handles); ++ kfree(ioc->device_remove_in_progress); ++ kfree(ioc->pend_os_device_add); + kfree(ioc->tm_cmds.reply); + kfree(ioc->transport_cmds.reply); + kfree(ioc->scsih_cmds.reply); +@@ -5491,6 +5508,8 @@ mpt3sas_base_detach(struct MPT3SAS_ADAPTER *ioc) + kfree(ioc->reply_post_host_index); + kfree(ioc->pd_handles); + kfree(ioc->blocking_handles); ++ kfree(ioc->device_remove_in_progress); ++ kfree(ioc->pend_os_device_add); + kfree(ioc->pfacts); + kfree(ioc->ctl_cmds.reply); + kfree(ioc->ctl_cmds.sense); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 1a614d7..241a660 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1093,6 +1093,9 @@ struct MPT3SAS_ADAPTER { + void *pd_handles; + u16 pd_handles_sz; + ++ void *pend_os_device_add; ++ u16 pend_os_device_add_sz; ++ + /* config page */ + u16 config_page_sz; + void *config_page; +@@ -1201,6 +1204,8 @@ struct MPT3SAS_ADAPTER { + struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event; + struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi; + struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi; ++ void *device_remove_in_progress; ++ u16 device_remove_in_progress_sz; + }; + + typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index 7d00f09..a75f8a3 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -655,6 +655,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + size_t data_in_sz = 0; + long ret; + u16 wait_state_count; ++ u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE; + + issue_reset = 0; + +@@ -739,10 +740,13 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + data_in_sz = karg.data_in_size; + + if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST || +- mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH) { +- if (!le16_to_cpu(mpi_request->FunctionDependent1) || +- le16_to_cpu(mpi_request->FunctionDependent1) > +- ioc->facts.MaxDevHandle) { ++ mpi_request->Function == MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH || ++ mpi_request->Function == MPI2_FUNCTION_SCSI_TASK_MGMT || ++ mpi_request->Function == MPI2_FUNCTION_SATA_PASSTHROUGH) { ++ ++ device_handle = le16_to_cpu(mpi_request->FunctionDependent1); ++ if (!device_handle || (device_handle > ++ ioc->facts.MaxDevHandle)) { + ret = -EINVAL; + mpt3sas_base_free_smid(ioc, smid); + goto out; +@@ -798,12 +802,18 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + scsiio_request->SenseBufferLowAddress = + mpt3sas_base_get_sense_buffer_dma(ioc, smid); + memset(ioc->ctl_cmds.sense, 0, SCSI_SENSE_BUFFERSIZE); ++ if (test_bit(device_handle, ioc->device_remove_in_progress)) { ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "handle(0x%04x) :ioctl failed due to device removal in progress\n", ++ ioc->name, device_handle)); ++ mpt3sas_base_free_smid(ioc, smid); ++ ret = -EINVAL; ++ goto out; ++ } + ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, + data_in_dma, data_in_sz); +- + if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) +- mpt3sas_base_put_smid_scsi_io(ioc, smid, +- le16_to_cpu(mpi_request->FunctionDependent1)); ++ mpt3sas_base_put_smid_scsi_io(ioc, smid, device_handle); + else + mpt3sas_base_put_smid_default(ioc, smid); + break; +@@ -828,6 +838,14 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + } + } + ++ if (test_bit(device_handle, ioc->device_remove_in_progress)) { ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "handle(0x%04x) :ioctl failed due to device removal in progress\n", ++ ioc->name, device_handle)); ++ mpt3sas_base_free_smid(ioc, smid); ++ ret = -EINVAL; ++ goto out; ++ } + mpt3sas_scsih_set_tm_flag(ioc, le16_to_cpu( + tm_request->DevHandle)); + ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, +@@ -867,6 +885,20 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + break; + } + case MPI2_FUNCTION_SATA_PASSTHROUGH: ++ { ++ if (test_bit(device_handle, ioc->device_remove_in_progress)) { ++ dtmprintk(ioc, pr_info(MPT3SAS_FMT ++ "handle(0x%04x) :ioctl failed due to device removal in progress\n", ++ ioc->name, device_handle)); ++ mpt3sas_base_free_smid(ioc, smid); ++ ret = -EINVAL; ++ goto out; ++ } ++ ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, ++ data_in_sz); ++ mpt3sas_base_put_smid_default(ioc, smid); ++ break; ++ } + case MPI2_FUNCTION_FW_DOWNLOAD: + case MPI2_FUNCTION_FW_UPLOAD: + { +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 9c61476..c6aa172 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -785,6 +785,11 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, + list_add_tail(&sas_device->list, &ioc->sas_device_list); + spin_unlock_irqrestore(&ioc->sas_device_lock, flags); + ++ if (ioc->hide_drives) { ++ clear_bit(sas_device->handle, ioc->pend_os_device_add); ++ return; ++ } ++ + if (!mpt3sas_transport_port_add(ioc, sas_device->handle, + sas_device->sas_address_parent)) { + _scsih_sas_device_remove(ioc, sas_device); +@@ -800,7 +805,8 @@ _scsih_sas_device_add(struct MPT3SAS_ADAPTER *ioc, + sas_device->sas_address_parent); + _scsih_sas_device_remove(ioc, sas_device); + } +- } ++ } else ++ clear_bit(sas_device->handle, ioc->pend_os_device_add); + } + + /** +@@ -3189,6 +3195,8 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) + if (test_bit(handle, ioc->pd_handles)) + return; + ++ clear_bit(handle, ioc->pend_os_device_add); ++ + spin_lock_irqsave(&ioc->sas_device_lock, flags); + sas_device = __mpt3sas_get_sdev_by_handle(ioc, handle); + if (sas_device && sas_device->starget && +@@ -3243,6 +3251,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) + mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; + mpi_request->DevHandle = cpu_to_le16(handle); + mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; ++ set_bit(handle, ioc->device_remove_in_progress); + mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); + mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); + +@@ -3377,6 +3386,11 @@ _scsih_sas_control_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, + ioc->name, le16_to_cpu(mpi_reply->DevHandle), smid, + le16_to_cpu(mpi_reply->IOCStatus), + le32_to_cpu(mpi_reply->IOCLogInfo))); ++ if (le16_to_cpu(mpi_reply->IOCStatus) == ++ MPI2_IOCSTATUS_SUCCESS) { ++ clear_bit(le16_to_cpu(mpi_reply->DevHandle), ++ ioc->device_remove_in_progress); ++ } + } else { + pr_err(MPT3SAS_FMT "mpi_reply not valid at %s:%d/%s()!\n", + ioc->name, __FILE__, __LINE__, __func__); +@@ -5506,6 +5520,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); + if (!(_scsih_is_end_device(device_info))) + return -1; ++ set_bit(handle, ioc->pend_os_device_add); + sas_address = le64_to_cpu(sas_device_pg0.SASAddress); + + /* check if device is present */ +@@ -5524,6 +5539,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + sas_device = mpt3sas_get_sdev_by_addr(ioc, + sas_address); + if (sas_device) { ++ clear_bit(handle, ioc->pend_os_device_add); + sas_device_put(sas_device); + return -1; + } +@@ -5846,6 +5862,9 @@ _scsih_sas_topology_change_event(struct MPT3SAS_ADAPTER *ioc, + _scsih_check_device(ioc, sas_address, handle, + phy_number, link_rate); + ++ if (!test_bit(handle, ioc->pend_os_device_add)) ++ break; ++ + + case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: + +@@ -7766,6 +7785,9 @@ mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) + complete(&ioc->tm_cmds.done); + } + ++ memset(ioc->pend_os_device_add, 0, ioc->pend_os_device_add_sz); ++ memset(ioc->device_remove_in_progress, 0, ++ ioc->device_remove_in_progress_sz); + _scsih_fw_event_cleanup_queue(ioc); + _scsih_flush_running_cmds(ioc); + break; +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0004-scsi-megaraid_sas-SAS3.5-Generic-Megaraid-Controller.patch b/SOURCES/centos-linux-3.10-0004-scsi-megaraid_sas-SAS3.5-Generic-Megaraid-Controller.patch new file mode 100644 index 0000000..e02f6ce --- /dev/null +++ b/SOURCES/centos-linux-3.10-0004-scsi-megaraid_sas-SAS3.5-Generic-Megaraid-Controller.patch @@ -0,0 +1,610 @@ +From a28d10b2a9bec8714f59e12fe7fb53bfe8c6ef17 Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:46 -0500 +Subject: [PATCH 04/11] scsi: megaraid_sas: SAS3.5 Generic Megaraid Controllers + Stream Detection and IO Coalescing + +Detect sequential Write IOs and pass the hint that it is part of sequential +stream to help HBA Firmware do the Full Stripe Writes. For read IOs on +certain RAID volumes like Read Ahead volumes,this will help driver to +send it to Firmware even if the IOs can potentially be sent to +hardware directly (called fast path) bypassing firmware. + +Design: 8 streams are maintained per RAID volume as per the combined +firmware/driver design. When there is no stream detected the LRU stream +is used for next potential stream and LRU/MRU map is updated to make this +as MRU stream. Every time a stream is detected the MRU map +is updated to make the current stream as MRU stream. + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 1 + + drivers/scsi/megaraid/megaraid_sas_base.c | 43 +++++++- + drivers/scsi/megaraid/megaraid_sas_fp.c | 2 + + drivers/scsi/megaraid/megaraid_sas_fusion.c | 165 +++++++++++++++++++++++----- + drivers/scsi/megaraid/megaraid_sas_fusion.h | 117 +++++++++++++++++++- + 5 files changed, 297 insertions(+), 31 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index ccef47b..f387b32 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -2070,6 +2070,7 @@ struct megasas_instance { + /* used to sync fire the cmd to fw */ + spinlock_t hba_lock; + /* used to synch producer, consumer ptrs in dpc */ ++ spinlock_t stream_lock; + spinlock_t completion_lock; + struct dma_pool *frame_dma_pool; + struct dma_pool *sense_dma_pool; +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index c78d7ee..0722286 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -5048,7 +5048,7 @@ static int megasas_init_fw(struct megasas_instance *instance) + struct megasas_register_set __iomem *reg_set; + struct megasas_ctrl_info *ctrl_info = NULL; + unsigned long bar_list; +- int i, loop, fw_msix_count = 0; ++ int i, j, loop, fw_msix_count = 0; + struct IOV_111 *iovPtr; + struct fusion_context *fusion; + +@@ -5235,6 +5235,36 @@ static int megasas_init_fw(struct megasas_instance *instance) + } + + memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); ++ ++ /* stream detection initialization */ ++ if (instance->is_ventura) { ++ fusion->stream_detect_by_ld = ++ kzalloc(sizeof(struct LD_STREAM_DETECT *) ++ * MAX_LOGICAL_DRIVES_EXT, ++ GFP_KERNEL); ++ if (!fusion->stream_detect_by_ld) { ++ dev_err(&instance->pdev->dev, ++ "unable to allocate stream detection for pool of LDs\n"); ++ goto fail_get_ld_pd_list; ++ } ++ for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) { ++ fusion->stream_detect_by_ld[i] = ++ kmalloc(sizeof(struct LD_STREAM_DETECT), ++ GFP_KERNEL); ++ if (!fusion->stream_detect_by_ld[i]) { ++ dev_err(&instance->pdev->dev, ++ "unable to allocate stream detect by LD\n "); ++ for (j = 0; j < i; ++j) ++ kfree(fusion->stream_detect_by_ld[j]); ++ kfree(fusion->stream_detect_by_ld); ++ fusion->stream_detect_by_ld = NULL; ++ goto fail_get_ld_pd_list; ++ } ++ fusion->stream_detect_by_ld[i]->mru_bit_map ++ = MR_STREAM_BITMAP; ++ } ++ } ++ + if (megasas_ld_list_query(instance, + MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) + megasas_get_ld_list(instance); +@@ -5354,6 +5384,8 @@ static int megasas_init_fw(struct megasas_instance *instance) + + return 0; + ++fail_get_ld_pd_list: ++ instance->instancet->disable_intr(instance); + fail_get_pd_list: + instance->instancet->disable_intr(instance); + megasas_destroy_irqs(instance); +@@ -5896,6 +5928,7 @@ static int megasas_probe_one(struct pci_dev *pdev, + + spin_lock_init(&instance->mfi_pool_lock); + spin_lock_init(&instance->hba_lock); ++ spin_lock_init(&instance->stream_lock); + spin_lock_init(&instance->completion_lock); + + mutex_init(&instance->reset_mutex); +@@ -6363,6 +6396,14 @@ static void megasas_detach_one(struct pci_dev *pdev) + if (instance->msix_vectors) + pci_disable_msix(instance->pdev); + ++ if (instance->is_ventura) { ++ for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) ++ kfree(fusion->stream_detect_by_ld[i]); ++ kfree(fusion->stream_detect_by_ld); ++ fusion->stream_detect_by_ld = NULL; ++ } ++ ++ + if (instance->ctrl_context) { + megasas_release_fusion(instance); + pd_seq_map_sz = sizeof(struct MR_PD_CFG_SEQ_NUM_SYNC) + +diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c +index e413113..fe5b074 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fp.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fp.c +@@ -933,6 +933,8 @@ MR_BuildRaidContext(struct megasas_instance *instance, + + ld = MR_TargetIdToLdGet(ldTgtId, map); + raid = MR_LdRaidGet(ld, map); ++ /*check read ahead bit*/ ++ io_info->ra_capable = raid->capability.ra_capable; + + /* + * if rowDataSize @RAID map and spanRowDataSize @SPAN INFO are zero +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 27c6a1f..946f7c0 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -1704,6 +1704,90 @@ megasas_set_pd_lba(struct MPI2_RAID_SCSI_IO_REQUEST *io_request, u8 cdb_len, + } + + /** ++ * megasas_stream_detect - stream detection on read and and write IOs ++ * @instance: Adapter soft state ++ * @cmd: Command to be prepared ++ * @io_info: IO Request info ++ * ++ */ ++ ++/** stream detection on read and and write IOs */ ++static void megasas_stream_detect(struct megasas_instance *instance, ++ struct megasas_cmd_fusion *cmd, ++ struct IO_REQUEST_INFO *io_info) ++{ ++ struct fusion_context *fusion = instance->ctrl_context; ++ u32 device_id = io_info->ldTgtId; ++ struct LD_STREAM_DETECT *current_ld_sd ++ = fusion->stream_detect_by_ld[device_id]; ++ u32 *track_stream = ¤t_ld_sd->mru_bit_map, stream_num; ++ u32 shifted_values, unshifted_values; ++ u32 index_value_mask, shifted_values_mask; ++ int i; ++ bool is_read_ahead = false; ++ struct STREAM_DETECT *current_sd; ++ /* find possible stream */ ++ for (i = 0; i < MAX_STREAMS_TRACKED; ++i) { ++ stream_num = ++ (*track_stream >> (i * BITS_PER_INDEX_STREAM)) & ++ STREAM_MASK; ++ current_sd = ¤t_ld_sd->stream_track[stream_num]; ++ /* if we found a stream, update the raid ++ * context and also update the mruBitMap ++ */ ++ /* boundary condition */ ++ if ((current_sd->next_seq_lba) && ++ (io_info->ldStartBlock >= current_sd->next_seq_lba) && ++ (io_info->ldStartBlock <= (current_sd->next_seq_lba+32)) && ++ (current_sd->is_read == io_info->isRead)) { ++ ++ if ((io_info->ldStartBlock != current_sd->next_seq_lba) ++ && ((!io_info->isRead) || (!is_read_ahead))) ++ /* ++ * Once the API availible we need to change this. ++ * At this point we are not allowing any gap ++ */ ++ continue; ++ ++ cmd->io_request->RaidContext.raid_context_g35.stream_detected = true; ++ current_sd->next_seq_lba = ++ io_info->ldStartBlock + io_info->numBlocks; ++ /* ++ * update the mruBitMap LRU ++ */ ++ shifted_values_mask = ++ (1 << i * BITS_PER_INDEX_STREAM) - 1; ++ shifted_values = ((*track_stream & shifted_values_mask) ++ << BITS_PER_INDEX_STREAM); ++ index_value_mask = ++ STREAM_MASK << i * BITS_PER_INDEX_STREAM; ++ unshifted_values = ++ *track_stream & ~(shifted_values_mask | ++ index_value_mask); ++ *track_stream = ++ unshifted_values | shifted_values | stream_num; ++ return; ++ ++ } ++ ++ } ++ /* ++ * if we did not find any stream, create a new one ++ * from the least recently used ++ */ ++ stream_num = ++ (*track_stream >> ((MAX_STREAMS_TRACKED - 1) * BITS_PER_INDEX_STREAM)) & ++ STREAM_MASK; ++ current_sd = ¤t_ld_sd->stream_track[stream_num]; ++ current_sd->is_read = io_info->isRead; ++ current_sd->next_seq_lba = io_info->ldStartBlock + io_info->numBlocks; ++ *track_stream = ++ (((*track_stream & ZERO_LAST_STREAM) << 4) | stream_num); ++ return; ++ ++} ++ ++/** + * megasas_build_ldio_fusion - Prepares IOs to devices + * @instance: Adapter soft state + * @scp: SCSI command +@@ -1725,15 +1809,17 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + struct fusion_context *fusion; + struct MR_DRV_RAID_MAP_ALL *local_map_ptr; + u8 *raidLUN; ++ unsigned long spinlock_flags; + + device_id = MEGASAS_DEV_INDEX(scp); + + fusion = instance->ctrl_context; + + io_request = cmd->io_request; +- io_request->RaidContext.VirtualDiskTgtId = cpu_to_le16(device_id); +- io_request->RaidContext.status = 0; +- io_request->RaidContext.exStatus = 0; ++ io_request->RaidContext.raid_context.VirtualDiskTgtId = ++ cpu_to_le16(device_id); ++ io_request->RaidContext.raid_context.status = 0; ++ io_request->RaidContext.raid_context.exStatus = 0; + + req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc; + +@@ -1804,11 +1890,11 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + + if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >= + instance->fw_supported_vd_count) || (!fusion->fast_path_io)) { +- io_request->RaidContext.regLockFlags = 0; ++ io_request->RaidContext.raid_context.regLockFlags = 0; + fp_possible = 0; + } else { + if (MR_BuildRaidContext(instance, &io_info, +- &io_request->RaidContext, ++ &io_request->RaidContext.raid_context, + local_map_ptr, &raidLUN)) + fp_possible = io_info.fpOkForIo; + } +@@ -1819,6 +1905,18 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + cmd->request_desc->SCSIIO.MSIxIndex = instance->msix_vectors ? + raw_smp_processor_id() % instance->msix_vectors : 0; + ++ if (instance->is_ventura) { ++ spin_lock_irqsave(&instance->stream_lock, spinlock_flags); ++ megasas_stream_detect(instance, cmd, &io_info); ++ spin_unlock_irqrestore(&instance->stream_lock, spinlock_flags); ++ /* In ventura if stream detected for a read and it is read ahead ++ * capable make this IO as LDIO ++ */ ++ if (io_request->RaidContext.raid_context_g35.stream_detected && ++ io_info.isRead && io_info.ra_capable) ++ fp_possible = false; ++ } ++ + if (fp_possible) { + megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp, + local_map_ptr, start_lba_lo); +@@ -1827,15 +1925,16 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + (MPI2_REQ_DESCRIPT_FLAGS_FP_IO + << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); + if (fusion->adapter_type == INVADER_SERIES) { +- if (io_request->RaidContext.regLockFlags == ++ if (io_request->RaidContext.raid_context.regLockFlags == + REGION_TYPE_UNUSED) + cmd->request_desc->SCSIIO.RequestFlags = + (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK << + MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); +- io_request->RaidContext.Type = MPI2_TYPE_CUDA; +- io_request->RaidContext.nseg = 0x1; ++ io_request->RaidContext.raid_context.Type ++ = MPI2_TYPE_CUDA; ++ io_request->RaidContext.raid_context.nseg = 0x1; + io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); +- io_request->RaidContext.regLockFlags |= ++ io_request->RaidContext.raid_context.regLockFlags |= + (MR_RL_FLAGS_GRANT_DESTINATION_CUDA | + MR_RL_FLAGS_SEQ_NUM_ENABLE); + } +@@ -1862,22 +1961,24 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + /* populate the LUN field */ + memcpy(io_request->LUN, raidLUN, 8); + } else { +- io_request->RaidContext.timeoutValue = ++ io_request->RaidContext.raid_context.timeoutValue = + cpu_to_le16(local_map_ptr->raidMap.fpPdIoTimeoutSec); + cmd->request_desc->SCSIIO.RequestFlags = + (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO + << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); + if (fusion->adapter_type == INVADER_SERIES) { + if (io_info.do_fp_rlbypass || +- (io_request->RaidContext.regLockFlags == REGION_TYPE_UNUSED)) ++ (io_request->RaidContext.raid_context.regLockFlags ++ == REGION_TYPE_UNUSED)) + cmd->request_desc->SCSIIO.RequestFlags = + (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK << + MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); +- io_request->RaidContext.Type = MPI2_TYPE_CUDA; +- io_request->RaidContext.regLockFlags |= ++ io_request->RaidContext.raid_context.Type ++ = MPI2_TYPE_CUDA; ++ io_request->RaidContext.raid_context.regLockFlags |= + (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 | + MR_RL_FLAGS_SEQ_NUM_ENABLE); +- io_request->RaidContext.nseg = 0x1; ++ io_request->RaidContext.raid_context.nseg = 0x1; + } + io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; + io_request->DevHandle = cpu_to_le16(device_id); +@@ -1913,7 +2014,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, + local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; + io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); + /* get RAID_Context pointer */ +- pRAID_Context = &io_request->RaidContext; ++ pRAID_Context = &io_request->RaidContext.raid_context; + /* Check with FW team */ + pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id); + pRAID_Context->regLockRowLBA = 0; +@@ -2000,7 +2101,7 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, + + io_request = cmd->io_request; + /* get RAID_Context pointer */ +- pRAID_Context = &io_request->RaidContext; ++ pRAID_Context = &io_request->RaidContext.raid_context; + pRAID_Context->regLockFlags = 0; + pRAID_Context->regLockRowLBA = 0; + pRAID_Context->regLockLength = 0; +@@ -2094,9 +2195,9 @@ megasas_build_io_fusion(struct megasas_instance *instance, + io_request->Control = 0; + io_request->EEDPBlockSize = 0; + io_request->ChainOffset = 0; +- io_request->RaidContext.RAIDFlags = 0; +- io_request->RaidContext.Type = 0; +- io_request->RaidContext.nseg = 0; ++ io_request->RaidContext.raid_context.RAIDFlags = 0; ++ io_request->RaidContext.raid_context.Type = 0; ++ io_request->RaidContext.raid_context.nseg = 0; + + memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len); + /* +@@ -2143,8 +2244,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, + /* numSGE store lower 8 bit of sge_count. + * numSGEExt store higher 8 bit of sge_count + */ +- io_request->RaidContext.numSGE = sge_count; +- io_request->RaidContext.numSGEExt = (u8)(sge_count >> 8); ++ io_request->RaidContext.raid_context.numSGE = sge_count; ++ io_request->RaidContext.raid_context.numSGEExt = (u8)(sge_count >> 8); + + io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING); + +@@ -2303,8 +2404,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + cmd_fusion->scmd->SCp.ptr = NULL; + + scmd_local = cmd_fusion->scmd; +- status = scsi_io_req->RaidContext.status; +- extStatus = scsi_io_req->RaidContext.exStatus; ++ status = scsi_io_req->RaidContext.raid_context.status; ++ extStatus = scsi_io_req->RaidContext.raid_context.exStatus; + + switch (scsi_io_req->Function) { + case MPI2_FUNCTION_SCSI_TASK_MGMT: +@@ -2337,8 +2438,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */ + /* Map the FW Cmd Status */ + map_cmd_status(cmd_fusion, status, extStatus); +- scsi_io_req->RaidContext.status = 0; +- scsi_io_req->RaidContext.exStatus = 0; ++ scsi_io_req->RaidContext.raid_context.status = 0; ++ scsi_io_req->RaidContext.raid_context.exStatus = 0; + if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO) + atomic_dec(&instance->ldio_outstanding); + megasas_return_cmd_fusion(instance, cmd_fusion); +@@ -2901,7 +3002,7 @@ void megasas_refire_mgmt_cmd(struct megasas_instance *instance) + && !(cmd_mfi->flags & DRV_DCMD_SKIP_REFIRE); + if (refire_cmd) + megasas_fire_cmd_fusion(instance, req_desc, +- instance->is_ventura); ++ instance->is_ventura); + else + megasas_return_cmd(instance, cmd_mfi); + } +@@ -3390,7 +3491,7 @@ int megasas_check_mpio_paths(struct megasas_instance *instance, + /* Core fusion reset function */ + int megasas_reset_fusion(struct Scsi_Host *shost, int reason) + { +- int retval = SUCCESS, i, convert = 0; ++ int retval = SUCCESS, i, j, convert = 0; + struct megasas_instance *instance; + struct megasas_cmd_fusion *cmd_fusion; + struct fusion_context *fusion; +@@ -3555,6 +3656,16 @@ transition_to_ready: + shost_for_each_device(sdev, shost) + megasas_update_sdev_properties(sdev); + ++ /* reset stream detection array */ ++ if (instance->is_ventura) { ++ for (j = 0; j < MAX_LOGICAL_DRIVES_EXT; ++j) { ++ memset(fusion->stream_detect_by_ld[j], ++ 0, sizeof(struct LD_STREAM_DETECT)); ++ fusion->stream_detect_by_ld[j]->mru_bit_map ++ = MR_STREAM_BITMAP; ++ } ++ } ++ + clear_bit(MEGASAS_FUSION_IN_RESET, + &instance->reset_flags); + instance->instancet->enable_intr(instance); +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index 3cd3d0a..d9cf496 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -133,12 +133,95 @@ struct RAID_CONTEXT { + u8 resvd2; + }; + ++/* ++ * Raid Context structure which describes ventura MegaRAID specific ++ * IO Paramenters ,This resides at offset 0x60 where the SGL normally ++ * starts in MPT IO Frames ++ */ ++struct RAID_CONTEXT_G35 { ++#if defined(__BIG_ENDIAN_BITFIELD) ++ u16 resvd0:8; ++ u16 nseg:4; ++ u16 type:4; ++#else ++ u16 type:4; /* 0x00 */ ++ u16 nseg:4; /* 0x00 */ ++ u16 resvd0:8; ++#endif ++ u16 timeout_value; /* 0x02 -0x03 */ ++ union { ++ struct { ++#if defined(__BIG_ENDIAN_BITFIELD) ++ u16 set_divert:4; ++ u16 cpu_sel:4; ++ u16 log:1; ++ u16 rw:1; ++ u16 sbs:1; ++ u16 sqn:1; ++ u16 fwn:1; ++ u16 c2f:1; ++ u16 sld:1; ++ u16 reserved:1; ++#else ++ u16 reserved:1; ++ u16 sld:1; ++ u16 c2f:1; ++ u16 fwn:1; ++ u16 sqn:1; ++ u16 sbs:1; ++ u16 rw:1; ++ u16 log:1; ++ u16 cpu_sel:4; ++ u16 set_divert:4; ++#endif ++ } bits; ++ u16 s; ++ } routing_flags; /* 0x04 -0x05 routing flags */ ++ u16 virtual_disk_tgt_id; /* 0x06 -0x07 */ ++ u64 reg_lock_row_lba; /* 0x08 - 0x0F */ ++ u32 reg_lock_length; /* 0x10 - 0x13 */ ++ union { ++ u16 next_lmid; /* 0x14 - 0x15 */ ++ u16 peer_smid; /* used for the raid 1/10 fp writes */ ++ } smid; ++ u8 ex_status; /* 0x16 : OUT */ ++ u8 status; /* 0x17 status */ ++ u8 RAIDFlags; /* 0x18 resvd[7:6], ioSubType[5:4], ++ * resvd[3:1], preferredCpu[0] ++ */ ++ u8 span_arm; /* 0x1C span[7:5], arm[4:0] */ ++ u16 config_seq_num; /* 0x1A -0x1B */ ++#if defined(__BIG_ENDIAN_BITFIELD) /* 0x1C - 0x1D */ ++ u16 stream_detected:1; ++ u16 reserved:3; ++ u16 num_sge:12; ++#else ++ u16 num_sge:12; ++ u16 reserved:3; ++ u16 stream_detected:1; ++#endif ++ u8 resvd2[2]; /* 0x1E-0x1F */ ++}; ++ ++union RAID_CONTEXT_UNION { ++ struct RAID_CONTEXT raid_context; ++ struct RAID_CONTEXT_G35 raid_context_g35; ++}; ++ + #define RAID_CTX_SPANARM_ARM_SHIFT (0) + #define RAID_CTX_SPANARM_ARM_MASK (0x1f) + + #define RAID_CTX_SPANARM_SPAN_SHIFT (5) + #define RAID_CTX_SPANARM_SPAN_MASK (0xE0) + ++/* number of bits per index in U32 TrackStream */ ++#define BITS_PER_INDEX_STREAM 4 ++#define INVALID_STREAM_NUM 16 ++#define MR_STREAM_BITMAP 0x76543210 ++#define STREAM_MASK ((1 << BITS_PER_INDEX_STREAM) - 1) ++#define ZERO_LAST_STREAM 0x0fffffff ++#define MAX_STREAMS_TRACKED 8 ++ + /* + * define region lock types + */ +@@ -409,7 +492,7 @@ struct MPI2_RAID_SCSI_IO_REQUEST { + u8 LUN[8]; /* 0x34 */ + __le32 Control; /* 0x3C */ + union MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */ +- struct RAID_CONTEXT RaidContext; /* 0x60 */ ++ union RAID_CONTEXT_UNION RaidContext; /* 0x60 */ + union MPI2_SGE_IO_UNION SGL; /* 0x80 */ + }; + +@@ -656,11 +739,13 @@ struct MR_LD_RAID { + u32 encryptionType:8; + u32 pdPiMode:4; + u32 ldPiMode:4; +- u32 reserved5:3; ++ u32 reserved5:2; ++ u32 ra_capable:1; + u32 fpCapable:1; + #else + u32 fpCapable:1; +- u32 reserved5:3; ++ u32 ra_capable:1; ++ u32 reserved5:2; + u32 ldPiMode:4; + u32 pdPiMode:4; + u32 encryptionType:8; +@@ -745,6 +830,7 @@ struct IO_REQUEST_INFO { + u64 start_row; + u8 span_arm; /* span[7:5], arm[4:0] */ + u8 pd_after_lb; ++ bool ra_capable; + }; + + struct MR_LD_TARGET_SYNC { +@@ -930,6 +1016,30 @@ struct MR_PD_CFG_SEQ_NUM_SYNC { + struct MR_PD_CFG_SEQ seq[1]; + } __packed; + ++/* stream detection */ ++struct STREAM_DETECT { ++ u64 next_seq_lba; /* next LBA to match sequential access */ ++ struct megasas_cmd_fusion *first_cmd_fusion; /* first cmd in group */ ++ struct megasas_cmd_fusion *last_cmd_fusion; /* last cmd in group */ ++ u32 count_cmds_in_stream; /* count of host commands in this stream */ ++ u16 num_sges_in_group; /* total number of SGEs in grouped IOs */ ++ u8 is_read; /* SCSI OpCode for this stream */ ++ u8 group_depth; /* total number of host commands in group */ ++ /* TRUE if cannot add any more commands to this group */ ++ bool group_flush; ++ u8 reserved[7]; /* pad to 64-bit alignment */ ++}; ++ ++struct LD_STREAM_DETECT { ++ bool write_back; /* TRUE if WB, FALSE if WT */ ++ bool fp_write_enabled; ++ bool members_ssds; ++ bool fp_cache_bypass_capable; ++ u32 mru_bit_map; /* bitmap used to track MRU and LRU stream indicies */ ++ /* this is the array of stream detect structures (one per stream) */ ++ struct STREAM_DETECT stream_track[MAX_STREAMS_TRACKED]; ++}; ++ + struct MPI2_IOC_INIT_RDPQ_ARRAY_ENTRY { + u64 RDPQBaseAddress; + u32 Reserved1; +@@ -983,6 +1093,7 @@ struct fusion_context { + struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT]; + LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT]; + u8 adapter_type; ++ struct LD_STREAM_DETECT **stream_detect_by_ld; + }; + + union desc_value { +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0004-scsi-mpt3sas-Remove-unused-macro-MPT_DEVICE_TLR_ON.patch b/SOURCES/centos-linux-3.10-0004-scsi-mpt3sas-Remove-unused-macro-MPT_DEVICE_TLR_ON.patch new file mode 100644 index 0000000..6e6c21b --- /dev/null +++ b/SOURCES/centos-linux-3.10-0004-scsi-mpt3sas-Remove-unused-macro-MPT_DEVICE_TLR_ON.patch @@ -0,0 +1,32 @@ +From 21cedcd2ba44b8e647a4c35affa5df9b584ccd54 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:35 +0530 +Subject: [PATCH 04/11] scsi: mpt3sas: Remove unused macro "MPT_DEVICE_TLR_ON" + +Removing macro "MPT_DEVICE_TLR_ON" defined in header file as its unused + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 241a660..f2fa742 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -379,7 +379,6 @@ struct MPT3SAS_TARGET { + * per device private data + */ + #define MPT_DEVICE_FLAGS_INIT 0x01 +-#define MPT_DEVICE_TLR_ON 0x02 + + #define MFG_PAGE10_HIDE_SSDS_MASK (0x00000003) + #define MFG_PAGE10_HIDE_ALL_DISKS (0x00) +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0005-scsi-megaraid_sas-SAS3.5-Generic-Megaraid-Controller.patch b/SOURCES/centos-linux-3.10-0005-scsi-megaraid_sas-SAS3.5-Generic-Megaraid-Controller.patch new file mode 100644 index 0000000..758ca5e --- /dev/null +++ b/SOURCES/centos-linux-3.10-0005-scsi-megaraid_sas-SAS3.5-Generic-Megaraid-Controller.patch @@ -0,0 +1,774 @@ +From 9fb69ac5aa175b55ba7d48596a3929e3206cbd4b Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:47 -0500 +Subject: [PATCH 05/11] scsi: megaraid_sas: SAS3.5 Generic Megaraid Controllers + Fast Path for RAID 1/10 Writes + +To improve RAID 1/10 Write performance, OS drivers need to issue the +required Write IOs as Fast Path IOs (after the appropriate checks +allowing Fast Path to be used) to the appropriate physical drives +(translated from the OS logical IO) and wait for all Write IOs to complete. + +Design: A write IO on RAID volume will be examined if it can be sent in +Fast Path based on IO size and starting LBA and ending LBA falling on to +a Physical Drive boundary. If the underlying RAID volume is a RAID 1/10, +driver issues two fast path write IOs one for each corresponding physical +drive after computing the corresponding start LBA for each physical drive. +Both write IOs will have the same payload and are posted to HW such that +replies land in the same reply queue. + +If there are no resources available for sending two IOs, driver will send +the original IO from SCSI layer to RAID volume through the Firmware. + +Based on PCI bandwidth and write payload, every second this feature is +enabled/disabled. + +When both IOs are completed by HW, the resources will be released +and SCSI IO completion handler will be called. + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 1 + + drivers/scsi/megaraid/megaraid_sas_fp.c | 31 ++- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 335 ++++++++++++++++++++++++---- + drivers/scsi/megaraid/megaraid_sas_fusion.h | 15 +- + 4 files changed, 329 insertions(+), 53 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index f387b32..0b4d37b 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -2056,6 +2056,7 @@ struct megasas_instance { + + u16 max_num_sge; + u16 max_fw_cmds; ++ u16 max_mpt_cmds; + u16 max_mfi_cmds; + u16 max_scsi_cmds; + u16 ldio_threshold; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c +index fe5b074..3644dbc 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fp.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fp.c +@@ -737,7 +737,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, + struct MR_DRV_RAID_MAP_ALL *map) + { + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); +- u32 pd, arRef; ++ u32 pd, arRef, r1_alt_pd; + u8 physArm, span; + u64 row; + u8 retval = TRUE; +@@ -772,9 +772,16 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, + arRef = MR_LdSpanArrayGet(ld, span, map); + pd = MR_ArPdGet(arRef, physArm, map); + +- if (pd != MR_PD_INVALID) ++ if (pd != MR_PD_INVALID) { + *pDevHandle = MR_PdDevHandleGet(pd, map); +- else { ++ /* get second pd also for raid 1/10 fast path writes*/ ++ if (raid->level == 1) { ++ r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); ++ if (r1_alt_pd != MR_PD_INVALID) ++ io_info->r1_alt_dev_handle = ++ MR_PdDevHandleGet(r1_alt_pd, map); ++ } ++ } else { + *pDevHandle = cpu_to_le16(MR_PD_INVALID); + if ((raid->level >= 5) && + ((fusion->adapter_type == THUNDERBOLT_SERIES) || +@@ -818,7 +825,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, + struct MR_DRV_RAID_MAP_ALL *map) + { + struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); +- u32 pd, arRef; ++ u32 pd, arRef, r1_alt_pd; + u8 physArm, span; + u64 row; + u8 retval = TRUE; +@@ -866,10 +873,17 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, + arRef = MR_LdSpanArrayGet(ld, span, map); + pd = MR_ArPdGet(arRef, physArm, map); /* Get the pd */ + +- if (pd != MR_PD_INVALID) ++ if (pd != MR_PD_INVALID) { + /* Get dev handle from Pd. */ + *pDevHandle = MR_PdDevHandleGet(pd, map); +- else { ++ /* get second pd also for raid 1/10 fast path writes*/ ++ if (raid->level == 1) { ++ r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); ++ if (r1_alt_pd != MR_PD_INVALID) ++ io_info->r1_alt_dev_handle = ++ MR_PdDevHandleGet(r1_alt_pd, map); ++ } ++ } else { + /* set dev handle as invalid. */ + *pDevHandle = cpu_to_le16(MR_PD_INVALID); + if ((raid->level >= 5) && +@@ -1124,6 +1138,11 @@ MR_BuildRaidContext(struct megasas_instance *instance, + /* If IO on an invalid Pd, then FP is not possible.*/ + if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID)) + io_info->fpOkForIo = FALSE; ++ /* set raid 1/10 fast path write capable bit in io_info */ ++ if (io_info->fpOkForIo && ++ (io_info->r1_alt_dev_handle != MR_PD_INVALID) && ++ (raid->level == 1) && !isRead) ++ io_info->is_raid_1_fp_write = 1; + return retval; + } else if (isRead) { + uint stripIdx; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 946f7c0..b146cd1 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -270,7 +270,8 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c + instance->ldio_threshold = ldio_threshold; + + if (!instance->is_rdpq) +- instance->max_fw_cmds = min_t(u16, instance->max_fw_cmds, 1024); ++ instance->max_fw_cmds = ++ min_t(u16, instance->max_fw_cmds, 1024); + + if (reset_devices) + instance->max_fw_cmds = min(instance->max_fw_cmds, +@@ -286,7 +287,14 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c + (MEGASAS_FUSION_INTERNAL_CMDS + + MEGASAS_FUSION_IOCTL_CMDS); + instance->cur_can_queue = instance->max_scsi_cmds; ++ instance->host->can_queue = instance->cur_can_queue; + } ++ ++ if (instance->is_ventura) ++ instance->max_mpt_cmds = ++ instance->max_fw_cmds * RAID_1_10_RMW_CMDS; ++ else ++ instance->max_mpt_cmds = instance->max_fw_cmds; + } + /** + * megasas_free_cmds_fusion - Free all the cmds in the free cmd pool +@@ -300,7 +308,7 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) + struct megasas_cmd_fusion *cmd; + + /* SG, Sense */ +- for (i = 0; i < instance->max_fw_cmds; i++) { ++ for (i = 0; i < instance->max_mpt_cmds; i++) { + cmd = fusion->cmd_list[i]; + if (cmd) { + if (cmd->sg_frame) +@@ -344,7 +352,7 @@ megasas_free_cmds_fusion(struct megasas_instance *instance) + + + /* cmd_list */ +- for (i = 0; i < instance->max_fw_cmds; i++) ++ for (i = 0; i < instance->max_mpt_cmds; i++) + kfree(fusion->cmd_list[i]); + + kfree(fusion->cmd_list); +@@ -396,33 +404,49 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) + return -ENOMEM; + } + } ++ ++ /* create sense buffer for the raid 1/10 fp */ ++ for (i = max_cmd; i < instance->max_mpt_cmds; i++) { ++ cmd = fusion->cmd_list[i]; ++ cmd->sense = pci_pool_alloc(fusion->sense_dma_pool, ++ GFP_KERNEL, &cmd->sense_phys_addr); ++ if (!cmd->sense) { ++ dev_err(&instance->pdev->dev, ++ "Failed from %s %d\n", __func__, __LINE__); ++ return -ENOMEM; ++ } ++ } ++ + return 0; + } + + int + megasas_alloc_cmdlist_fusion(struct megasas_instance *instance) + { +- u32 max_cmd, i; ++ u32 max_mpt_cmd, i; + struct fusion_context *fusion; + + fusion = instance->ctrl_context; + +- max_cmd = instance->max_fw_cmds; ++ max_mpt_cmd = instance->max_mpt_cmds; + + /* + * fusion->cmd_list is an array of struct megasas_cmd_fusion pointers. + * Allocate the dynamic array first and then allocate individual + * commands. + */ +- fusion->cmd_list = kzalloc(sizeof(struct megasas_cmd_fusion *) * max_cmd, +- GFP_KERNEL); ++ fusion->cmd_list = ++ kzalloc(sizeof(struct megasas_cmd_fusion *) * max_mpt_cmd, ++ GFP_KERNEL); + if (!fusion->cmd_list) { + dev_err(&instance->pdev->dev, + "Failed from %s %d\n", __func__, __LINE__); + return -ENOMEM; + } + +- for (i = 0; i < max_cmd; i++) { ++ ++ ++ for (i = 0; i < max_mpt_cmd; i++) { + fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion), + GFP_KERNEL); + if (!fusion->cmd_list[i]) { +@@ -657,13 +681,14 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) + */ + + /* SMID 0 is reserved. Set SMID/index from 1 */ +- for (i = 0; i < instance->max_fw_cmds; i++) { ++ for (i = 0; i < instance->max_mpt_cmds; i++) { + cmd = fusion->cmd_list[i]; + offset = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * i; + memset(cmd, 0, sizeof(struct megasas_cmd_fusion)); + cmd->index = i + 1; + cmd->scmd = NULL; +- cmd->sync_cmd_idx = (i >= instance->max_scsi_cmds) ? ++ cmd->sync_cmd_idx = ++ (i >= instance->max_scsi_cmds && i < instance->max_fw_cmds) ? + (i - instance->max_scsi_cmds) : + (u32)ULONG_MAX; /* Set to Invalid */ + cmd->instance = instance; +@@ -673,6 +698,7 @@ megasas_alloc_cmds_fusion(struct megasas_instance *instance) + memset(cmd->io_request, 0, + sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); + cmd->io_request_phys_addr = io_req_base_phys + offset; ++ cmd->is_raid_1_fp_write = 0; + } + + if (megasas_create_sg_sense_fusion(instance)) +@@ -1262,12 +1288,12 @@ megasas_init_adapter_fusion(struct megasas_instance *instance) + fusion->reply_q_depth = 2 * (((max_cmd + 1 + 15)/16)*16); + + fusion->request_alloc_sz = +- sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *max_cmd; ++ sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * instance->max_mpt_cmds; + fusion->reply_alloc_sz = sizeof(union MPI2_REPLY_DESCRIPTORS_UNION) + *(fusion->reply_q_depth); + fusion->io_frames_alloc_sz = MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + +- (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * +- (max_cmd + 1)); /* Extra 1 for SMID 0 */ ++ (MEGA_MPI2_RAID_DEFAULT_IO_FRAME_SIZE ++ * (instance->max_mpt_cmds + 1)); /* Extra 1 for SMID 0 */ + + scratch_pad_2 = readl(&instance->reg_set->outbound_scratch_pad_2); + /* If scratch_pad_2 & MEGASAS_MAX_CHAIN_SIZE_UNITS_MASK is set, +@@ -1403,42 +1429,43 @@ fail_alloc_mfi_cmds: + */ + + void +-map_cmd_status(struct megasas_cmd_fusion *cmd, u8 status, u8 ext_status) ++map_cmd_status(struct fusion_context *fusion, ++ struct scsi_cmnd *scmd, u8 status, u8 ext_status, ++ u32 data_length, u8 *sense) + { + + switch (status) { + + case MFI_STAT_OK: +- cmd->scmd->result = DID_OK << 16; ++ scmd->result = DID_OK << 16; + break; + + case MFI_STAT_SCSI_IO_FAILED: + case MFI_STAT_LD_INIT_IN_PROGRESS: +- cmd->scmd->result = (DID_ERROR << 16) | ext_status; ++ scmd->result = (DID_ERROR << 16) | ext_status; + break; + + case MFI_STAT_SCSI_DONE_WITH_ERROR: + +- cmd->scmd->result = (DID_OK << 16) | ext_status; ++ scmd->result = (DID_OK << 16) | ext_status; + if (ext_status == SAM_STAT_CHECK_CONDITION) { +- memset(cmd->scmd->sense_buffer, 0, ++ memset(scmd->sense_buffer, 0, + SCSI_SENSE_BUFFERSIZE); +- memcpy(cmd->scmd->sense_buffer, cmd->sense, ++ memcpy(scmd->sense_buffer, sense, + SCSI_SENSE_BUFFERSIZE); +- cmd->scmd->result |= DRIVER_SENSE << 24; ++ scmd->result |= DRIVER_SENSE << 24; + } + break; + + case MFI_STAT_LD_OFFLINE: + case MFI_STAT_DEVICE_NOT_FOUND: +- cmd->scmd->result = DID_BAD_TARGET << 16; ++ scmd->result = DID_BAD_TARGET << 16; + break; + case MFI_STAT_CONFIG_SEQ_MISMATCH: +- cmd->scmd->result = DID_IMM_RETRY << 16; ++ scmd->result = DID_IMM_RETRY << 16; + break; + default: +- dev_printk(KERN_DEBUG, &cmd->instance->pdev->dev, "FW status %#x\n", status); +- cmd->scmd->result = DID_ERROR << 16; ++ scmd->result = DID_ERROR << 16; + break; + } + } +@@ -1881,6 +1908,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + io_info.ldStartBlock = ((u64)start_lba_hi << 32) | start_lba_lo; + io_info.numBlocks = datalength; + io_info.ldTgtId = device_id; ++ io_info.r1_alt_dev_handle = MR_PD_INVALID; + io_request->DataLength = cpu_to_le32(scsi_bufflen(scp)); + + if (scp->sc_data_direction == PCI_DMA_FROMDEVICE) +@@ -1949,6 +1977,10 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + } else + scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG; + ++ cmd->is_raid_1_fp_write = io_info.is_raid_1_fp_write; ++ if (io_info.is_raid_1_fp_write) ++ cmd->r1_alt_dev_handle = io_info.r1_alt_dev_handle; ++ + if ((raidLUN[0] == 1) && + (local_map_ptr->raidMap.devHndlInfo[io_info.pd_after_lb].validHandles > 1)) { + instance->dev_handle = !(instance->dev_handle); +@@ -2272,19 +2304,118 @@ megasas_get_request_descriptor(struct megasas_instance *instance, u16 index) + u8 *p; + struct fusion_context *fusion; + +- if (index >= instance->max_fw_cmds) { ++ if (index >= instance->max_mpt_cmds) { + dev_err(&instance->pdev->dev, "Invalid SMID (0x%x)request for " + "descriptor for scsi%d\n", index, + instance->host->host_no); + return NULL; + } + fusion = instance->ctrl_context; +- p = fusion->req_frames_desc +- +sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) *index; ++ p = fusion->req_frames_desc + ++ sizeof(union MEGASAS_REQUEST_DESCRIPTOR_UNION) * index; + + return (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)p; + } + ++/* ++ * megasas_fpio_to_ldio- ++ * This function converts an fp io to ldio ++ */ ++ ++void megasas_fpio_to_ldio(struct megasas_instance *instance, ++ struct megasas_cmd_fusion *cmd, struct scsi_cmnd *scmd) ++{ ++ struct fusion_context *fusion; ++ ++ fusion = instance->ctrl_context; ++ cmd->request_desc->SCSIIO.RequestFlags = ++ (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO ++ << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); ++ cmd->io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; ++ cmd->io_request->DevHandle = cpu_to_le16(MEGASAS_DEV_INDEX(scmd)); ++ ++ /*remove FAST PATH ENABLE bit in IoFlags */ ++ cmd->io_request->IoFlags &= ++ cpu_to_le16(~MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); ++ ++ /* if the numSGE > max_sge_in_main_sge set the chain offset*/ ++ if (cmd->io_request->RaidContext.raid_context_g35.num_sge > ++ fusion->max_sge_in_main_msg) ++ cmd->io_request->ChainOffset = fusion->chain_offset_io_request; ++ memcpy(cmd->io_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); ++ cmd->io_request->CDB.EEDP32.PrimaryReferenceTag = 0; ++ cmd->io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0; ++ cmd->io_request->EEDPFlags = 0; ++ cmd->io_request->Control = 0; ++ cmd->io_request->EEDPBlockSize = 0; ++ cmd->is_raid_1_fp_write = 0; ++} ++ ++/* megasas_prepate_secondRaid1_IO ++ * It prepares the raid 1 second IO ++ */ ++void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance, ++ struct megasas_cmd_fusion *cmd, ++ struct megasas_cmd_fusion *r1_cmd) ++{ ++ union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, *req_desc2 = NULL; ++ struct fusion_context *fusion; ++ ++ fusion = instance->ctrl_context; ++ req_desc = cmd->request_desc; ++ if (r1_cmd) { ++ /* copy the io request frame as well ++ * as 8 SGEs data for r1 command ++ */ ++ memcpy(r1_cmd->io_request, cmd->io_request, ++ sizeof(struct MPI2_RAID_SCSI_IO_REQUEST)); ++ memcpy(&r1_cmd->io_request->SGL, &cmd->io_request->SGL, ++ (fusion->max_sge_in_main_msg * ++ sizeof(union MPI2_SGE_IO_UNION))); ++ /*sense buffer is different for r1 command*/ ++ r1_cmd->io_request->SenseBufferLowAddress = ++ cpu_to_le32(r1_cmd->sense_phys_addr); ++ r1_cmd->scmd = cmd->scmd; ++ req_desc2 = ++ megasas_get_request_descriptor(instance, r1_cmd->index-1); ++ if (req_desc2) { ++ req_desc2->Words = 0; ++ r1_cmd->request_desc = req_desc2; ++ req_desc2->SCSIIO.SMID = ++ cpu_to_le16(r1_cmd->index); ++ req_desc2->SCSIIO.RequestFlags = ++ req_desc->SCSIIO.RequestFlags; ++ r1_cmd->is_raid_1_fp_write = 1; ++ r1_cmd->request_desc->SCSIIO.DevHandle = ++ cmd->r1_alt_dev_handle; ++ r1_cmd->io_request->DevHandle = cmd->r1_alt_dev_handle; ++ cmd->io_request->RaidContext.raid_context_g35.smid.peer_smid = ++ cpu_to_le16(r1_cmd->index); ++ r1_cmd->io_request->RaidContext.raid_context_g35.smid.peer_smid = ++ cpu_to_le16(cmd->index); ++ /* MSIxIndex of both commands request ++ * descriptors should be same ++ */ ++ r1_cmd->request_desc->SCSIIO.MSIxIndex = ++ cmd->request_desc->SCSIIO.MSIxIndex; ++ /*span arm is different for r1 cmd*/ ++ r1_cmd->io_request->RaidContext.raid_context_g35.span_arm = ++ cmd->io_request->RaidContext.raid_context_g35.span_arm + 1; ++ } else { ++ megasas_return_cmd_fusion(instance, r1_cmd); ++ dev_info(&instance->pdev->dev, ++ "unable to get request descriptor, firing as normal IO\n"); ++ atomic_dec(&instance->fw_outstanding); ++ megasas_fpio_to_ldio(instance, cmd, cmd->scmd); ++ } ++ } else { ++ dev_info(&instance->pdev->dev, ++ "unable to get command, firing as normal IO\n"); ++ atomic_dec(&instance->fw_outstanding); ++ megasas_fpio_to_ldio(instance, cmd, cmd->scmd); ++ } ++} ++ + /** + * megasas_build_and_issue_cmd_fusion -Main routine for building and + * issuing non IOCTL cmd +@@ -2295,7 +2426,7 @@ static u32 + megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + struct scsi_cmnd *scmd) + { +- struct megasas_cmd_fusion *cmd; ++ struct megasas_cmd_fusion *cmd, *r1_cmd = NULL; + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; + u32 index; + struct fusion_context *fusion; +@@ -2310,13 +2441,27 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + return SCSI_MLQUEUE_DEVICE_BUSY; + } + ++ if (atomic_inc_return(&instance->fw_outstanding) > ++ instance->host->can_queue) { ++ dev_err(&instance->pdev->dev, "Throttle IOs beyond Controller queue depth\n"); ++ atomic_dec(&instance->fw_outstanding); ++ return SCSI_MLQUEUE_HOST_BUSY; ++ } ++ + cmd = megasas_get_cmd_fusion(instance, scmd->request->tag); + ++ if (!cmd) { ++ atomic_dec(&instance->fw_outstanding); ++ return SCSI_MLQUEUE_HOST_BUSY; ++ } ++ + index = cmd->index; + + req_desc = megasas_get_request_descriptor(instance, index-1); +- if (!req_desc) ++ if (!req_desc) { ++ atomic_dec(&instance->fw_outstanding); + return SCSI_MLQUEUE_HOST_BUSY; ++ } + + req_desc->Words = 0; + cmd->request_desc = req_desc; +@@ -2325,6 +2470,7 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + megasas_return_cmd_fusion(instance, cmd); + dev_err(&instance->pdev->dev, "Error building command\n"); + cmd->request_desc = NULL; ++ atomic_dec(&instance->fw_outstanding); + return SCSI_MLQUEUE_HOST_BUSY; + } + +@@ -2335,14 +2481,39 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + cmd->io_request->ChainOffset != 0xF) + dev_err(&instance->pdev->dev, "The chain offset value is not " + "correct : %x\n", cmd->io_request->ChainOffset); ++ /* ++ * if it is raid 1/10 fp write capable. ++ * try to get second command from pool and construct it. ++ * From FW, it has confirmed that lba values of two PDs ++ * corresponds to single R1/10 LD are always same ++ * ++ */ ++ /* driver side count always should be less than max_fw_cmds ++ * to get new command ++ */ ++ if (cmd->is_raid_1_fp_write && ++ atomic_inc_return(&instance->fw_outstanding) > ++ (instance->host->can_queue)) { ++ megasas_fpio_to_ldio(instance, cmd, cmd->scmd); ++ atomic_dec(&instance->fw_outstanding); ++ } else if (cmd->is_raid_1_fp_write) { ++ r1_cmd = megasas_get_cmd_fusion(instance, ++ (scmd->request->tag + instance->max_fw_cmds)); ++ megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd); ++ } ++ + + /* + * Issue the command to the FW + */ +- atomic_inc(&instance->fw_outstanding); + + megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + ++ if (r1_cmd) ++ megasas_fire_cmd_fusion(instance, r1_cmd->request_desc, ++ instance->is_ventura); ++ ++ + return 0; + } + +@@ -2359,10 +2530,10 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + struct MPI2_RAID_SCSI_IO_REQUEST *scsi_io_req; + struct fusion_context *fusion; + struct megasas_cmd *cmd_mfi; +- struct megasas_cmd_fusion *cmd_fusion; ++ struct megasas_cmd_fusion *cmd_fusion, *r1_cmd = NULL; + u16 smid, num_completed; +- u8 reply_descript_type; +- u32 status, extStatus, device_id; ++ u8 reply_descript_type, *sense; ++ u32 status, extStatus, device_id, data_length; + union desc_value d_val; + struct LD_LOAD_BALANCE_INFO *lbinfo; + int threshold_reply_count = 0; +@@ -2392,6 +2563,15 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + + while (d_val.u.low != cpu_to_le32(UINT_MAX) && + d_val.u.high != cpu_to_le32(UINT_MAX)) { ++ /* ++ * Ensure that the peer command is NULL here in case a ++ * command has completed but the R1 FP Write peer has ++ * not completed yet.If not null, it's possible that ++ * another thread will complete the peer ++ * command and should not. ++ */ ++ r1_cmd = NULL; ++ + smid = le16_to_cpu(reply_desc->SMID); + + cmd_fusion = fusion->cmd_list[smid - 1]; +@@ -2406,6 +2586,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + scmd_local = cmd_fusion->scmd; + status = scsi_io_req->RaidContext.raid_context.status; + extStatus = scsi_io_req->RaidContext.raid_context.exStatus; ++ sense = cmd_fusion->sense; ++ data_length = scsi_io_req->DataLength; + + switch (scsi_io_req->Function) { + case MPI2_FUNCTION_SCSI_TASK_MGMT: +@@ -2422,12 +2604,28 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + /* Update load balancing info */ + device_id = MEGASAS_DEV_INDEX(scmd_local); + lbinfo = &fusion->load_balance_info[device_id]; +- if (cmd_fusion->scmd->SCp.Status & +- MEGASAS_LOAD_BALANCE_FLAG) { ++ /* ++ * check for the raid 1/10 fast path writes ++ */ ++ if (!cmd_fusion->is_raid_1_fp_write && ++ (cmd_fusion->scmd->SCp.Status & ++ MEGASAS_LOAD_BALANCE_FLAG)) { + atomic_dec(&lbinfo->scsi_pending_cmds[cmd_fusion->pd_r1_lb]); + cmd_fusion->scmd->SCp.Status &= + ~MEGASAS_LOAD_BALANCE_FLAG; ++ } else if (cmd_fusion->is_raid_1_fp_write) { ++ /* get peer command */ ++ if (cmd_fusion->index < instance->max_fw_cmds) ++ r1_cmd = fusion->cmd_list[(cmd_fusion->index + ++ instance->max_fw_cmds)-1]; ++ else { ++ r1_cmd = ++ fusion->cmd_list[(cmd_fusion->index - ++ instance->max_fw_cmds)-1]; ++ } ++ cmd_fusion->cmd_completed = true; + } ++ + if (reply_descript_type == + MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS) { + if (megasas_dbg_lvl == 5) +@@ -2437,14 +2635,48 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + /* Fall thru and complete IO */ + case MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST: /* LD-IO Path */ + /* Map the FW Cmd Status */ +- map_cmd_status(cmd_fusion, status, extStatus); +- scsi_io_req->RaidContext.raid_context.status = 0; +- scsi_io_req->RaidContext.raid_context.exStatus = 0; +- if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO) +- atomic_dec(&instance->ldio_outstanding); +- megasas_return_cmd_fusion(instance, cmd_fusion); +- scsi_dma_unmap(scmd_local); +- scmd_local->scsi_done(scmd_local); ++ /* ++ * check for the raid 1/10 fast path writes ++ */ ++ if (r1_cmd && r1_cmd->is_raid_1_fp_write ++ && r1_cmd->cmd_completed) { ++ /* ++ * if the peer Raid 1/10 fast path failed, ++ * mark IO as failed to the scsi layer. ++ * over write the current status by the failed ++ * status makes sure that if any one of ++ * command fails,return fail status to ++ * scsi layer ++ */ ++ if (r1_cmd->io_request->RaidContext.raid_context.status != ++ MFI_STAT_OK) { ++ status = ++ r1_cmd->io_request->RaidContext.raid_context.status; ++ extStatus = ++ r1_cmd->io_request->RaidContext.raid_context.exStatus; ++ data_length = ++ r1_cmd->io_request->DataLength; ++ sense = r1_cmd->sense; ++ } ++ r1_cmd->io_request->RaidContext.raid_context.status = 0; ++ r1_cmd->io_request->RaidContext.raid_context.exStatus = 0; ++ cmd_fusion->is_raid_1_fp_write = 0; ++ r1_cmd->is_raid_1_fp_write = 0; ++ r1_cmd->cmd_completed = false; ++ cmd_fusion->cmd_completed = false; ++ megasas_return_cmd_fusion(instance, r1_cmd); ++ } ++ if (!cmd_fusion->is_raid_1_fp_write) { ++ map_cmd_status(fusion, scmd_local, status, ++ extStatus, data_length, sense); ++ scsi_io_req->RaidContext.raid_context.status ++ = 0; ++ scsi_io_req->RaidContext.raid_context.exStatus ++ = 0; ++ megasas_return_cmd_fusion(instance, cmd_fusion); ++ scsi_dma_unmap(scmd_local); ++ scmd_local->scsi_done(scmd_local); ++ } + atomic_dec(&instance->fw_outstanding); + + break; +@@ -3493,7 +3725,7 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) + { + int retval = SUCCESS, i, j, convert = 0; + struct megasas_instance *instance; +- struct megasas_cmd_fusion *cmd_fusion; ++ struct megasas_cmd_fusion *cmd_fusion, *mpt_cmd_fusion; + struct fusion_context *fusion; + u32 abs_state, status_reg, reset_adapter; + u32 io_timeout_in_crash_mode = 0; +@@ -3568,6 +3800,18 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) + /* Now return commands back to the OS */ + for (i = 0 ; i < instance->max_scsi_cmds; i++) { + cmd_fusion = fusion->cmd_list[i]; ++ /*check for extra commands issued by driver*/ ++ if (instance->is_ventura) { ++ cmd_fusion->is_raid_1_fp_write = 0; ++ cmd_fusion->cmd_completed = false; ++ mpt_cmd_fusion = ++ fusion->cmd_list[i + instance->max_fw_cmds]; ++ mpt_cmd_fusion->is_raid_1_fp_write = 0; ++ mpt_cmd_fusion->cmd_completed = false; ++ if (mpt_cmd_fusion->scmd) ++ megasas_return_cmd_fusion(instance, ++ mpt_cmd_fusion); ++ } + scmd_local = cmd_fusion->scmd; + if (cmd_fusion->scmd) { + scmd_local->result = +@@ -3578,10 +3822,11 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) + megasas_return_cmd_fusion(instance, cmd_fusion); + scsi_dma_unmap(scmd_local); + scmd_local->scsi_done(scmd_local); +- atomic_dec(&instance->fw_outstanding); + } + } + ++ atomic_set(&instance->fw_outstanding, 0); ++ + status_reg = instance->instancet->read_fw_status_reg( + instance->reg_set); + abs_state = status_reg & MFI_STATE_MASK; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index d9cf496..7a3c3d1 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -94,6 +94,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { + #define MEGASAS_FP_CMD_LEN 16 + #define MEGASAS_FUSION_IN_RESET 0 + #define THRESHOLD_REPLY_COUNT 50 ++#define RAID_1_10_RMW_CMDS 3 + #define JBOD_MAPS_COUNT 2 + + enum MR_FUSION_ADAPTER_TYPE { +@@ -728,7 +729,9 @@ struct MR_SPAN_BLOCK_INFO { + struct MR_LD_RAID { + struct { + #if defined(__BIG_ENDIAN_BITFIELD) +- u32 reserved4:5; ++ u32 reserved4:3; ++ u32 fp_cache_bypass_capable:1; ++ u32 fp_rmw_capable:1; + u32 fpBypassRegionLock:1; + u32 tmCapable:1; + u32 fpNonRWCapable:1; +@@ -756,7 +759,9 @@ struct MR_LD_RAID { + u32 fpNonRWCapable:1; + u32 tmCapable:1; + u32 fpBypassRegionLock:1; +- u32 reserved4:5; ++ u32 fp_rmw_capable:1; ++ u32 fp_cache_bypass_capable:1; ++ u32 reserved4:3; + #endif + } capability; + __le32 reserved6; +@@ -830,6 +835,8 @@ struct IO_REQUEST_INFO { + u64 start_row; + u8 span_arm; /* span[7:5], arm[4:0] */ + u8 pd_after_lb; ++ u16 r1_alt_dev_handle; /* raid 1/10 only */ ++ bool is_raid_1_fp_write; + bool ra_capable; + }; + +@@ -883,6 +890,10 @@ struct megasas_cmd_fusion { + u32 index; + u8 pd_r1_lb; + struct completion done; ++ bool is_raid_1_fp_write; ++ u16 r1_alt_dev_handle; /* raid 1/10 only*/ ++ bool cmd_completed; /* raid 1/10 fp writes status holder */ ++ + }; + + struct LD_LOAD_BALANCE_INFO { +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0005-scsi-mpt3sas-Bump-driver-version-as-14.100.00.00.patch b/SOURCES/centos-linux-3.10-0005-scsi-mpt3sas-Bump-driver-version-as-14.100.00.00.patch new file mode 100644 index 0000000..d6d2120 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0005-scsi-mpt3sas-Bump-driver-version-as-14.100.00.00.patch @@ -0,0 +1,31 @@ +From 0815c65e49489bdbfbd0f90e4a2b78184a603eea Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:36 +0530 +Subject: [PATCH 05/11] scsi: mpt3sas: Bump driver version as "14.100.00.00" + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index f2fa742..66cfa0f 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -73,8 +73,8 @@ + #define MPT3SAS_DRIVER_NAME "mpt3sas" + #define MPT3SAS_AUTHOR "Avago Technologies " + #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" +-#define MPT3SAS_DRIVER_VERSION "13.100.00.00" +-#define MPT3SAS_MAJOR_VERSION 13 ++#define MPT3SAS_DRIVER_VERSION "14.100.00.00" ++#define MPT3SAS_MAJOR_VERSION 14 + #define MPT3SAS_MINOR_VERSION 100 + #define MPT3SAS_BUILD_VERSION 0 + #define MPT3SAS_RELEASE_VERSION 00 +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0006-scsi-megaraid_sas-Dynamic-Raid-Map-Changes-for-SAS3..patch b/SOURCES/centos-linux-3.10-0006-scsi-megaraid_sas-Dynamic-Raid-Map-Changes-for-SAS3..patch new file mode 100644 index 0000000..ed725a1 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0006-scsi-megaraid_sas-Dynamic-Raid-Map-Changes-for-SAS3..patch @@ -0,0 +1,1332 @@ +From 88b3ac2949cb535c5213324f33e9745d769f7dad Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:48 -0500 +Subject: [PATCH 06/11] scsi: megaraid_sas: Dynamic Raid Map Changes for SAS3.5 + Generic Megaraid Controllers + +SAS3.5 Generic Megaraid Controllers FW will support new dynamic RaidMap to have different +sizes for different number of supported VDs. + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 7 + + drivers/scsi/megaraid/megaraid_sas_base.c | 60 ++++-- + drivers/scsi/megaraid/megaraid_sas_fp.c | 301 ++++++++++++++++++++++++---- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 225 ++++++++++++++++----- + drivers/scsi/megaraid/megaraid_sas_fusion.h | 240 ++++++++++++++++++---- + 5 files changed, 695 insertions(+), 138 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index 0b4d37b..d5205c4 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -1434,6 +1434,12 @@ enum FW_BOOT_CONTEXT { + #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14 + #define MR_MAX_MSIX_REG_ARRAY 16 + #define MR_RDPQ_MODE_OFFSET 0X00800000 ++ ++#define MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT 16 ++#define MR_MAX_RAID_MAP_SIZE_MASK 0x1FF ++#define MR_MIN_MAP_SIZE 0x10000 ++/* 64k */ ++ + #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET 0X01000000 + + /* +@@ -2152,6 +2158,7 @@ struct megasas_instance { + bool fw_sync_cache_support; + bool is_ventura; + bool msix_combined; ++ u16 max_raid_mapsize; + }; + struct MR_LD_VF_MAP { + u32 size; +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 0722286..1d8cf03 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -4457,8 +4457,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type) + static void megasas_update_ext_vd_details(struct megasas_instance *instance) + { + struct fusion_context *fusion; +- u32 old_map_sz; +- u32 new_map_sz; ++ u32 ventura_map_sz = 0; + + fusion = instance->ctrl_context; + /* For MFI based controllers return dummy success */ +@@ -4488,21 +4487,38 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance) + instance->supportmax256vd ? "Extended VD(240 VD)firmware" : + "Legacy(64 VD) firmware"); + +- old_map_sz = sizeof(struct MR_FW_RAID_MAP) + +- (sizeof(struct MR_LD_SPAN_MAP) * +- (instance->fw_supported_vd_count - 1)); +- new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); +- fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) + +- (sizeof(struct MR_LD_SPAN_MAP) * +- (instance->drv_supported_vd_count - 1)); +- +- fusion->max_map_sz = max(old_map_sz, new_map_sz); ++ if (instance->max_raid_mapsize) { ++ ventura_map_sz = instance->max_raid_mapsize * ++ MR_MIN_MAP_SIZE; /* 64k */ ++ fusion->current_map_sz = ventura_map_sz; ++ fusion->max_map_sz = ventura_map_sz; ++ } else { ++ fusion->old_map_sz = sizeof(struct MR_FW_RAID_MAP) + ++ (sizeof(struct MR_LD_SPAN_MAP) * ++ (instance->fw_supported_vd_count - 1)); ++ fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); + ++ fusion->max_map_sz = ++ max(fusion->old_map_sz, fusion->new_map_sz); + +- if (instance->supportmax256vd) +- fusion->current_map_sz = new_map_sz; +- else +- fusion->current_map_sz = old_map_sz; ++ if (instance->supportmax256vd) ++ fusion->current_map_sz = fusion->new_map_sz; ++ else ++ fusion->current_map_sz = fusion->old_map_sz; ++ } ++ /* irrespective of FW raid maps, driver raid map is constant */ ++ fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); ++ ++#if VD_EXT_DEBUG ++ dev_info(&instance->pdev->dev, "instance->max_raid_mapsize 0x%x\n ", ++ instance->max_raid_mapsize); ++ dev_info(&instance->pdev->dev, "new_map_sz = 0x%x, old_map_sz = 0x%x\n", ++ fusion->new_map_sz, fusion->old_map_sz); ++ dev_info(&instance->pdev->dev, "ventura_map_sz = 0x%x, current_map_sz = 0x%x\n", ++ ventura_map_sz, fusion->current_map_sz); ++ dev_info(&instance->pdev->dev, "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n", ++ fusion->drv_map_sz, sizeof(struct MR_DRV_RAID_MAP_ALL)); ++#endif + } + + /** +@@ -5043,7 +5059,7 @@ static int megasas_init_fw(struct megasas_instance *instance) + { + u32 max_sectors_1; + u32 max_sectors_2; +- u32 tmp_sectors, msix_enable, scratch_pad_2; ++ u32 tmp_sectors, msix_enable, scratch_pad_2, scratch_pad_3; + resource_size_t base_addr; + struct megasas_register_set __iomem *reg_set; + struct megasas_ctrl_info *ctrl_info = NULL; +@@ -5119,7 +5135,17 @@ static int megasas_init_fw(struct megasas_instance *instance) + goto fail_ready_state; + } + +- ++ if (instance->is_ventura) { ++ scratch_pad_3 = ++ readl(&instance->reg_set->outbound_scratch_pad_3); ++#if VD_EXT_DEBUG ++ dev_info(&instance->pdev->dev, "scratch_pad3 0x%x\n", ++ scratch_pad_3); ++#endif ++ instance->max_raid_mapsize = ((scratch_pad_3 >> ++ MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT) & ++ MR_MAX_RAID_MAP_SIZE_MASK); ++ } + + /* Check if MSI-X is supported while in ready state */ + msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & +diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c +index 3644dbc..e45affe 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fp.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fp.c +@@ -179,18 +179,204 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) + struct fusion_context *fusion = instance->ctrl_context; + struct MR_FW_RAID_MAP_ALL *fw_map_old = NULL; + struct MR_FW_RAID_MAP *pFwRaidMap = NULL; +- int i; ++ int i, j; + u16 ld_count; ++ struct MR_FW_RAID_MAP_DYNAMIC *fw_map_dyn; ++ struct MR_FW_RAID_MAP_EXT *fw_map_ext; ++ struct MR_RAID_MAP_DESC_TABLE *desc_table; + + + struct MR_DRV_RAID_MAP_ALL *drv_map = + fusion->ld_drv_map[(instance->map_id & 1)]; + struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap; ++ void *raid_map_data = NULL; ++ ++ memset(drv_map, 0, fusion->drv_map_sz); ++ memset(pDrvRaidMap->ldTgtIdToLd, ++ 0xff, (sizeof(u16) * MAX_LOGICAL_DRIVES_DYN)); ++ ++ if (instance->max_raid_mapsize) { ++ fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n", ++ le32_to_cpu(fw_map_dyn->raid_map_size), ++ le32_to_cpu(fw_map_dyn->desc_table_offset)); ++ dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n", ++ le32_to_cpu(fw_map_dyn->desc_table_size), ++ le32_to_cpu(fw_map_dyn->desc_table_num_elements)); ++ dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n", ++ drv_map, fw_map_dyn->ld_count); ++#endif ++ desc_table = ++ (struct MR_RAID_MAP_DESC_TABLE *)((void *)fw_map_dyn + le32_to_cpu(fw_map_dyn->desc_table_offset)); ++ if (desc_table != fw_map_dyn->raid_map_desc_table) ++ dev_dbg(&instance->pdev->dev, "offsets of desc table are not matching desc %p original %p\n", ++ desc_table, fw_map_dyn->raid_map_desc_table); ++ ++ ld_count = (u16)le16_to_cpu(fw_map_dyn->ld_count); ++ pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); ++ pDrvRaidMap->fpPdIoTimeoutSec = ++ fw_map_dyn->fp_pd_io_timeout_sec; ++ pDrvRaidMap->totalSize = sizeof(struct MR_DRV_RAID_MAP_ALL); ++ /* point to actual data starting point*/ ++ raid_map_data = (void *)fw_map_dyn + ++ le32_to_cpu(fw_map_dyn->desc_table_offset) + ++ le32_to_cpu(fw_map_dyn->desc_table_size); ++ ++ for (i = 0; i < le32_to_cpu(fw_map_dyn->desc_table_num_elements); ++i) { ++ ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, "desc table %p\n", ++ desc_table); ++ dev_dbg(&instance->pdev->dev, "raidmap type %d, raidmapOffset 0x%x\n", ++ desc_table->raid_map_desc_type, ++ desc_table->raid_map_desc_offset); ++ dev_dbg(&instance->pdev->dev, "raid map number of elements 0%x, raidmapsize 0x%x\n", ++ desc_table->raid_map_desc_elements, ++ desc_table->raid_map_desc_buffer_size); ++#endif ++ switch (le32_to_cpu(desc_table->raid_map_desc_type)) { ++ case RAID_MAP_DESC_TYPE_DEVHDL_INFO: ++ fw_map_dyn->dev_hndl_info = ++ (struct MR_DEV_HANDLE_INFO *)(raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset)); ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, "devHndlInfo address %p\n", ++ fw_map_dyn->dev_hndl_info); ++#endif ++ memcpy(pDrvRaidMap->devHndlInfo, ++ fw_map_dyn->dev_hndl_info, ++ sizeof(struct MR_DEV_HANDLE_INFO) * ++ le32_to_cpu(desc_table->raid_map_desc_elements)); ++ break; ++ case RAID_MAP_DESC_TYPE_TGTID_INFO: ++ fw_map_dyn->ld_tgt_id_to_ld = ++ (u16 *) (raid_map_data + ++ le32_to_cpu(desc_table->raid_map_desc_offset)); ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, "ldTgtIdToLd address %p\n", ++ fw_map_dyn->ld_tgt_id_to_ld); ++#endif ++ for (j = 0; j < le32_to_cpu(desc_table->raid_map_desc_elements); j++) { ++ pDrvRaidMap->ldTgtIdToLd[j] = ++ fw_map_dyn->ld_tgt_id_to_ld[j]; ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, " %d drv ldTgtIdToLd %d\n", ++ j, pDrvRaidMap->ldTgtIdToLd[j]); ++#endif ++ } ++ break; ++ case RAID_MAP_DESC_TYPE_ARRAY_INFO: ++ fw_map_dyn->ar_map_info = ++ (struct MR_ARRAY_INFO *) ++ (raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset)); ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, "arMapInfo address %p\n", ++ fw_map_dyn->ar_map_info); ++#endif ++ ++ memcpy(pDrvRaidMap->arMapInfo, ++ fw_map_dyn->ar_map_info, ++ sizeof(struct MR_ARRAY_INFO) * le32_to_cpu(desc_table->raid_map_desc_elements)); ++ break; ++ case RAID_MAP_DESC_TYPE_SPAN_INFO: ++ fw_map_dyn->ld_span_map = ++ (struct MR_LD_SPAN_MAP *) ++ (raid_map_data + le32_to_cpu(desc_table->raid_map_desc_offset)); ++ memcpy(pDrvRaidMap->ldSpanMap, ++ fw_map_dyn->ld_span_map, ++ sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(desc_table->raid_map_desc_elements)); ++#if VD_EXT_DEBUG ++ dev_dbg(&instance->pdev->dev, "ldSpanMap address %p\n", ++ fw_map_dyn->ld_span_map); ++ dev_dbg(&instance->pdev->dev, "MR_LD_SPAN_MAP size 0x%lx\n", ++ sizeof(struct MR_LD_SPAN_MAP)); ++ for (j = 0; j < ld_count; j++) { ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : fw_map_dyn->ldSpanMap[%d].ldRaid.targetId 0x%x\n", ++ j, j, fw_map_dyn->ld_span_map[j].ldRaid.targetId); ++ dev_dbg(&instance->pdev->dev, "fw_map_dyn->ldSpanMap[%d].ldRaid.seqNum 0x%x\n", ++ j, fw_map_dyn->ld_span_map[j].ldRaid.seqNum); ++ dev_dbg(&instance->pdev->dev, "fw_map_dyn->ld_span_map[%d].ldRaid.rowSize 0x%x\n", ++ j, (u32)fw_map_dyn->ld_span_map[j].ldRaid.rowSize); ++ ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) :pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x\n", ++ j, j, pDrvRaidMap->ldSpanMap[j].ldRaid.targetId); ++ dev_dbg(&instance->pdev->dev, "DrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x\n", ++ j, pDrvRaidMap->ldSpanMap[j].ldRaid.seqNum); ++ dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.rowSize 0x%x\n", ++ j, (u32)pDrvRaidMap->ldSpanMap[j].ldRaid.rowSize); ++ ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : drv raid map all %p\n", ++ instance->unique_id, drv_map); ++ dev_dbg(&instance->pdev->dev, "raid map %p LD RAID MAP %p/%p\n", ++ pDrvRaidMap, ++ &fw_map_dyn->ld_span_map[j].ldRaid, ++ &pDrvRaidMap->ldSpanMap[j].ldRaid); ++ } ++#endif ++ break; ++ default: ++ dev_dbg(&instance->pdev->dev, "wrong number of desctableElements %d\n", ++ fw_map_dyn->desc_table_num_elements); ++ } ++ ++desc_table; ++ } ++ ++ } else if (instance->supportmax256vd) { ++ fw_map_ext = ++ (struct MR_FW_RAID_MAP_EXT *) fusion->ld_map[(instance->map_id & 1)]; ++ ld_count = (u16)le16_to_cpu(fw_map_ext->ldCount); ++ if (ld_count > MAX_LOGICAL_DRIVES_EXT) { ++ dev_dbg(&instance->pdev->dev, "megaraid_sas: LD count exposed in RAID map in not valid\n"); ++ return; ++ } ++#if VD_EXT_DEBUG ++ for (i = 0; i < ld_count; i++) { ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) :Index 0x%x\n", ++ instance->unique_id, i); ++ dev_dbg(&instance->pdev->dev, "Target Id 0x%x\n", ++ fw_map_ext->ldSpanMap[i].ldRaid.targetId); ++ dev_dbg(&instance->pdev->dev, "Seq Num 0x%x Size 0/%llx\n", ++ fw_map_ext->ldSpanMap[i].ldRaid.seqNum, ++ fw_map_ext->ldSpanMap[i].ldRaid.size); ++ } ++#endif ++ ++ pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); ++ pDrvRaidMap->fpPdIoTimeoutSec = fw_map_ext->fpPdIoTimeoutSec; ++ for (i = 0; i < (MAX_LOGICAL_DRIVES_EXT); i++) ++ pDrvRaidMap->ldTgtIdToLd[i] = ++ (u16)fw_map_ext->ldTgtIdToLd[i]; ++ memcpy(pDrvRaidMap->ldSpanMap, fw_map_ext->ldSpanMap, ++ sizeof(struct MR_LD_SPAN_MAP) * ld_count); ++#if VD_EXT_DEBUG ++ for (i = 0; i < ld_count; i++) { ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : fw_map_ext->ldSpanMap[%d].ldRaid.targetId 0x%x\n", ++ i, i, fw_map_ext->ldSpanMap[i].ldRaid.targetId); ++ dev_dbg(&instance->pdev->dev, "fw_map_ext->ldSpanMap[%d].ldRaid.seqNum 0x%x\n", ++ i, fw_map_ext->ldSpanMap[i].ldRaid.seqNum); ++ dev_dbg(&instance->pdev->dev, "fw_map_ext->ldSpanMap[%d].ldRaid.rowSize 0x%x\n", ++ i, (u32)fw_map_ext->ldSpanMap[i].ldRaid.rowSize); ++ ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x\n", ++ i, i, pDrvRaidMap->ldSpanMap[i].ldRaid.targetId); ++ dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x\n", ++ i, pDrvRaidMap->ldSpanMap[i].ldRaid.seqNum); ++ dev_dbg(&instance->pdev->dev, "pDrvRaidMap->ldSpanMap[%d].ldRaid.rowSize 0x%x\n", ++ i, (u32)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize); ++ ++ dev_dbg(&instance->pdev->dev, "megaraid_sas(%d) : drv raid map all %p\n", ++ instance->unique_id, drv_map); ++ dev_dbg(&instance->pdev->dev, "raid map %p LD RAID MAP %p %p\n", ++ pDrvRaidMap, &fw_map_ext->ldSpanMap[i].ldRaid, ++ &pDrvRaidMap->ldSpanMap[i].ldRaid); ++ } ++#endif ++ memcpy(pDrvRaidMap->arMapInfo, fw_map_ext->arMapInfo, ++ sizeof(struct MR_ARRAY_INFO) * MAX_API_ARRAYS_EXT); ++ memcpy(pDrvRaidMap->devHndlInfo, fw_map_ext->devHndlInfo, ++ sizeof(struct MR_DEV_HANDLE_INFO) * ++ MAX_RAIDMAP_PHYSICAL_DEVICES); + +- if (instance->supportmax256vd) { +- memcpy(fusion->ld_drv_map[instance->map_id & 1], +- fusion->ld_map[instance->map_id & 1], +- fusion->current_map_sz); + /* New Raid map will not set totalSize, so keep expected value + * for legacy code in ValidateMapInfo + */ +@@ -213,16 +399,12 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) + } + #endif + +- memset(drv_map, 0, fusion->drv_map_sz); + pDrvRaidMap->totalSize = pFwRaidMap->totalSize; + pDrvRaidMap->ldCount = (__le16)cpu_to_le16(ld_count); + pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec; + for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; i++) + pDrvRaidMap->ldTgtIdToLd[i] = + (u8)pFwRaidMap->ldTgtIdToLd[i]; +- for (i = (MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS); +- i < MAX_LOGICAL_DRIVES_EXT; i++) +- pDrvRaidMap->ldTgtIdToLd[i] = 0xff; + for (i = 0; i < ld_count; i++) { + pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i]; + #if VD_EXT_DEBUG +@@ -279,7 +461,9 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) + lbInfo = fusion->load_balance_info; + ldSpanInfo = fusion->log_to_span; + +- if (instance->supportmax256vd) ++ if (instance->max_raid_mapsize) ++ expected_size = sizeof(struct MR_DRV_RAID_MAP_ALL); ++ else if (instance->supportmax256vd) + expected_size = sizeof(struct MR_FW_RAID_MAP_EXT); + else + expected_size = +@@ -287,8 +471,10 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance) + (sizeof(struct MR_LD_SPAN_MAP) * le16_to_cpu(pDrvRaidMap->ldCount))); + + if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) { +- dev_err(&instance->pdev->dev, "map info structure size 0x%x is not matching with ld count\n", +- (unsigned int) expected_size); ++ dev_dbg(&instance->pdev->dev, "megasas: map info structure size 0x%x", ++ le32_to_cpu(pDrvRaidMap->totalSize)); ++ dev_dbg(&instance->pdev->dev, "is not matching expected size 0x%x\n", ++ (unsigned int) expected_size); + dev_err(&instance->pdev->dev, "megasas: span map %x, pDrvRaidMap->totalSize : %x\n", + (unsigned int)sizeof(struct MR_LD_SPAN_MAP), + le32_to_cpu(pDrvRaidMap->totalSize)); +@@ -787,7 +973,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, + ((fusion->adapter_type == THUNDERBOLT_SERIES) || + ((fusion->adapter_type == INVADER_SERIES) && + (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) +- pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; ++ pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE; + else if (raid->level == 1) { + pd = MR_ArPdGet(arRef, physArm + 1, map); + if (pd != MR_PD_INVALID) +@@ -796,9 +982,16 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, + } + + *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk); +- pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | +- physArm; +- io_info->span_arm = pRAID_Context->spanArm; ++ if (instance->is_ventura) { ++ ((struct RAID_CONTEXT_G35 *) pRAID_Context)->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; ++ io_info->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; ++ } else { ++ pRAID_Context->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; ++ io_info->span_arm = pRAID_Context->span_arm; ++ } + return retval; + } + +@@ -890,7 +1083,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, + ((fusion->adapter_type == THUNDERBOLT_SERIES) || + ((fusion->adapter_type == INVADER_SERIES) && + (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) +- pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; ++ pRAID_Context->reg_lock_flags = REGION_TYPE_EXCLUSIVE; + else if (raid->level == 1) { + /* Get alternate Pd. */ + pd = MR_ArPdGet(arRef, physArm + 1, map); +@@ -901,9 +1094,16 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, + } + + *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk); +- pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | +- physArm; +- io_info->span_arm = pRAID_Context->spanArm; ++ if (instance->is_ventura) { ++ ((struct RAID_CONTEXT_G35 *) pRAID_Context)->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; ++ io_info->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; ++ } else { ++ pRAID_Context->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; ++ io_info->span_arm = pRAID_Context->span_arm; ++ } + return retval; + } + +@@ -1107,20 +1307,20 @@ MR_BuildRaidContext(struct megasas_instance *instance, + regSize += stripSize; + } + +- pRAID_Context->timeoutValue = ++ pRAID_Context->timeout_value = + cpu_to_le16(raid->fpIoTimeoutForLd ? + raid->fpIoTimeoutForLd : + map->raidMap.fpPdIoTimeoutSec); + if (fusion->adapter_type == INVADER_SERIES) +- pRAID_Context->regLockFlags = (isRead) ? ++ pRAID_Context->reg_lock_flags = (isRead) ? + raid->regTypeReqOnRead : raid->regTypeReqOnWrite; +- else +- pRAID_Context->regLockFlags = (isRead) ? ++ else if (!instance->is_ventura) ++ pRAID_Context->reg_lock_flags = (isRead) ? + REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite; +- pRAID_Context->VirtualDiskTgtId = raid->targetId; +- pRAID_Context->regLockRowLBA = cpu_to_le64(regStart); +- pRAID_Context->regLockLength = cpu_to_le32(regSize); +- pRAID_Context->configSeqNum = raid->seqNum; ++ pRAID_Context->virtual_disk_tgt_id = raid->targetId; ++ pRAID_Context->reg_lock_row_lba = cpu_to_le64(regStart); ++ pRAID_Context->reg_lock_length = cpu_to_le32(regSize); ++ pRAID_Context->config_seq_num = raid->seqNum; + /* save pointer to raid->LUN array */ + *raidLUN = raid->LUN; + +@@ -1138,6 +1338,13 @@ MR_BuildRaidContext(struct megasas_instance *instance, + /* If IO on an invalid Pd, then FP is not possible.*/ + if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID)) + io_info->fpOkForIo = FALSE; ++ /* if FP possible, set the SLUD bit in ++ * regLockFlags for ventura ++ */ ++ else if ((instance->is_ventura) && (!isRead) && ++ (raid->writeMode == MR_RL_WRITE_BACK_MODE) && ++ (raid->capability.fp_cache_bypass_capable)) ++ ((struct RAID_CONTEXT_G35 *) pRAID_Context)->routing_flags.bits.sld = 1; + /* set raid 1/10 fast path write capable bit in io_info */ + if (io_info->fpOkForIo && + (io_info->r1_alt_dev_handle != MR_PD_INVALID) && +@@ -1317,6 +1524,7 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance, + struct fusion_context *fusion; + struct MR_LD_RAID *raid; + struct MR_DRV_RAID_MAP_ALL *drv_map; ++ u16 pd1_dev_handle; + u16 pend0, pend1, ld; + u64 diff0, diff1; + u8 bestArm, pd0, pd1, span, arm; +@@ -1342,23 +1550,36 @@ u8 megasas_get_best_arm_pd(struct megasas_instance *instance, + pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ? + (arm + 1 - span_row_size) : arm + 1, drv_map); + +- /* get the pending cmds for the data and mirror arms */ +- pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]); +- pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]); ++ /* Get PD1 Dev Handle */ ++ ++ pd1_dev_handle = MR_PdDevHandleGet(pd1, drv_map); ++ ++ if (pd1_dev_handle == MR_PD_INVALID) { ++ bestArm = arm; ++ } else { ++ /* get the pending cmds for the data and mirror arms */ ++ pend0 = atomic_read(&lbInfo->scsi_pending_cmds[pd0]); ++ pend1 = atomic_read(&lbInfo->scsi_pending_cmds[pd1]); + +- /* Determine the disk whose head is nearer to the req. block */ +- diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]); +- diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]); +- bestArm = (diff0 <= diff1 ? arm : arm ^ 1); ++ /* Determine the disk whose head is nearer to the req. block */ ++ diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]); ++ diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]); ++ bestArm = (diff0 <= diff1 ? arm : arm ^ 1); + +- if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds) || ++ /* Make balance count from 16 to 4 to ++ * keep driver in sync with Firmware ++ */ ++ if ((bestArm == arm && pend0 > pend1 + lb_pending_cmds) || + (bestArm != arm && pend1 > pend0 + lb_pending_cmds)) +- bestArm ^= 1; ++ bestArm ^= 1; ++ ++ /* Update the last accessed block on the correct pd */ ++ io_info->span_arm = ++ (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm; ++ io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1; ++ } + +- /* Update the last accessed block on the correct pd */ +- io_info->pd_after_lb = (bestArm == arm) ? pd0 : pd1; + lbInfo->last_accessed_block[io_info->pd_after_lb] = block + count - 1; +- io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm; + #if SPAN_DEBUG + if (arm != bestArm) + dev_dbg(&instance->pdev->dev, "LSI Debug R1 Load balance " +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index b146cd1..178f166 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -1829,7 +1829,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + struct megasas_cmd_fusion *cmd) + { + u8 fp_possible; +- u32 start_lba_lo, start_lba_hi, device_id, datalength = 0; ++ u32 start_lba_lo, start_lba_hi, device_id, datalength = 0, ld; + struct MPI2_RAID_SCSI_IO_REQUEST *io_request; + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc; + struct IO_REQUEST_INFO io_info; +@@ -1837,16 +1837,18 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + struct MR_DRV_RAID_MAP_ALL *local_map_ptr; + u8 *raidLUN; + unsigned long spinlock_flags; ++ union RAID_CONTEXT_UNION *praid_context; ++ struct MR_LD_RAID *raid; + + device_id = MEGASAS_DEV_INDEX(scp); + + fusion = instance->ctrl_context; + + io_request = cmd->io_request; +- io_request->RaidContext.raid_context.VirtualDiskTgtId = ++ io_request->RaidContext.raid_context.virtual_disk_tgt_id = + cpu_to_le16(device_id); + io_request->RaidContext.raid_context.status = 0; +- io_request->RaidContext.raid_context.exStatus = 0; ++ io_request->RaidContext.raid_context.ex_status = 0; + + req_desc = (union MEGASAS_REQUEST_DESCRIPTOR_UNION *)cmd->request_desc; + +@@ -1915,10 +1917,12 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + io_info.isRead = 1; + + local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ++ ld = MR_TargetIdToLdGet(device_id, local_map_ptr); ++ raid = MR_LdRaidGet(ld, local_map_ptr); + + if ((MR_TargetIdToLdGet(device_id, local_map_ptr) >= + instance->fw_supported_vd_count) || (!fusion->fast_path_io)) { +- io_request->RaidContext.raid_context.regLockFlags = 0; ++ io_request->RaidContext.raid_context.reg_lock_flags = 0; + fp_possible = 0; + } else { + if (MR_BuildRaidContext(instance, &io_info, +@@ -1945,6 +1949,8 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + fp_possible = false; + } + ++ praid_context = &io_request->RaidContext; ++ + if (fp_possible) { + megasas_set_pd_lba(io_request, scp->cmd_len, &io_info, scp, + local_map_ptr, start_lba_lo); +@@ -1953,18 +1959,25 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + (MPI2_REQ_DESCRIPT_FLAGS_FP_IO + << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); + if (fusion->adapter_type == INVADER_SERIES) { +- if (io_request->RaidContext.raid_context.regLockFlags == ++ if (io_request->RaidContext.raid_context.reg_lock_flags == + REGION_TYPE_UNUSED) + cmd->request_desc->SCSIIO.RequestFlags = + (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK << + MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); +- io_request->RaidContext.raid_context.Type ++ io_request->RaidContext.raid_context.type + = MPI2_TYPE_CUDA; + io_request->RaidContext.raid_context.nseg = 0x1; + io_request->IoFlags |= cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); +- io_request->RaidContext.raid_context.regLockFlags |= ++ io_request->RaidContext.raid_context.reg_lock_flags |= + (MR_RL_FLAGS_GRANT_DESTINATION_CUDA | + MR_RL_FLAGS_SEQ_NUM_ENABLE); ++ } else if (instance->is_ventura) { ++ io_request->RaidContext.raid_context_g35.type ++ = MPI2_TYPE_CUDA; ++ io_request->RaidContext.raid_context_g35.nseg = 0x1; ++ io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1; ++ io_request->IoFlags |= ++ cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); + } + if ((fusion->load_balance_info[device_id].loadBalanceFlag) && + (io_info.isRead)) { +@@ -1974,6 +1987,13 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + &io_info); + scp->SCp.Status |= MEGASAS_LOAD_BALANCE_FLAG; + cmd->pd_r1_lb = io_info.pd_after_lb; ++ if (instance->is_ventura) ++ io_request->RaidContext.raid_context_g35.span_arm ++ = io_info.span_arm; ++ else ++ io_request->RaidContext.raid_context.span_arm ++ = io_info.span_arm; ++ + } else + scp->SCp.Status &= ~MEGASAS_LOAD_BALANCE_FLAG; + +@@ -1992,28 +2012,98 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, + io_request->DevHandle = io_info.devHandle; + /* populate the LUN field */ + memcpy(io_request->LUN, raidLUN, 8); ++ if (instance->is_ventura) { ++ if (io_info.isRead) { ++ if ((raid->cpuAffinity.pdRead.cpu0) && ++ (raid->cpuAffinity.pdRead.cpu1)) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_FCFS; ++ else if (raid->cpuAffinity.pdRead.cpu1) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_1; ++ else ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ } else { ++ if ((raid->cpuAffinity.pdWrite.cpu0) ++ && (raid->cpuAffinity.pdWrite.cpu1)) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_FCFS; ++ else if (raid->cpuAffinity.pdWrite.cpu1) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_1; ++ else ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ if (praid_context->raid_context_g35.routing_flags.bits.sld) { ++ praid_context->raid_context_g35.raid_flags ++ = (MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS ++ << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT); ++ } ++ } ++ } + } else { +- io_request->RaidContext.raid_context.timeoutValue = ++ io_request->RaidContext.raid_context.timeout_value = + cpu_to_le16(local_map_ptr->raidMap.fpPdIoTimeoutSec); + cmd->request_desc->SCSIIO.RequestFlags = + (MEGASAS_REQ_DESCRIPT_FLAGS_LD_IO + << MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); + if (fusion->adapter_type == INVADER_SERIES) { + if (io_info.do_fp_rlbypass || +- (io_request->RaidContext.raid_context.regLockFlags ++ (io_request->RaidContext.raid_context.reg_lock_flags + == REGION_TYPE_UNUSED)) + cmd->request_desc->SCSIIO.RequestFlags = + (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK << + MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); +- io_request->RaidContext.raid_context.Type ++ io_request->RaidContext.raid_context.type + = MPI2_TYPE_CUDA; +- io_request->RaidContext.raid_context.regLockFlags |= ++ io_request->RaidContext.raid_context.reg_lock_flags |= + (MR_RL_FLAGS_GRANT_DESTINATION_CPU0 | + MR_RL_FLAGS_SEQ_NUM_ENABLE); + io_request->RaidContext.raid_context.nseg = 0x1; ++ } else if (instance->is_ventura) { ++ io_request->RaidContext.raid_context_g35.type ++ = MPI2_TYPE_CUDA; ++ io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1; ++ io_request->RaidContext.raid_context_g35.nseg = 0x1; + } + io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; + io_request->DevHandle = cpu_to_le16(device_id); ++ ++ if (instance->is_ventura) { ++ if (io_info.isRead) { ++ if ((raid->cpuAffinity.ldRead.cpu0) ++ && (raid->cpuAffinity.ldRead.cpu1)) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_FCFS; ++ else if (raid->cpuAffinity.ldRead.cpu1) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_1; ++ else ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ } else { ++ if ((raid->cpuAffinity.ldWrite.cpu0) && ++ (raid->cpuAffinity.ldWrite.cpu1)) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_FCFS; ++ else if (raid->cpuAffinity.ldWrite.cpu1) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_1; ++ else ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ ++ if (io_request->RaidContext.raid_context_g35.stream_detected ++ && (raid->level == 5) && ++ (raid->writeMode == MR_RL_WRITE_THROUGH_MODE)) { ++ if (praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ == MR_RAID_CTX_CPUSEL_FCFS) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ } ++ } ++ } + } /* Not FP */ + } + +@@ -2048,9 +2138,9 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, + /* get RAID_Context pointer */ + pRAID_Context = &io_request->RaidContext.raid_context; + /* Check with FW team */ +- pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id); +- pRAID_Context->regLockRowLBA = 0; +- pRAID_Context->regLockLength = 0; ++ pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id); ++ pRAID_Context->reg_lock_row_lba = 0; ++ pRAID_Context->reg_lock_length = 0; + + if (fusion->fast_path_io && ( + device_id < instance->fw_supported_vd_count)) { +@@ -2069,7 +2159,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, + io_request->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST; + io_request->DevHandle = cpu_to_le16(device_id); + io_request->LUN[1] = scmd->device->lun; +- pRAID_Context->timeoutValue = ++ pRAID_Context->timeout_value = + cpu_to_le16 (scmd->request->timeout / HZ); + cmd->request_desc->SCSIIO.RequestFlags = + (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << +@@ -2077,9 +2167,11 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, + } else { + + /* set RAID context values */ +- pRAID_Context->configSeqNum = raid->seqNum; +- pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ; +- pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd); ++ pRAID_Context->config_seq_num = raid->seqNum; ++ if (!instance->is_ventura) ++ pRAID_Context->reg_lock_flags = REGION_TYPE_SHARED_READ; ++ pRAID_Context->timeout_value = ++ cpu_to_le16(raid->fpIoTimeoutForLd); + + /* get the DevHandle for the PD (since this is + fpNonRWCapable, this is a single disk RAID0) */ +@@ -2134,12 +2226,12 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, + io_request = cmd->io_request; + /* get RAID_Context pointer */ + pRAID_Context = &io_request->RaidContext.raid_context; +- pRAID_Context->regLockFlags = 0; +- pRAID_Context->regLockRowLBA = 0; +- pRAID_Context->regLockLength = 0; ++ pRAID_Context->reg_lock_flags = 0; ++ pRAID_Context->reg_lock_row_lba = 0; ++ pRAID_Context->reg_lock_length = 0; + io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); + io_request->LUN[1] = scmd->device->lun; +- pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD ++ pRAID_Context->raid_flags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD + << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT; + + /* If FW supports PD sequence number */ +@@ -2148,24 +2240,27 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, + /* TgtId must be incremented by 255 as jbod seq number is index + * below raid map + */ +- pRAID_Context->VirtualDiskTgtId = ++ pRAID_Context->virtual_disk_tgt_id = + cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1)); +- pRAID_Context->configSeqNum = pd_sync->seq[pd_index].seqNum; ++ pRAID_Context->config_seq_num = pd_sync->seq[pd_index].seqNum; + io_request->DevHandle = pd_sync->seq[pd_index].devHandle; +- pRAID_Context->regLockFlags |= ++ if (instance->is_ventura) ++ io_request->RaidContext.raid_context_g35.routing_flags.bits.sqn = 1; ++ else ++ pRAID_Context->reg_lock_flags |= + (MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA); +- pRAID_Context->Type = MPI2_TYPE_CUDA; ++ pRAID_Context->type = MPI2_TYPE_CUDA; + pRAID_Context->nseg = 0x1; + } else if (fusion->fast_path_io) { +- pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id); +- pRAID_Context->configSeqNum = 0; ++ pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id); ++ pRAID_Context->config_seq_num = 0; + local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; + io_request->DevHandle = + local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl; + } else { + /* Want to send all IO via FW path */ +- pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id); +- pRAID_Context->configSeqNum = 0; ++ pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id); ++ pRAID_Context->config_seq_num = 0; + io_request->DevHandle = cpu_to_le16(0xFFFF); + } + +@@ -2181,14 +2276,14 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, + cmd->request_desc->SCSIIO.RequestFlags = + (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << + MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); +- pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value); +- pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id); ++ pRAID_Context->timeout_value = cpu_to_le16(os_timeout_value); ++ pRAID_Context->virtual_disk_tgt_id = cpu_to_le16(device_id); + } else { + /* system pd Fast Path */ + io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; + timeout_limit = (scmd->device->type == TYPE_DISK) ? + 255 : 0xFFFF; +- pRAID_Context->timeoutValue = ++ pRAID_Context->timeout_value = + cpu_to_le16((os_timeout_value > timeout_limit) ? + timeout_limit : os_timeout_value); + if (fusion->adapter_type == INVADER_SERIES) +@@ -2227,8 +2322,8 @@ megasas_build_io_fusion(struct megasas_instance *instance, + io_request->Control = 0; + io_request->EEDPBlockSize = 0; + io_request->ChainOffset = 0; +- io_request->RaidContext.raid_context.RAIDFlags = 0; +- io_request->RaidContext.raid_context.Type = 0; ++ io_request->RaidContext.raid_context.raid_flags = 0; ++ io_request->RaidContext.raid_context.type = 0; + io_request->RaidContext.raid_context.nseg = 0; + + memcpy(io_request->CDB.CDB32, scp->cmnd, scp->cmd_len); +@@ -2273,11 +2368,16 @@ megasas_build_io_fusion(struct megasas_instance *instance, + return 1; + } + +- /* numSGE store lower 8 bit of sge_count. +- * numSGEExt store higher 8 bit of sge_count +- */ +- io_request->RaidContext.raid_context.numSGE = sge_count; +- io_request->RaidContext.raid_context.numSGEExt = (u8)(sge_count >> 8); ++ if (instance->is_ventura) ++ io_request->RaidContext.raid_context_g35.num_sge = sge_count; ++ else { ++ /* numSGE store lower 8 bit of sge_count. ++ * numSGEExt store higher 8 bit of sge_count ++ */ ++ io_request->RaidContext.raid_context.num_sge = sge_count; ++ io_request->RaidContext.raid_context.num_sge_ext = ++ (u8)(sge_count >> 8); ++ } + + io_request->SGLFlags = cpu_to_le16(MPI2_SGE_FLAGS_64_BIT_ADDRESSING); + +@@ -2326,6 +2426,10 @@ void megasas_fpio_to_ldio(struct megasas_instance *instance, + struct megasas_cmd_fusion *cmd, struct scsi_cmnd *scmd) + { + struct fusion_context *fusion; ++ union RAID_CONTEXT_UNION *praid_context; ++ struct MR_LD_RAID *raid; ++ struct MR_DRV_RAID_MAP_ALL *local_map_ptr; ++ u32 device_id, ld; + + fusion = instance->ctrl_context; + cmd->request_desc->SCSIIO.RequestFlags = +@@ -2349,6 +2453,35 @@ void megasas_fpio_to_ldio(struct megasas_instance *instance, + cmd->io_request->Control = 0; + cmd->io_request->EEDPBlockSize = 0; + cmd->is_raid_1_fp_write = 0; ++ ++ device_id = MEGASAS_DEV_INDEX(cmd->scmd); ++ local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; ++ ld = MR_TargetIdToLdGet(device_id, local_map_ptr); ++ raid = MR_LdRaidGet(ld, local_map_ptr); ++ praid_context = &cmd->io_request->RaidContext; ++ if (cmd->scmd->sc_data_direction == PCI_DMA_FROMDEVICE) { ++ if ((raid->cpuAffinity.ldRead.cpu0) ++ && (raid->cpuAffinity.ldRead.cpu1)) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_FCFS; ++ else if (raid->cpuAffinity.ldRead.cpu1) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_1; ++ else ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ } else { ++ if ((raid->cpuAffinity.ldWrite.cpu0) ++ && (raid->cpuAffinity.ldWrite.cpu1)) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_FCFS; ++ else if (raid->cpuAffinity.ldWrite.cpu1) ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_1; ++ else ++ praid_context->raid_context_g35.routing_flags.bits.cpu_sel ++ = MR_RAID_CTX_CPUSEL_0; ++ } + } + + /* megasas_prepate_secondRaid1_IO +@@ -2585,7 +2718,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + + scmd_local = cmd_fusion->scmd; + status = scsi_io_req->RaidContext.raid_context.status; +- extStatus = scsi_io_req->RaidContext.raid_context.exStatus; ++ extStatus = scsi_io_req->RaidContext.raid_context.ex_status; + sense = cmd_fusion->sense; + data_length = scsi_io_req->DataLength; + +@@ -2653,13 +2786,13 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + status = + r1_cmd->io_request->RaidContext.raid_context.status; + extStatus = +- r1_cmd->io_request->RaidContext.raid_context.exStatus; ++ r1_cmd->io_request->RaidContext.raid_context.ex_status; + data_length = + r1_cmd->io_request->DataLength; + sense = r1_cmd->sense; + } + r1_cmd->io_request->RaidContext.raid_context.status = 0; +- r1_cmd->io_request->RaidContext.raid_context.exStatus = 0; ++ r1_cmd->io_request->RaidContext.raid_context.ex_status = 0; + cmd_fusion->is_raid_1_fp_write = 0; + r1_cmd->is_raid_1_fp_write = 0; + r1_cmd->cmd_completed = false; +@@ -2669,10 +2802,8 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + if (!cmd_fusion->is_raid_1_fp_write) { + map_cmd_status(fusion, scmd_local, status, + extStatus, data_length, sense); +- scsi_io_req->RaidContext.raid_context.status +- = 0; +- scsi_io_req->RaidContext.raid_context.exStatus +- = 0; ++ scsi_io_req->RaidContext.raid_context.status = 0; ++ scsi_io_req->RaidContext.raid_context.ex_status = 0; + megasas_return_cmd_fusion(instance, cmd_fusion); + scsi_dma_unmap(scmd_local); + scmd_local->scsi_done(scmd_local); +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index 7a3c3d1..2de12b4 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -59,6 +59,8 @@ + #define MR_RL_FLAGS_GRANT_DESTINATION_CPU1 0x10 + #define MR_RL_FLAGS_GRANT_DESTINATION_CUDA 0x80 + #define MR_RL_FLAGS_SEQ_NUM_ENABLE 0x8 ++#define MR_RL_WRITE_THROUGH_MODE 0x00 ++#define MR_RL_WRITE_BACK_MODE 0x01 + + /* T10 PI defines */ + #define MR_PROT_INFO_TYPE_CONTROLLER 0x8 +@@ -81,6 +83,11 @@ + enum MR_RAID_FLAGS_IO_SUB_TYPE { + MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0, + MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1, ++ MR_RAID_FLAGS_IO_SUB_TYPE_RMW_DATA = 2, ++ MR_RAID_FLAGS_IO_SUB_TYPE_RMW_P = 3, ++ MR_RAID_FLAGS_IO_SUB_TYPE_RMW_Q = 4, ++ MR_RAID_FLAGS_IO_SUB_TYPE_CACHE_BYPASS = 6, ++ MR_RAID_FLAGS_IO_SUB_TYPE_LDIO_BW_LIMIT = 7 + }; + + /* +@@ -109,29 +116,29 @@ enum MR_FUSION_ADAPTER_TYPE { + + struct RAID_CONTEXT { + #if defined(__BIG_ENDIAN_BITFIELD) +- u8 nseg:4; +- u8 Type:4; ++ u8 nseg:4; ++ u8 type:4; + #else +- u8 Type:4; +- u8 nseg:4; ++ u8 type:4; ++ u8 nseg:4; + #endif +- u8 resvd0; +- __le16 timeoutValue; +- u8 regLockFlags; +- u8 resvd1; +- __le16 VirtualDiskTgtId; +- __le64 regLockRowLBA; +- __le32 regLockLength; +- __le16 nextLMId; +- u8 exStatus; +- u8 status; +- u8 RAIDFlags; +- u8 numSGE; +- __le16 configSeqNum; +- u8 spanArm; +- u8 priority; +- u8 numSGEExt; +- u8 resvd2; ++ u8 resvd0; ++ __le16 timeout_value; ++ u8 reg_lock_flags; ++ u8 resvd1; ++ __le16 virtual_disk_tgt_id; ++ __le64 reg_lock_row_lba; ++ __le32 reg_lock_length; ++ __le16 next_lmid; ++ u8 ex_status; ++ u8 status; ++ u8 raid_flags; ++ u8 num_sge; ++ __le16 config_seq_num; ++ u8 span_arm; ++ u8 priority; ++ u8 num_sge_ext; ++ u8 resvd2; + }; + + /* +@@ -187,7 +194,7 @@ struct RAID_CONTEXT_G35 { + } smid; + u8 ex_status; /* 0x16 : OUT */ + u8 status; /* 0x17 status */ +- u8 RAIDFlags; /* 0x18 resvd[7:6], ioSubType[5:4], ++ u8 raid_flags; /* 0x18 resvd[7:6], ioSubType[5:4], + * resvd[3:1], preferredCpu[0] + */ + u8 span_arm; /* 0x1C span[7:5], arm[4:0] */ +@@ -672,14 +679,17 @@ struct MPI2_IOC_INIT_REQUEST { + #define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE) + #define MAX_LOGICAL_DRIVES 64 + #define MAX_LOGICAL_DRIVES_EXT 256 ++#define MAX_LOGICAL_DRIVES_DYN 512 + #define MAX_RAIDMAP_LOGICAL_DRIVES (MAX_LOGICAL_DRIVES) + #define MAX_RAIDMAP_VIEWS (MAX_LOGICAL_DRIVES) + #define MAX_ARRAYS 128 + #define MAX_RAIDMAP_ARRAYS (MAX_ARRAYS) + #define MAX_ARRAYS_EXT 256 + #define MAX_API_ARRAYS_EXT (MAX_ARRAYS_EXT) ++#define MAX_API_ARRAYS_DYN 512 + #define MAX_PHYSICAL_DEVICES 256 + #define MAX_RAIDMAP_PHYSICAL_DEVICES (MAX_PHYSICAL_DEVICES) ++#define MAX_RAIDMAP_PHYSICAL_DEVICES_DYN 512 + #define MR_DCMD_LD_MAP_GET_INFO 0x0300e101 + #define MR_DCMD_SYSTEM_PD_MAP_GET_INFO 0x0200e102 + #define MR_DCMD_CTRL_SHARED_HOST_MEM_ALLOC 0x010e8485 /* SR-IOV HB alloc*/ +@@ -726,12 +736,56 @@ struct MR_SPAN_BLOCK_INFO { + struct MR_SPAN_INFO block_span_info; + }; + ++#define MR_RAID_CTX_CPUSEL_0 0 ++#define MR_RAID_CTX_CPUSEL_1 1 ++#define MR_RAID_CTX_CPUSEL_2 2 ++#define MR_RAID_CTX_CPUSEL_3 3 ++#define MR_RAID_CTX_CPUSEL_FCFS 0xF ++ ++struct MR_CPU_AFFINITY_MASK { ++ union { ++ struct { ++#ifndef MFI_BIG_ENDIAN ++ u8 hw_path:1; ++ u8 cpu0:1; ++ u8 cpu1:1; ++ u8 cpu2:1; ++ u8 cpu3:1; ++ u8 reserved:3; ++#else ++ u8 reserved:3; ++ u8 cpu3:1; ++ u8 cpu2:1; ++ u8 cpu1:1; ++ u8 cpu0:1; ++ u8 hw_path:1; ++#endif ++ }; ++ u8 core_mask; ++ }; ++}; ++ ++struct MR_IO_AFFINITY { ++ union { ++ struct { ++ struct MR_CPU_AFFINITY_MASK pdRead; ++ struct MR_CPU_AFFINITY_MASK pdWrite; ++ struct MR_CPU_AFFINITY_MASK ldRead; ++ struct MR_CPU_AFFINITY_MASK ldWrite; ++ }; ++ u32 word; ++ }; ++ u8 maxCores; /* Total cores + HW Path in ROC */ ++ u8 reserved[3]; ++}; ++ + struct MR_LD_RAID { + struct { + #if defined(__BIG_ENDIAN_BITFIELD) +- u32 reserved4:3; +- u32 fp_cache_bypass_capable:1; +- u32 fp_rmw_capable:1; ++ u32 reserved4:2; ++ u32 fp_cache_bypass_capable:1; ++ u32 fp_rmw_capable:1; ++ u32 disable_coalescing:1; + u32 fpBypassRegionLock:1; + u32 tmCapable:1; + u32 fpNonRWCapable:1; +@@ -759,9 +813,10 @@ struct MR_LD_RAID { + u32 fpNonRWCapable:1; + u32 tmCapable:1; + u32 fpBypassRegionLock:1; +- u32 fp_rmw_capable:1; +- u32 fp_cache_bypass_capable:1; +- u32 reserved4:3; ++ u32 disable_coalescing:1; ++ u32 fp_rmw_capable:1; ++ u32 fp_cache_bypass_capable:1; ++ u32 reserved4:2; + #endif + } capability; + __le32 reserved6; +@@ -788,7 +843,36 @@ struct MR_LD_RAID { + + u8 LUN[8]; /* 0x24 8 byte LUN field used for SCSI IO's */ + u8 fpIoTimeoutForLd;/*0x2C timeout value used by driver in FP IO*/ +- u8 reserved3[0x80-0x2D]; /* 0x2D */ ++ /* Ox2D This LD accept priority boost of this type */ ++ u8 ld_accept_priority_type; ++ u8 reserved2[2]; /* 0x2E - 0x2F */ ++ /* 0x30 - 0x33, Logical block size for the LD */ ++ u32 logical_block_length; ++ struct { ++#ifndef MFI_BIG_ENDIAN ++ /* 0x34, P_I_EXPONENT from READ CAPACITY 16 */ ++ u32 ld_pi_exp:4; ++ /* 0x34, LOGICAL BLOCKS PER PHYSICAL ++ * BLOCK EXPONENT from READ CAPACITY 16 ++ */ ++ u32 ld_logical_block_exp:4; ++ u32 reserved1:24; /* 0x34 */ ++#else ++ u32 reserved1:24; /* 0x34 */ ++ /* 0x34, LOGICAL BLOCKS PER PHYSICAL ++ * BLOCK EXPONENT from READ CAPACITY 16 ++ */ ++ u32 ld_logical_block_exp:4; ++ /* 0x34, P_I_EXPONENT from READ CAPACITY 16 */ ++ u32 ld_pi_exp:4; ++#endif ++ }; /* 0x34 - 0x37 */ ++ /* 0x38 - 0x3f, This will determine which ++ * core will process LD IO and PD IO. ++ */ ++ struct MR_IO_AFFINITY cpuAffinity; ++ /* Bit definiations are specified by MR_IO_AFFINITY */ ++ u8 reserved3[0x80-0x40]; /* 0x40 - 0x7f */ + }; + + struct MR_LD_SPAN_MAP { +@@ -846,6 +930,91 @@ struct MR_LD_TARGET_SYNC { + __le16 seqNum; + }; + ++/* ++ * RAID Map descriptor Types. ++ * Each element should uniquely idetify one data structure in the RAID map ++ */ ++enum MR_RAID_MAP_DESC_TYPE { ++ /* MR_DEV_HANDLE_INFO data */ ++ RAID_MAP_DESC_TYPE_DEVHDL_INFO = 0x0, ++ /* target to Ld num Index map */ ++ RAID_MAP_DESC_TYPE_TGTID_INFO = 0x1, ++ /* MR_ARRAY_INFO data */ ++ RAID_MAP_DESC_TYPE_ARRAY_INFO = 0x2, ++ /* MR_LD_SPAN_MAP data */ ++ RAID_MAP_DESC_TYPE_SPAN_INFO = 0x3, ++ RAID_MAP_DESC_TYPE_COUNT, ++}; ++ ++/* ++ * This table defines the offset, size and num elements of each descriptor ++ * type in the RAID Map buffer ++ */ ++struct MR_RAID_MAP_DESC_TABLE { ++ /* Raid map descriptor type */ ++ u32 raid_map_desc_type; ++ /* Offset into the RAID map buffer where ++ * descriptor data is saved ++ */ ++ u32 raid_map_desc_offset; ++ /* total size of the ++ * descriptor buffer ++ */ ++ u32 raid_map_desc_buffer_size; ++ /* Number of elements contained in the ++ * descriptor buffer ++ */ ++ u32 raid_map_desc_elements; ++}; ++ ++/* ++ * Dynamic Raid Map Structure. ++ */ ++struct MR_FW_RAID_MAP_DYNAMIC { ++ u32 raid_map_size; /* total size of RAID Map structure */ ++ u32 desc_table_offset;/* Offset of desc table into RAID map*/ ++ u32 desc_table_size; /* Total Size of desc table */ ++ /* Total Number of elements in the desc table */ ++ u32 desc_table_num_elements; ++ u64 reserved1; ++ u32 reserved2[3]; /*future use */ ++ /* timeout value used by driver in FP IOs */ ++ u8 fp_pd_io_timeout_sec; ++ u8 reserved3[3]; ++ /* when this seqNum increments, driver needs to ++ * release RMW buffers asap ++ */ ++ u32 rmw_fp_seq_num; ++ u16 ld_count; /* count of lds. */ ++ u16 ar_count; /* count of arrays */ ++ u16 span_count; /* count of spans */ ++ u16 reserved4[3]; ++/* ++ * The below structure of pointers is only to be used by the driver. ++ * This is added in the ,API to reduce the amount of code changes ++ * needed in the driver to support dynamic RAID map Firmware should ++ * not update these pointers while preparing the raid map ++ */ ++ union { ++ struct { ++ struct MR_DEV_HANDLE_INFO *dev_hndl_info; ++ u16 *ld_tgt_id_to_ld; ++ struct MR_ARRAY_INFO *ar_map_info; ++ struct MR_LD_SPAN_MAP *ld_span_map; ++ }; ++ u64 ptr_structure_size[RAID_MAP_DESC_TYPE_COUNT]; ++ }; ++/* ++ * RAID Map descriptor table defines the layout of data in the RAID Map. ++ * The size of the descriptor table itself could change. ++ */ ++ /* Variable Size descriptor Table. */ ++ struct MR_RAID_MAP_DESC_TABLE ++ raid_map_desc_table[RAID_MAP_DESC_TYPE_COUNT]; ++ /* Variable Size buffer containing all data */ ++ u32 raid_map_desc_data[1]; ++}; /* Dynamicaly sized RAID MAp structure */ ++ + #define IEEE_SGE_FLAGS_ADDR_MASK (0x03) + #define IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00) + #define IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01) +@@ -955,9 +1124,10 @@ struct MR_DRV_RAID_MAP { + __le16 spanCount; + __le16 reserve3; + +- struct MR_DEV_HANDLE_INFO devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES]; +- u8 ldTgtIdToLd[MAX_LOGICAL_DRIVES_EXT]; +- struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_EXT]; ++ struct MR_DEV_HANDLE_INFO ++ devHndlInfo[MAX_RAIDMAP_PHYSICAL_DEVICES_DYN]; ++ u16 ldTgtIdToLd[MAX_LOGICAL_DRIVES_DYN]; ++ struct MR_ARRAY_INFO arMapInfo[MAX_API_ARRAYS_DYN]; + struct MR_LD_SPAN_MAP ldSpanMap[1]; + + }; +@@ -969,7 +1139,7 @@ struct MR_DRV_RAID_MAP { + struct MR_DRV_RAID_MAP_ALL { + + struct MR_DRV_RAID_MAP raidMap; +- struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_EXT - 1]; ++ struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES_DYN - 1]; + } __packed; + + +@@ -1088,7 +1258,7 @@ struct fusion_context { + u8 chain_offset_io_request; + u8 chain_offset_mfi_pthru; + +- struct MR_FW_RAID_MAP_ALL *ld_map[2]; ++ struct MR_FW_RAID_MAP_DYNAMIC *ld_map[2]; + dma_addr_t ld_map_phys[2]; + + /*Non dma-able memory. Driver local copy.*/ +@@ -1096,6 +1266,8 @@ struct fusion_context { + + u32 max_map_sz; + u32 current_map_sz; ++ u32 old_map_sz; ++ u32 new_map_sz; + u32 drv_map_sz; + u32 drv_map_pages; + struct MR_PD_CFG_SEQ_NUM_SYNC *pd_seq_sync[JBOD_MAPS_COUNT]; +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0006-scsi-mpt3sas-Added-Device-ID-s-for-SAS35-devices-and.patch b/SOURCES/centos-linux-3.10-0006-scsi-mpt3sas-Added-Device-ID-s-for-SAS35-devices-and.patch new file mode 100644 index 0000000..1d1a251 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0006-scsi-mpt3sas-Added-Device-ID-s-for-SAS35-devices-and.patch @@ -0,0 +1,141 @@ +From 60eded7faed3769b20a519c65a04d9eb9dd48332 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:37 +0530 +Subject: [PATCH 06/11] scsi: mpt3sas: Added Device ID's for SAS35 devices and + updated MPI header. + +Added Device ID's for SAS35 devices (Ventura, Crusader, Harpoon & +Tomcat) and updated mpi header file for the same. Also added +"is_gen35_ioc" to MPT3SAS_ADAPTER structure for identifying SAS35 adapters. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | 7 +++++++ + drivers/scsi/mpt3sas/mpt3sas_base.h | 1 + + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 ++++- + drivers/scsi/mpt3sas/mpt3sas_ctl.h | 1 + + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 31 +++++++++++++++++++++++++++++++ + 5 files changed, 44 insertions(+), 1 deletion(-) + +diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +index 95356a8..fa61baf 100644 +--- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h ++++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +@@ -478,6 +478,13 @@ typedef struct _MPI2_CONFIG_REPLY { + #define MPI26_MFGPAGE_DEVID_SAS3324_3 (0x00C2) + #define MPI26_MFGPAGE_DEVID_SAS3324_4 (0x00C3) + ++#define MPI26_MFGPAGE_DEVID_SAS3516 (0x00AA) ++#define MPI26_MFGPAGE_DEVID_SAS3516_1 (0x00AB) ++#define MPI26_MFGPAGE_DEVID_SAS3416 (0x00AC) ++#define MPI26_MFGPAGE_DEVID_SAS3508 (0x00AD) ++#define MPI26_MFGPAGE_DEVID_SAS3508_1 (0x00AE) ++#define MPI26_MFGPAGE_DEVID_SAS3408 (0x00AF) ++ + /*Manufacturing Page 0 */ + + typedef struct _MPI2_CONFIG_PAGE_MAN_0 { +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 66cfa0f..c3a39e8 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -1205,6 +1205,7 @@ struct MPT3SAS_ADAPTER { + struct SL_WH_MPI_TRIGGERS_T diag_trigger_mpi; + void *device_remove_in_progress; + u16 device_remove_in_progress_sz; ++ u8 is_gen35_ioc; + }; + + typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index a75f8a3..a66c0c8 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -1101,7 +1101,10 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) + break; + case MPI25_VERSION: + case MPI26_VERSION: +- karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3; ++ if (ioc->is_gen35_ioc) ++ karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS35; ++ else ++ karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3; + strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION); + break; + } +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h +index 8940835..f3e17a8 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h +@@ -143,6 +143,7 @@ struct mpt3_ioctl_pci_info { + #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) + #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) + #define MPT3_IOCTL_INTERFACE_SAS3 (0x06) ++#define MPT3_IOCTL_INTERFACE_SAS35 (0x07) + #define MPT2_IOCTL_VERSION_LENGTH (32) + + /** +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index c6aa172..eaef45c 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -8722,6 +8722,12 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev) + case MPI26_MFGPAGE_DEVID_SAS3324_2: + case MPI26_MFGPAGE_DEVID_SAS3324_3: + case MPI26_MFGPAGE_DEVID_SAS3324_4: ++ case MPI26_MFGPAGE_DEVID_SAS3508: ++ case MPI26_MFGPAGE_DEVID_SAS3508_1: ++ case MPI26_MFGPAGE_DEVID_SAS3408: ++ case MPI26_MFGPAGE_DEVID_SAS3516: ++ case MPI26_MFGPAGE_DEVID_SAS3516_1: ++ case MPI26_MFGPAGE_DEVID_SAS3416: + return MPI26_VERSION; + } + return 0; +@@ -8777,6 +8783,18 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + ioc->hba_mpi_version_belonged = hba_mpi_version; + ioc->id = mpt3_ids++; + sprintf(ioc->driver_name, "%s", MPT3SAS_DRIVER_NAME); ++ switch (pdev->device) { ++ case MPI26_MFGPAGE_DEVID_SAS3508: ++ case MPI26_MFGPAGE_DEVID_SAS3508_1: ++ case MPI26_MFGPAGE_DEVID_SAS3408: ++ case MPI26_MFGPAGE_DEVID_SAS3516: ++ case MPI26_MFGPAGE_DEVID_SAS3516_1: ++ case MPI26_MFGPAGE_DEVID_SAS3416: ++ ioc->is_gen35_ioc = 1; ++ break; ++ default: ++ ioc->is_gen35_ioc = 0; ++ } + if ((ioc->hba_mpi_version_belonged == MPI25_VERSION && + pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) || + (ioc->hba_mpi_version_belonged == MPI26_VERSION)) +@@ -9186,6 +9204,19 @@ static const struct pci_device_id mpt3sas_pci_table[] = { + PCI_ANY_ID, PCI_ANY_ID }, + { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3324_4, + PCI_ANY_ID, PCI_ANY_ID }, ++ /* Ventura, Crusader, Harpoon & Tomcat ~ 3516, 3416, 3508 & 3408*/ ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3508, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3508_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3408, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3516, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3516_1, ++ PCI_ANY_ID, PCI_ANY_ID }, ++ { MPI2_MFGPAGE_VENDORID_LSI, MPI26_MFGPAGE_DEVID_SAS3416, ++ PCI_ANY_ID, PCI_ANY_ID }, + #endif /* MPT2SAS_SCSI */ + {0} /* Terminating entry */ + }; +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0007-scsi-megaraid_sas-Add-the-Support-for-SAS3.5-Generic.patch b/SOURCES/centos-linux-3.10-0007-scsi-megaraid_sas-Add-the-Support-for-SAS3.5-Generic.patch new file mode 100644 index 0000000..6e01fe2 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0007-scsi-megaraid_sas-Add-the-Support-for-SAS3.5-Generic.patch @@ -0,0 +1,183 @@ +From 1d7d67352bddfd44384bd8778f822da279ff78f8 Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:49 -0500 +Subject: [PATCH 07/11] scsi: megaraid_sas: Add the Support for SAS3.5 Generic + Megaraid Controllers Capabilities + +The Megaraid driver has to support the SAS3.5 Generic Megaraid Controllers Firmware functionality. + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas_base.c | 53 ++++++++++++++--------------- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 19 ++++++----- + drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 + + 3 files changed, 37 insertions(+), 36 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 1d8cf03..8b0c686 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -5089,34 +5089,29 @@ static int megasas_init_fw(struct megasas_instance *instance) + + reg_set = instance->reg_set; + +- switch (instance->pdev->device) { +- case PCI_DEVICE_ID_LSI_FUSION: +- case PCI_DEVICE_ID_LSI_PLASMA: +- case PCI_DEVICE_ID_LSI_INVADER: +- case PCI_DEVICE_ID_LSI_FURY: +- case PCI_DEVICE_ID_LSI_INTRUDER: +- case PCI_DEVICE_ID_LSI_INTRUDER_24: +- case PCI_DEVICE_ID_LSI_CUTLASS_52: +- case PCI_DEVICE_ID_LSI_CUTLASS_53: ++ if (fusion) + instance->instancet = &megasas_instance_template_fusion; +- break; +- case PCI_DEVICE_ID_LSI_SAS1078R: +- case PCI_DEVICE_ID_LSI_SAS1078DE: +- instance->instancet = &megasas_instance_template_ppc; +- break; +- case PCI_DEVICE_ID_LSI_SAS1078GEN2: +- case PCI_DEVICE_ID_LSI_SAS0079GEN2: +- instance->instancet = &megasas_instance_template_gen2; +- break; +- case PCI_DEVICE_ID_LSI_SAS0073SKINNY: +- case PCI_DEVICE_ID_LSI_SAS0071SKINNY: +- instance->instancet = &megasas_instance_template_skinny; +- break; +- case PCI_DEVICE_ID_LSI_SAS1064R: +- case PCI_DEVICE_ID_DELL_PERC5: +- default: +- instance->instancet = &megasas_instance_template_xscale; +- break; ++ else { ++ switch (instance->pdev->device) { ++ case PCI_DEVICE_ID_LSI_SAS1078R: ++ case PCI_DEVICE_ID_LSI_SAS1078DE: ++ instance->instancet = &megasas_instance_template_ppc; ++ break; ++ case PCI_DEVICE_ID_LSI_SAS1078GEN2: ++ case PCI_DEVICE_ID_LSI_SAS0079GEN2: ++ instance->instancet = &megasas_instance_template_gen2; ++ break; ++ case PCI_DEVICE_ID_LSI_SAS0073SKINNY: ++ case PCI_DEVICE_ID_LSI_SAS0071SKINNY: ++ instance->instancet = &megasas_instance_template_skinny; ++ break; ++ case PCI_DEVICE_ID_LSI_SAS1064R: ++ case PCI_DEVICE_ID_DELL_PERC5: ++ default: ++ instance->instancet = &megasas_instance_template_xscale; ++ instance->pd_list_not_supported = 1; ++ break; ++ } + } + + if (megasas_transition_to_ready(instance, 0)) { +@@ -5869,7 +5864,9 @@ static int megasas_probe_one(struct pci_dev *pdev, + if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || + (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) + fusion->adapter_type = THUNDERBOLT_SERIES; +- else if (!instance->is_ventura) ++ else if (instance->is_ventura) ++ fusion->adapter_type = VENTURA_SERIES; ++ else + fusion->adapter_type = INVADER_SERIES; + } + break; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 178f166..1802c57 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -244,7 +244,10 @@ megasas_fusion_update_can_queue(struct megasas_instance *instance, int fw_boot_c + + reg_set = instance->reg_set; + +- cur_max_fw_cmds = readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00FFFF; ++ /* ventura FW does not fill outbound_scratch_pad_3 with queue depth */ ++ if (!instance->is_ventura) ++ cur_max_fw_cmds = ++ readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00FFFF; + + if (dual_qdepth_disable || !cur_max_fw_cmds) + cur_max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF; +@@ -837,7 +840,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) + drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations); + + /* driver support Extended MSIX */ +- if (fusion->adapter_type == INVADER_SERIES) ++ if (fusion->adapter_type >= INVADER_SERIES) + drv_ops->mfi_capabilities.support_additional_msix = 1; + /* driver supports HA / Remote LUN over Fast Path interface */ + drv_ops->mfi_capabilities.support_fp_remote_lun = 1; +@@ -1491,7 +1494,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, + + fusion = instance->ctrl_context; + +- if (fusion->adapter_type == INVADER_SERIES) { ++ if (fusion->adapter_type >= INVADER_SERIES) { + struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = sgl_ptr; + sgl_ptr_end += fusion->max_sge_in_main_msg - 1; + sgl_ptr_end->Flags = 0; +@@ -1508,7 +1511,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, + sgl_ptr->Length = cpu_to_le32(sg_dma_len(os_sgl)); + sgl_ptr->Address = cpu_to_le64(sg_dma_address(os_sgl)); + sgl_ptr->Flags = 0; +- if (fusion->adapter_type == INVADER_SERIES) ++ if (fusion->adapter_type >= INVADER_SERIES) + if (i == sge_count - 1) + sgl_ptr->Flags = IEEE_SGE_FLAGS_END_OF_LIST; + sgl_ptr++; +@@ -1519,7 +1522,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, + (sge_count > fusion->max_sge_in_main_msg)) { + + struct MPI25_IEEE_SGE_CHAIN64 *sg_chain; +- if (fusion->adapter_type == INVADER_SERIES) { ++ if (fusion->adapter_type >= INVADER_SERIES) { + if ((le16_to_cpu(cmd->io_request->IoFlags) & + MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) != + MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH) +@@ -1535,7 +1538,7 @@ megasas_make_sgl_fusion(struct megasas_instance *instance, + sg_chain = sgl_ptr; + /* Prepare chain element */ + sg_chain->NextChainOffset = 0; +- if (fusion->adapter_type == INVADER_SERIES) ++ if (fusion->adapter_type >= INVADER_SERIES) + sg_chain->Flags = IEEE_SGE_FLAGS_CHAIN_ELEMENT; + else + sg_chain->Flags = +@@ -2286,7 +2289,7 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, + pRAID_Context->timeout_value = + cpu_to_le16((os_timeout_value > timeout_limit) ? + timeout_limit : os_timeout_value); +- if (fusion->adapter_type == INVADER_SERIES) ++ if (fusion->adapter_type >= INVADER_SERIES) + io_request->IoFlags |= + cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH); + +@@ -2995,7 +2998,7 @@ build_mpt_mfi_pass_thru(struct megasas_instance *instance, + + io_req = cmd->io_request; + +- if (fusion->adapter_type == INVADER_SERIES) { ++ if (fusion->adapter_type >= INVADER_SERIES) { + struct MPI25_IEEE_SGE_CHAIN64 *sgl_ptr_end = + (struct MPI25_IEEE_SGE_CHAIN64 *)&io_req->SGL; + sgl_ptr_end += fusion->max_sge_in_main_msg - 1; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index 2de12b4..b24262a 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -107,6 +107,7 @@ enum MR_RAID_FLAGS_IO_SUB_TYPE { + enum MR_FUSION_ADAPTER_TYPE { + THUNDERBOLT_SERIES = 0, + INVADER_SERIES = 1, ++ VENTURA_SERIES = 2, + }; + + /* +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0007-scsi-mpt3sas-Increased-Additional-MSIX-support-for-S.patch b/SOURCES/centos-linux-3.10-0007-scsi-mpt3sas-Increased-Additional-MSIX-support-for-S.patch new file mode 100644 index 0000000..45b0c9f --- /dev/null +++ b/SOURCES/centos-linux-3.10-0007-scsi-mpt3sas-Increased-Additional-MSIX-support-for-S.patch @@ -0,0 +1,141 @@ +From bd2314e40123381058f15b3ae49616d1cccb4f44 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:38 +0530 +Subject: [PATCH 07/11] scsi: mpt3sas: Increased/Additional MSIX support for + SAS35 devices. + +For SAS35 devices MSIX vectors are inceased to 128 from 96. To support this +Reply post host index register count is increased to 16. Also variable +msix96_vector is replaced with combined_reply_queue and variable +combined_reply_index_count is added to set different values for SAS3 and +SAS35 devices. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 14 +++++++------- + drivers/scsi/mpt3sas/mpt3sas_base.h | 8 +++++--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 11 +++++++++-- + 3 files changed, 21 insertions(+), 12 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index ac87e12..b26fa23 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -1079,7 +1079,7 @@ _base_interrupt(int irq, void *bus_id) + * new reply host index value in ReplyPostIndex Field and msix_index + * value in MSIxIndex field. + */ +- if (ioc->msix96_vector) ++ if (ioc->combined_reply_queue) + writel(reply_q->reply_post_host_index | ((msix_index & 7) << + MPI2_RPHI_MSIX_INDEX_SHIFT), + ioc->replyPostRegisterIndex[msix_index/8]); +@@ -2053,7 +2053,7 @@ mpt3sas_base_unmap_resources(struct MPT3SAS_ADAPTER *ioc) + _base_free_irq(ioc); + _base_disable_msix(ioc); + +- if (ioc->msix96_vector) { ++ if (ioc->combined_reply_queue) { + kfree(ioc->replyPostRegisterIndex); + ioc->replyPostRegisterIndex = NULL; + } +@@ -2163,7 +2163,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) + /* Use the Combined reply queue feature only for SAS3 C0 & higher + * revision HBAs and also only when reply queue count is greater than 8 + */ +- if (ioc->msix96_vector && ioc->reply_queue_count > 8) { ++ if (ioc->combined_reply_queue && ioc->reply_queue_count > 8) { + /* Determine the Supplemental Reply Post Host Index Registers + * Addresse. Supplemental Reply Post Host Index Registers + * starts at offset MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET and +@@ -2171,7 +2171,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) + * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one. + */ + ioc->replyPostRegisterIndex = kcalloc( +- MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT, ++ ioc->combined_reply_index_count, + sizeof(resource_size_t *), GFP_KERNEL); + if (!ioc->replyPostRegisterIndex) { + dfailprintk(ioc, printk(MPT3SAS_FMT +@@ -2181,14 +2181,14 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) + goto out_fail; + } + +- for (i = 0; i < MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT; i++) { ++ for (i = 0; i < ioc->combined_reply_index_count; i++) { + ioc->replyPostRegisterIndex[i] = (resource_size_t *) + ((u8 *)&ioc->chip->Doorbell + + MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET + + (i * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET)); + } + } else +- ioc->msix96_vector = 0; ++ ioc->combined_reply_queue = 0; + + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) + pr_info(MPT3SAS_FMT "%s: IRQ %d\n", +@@ -5161,7 +5161,7 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) + + /* initialize reply post host index */ + list_for_each_entry(reply_q, &ioc->reply_queue_list, list) { +- if (ioc->msix96_vector) ++ if (ioc->combined_reply_queue) + writel((reply_q->msix_index & 7)<< + MPI2_RPHI_MSIX_INDEX_SHIFT, + ioc->replyPostRegisterIndex[reply_q->msix_index/8]); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index c3a39e8..240c360 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -304,8 +304,9 @@ + * There are twelve Supplemental Reply Post Host Index Registers + * and each register is at offset 0x10 bytes from the previous one. + */ +-#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT 12 +-#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10) ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G3 12 ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G35 16 ++#define MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET (0x10) + + /* OEM Identifiers */ + #define MFG10_OEM_ID_INVALID (0x00000000) +@@ -1172,7 +1173,8 @@ struct MPT3SAS_ADAPTER { + u8 reply_queue_count; + struct list_head reply_queue_list; + +- u8 msix96_vector; ++ u8 combined_reply_queue; ++ u8 combined_reply_index_count; + /* reply post register index */ + resource_size_t **replyPostRegisterIndex; + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index eaef45c..980c69d 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -8797,8 +8797,15 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) + } + if ((ioc->hba_mpi_version_belonged == MPI25_VERSION && + pdev->revision >= SAS3_PCI_DEVICE_C0_REVISION) || +- (ioc->hba_mpi_version_belonged == MPI26_VERSION)) +- ioc->msix96_vector = 1; ++ (ioc->hba_mpi_version_belonged == MPI26_VERSION)) { ++ ioc->combined_reply_queue = 1; ++ if (ioc->is_gen35_ioc) ++ ioc->combined_reply_index_count = ++ MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G35; ++ else ++ ioc->combined_reply_index_count = ++ MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G3; ++ } + break; + default: + return -ENODEV; +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0008-scsi-megaraid_sas-Enable-or-Disable-Fast-path-based-.patch b/SOURCES/centos-linux-3.10-0008-scsi-megaraid_sas-Enable-or-Disable-Fast-path-based-.patch new file mode 100644 index 0000000..8b08508 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0008-scsi-megaraid_sas-Enable-or-Disable-Fast-path-based-.patch @@ -0,0 +1,249 @@ +From 87029b097c79483c8a03c68a065a78973e0456db Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:50 -0500 +Subject: [PATCH 08/11] scsi: megaraid_sas: Enable or Disable Fast path based + on the PCI Threshold Bandwidth + +Large SEQ IO workload should sent as non fast path commands + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 8 +++++ + drivers/scsi/megaraid/megaraid_sas_base.c | 48 +++++++++++++++++++++++++++++ + drivers/scsi/megaraid/megaraid_sas_fp.c | 7 +++++ + drivers/scsi/megaraid/megaraid_sas_fusion.c | 16 ++++++---- + drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- + 5 files changed, 74 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index d5205c4..f6ac1b2 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT { + #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 + #define MFI_1068_FW_READY 0xDDDD0000 + ++#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ ++ + #define MR_MAX_REPLY_QUEUES_OFFSET 0X0000001F + #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 + #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14 +@@ -2101,6 +2103,10 @@ struct megasas_instance { + atomic_t ldio_outstanding; + atomic_t fw_reset_no_pci_access; + ++ atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */ ++ atomic_t r1_write_fp_capable; ++ ++ + struct megasas_instance_template *instancet; + struct tasklet_struct isr_tasklet; + struct work_struct work_init; +@@ -2143,6 +2149,7 @@ struct megasas_instance { + long reset_flags; + struct mutex reset_mutex; + struct timer_list sriov_heartbeat_timer; ++ struct timer_list r1_fp_hold_timer; + char skip_heartbeat_timer_del; + u8 requestorId; + char PlasmaFW111; +@@ -2159,6 +2166,7 @@ struct megasas_instance { + bool is_ventura; + bool msix_combined; + u16 max_raid_mapsize; ++ u64 pci_threshold_bandwidth; /* used to control the fp writes */ + }; + struct MR_LD_VF_MAP { + u32 size; +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 8b0c686..cab3be8 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -1959,6 +1959,9 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) + } + /* Complete outstanding ioctls when adapter is killed */ + megasas_complete_outstanding_ioctls(instance); ++ if (instance->is_ventura) ++ del_timer_sync(&instance->r1_fp_hold_timer); ++ + } + + /** +@@ -2457,6 +2460,24 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) + } + } + ++/*Handler for disabling/enabling raid 1 fast paths*/ ++void megasas_change_r1_fp_status(unsigned long instance_addr) ++{ ++ struct megasas_instance *instance = ++ (struct megasas_instance *)instance_addr; ++ if (atomic64_read(&instance->bytes_wrote) >= ++ instance->pci_threshold_bandwidth) { ++ ++ atomic64_set(&instance->bytes_wrote, 0); ++ atomic_set(&instance->r1_write_fp_capable, 0); ++ } else { ++ atomic64_set(&instance->bytes_wrote, 0); ++ atomic_set(&instance->r1_write_fp_capable, 1); ++ } ++ mod_timer(&instance->r1_fp_hold_timer, ++ jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); ++} ++ + /** + * megasas_wait_for_outstanding - Wait for all outstanding cmds + * @instance: Adapter soft state +@@ -5403,6 +5424,17 @@ static int megasas_init_fw(struct megasas_instance *instance) + instance->skip_heartbeat_timer_del = 1; + } + ++ if (instance->is_ventura) { ++ atomic64_set(&instance->bytes_wrote, 0); ++ atomic_set(&instance->r1_write_fp_capable, 1); ++ megasas_start_timer(instance, ++ &instance->r1_fp_hold_timer, ++ megasas_change_r1_fp_status, ++ MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); ++ dev_info(&instance->pdev->dev, "starting the raid 1 fp timer with interval %d\n", ++ MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); ++ } ++ + return 0; + + fail_get_ld_pd_list: +@@ -6202,6 +6234,9 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state) + if (instance->requestorId && !instance->skip_heartbeat_timer_del) + del_timer_sync(&instance->sriov_heartbeat_timer); + ++ if (instance->is_ventura) ++ del_timer_sync(&instance->r1_fp_hold_timer); ++ + megasas_flush_cache(instance); + megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); + +@@ -6321,6 +6356,16 @@ megasas_resume(struct pci_dev *pdev) + megasas_setup_jbod_map(instance); + instance->unload = 0; + ++ if (instance->is_ventura) { ++ atomic64_set(&instance->bytes_wrote, 0); ++ atomic_set(&instance->r1_write_fp_capable, 1); ++ megasas_start_timer(instance, ++ &instance->r1_fp_hold_timer, ++ megasas_change_r1_fp_status, ++ MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); ++ } ++ ++ + /* + * Initiate AEN (Asynchronous Event Notification) + */ +@@ -6381,6 +6426,9 @@ static void megasas_detach_one(struct pci_dev *pdev) + if (instance->requestorId && !instance->skip_heartbeat_timer_del) + del_timer_sync(&instance->sriov_heartbeat_timer); + ++ if (instance->is_ventura) ++ del_timer_sync(&instance->r1_fp_hold_timer); ++ + if (instance->fw_crash_state != UNAVAILABLE) + megasas_free_host_crash_buffer(instance); + scsi_remove_host(instance->host); +diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c +index e45affe..5cad7c6 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fp.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fp.c +@@ -197,6 +197,9 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) + + if (instance->max_raid_mapsize) { + fw_map_dyn = fusion->ld_map[(instance->map_id & 1)]; ++ if (fw_map_dyn->pci_threshold_bandwidth) ++ instance->pci_threshold_bandwidth = ++ le64_to_cpu(fw_map_dyn->pci_threshold_bandwidth); + #if VD_EXT_DEBUG + dev_dbg(&instance->pdev->dev, "raidMapSize 0x%x fw_map_dyn->descTableOffset 0x%x\n", + le32_to_cpu(fw_map_dyn->raid_map_size), +@@ -204,6 +207,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) + dev_dbg(&instance->pdev->dev, "descTableSize 0x%x descTableNumElements 0x%x\n", + le32_to_cpu(fw_map_dyn->desc_table_size), + le32_to_cpu(fw_map_dyn->desc_table_num_elements)); ++ dev_dbg(&instance->pdev->dev, "PCIThreasholdBandwidth %llu\n", ++ instance->pci_threshold_bandwidth); + dev_dbg(&instance->pdev->dev, "drv map %p ldCount %d\n", + drv_map, fw_map_dyn->ld_count); + #endif +@@ -434,6 +439,8 @@ void MR_PopulateDrvRaidMap(struct megasas_instance *instance) + sizeof(struct MR_DEV_HANDLE_INFO) * + MAX_RAIDMAP_PHYSICAL_DEVICES); + } ++ if (instance->is_ventura && !instance->pci_threshold_bandwidth) ++ instance->pci_threshold_bandwidth = ULLONG_MAX; + } + + /* +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 1802c57..5689a44 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -95,6 +95,7 @@ extern unsigned int resetwaittime; + extern unsigned int dual_qdepth_disable; + static void megasas_free_rdpq_fusion(struct megasas_instance *instance); + static void megasas_free_reply_fusion(struct megasas_instance *instance); ++void megasas_change_r1_fp_status(unsigned long instance_addr); + + + +@@ -2628,8 +2629,9 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + * to get new command + */ + if (cmd->is_raid_1_fp_write && +- atomic_inc_return(&instance->fw_outstanding) > +- (instance->host->can_queue)) { ++ (atomic_inc_return(&instance->fw_outstanding) > ++ (instance->host->can_queue) || ++ (!atomic_read(&instance->r1_write_fp_capable)))) { + megasas_fpio_to_ldio(instance, cmd, cmd->scmd); + atomic_dec(&instance->fw_outstanding); + } else if (cmd->is_raid_1_fp_write) { +@@ -2638,17 +2640,19 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + megasas_prepare_secondRaid1_IO(instance, cmd, r1_cmd); + } + +- + /* + * Issue the command to the FW + */ ++ if (scmd->sc_data_direction == PCI_DMA_TODEVICE && instance->is_ventura) ++ atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote); + + megasas_fire_cmd_fusion(instance, req_desc, instance->is_ventura); + +- if (r1_cmd) ++ if (r1_cmd) { ++ atomic64_add(scsi_bufflen(scmd), &instance->bytes_wrote); + megasas_fire_cmd_fusion(instance, r1_cmd->request_desc, +- instance->is_ventura); +- ++ instance->is_ventura); ++ } + + return 0; + } +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index b24262a..f7384c1 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -977,7 +977,7 @@ struct MR_FW_RAID_MAP_DYNAMIC { + u32 desc_table_size; /* Total Size of desc table */ + /* Total Number of elements in the desc table */ + u32 desc_table_num_elements; +- u64 reserved1; ++ u64 pci_threshold_bandwidth; + u32 reserved2[3]; /*future use */ + /* timeout value used by driver in FP IOs */ + u8 fp_pd_io_timeout_sec; +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0008-scsi-mpt3sas-set-EEDP-escape-flags-for-SAS35-devices.patch b/SOURCES/centos-linux-3.10-0008-scsi-mpt3sas-set-EEDP-escape-flags-for-SAS35-devices.patch new file mode 100644 index 0000000..f099d87 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0008-scsi-mpt3sas-set-EEDP-escape-flags-for-SAS35-devices.patch @@ -0,0 +1,43 @@ +From cf10a0af2c72e9972fa436aa6c2420a00ac69e46 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:39 +0530 +Subject: [PATCH 08/11] scsi: mpt3sas: set EEDP-escape-flags for SAS35 devices. + +An UNMAP command on a PI formatted device will leave the Logical Block +Application Tag and Logical Block Reference Tag as all F's (for those LBAs +that are unmapped). To avoid IO errors if those LBAs are subsequently read +before they are written with valid tag fields, the MPI SCSI IO requests +need to set the EEDPFlags element EEDP Escape Mode field, Bits [7:6] +appropriately. A value of 2 should be set to disable all PI checks if the +Logical Block Application Tag is 0xFFFF for PI types 1 and 2. A value +of 3 should be set to disable all PI checks if the Logical Block +Application Tag is 0xFFFF and the Logical Block Reference Tag is +0xFFFFFFFF for PI type 3. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 980c69d..0ff2ed3 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -4040,6 +4040,9 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, + + mpi_request_3v->EEDPBlockSize = + cpu_to_le16(scmd->device->sector_size); ++ ++ if (ioc->is_gen35_ioc) ++ eedp_flags |= MPI25_SCSIIO_EEDPFLAGS_APPTAG_DISABLE_MODE; + mpi_request->EEDPFlags = cpu_to_le16(eedp_flags); + } + +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0009-scsi-megaraid_sas-ldio_outstanding-variable-is-not-d.patch b/SOURCES/centos-linux-3.10-0009-scsi-megaraid_sas-ldio_outstanding-variable-is-not-d.patch new file mode 100644 index 0000000..5db5c08 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0009-scsi-megaraid_sas-ldio_outstanding-variable-is-not-d.patch @@ -0,0 +1,51 @@ +From b151f44de5717ff9be9695f744c9bd0060b3fcb4 Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:51 -0500 +Subject: [PATCH 09/11] scsi: megaraid_sas: ldio_outstanding variable is not + decremented in completion path + +ldio outstanding variable needs to be decremented in io completion path for +iMR dual queue depth + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas_fusion.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 5689a44..82dd2da 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -2580,7 +2580,6 @@ megasas_build_and_issue_cmd_fusion(struct megasas_instance *instance, + + if (atomic_inc_return(&instance->fw_outstanding) > + instance->host->can_queue) { +- dev_err(&instance->pdev->dev, "Throttle IOs beyond Controller queue depth\n"); + atomic_dec(&instance->fw_outstanding); + return SCSI_MLQUEUE_HOST_BUSY; + } +@@ -2811,6 +2810,9 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) + extStatus, data_length, sense); + scsi_io_req->RaidContext.raid_context.status = 0; + scsi_io_req->RaidContext.raid_context.ex_status = 0; ++ if (instance->ldio_threshold ++ && megasas_cmd_type(scmd_local) == READ_WRITE_LDIO) ++ atomic_dec(&instance->ldio_outstanding); + megasas_return_cmd_fusion(instance, cmd_fusion); + scsi_dma_unmap(scmd_local); + scmd_local->scsi_done(scmd_local); +@@ -3955,7 +3957,8 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) + scmd_local->result = + megasas_check_mpio_paths(instance, + scmd_local); +- if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO) ++ if (instance->ldio_threshold && ++ megasas_cmd_type(scmd_local) == READ_WRITE_LDIO) + atomic_dec(&instance->ldio_outstanding); + megasas_return_cmd_fusion(instance, cmd_fusion); + scsi_dma_unmap(scmd_local); +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0009-scsi-mpt3sas-Use-the-new-MPI-2.6-32-bit-Atomic-Reque.patch b/SOURCES/centos-linux-3.10-0009-scsi-mpt3sas-Use-the-new-MPI-2.6-32-bit-Atomic-Reque.patch new file mode 100644 index 0000000..b867d5b --- /dev/null +++ b/SOURCES/centos-linux-3.10-0009-scsi-mpt3sas-Use-the-new-MPI-2.6-32-bit-Atomic-Reque.patch @@ -0,0 +1,581 @@ +From 081008132942c3c50c43d1fded60080cfa8cda91 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:40 +0530 +Subject: [PATCH 09/11] scsi: mpt3sas: Use the new MPI 2.6 32-bit Atomic + Request Descriptors for SAS35 devices. + +Support Atomic Request Descriptors for Ventura/SAS35 devices. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.c | 141 +++++++++++++++++++++++++++---- + drivers/scsi/mpt3sas/mpt3sas_base.h | 18 ++-- + drivers/scsi/mpt3sas/mpt3sas_config.c | 2 +- + drivers/scsi/mpt3sas/mpt3sas_ctl.c | 22 ++--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 24 +++--- + drivers/scsi/mpt3sas/mpt3sas_transport.c | 8 +- + 6 files changed, 161 insertions(+), 54 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c +index b26fa23..9ef253b 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.c +@@ -850,7 +850,7 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply) + ack_request->EventContext = mpi_reply->EventContext; + ack_request->VF_ID = 0; /* TODO */ + ack_request->VP_ID = 0; +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + + out: + +@@ -2454,15 +2454,15 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) + #endif + + /** +- * mpt3sas_base_put_smid_scsi_io - send SCSI_IO request to firmware ++ * _base_put_smid_scsi_io - send SCSI_IO request to firmware + * @ioc: per adapter object + * @smid: system request message index + * @handle: device handle + * + * Return nothing. + */ +-void +-mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) ++static void ++_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) + { + Mpi2RequestDescriptorUnion_t descriptor; + u64 *request = (u64 *)&descriptor; +@@ -2478,15 +2478,15 @@ mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) + } + + /** +- * mpt3sas_base_put_smid_fast_path - send fast path request to firmware ++ * _base_put_smid_fast_path - send fast path request to firmware + * @ioc: per adapter object + * @smid: system request message index + * @handle: device handle + * + * Return nothing. + */ +-void +-mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++static void ++_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, + u16 handle) + { + Mpi2RequestDescriptorUnion_t descriptor; +@@ -2503,14 +2503,14 @@ mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, + } + + /** +- * mpt3sas_base_put_smid_hi_priority - send Task Managment request to firmware ++ * _base_put_smid_hi_priority - send Task Management request to firmware + * @ioc: per adapter object + * @smid: system request message index + * @msix_task: msix_task will be same as msix of IO incase of task abort else 0. + * Return nothing. + */ +-void +-mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++static void ++_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, + u16 msix_task) + { + Mpi2RequestDescriptorUnion_t descriptor; +@@ -2527,14 +2527,14 @@ mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, + } + + /** +- * mpt3sas_base_put_smid_default - Default, primarily used for config pages ++ * _base_put_smid_default - Default, primarily used for config pages + * @ioc: per adapter object + * @smid: system request message index + * + * Return nothing. + */ +-void +-mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++static void ++_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) + { + Mpi2RequestDescriptorUnion_t descriptor; + u64 *request = (u64 *)&descriptor; +@@ -2549,6 +2549,95 @@ mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) + } + + /** ++* _base_put_smid_scsi_io_atomic - send SCSI_IO request to firmware using ++* Atomic Request Descriptor ++* @ioc: per adapter object ++* @smid: system request message index ++* @handle: device handle, unused in this function, for function type match ++* ++* Return nothing. ++*/ ++static void ++_base_put_smid_scsi_io_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle) ++{ ++ Mpi26AtomicRequestDescriptor_t descriptor; ++ u32 *request = (u32 *)&descriptor; ++ ++ descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; ++ descriptor.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SMID = cpu_to_le16(smid); ++ ++ writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); ++} ++ ++/** ++ * _base_put_smid_fast_path_atomic - send fast path request to firmware ++ * using Atomic Request Descriptor ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @handle: device handle, unused in this function, for function type match ++ * Return nothing ++ */ ++static void ++_base_put_smid_fast_path_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 handle) ++{ ++ Mpi26AtomicRequestDescriptor_t descriptor; ++ u32 *request = (u32 *)&descriptor; ++ ++ descriptor.RequestFlags = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; ++ descriptor.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SMID = cpu_to_le16(smid); ++ ++ writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); ++} ++ ++/** ++ * _base_put_smid_hi_priority_atomic - send Task Management request to ++ * firmware using Atomic Request Descriptor ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * @msix_task: msix_task will be same as msix of IO incase of task abort else 0 ++ * ++ * Return nothing. ++ */ ++static void ++_base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 msix_task) ++{ ++ Mpi26AtomicRequestDescriptor_t descriptor; ++ u32 *request = (u32 *)&descriptor; ++ ++ descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; ++ descriptor.MSIxIndex = msix_task; ++ descriptor.SMID = cpu_to_le16(smid); ++ ++ writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); ++} ++ ++/** ++ * _base_put_smid_default - Default, primarily used for config pages ++ * use Atomic Request Descriptor ++ * @ioc: per adapter object ++ * @smid: system request message index ++ * ++ * Return nothing. ++ */ ++static void ++_base_put_smid_default_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid) ++{ ++ Mpi26AtomicRequestDescriptor_t descriptor; ++ u32 *request = (u32 *)&descriptor; ++ ++ descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; ++ descriptor.MSIxIndex = _base_get_msix_index(ioc); ++ descriptor.SMID = cpu_to_le16(smid); ++ ++ writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); ++} ++ ++/** + * _base_display_OEMs_branding - Display branding string + * @ioc: per adapter object + * +@@ -4058,7 +4147,7 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, + mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) + ioc->ioc_link_reset_in_progress = 1; + init_completion(&ioc->base_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, + msecs_to_jiffies(10000)); + if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || +@@ -4160,7 +4249,7 @@ mpt3sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, + ioc->base_cmds.smid = smid; + memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); + init_completion(&ioc->base_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, + msecs_to_jiffies(10000)); + if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { +@@ -4351,6 +4440,8 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) + if ((facts->IOCCapabilities & + MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE)) + ioc->rdpq_array_capable = 1; ++ if (facts->IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ) ++ ioc->atomic_desc_capable = 1; + facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); + facts->IOCRequestFrameSize = + le16_to_cpu(mpi_reply.IOCRequestFrameSize); +@@ -4582,7 +4673,7 @@ _base_send_port_enable(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) + mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; + + init_completion(&ioc->port_enable_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->port_enable_cmds.done, + 300*HZ); + if (!(ioc->port_enable_cmds.status & MPT3_CMD_COMPLETE)) { +@@ -4646,7 +4737,7 @@ mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc) + memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); + mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; + +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + return 0; + } + +@@ -4767,7 +4858,7 @@ _base_event_notification(struct MPT3SAS_ADAPTER *ioc, int sleep_flag) + mpi_request->EventMasks[i] = + cpu_to_le32(ioc->event_masks[i]); + init_completion(&ioc->base_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); + if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { + pr_err(MPT3SAS_FMT "%s: timeout\n", +@@ -5316,9 +5407,23 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) + ioc->build_sg = &_base_build_sg_ieee; + ioc->build_zero_len_sge = &_base_build_zero_len_sge_ieee; + ioc->sge_size_ieee = sizeof(Mpi2IeeeSgeSimple64_t); ++ + break; + } + ++ if (ioc->atomic_desc_capable) { ++ ioc->put_smid_default = &_base_put_smid_default_atomic; ++ ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic; ++ ioc->put_smid_fast_path = &_base_put_smid_fast_path_atomic; ++ ioc->put_smid_hi_priority = &_base_put_smid_hi_priority_atomic; ++ } else { ++ ioc->put_smid_default = &_base_put_smid_default; ++ ioc->put_smid_scsi_io = &_base_put_smid_scsi_io; ++ ioc->put_smid_fast_path = &_base_put_smid_fast_path; ++ ioc->put_smid_hi_priority = &_base_put_smid_hi_priority; ++ } ++ ++ + /* + * These function pointers for other requests that don't + * the require IEEE scatter gather elements. +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index 240c360..b8c8be4 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -740,7 +740,10 @@ typedef void (*MPT_BUILD_SG)(struct MPT3SAS_ADAPTER *ioc, void *psge, + typedef void (*MPT_BUILD_ZERO_LEN_SGE)(struct MPT3SAS_ADAPTER *ioc, + void *paddr); + +- ++/* To support atomic and non atomic descriptors*/ ++typedef void (*PUT_SMID_IO_FP_HIP) (struct MPT3SAS_ADAPTER *ioc, u16 smid, ++ u16 funcdep); ++typedef void (*PUT_SMID_DEFAULT) (struct MPT3SAS_ADAPTER *ioc, u16 smid); + + /* IOC Facts and Port Facts converted from little endian to cpu */ + union mpi3_version_union { +@@ -1208,6 +1211,12 @@ struct MPT3SAS_ADAPTER { + void *device_remove_in_progress; + u16 device_remove_in_progress_sz; + u8 is_gen35_ioc; ++ u8 atomic_desc_capable; ++ PUT_SMID_IO_FP_HIP put_smid_scsi_io; ++ PUT_SMID_IO_FP_HIP put_smid_fast_path; ++ PUT_SMID_IO_FP_HIP put_smid_hi_priority; ++ PUT_SMID_DEFAULT put_smid_default; ++ + }; + + typedef u8 (*MPT_CALLBACK)(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, +@@ -1253,13 +1262,6 @@ u16 mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, + + u16 mpt3sas_base_get_smid(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); + void mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid); +-void mpt3sas_base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, +- u16 handle); +-void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, +- u16 handle); +-void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, +- u16 smid, u16 msix_task); +-void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid); + void mpt3sas_base_initialize_callback_handler(void); + u8 mpt3sas_base_register_callback_handler(MPT_CALLBACK cb_func); + void mpt3sas_base_release_callback_handler(u8 cb_idx); +diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c +index a6914ec..b024e14 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_config.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_config.c +@@ -385,7 +385,7 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t + memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); + _config_display_some_debug(ioc, smid, "config_request", NULL); + init_completion(&ioc->config_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->config_cmds.done, + timeout*HZ); + if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { +diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +index a66c0c8..8273e8c 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c +@@ -813,9 +813,9 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, + data_in_dma, data_in_sz); + if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) +- mpt3sas_base_put_smid_scsi_io(ioc, smid, device_handle); ++ ioc->put_smid_scsi_io(ioc, smid, device_handle); + else +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + break; + } + case MPI2_FUNCTION_SCSI_TASK_MGMT: +@@ -850,7 +850,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + tm_request->DevHandle)); + ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, + data_in_dma, data_in_sz); +- mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); ++ ioc->put_smid_hi_priority(ioc, smid, 0); + break; + } + case MPI2_FUNCTION_SMP_PASSTHROUGH: +@@ -881,7 +881,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + } + ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, + data_in_sz); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + break; + } + case MPI2_FUNCTION_SATA_PASSTHROUGH: +@@ -896,7 +896,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + } + ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, + data_in_sz); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + break; + } + case MPI2_FUNCTION_FW_DOWNLOAD: +@@ -904,7 +904,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + { + ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, + data_in_sz); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + break; + } + case MPI2_FUNCTION_TOOLBOX: +@@ -919,7 +919,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, + data_in_dma, data_in_sz); + } +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + break; + } + case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: +@@ -938,7 +938,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, + default: + ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, + data_in_dma, data_in_sz); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + break; + } + +@@ -1533,7 +1533,7 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, + cpu_to_le32(ioc->product_specific[buffer_type][i]); + + init_completion(&ioc->ctl_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, + MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); + +@@ -1882,7 +1882,7 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, + mpi_request->VP_ID = 0; + + init_completion(&ioc->ctl_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, + MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); + +@@ -2150,7 +2150,7 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg) + mpi_request->VP_ID = 0; + + init_completion(&ioc->ctl_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->ctl_cmds.done, + MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 0ff2ed3..0dcf826 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -2339,7 +2339,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, uint channel, + msix_task = scsi_lookup->msix_io; + else + msix_task = 0; +- mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task); ++ ioc->put_smid_hi_priority(ioc, smid, msix_task); + timeleft = wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); + if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { + pr_err(MPT3SAS_FMT "%s: timeout\n", +@@ -3252,7 +3252,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) + mpi_request->DevHandle = cpu_to_le16(handle); + mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; + set_bit(handle, ioc->device_remove_in_progress); +- mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); ++ ioc->put_smid_hi_priority(ioc, smid, 0); + mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); + + out: +@@ -3351,7 +3351,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, + mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; + mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; + mpi_request->DevHandle = mpi_request_tm->DevHandle; +- mpt3sas_base_put_smid_default(ioc, smid_sas_ctrl); ++ ioc->put_smid_default(ioc, smid_sas_ctrl); + + return _scsih_check_for_pending_tm(ioc, smid); + } +@@ -3446,7 +3446,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) + mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; + mpi_request->DevHandle = cpu_to_le16(handle); + mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; +- mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); ++ ioc->put_smid_hi_priority(ioc, smid, 0); + } + + /** +@@ -3538,7 +3538,7 @@ _scsih_issue_delayed_event_ack(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event, + ack_request->EventContext = event_context; + ack_request->VF_ID = 0; /* TODO */ + ack_request->VP_ID = 0; +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + } + + /** +@@ -3595,7 +3595,7 @@ _scsih_issue_delayed_sas_io_unit_ctrl(struct MPT3SAS_ADAPTER *ioc, + mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; + mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; + mpi_request->DevHandle = handle; +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + } + + /** +@@ -4218,12 +4218,12 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) + if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { + mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | + MPI25_SCSIIO_IOFLAGS_FAST_PATH); +- mpt3sas_base_put_smid_fast_path(ioc, smid, handle); ++ ioc->put_smid_fast_path(ioc, smid, handle); + } else +- mpt3sas_base_put_smid_scsi_io(ioc, smid, ++ ioc->put_smid_scsi_io(ioc, smid, + le16_to_cpu(mpi_request->DevHandle)); + } else +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + return 0; + + out: +@@ -4719,7 +4719,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) + memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len); + mpi_request->DevHandle = + cpu_to_le16(sas_device_priv_data->sas_target->handle); +- mpt3sas_base_put_smid_scsi_io(ioc, smid, ++ ioc->put_smid_scsi_io(ioc, smid, + sas_device_priv_data->sas_target->handle); + return 0; + } +@@ -6330,7 +6330,7 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num) + handle, phys_disk_num)); + + init_completion(&ioc->scsih_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); + + if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { +@@ -8180,7 +8180,7 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) + if (!ioc->hide_ir_msg) + pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); + init_completion(&ioc->scsih_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); + + if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { +diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c +index a01b235..4b7c32b 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c +@@ -393,7 +393,7 @@ _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, + "report_manufacture - send to sas_addr(0x%016llx)\n", + ioc->name, (unsigned long long)sas_address)); + init_completion(&ioc->transport_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, + 10*HZ); + +@@ -1197,7 +1197,7 @@ _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc, + ioc->name, (unsigned long long)phy->identify.sas_address, + phy->number)); + init_completion(&ioc->transport_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, + 10*HZ); + +@@ -1516,7 +1516,7 @@ _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc, + ioc->name, (unsigned long long)phy->identify.sas_address, + phy->number, phy_operation)); + init_completion(&ioc->transport_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, + 10*HZ); + +@@ -2036,7 +2036,7 @@ _transport_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy, + "%s - sending smp request\n", ioc->name, __func__)); + + init_completion(&ioc->transport_cmds.done); +- mpt3sas_base_put_smid_default(ioc, smid); ++ ioc->put_smid_default(ioc, smid); + timeleft = wait_for_completion_timeout(&ioc->transport_cmds.done, + 10*HZ); + +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0010-scsi-megaraid_sas-Implement-the-PD-Map-support-for-S.patch b/SOURCES/centos-linux-3.10-0010-scsi-megaraid_sas-Implement-the-PD-Map-support-for-S.patch new file mode 100644 index 0000000..831b3c5 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0010-scsi-megaraid_sas-Implement-the-PD-Map-support-for-S.patch @@ -0,0 +1,211 @@ +From dffd1263c440568ca20d97ff01aea74b1f20223c Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:52 -0500 +Subject: [PATCH 10/11] scsi: megaraid_sas: Implement the PD Map support for + SAS3.5 Generic Megaraid Controllers + +Update Linux driver to use new pdTargetId field for JBOD target ID + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 105 +++++++++++++++++++++------- + drivers/scsi/megaraid/megaraid_sas_base.c | 3 + + drivers/scsi/megaraid/megaraid_sas_fusion.c | 6 ++ + drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- + 4 files changed, 89 insertions(+), 28 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index f6ac1b2..a38dbe5 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -1317,7 +1317,55 @@ struct megasas_ctrl_info { + #endif + } adapterOperations3; + +- u8 pad[0x800-0x7EC]; ++ struct { ++#if defined(__BIG_ENDIAN_BITFIELD) ++ u8 reserved:7; ++ /* Indicates whether the CPLD image is part of ++ * the package and stored in flash ++ */ ++ u8 cpld_in_flash:1; ++#else ++ u8 cpld_in_flash:1; ++ u8 reserved:7; ++#endif ++ u8 reserved1[3]; ++ /* Null terminated string. Has the version ++ * information if cpld_in_flash = FALSE ++ */ ++ u8 userCodeDefinition[12]; ++ } cpld; /* Valid only if upgradableCPLD is TRUE */ ++ ++ struct { ++ #if defined(__BIG_ENDIAN_BITFIELD) ++ u16 reserved:8; ++ u16 fw_swaps_bbu_vpd_info:1; ++ u16 support_pd_map_target_id:1; ++ u16 support_ses_ctrl_in_multipathcfg:1; ++ u16 image_upload_supported:1; ++ u16 support_encrypted_mfc:1; ++ u16 supported_enc_algo:1; ++ u16 support_ibutton_less:1; ++ u16 ctrl_info_ext_supported:1; ++ #else ++ ++ u16 ctrl_info_ext_supported:1; ++ u16 support_ibutton_less:1; ++ u16 supported_enc_algo:1; ++ u16 support_encrypted_mfc:1; ++ u16 image_upload_supported:1; ++ /* FW supports LUN based association and target port based */ ++ u16 support_ses_ctrl_in_multipathcfg:1; ++ /* association for the SES device connected in multipath mode */ ++ /* FW defines Jbod target Id within MR_PD_CFG_SEQ */ ++ u16 support_pd_map_target_id:1; ++ /* FW swaps relevant fields in MR_BBU_VPD_INFO_FIXED to ++ * provide the data in little endian order ++ */ ++ u16 fw_swaps_bbu_vpd_info:1; ++ u16 reserved:8; ++ #endif ++ } adapter_operations4; ++ u8 pad[0x800-0x7FE]; /* 0x7FE pad to 2K for expansion */ + } __packed; + + /* +@@ -1557,33 +1605,35 @@ union megasas_sgl_frame { + typedef union _MFI_CAPABILITIES { + struct { + #if defined(__BIG_ENDIAN_BITFIELD) +- u32 reserved:20; +- u32 support_qd_throttling:1; +- u32 support_fp_rlbypass:1; +- u32 support_vfid_in_ioframe:1; +- u32 support_ext_io_size:1; +- u32 support_ext_queue_depth:1; +- u32 security_protocol_cmds_fw:1; +- u32 support_core_affinity:1; +- u32 support_ndrive_r1_lb:1; +- u32 support_max_255lds:1; +- u32 support_fastpath_wb:1; +- u32 support_additional_msix:1; +- u32 support_fp_remote_lun:1; ++ u32 reserved:19; ++ u32 support_pd_map_target_id:1; ++ u32 support_qd_throttling:1; ++ u32 support_fp_rlbypass:1; ++ u32 support_vfid_in_ioframe:1; ++ u32 support_ext_io_size:1; ++ u32 support_ext_queue_depth:1; ++ u32 security_protocol_cmds_fw:1; ++ u32 support_core_affinity:1; ++ u32 support_ndrive_r1_lb:1; ++ u32 support_max_255lds:1; ++ u32 support_fastpath_wb:1; ++ u32 support_additional_msix:1; ++ u32 support_fp_remote_lun:1; + #else +- u32 support_fp_remote_lun:1; +- u32 support_additional_msix:1; +- u32 support_fastpath_wb:1; +- u32 support_max_255lds:1; +- u32 support_ndrive_r1_lb:1; +- u32 support_core_affinity:1; +- u32 security_protocol_cmds_fw:1; +- u32 support_ext_queue_depth:1; +- u32 support_ext_io_size:1; +- u32 support_vfid_in_ioframe:1; +- u32 support_fp_rlbypass:1; +- u32 support_qd_throttling:1; +- u32 reserved:20; ++ u32 support_fp_remote_lun:1; ++ u32 support_additional_msix:1; ++ u32 support_fastpath_wb:1; ++ u32 support_max_255lds:1; ++ u32 support_ndrive_r1_lb:1; ++ u32 support_core_affinity:1; ++ u32 security_protocol_cmds_fw:1; ++ u32 support_ext_queue_depth:1; ++ u32 support_ext_io_size:1; ++ u32 support_vfid_in_ioframe:1; ++ u32 support_fp_rlbypass:1; ++ u32 support_qd_throttling:1; ++ u32 support_pd_map_target_id:1; ++ u32 reserved:19; + #endif + } mfi_capabilities; + __le32 reg; +@@ -2052,6 +2102,7 @@ struct megasas_instance { + u32 crash_dump_drv_support; + u32 crash_dump_app_support; + u32 secure_jbod_support; ++ u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ + bool use_seqnum_jbod_fp; /* Added for PD sequence */ + spinlock_t crashdump_lock; + +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index cab3be8..e7249f9 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -4609,6 +4609,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance) + le32_to_cpus((u32 *)&ctrl_info->properties.OnOffProperties); + le32_to_cpus((u32 *)&ctrl_info->adapterOperations2); + le32_to_cpus((u32 *)&ctrl_info->adapterOperations3); ++ le16_to_cpus((u16 *)&ctrl_info->adapter_operations4); + + /* Update the latest Ext VD info. + * From Init path, store current firmware details. +@@ -4618,6 +4619,8 @@ megasas_get_ctrl_info(struct megasas_instance *instance) + megasas_update_ext_vd_details(instance); + instance->use_seqnum_jbod_fp = + ctrl_info->adapterOperations3.useSeqNumJbodFP; ++ instance->support_morethan256jbod = ++ ctrl_info->adapter_operations4.support_pd_map_target_id; + + /*Check whether controller is iMR or MR */ + instance->is_imr = (ctrl_info->memory_size ? 0 : 1); +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c +index 82dd2da..85f0af6 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c +@@ -858,6 +858,7 @@ megasas_ioc_init_fusion(struct megasas_instance *instance) + drv_ops->mfi_capabilities.support_ext_queue_depth = 1; + + drv_ops->mfi_capabilities.support_qd_throttling = 1; ++ drv_ops->mfi_capabilities.support_pd_map_target_id = 1; + /* Convert capability to LE32 */ + cpu_to_le32s((u32 *)&init_frame->driver_operations.mfi_capabilities); + +@@ -2244,6 +2245,11 @@ megasas_build_syspd_fusion(struct megasas_instance *instance, + /* TgtId must be incremented by 255 as jbod seq number is index + * below raid map + */ ++ /* More than 256 PD/JBOD support for Ventura */ ++ if (instance->support_morethan256jbod) ++ pRAID_Context->virtual_disk_tgt_id = ++ pd_sync->seq[pd_index].pd_target_id; ++ else + pRAID_Context->virtual_disk_tgt_id = + cpu_to_le16(device_id + (MAX_PHYSICAL_DEVICES - 1)); + pRAID_Context->config_seq_num = pd_sync->seq[pd_index].seqNum; +diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h +index f7384c1..ad68a85 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_fusion.h ++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h +@@ -1189,7 +1189,8 @@ struct MR_PD_CFG_SEQ { + u8 reserved:7; + #endif + } capability; +- u8 reserved[3]; ++ u8 reserved; ++ u16 pd_target_id; + } __packed; + + struct MR_PD_CFG_SEQ_NUM_SYNC { +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0010-scsi-mpt3sas-Fix-for-Endianness-issue.patch b/SOURCES/centos-linux-3.10-0010-scsi-mpt3sas-Fix-for-Endianness-issue.patch new file mode 100644 index 0000000..da80a74 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0010-scsi-mpt3sas-Fix-for-Endianness-issue.patch @@ -0,0 +1,67 @@ +From c73c42f25ffbb9a519ea942a9a943069abf6d6be Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:41 +0530 +Subject: [PATCH 10/11] scsi: mpt3sas: Fix for Endianness issue. + +Use le16_to_cpu only for accessing two byte data provided by controller. + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Reviewed-by: Hannes Reinecke +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_scsih.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +index 0dcf826..55b4472 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c ++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c +@@ -5442,10 +5442,10 @@ _scsih_check_device(struct MPT3SAS_ADAPTER *ioc, + sas_device->handle, handle); + sas_target_priv_data->handle = handle; + sas_device->handle = handle; +- if (sas_device_pg0.Flags & ++ if (le16_to_cpu(sas_device_pg0.Flags) & + MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { + sas_device->enclosure_level = +- le16_to_cpu(sas_device_pg0.EnclosureLevel); ++ sas_device_pg0.EnclosureLevel; + memcpy(&sas_device->connector_name[0], + &sas_device_pg0.ConnectorName[0], 4); + } else { +@@ -5573,9 +5573,10 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phy_num, + sas_device->fast_path = (le16_to_cpu(sas_device_pg0.Flags) & + MPI25_SAS_DEVICE0_FLAGS_FAST_PATH_CAPABLE) ? 1 : 0; + +- if (sas_device_pg0.Flags & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { ++ if (le16_to_cpu(sas_device_pg0.Flags) ++ & MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { + sas_device->enclosure_level = +- le16_to_cpu(sas_device_pg0.EnclosureLevel); ++ sas_device_pg0.EnclosureLevel; + memcpy(&sas_device->connector_name[0], + &sas_device_pg0.ConnectorName[0], 4); + } else { +@@ -7115,7 +7116,7 @@ Mpi2SasDevicePage0_t *sas_device_pg0) + if (sas_device_pg0->Flags & + MPI2_SAS_DEVICE0_FLAGS_ENCL_LEVEL_VALID) { + sas_device->enclosure_level = +- le16_to_cpu(sas_device_pg0->EnclosureLevel); ++ sas_device_pg0->EnclosureLevel; + memcpy(&sas_device->connector_name[0], + &sas_device_pg0->ConnectorName[0], 4); + } else { +@@ -7177,6 +7178,7 @@ _scsih_search_responding_sas_devices(struct MPT3SAS_ADAPTER *ioc) + sas_device_pg0.SASAddress = + le64_to_cpu(sas_device_pg0.SASAddress); + sas_device_pg0.Slot = le16_to_cpu(sas_device_pg0.Slot); ++ sas_device_pg0.Flags = le16_to_cpu(sas_device_pg0.Flags); + _scsih_mark_responding_sas_device(ioc, &sas_device_pg0); + } + +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0011-scsi-megaraid_sas-driver-version-upgrade.patch b/SOURCES/centos-linux-3.10-0011-scsi-megaraid_sas-driver-version-upgrade.patch new file mode 100644 index 0000000..1425953 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0011-scsi-megaraid_sas-driver-version-upgrade.patch @@ -0,0 +1,32 @@ +From 50c9c8f47e8ab6e4bc5a3a374a8b3ac5833aab1f Mon Sep 17 00:00:00 2001 +From: Sasikumar Chandrasekaran +Date: Tue, 10 Jan 2017 18:20:53 -0500 +Subject: [PATCH 11/11] scsi: megaraid_sas: driver version upgrade + +Upgrade driver version. + +Signed-off-by: Sasikumar Chandrasekaran +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h +index a38dbe5..83886a5 100644 +--- a/drivers/scsi/megaraid/megaraid_sas.h ++++ b/drivers/scsi/megaraid/megaraid_sas.h +@@ -35,8 +35,8 @@ + /* + * MegaRAID SAS Driver meta data + */ +-#define MEGASAS_VERSION "06.811.02.00-rh1" +-#define MEGASAS_RELDATE "April 12, 2016" ++#define MEGASAS_VERSION "07.700.00.00-rc1" ++#define MEGASAS_RELDATE "November 29, 2016" + + /* + * Device IDs +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-0011-scsi-mpt3sas-Bump-driver-version-as-14.101.00.00.patch b/SOURCES/centos-linux-3.10-0011-scsi-mpt3sas-Bump-driver-version-as-14.101.00.00.patch new file mode 100644 index 0000000..3616401 --- /dev/null +++ b/SOURCES/centos-linux-3.10-0011-scsi-mpt3sas-Bump-driver-version-as-14.101.00.00.patch @@ -0,0 +1,32 @@ +From 9b19a8b6bc41be91ddeb74e1ef3e484774f87a21 Mon Sep 17 00:00:00 2001 +From: Suganath Prabu Subramani +Date: Wed, 26 Oct 2016 13:34:42 +0530 +Subject: [PATCH 11/11] scsi: mpt3sas: Bump driver version as "14.101.00.00" + +Signed-off-by: Chaitra P B +Signed-off-by: Sathya Prakash +Signed-off-by: Suganath Prabu S +Signed-off-by: Martin K. Petersen +--- + drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h +index b8c8be4..ab8d6eb 100644 +--- a/drivers/scsi/mpt3sas/mpt3sas_base.h ++++ b/drivers/scsi/mpt3sas/mpt3sas_base.h +@@ -73,9 +73,9 @@ + #define MPT3SAS_DRIVER_NAME "mpt3sas" + #define MPT3SAS_AUTHOR "Avago Technologies " + #define MPT3SAS_DESCRIPTION "LSI MPT Fusion SAS 3.0 Device Driver" +-#define MPT3SAS_DRIVER_VERSION "14.100.00.00" ++#define MPT3SAS_DRIVER_VERSION "14.101.00.00" + #define MPT3SAS_MAJOR_VERSION 14 +-#define MPT3SAS_MINOR_VERSION 100 ++#define MPT3SAS_MINOR_VERSION 101 + #define MPT3SAS_BUILD_VERSION 0 + #define MPT3SAS_RELEASE_VERSION 00 + +-- +1.8.3.1 + diff --git a/SOURCES/centos-linux-3.10-fix-ecryptfs-error-bug7369.patch b/SOURCES/centos-linux-3.10-fix-ecryptfs-error-bug7369.patch new file mode 100644 index 0000000..b5028c9 --- /dev/null +++ b/SOURCES/centos-linux-3.10-fix-ecryptfs-error-bug7369.patch @@ -0,0 +1,31 @@ +https://bugs.centos.org/view.php?id=7369 +http://kozlex.blogspot.com/2015/05/building-ecryptfs-on-redhat-7_19.html + +To fix ecryptfs and build it in the kernel follow is the partial fix: +This is a fix that will not be proposed to upstream cause it is not +compatible with other kernels; instead it is a patch to make ecryptfs +work on Rhel7 only. + +--- a/fs/ecryptfs/main.c 2015-03-06 13:45:38.000000000 -0800 ++++ b/fs/ecryptfs/main.c 2015-07-02 14:46:37.000000000 -0700 +@@ -500,6 +500,7 @@ static struct dentry *ecryptfs_mount(str + struct path path; + uid_t check_ruid; + int rc; ++ int *s_stack_depth; + + sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); + if (!sbi) { +@@ -567,10 +568,10 @@ static struct dentry *ecryptfs_mount(str + s->s_maxbytes = path.dentry->d_sb->s_maxbytes; + s->s_blocksize = path.dentry->d_sb->s_blocksize; + s->s_magic = ECRYPTFS_SUPER_MAGIC; +- s->s_stack_depth = path.dentry->d_sb->s_stack_depth + 1; ++ s_stack_depth = get_s_stack_depth(path.dentry->d_sb); + + rc = -EINVAL; +- if (s->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { ++ if ( *s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { + pr_err("eCryptfs: maximum fs stacking depth exceeded\n"); + goto out_free; + } diff --git a/SOURCES/centos-linux-3.10-fix-em28xx-cards-bug8285.patch b/SOURCES/centos-linux-3.10-fix-em28xx-cards-bug8285.patch new file mode 100644 index 0000000..95ebc46 --- /dev/null +++ b/SOURCES/centos-linux-3.10-fix-em28xx-cards-bug8285.patch @@ -0,0 +1,25 @@ +centosplus kernel patch (bug#8285) + +Reported by armada: +DVB-T Receiver "Terratec Cinergy Hybrid T USB XS" not working + +My problem is exactly the same as described in +http://linuxtv.org/pipermail/linux-dvb/2014-May/032967.html [^] +This post also has a patch which solved the problem for me. + +The em28xx driver causes the : +em2882/3 #0: /2: dvb frontend not attached. Can't attach xc3028 + +Changing the USB_DEVICE(0x0ccd, 0x0042) from driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS to EM2880_BOARD_TERRATEC_HYBRID_XS solved the problem. + +--- a/drivers/media/usb/em28xx/em28xx-cards.c 2015-01-29 15:15:53.000000000 -0800 ++++ b/drivers/media/usb/em28xx/em28xx-cards.c 2015-03-07 08:50:38.737699310 -0800 +@@ -2091,7 +2091,7 @@ struct usb_device_id em28xx_id_table[] = + { USB_DEVICE(0x0ccd, 0x005e), + .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0042), +- .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, ++ .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS }, + { USB_DEVICE(0x0ccd, 0x0043), + .driver_info = EM2870_BOARD_TERRATEC_XS }, + { USB_DEVICE(0x0ccd, 0x008e), /* Cinergy HTC USB XS Rev. 1 */ diff --git a/SOURCES/centos-linux-3.10-hid-non-LogiTech-remote-bug5780.patch b/SOURCES/centos-linux-3.10-hid-non-LogiTech-remote-bug5780.patch new file mode 100644 index 0000000..31ff1d5 --- /dev/null +++ b/SOURCES/centos-linux-3.10-hid-non-LogiTech-remote-bug5780.patch @@ -0,0 +1,45 @@ +CentOS-7 patch: Allow non-LogiTech remote to work with a generic wireless +keyboard reciever that sends LogiTech scancodes. + +CentOSplus bug: 0005780 +Submitted by: Alex Timm + +LIRCD and devinput driver connected to the HOLTEK USB Keyboard remote reciever, +connected on /dev/input/eventx, was not reading the scancodes that should be +found in drivers/hid/lg.c. The following patch adds the scan codes to +hid-input.c as they were in centos/centosplus 5. + +Applied by: Akemi Yagi + +--- a/drivers/hid/hid-input.c 2009-12-02 21:51:21.000000000 -0600 ++++ b/drivers/hid/hid-input.c 2012-06-20 15:20:04.000000000 -0500 +@@ -886,7 +886,28 @@ static void hidinput_configure_usage(str + goto ignore; + + case HID_UP_LOGIVENDOR: +- goto ignore; ++ set_bit(EV_REP, input->evbit); ++ switch(usage->hid & HID_USAGE) { ++ case 0x004: map_key_clear(KEY_AGAIN); break; ++ case 0x00d: map_key_clear(KEY_HOME); break; ++ case 0x024: map_key_clear(KEY_SHUFFLE); break; ++ case 0x025: map_key_clear(KEY_TV); break; ++ case 0x026: map_key_clear(KEY_MENU); break; ++ case 0x031: map_key_clear(KEY_AUDIO); break; ++ case 0x032: map_key_clear(KEY_TEXT); break; ++ case 0x033: map_key_clear(KEY_LAST); break; ++ case 0x047: map_key_clear(KEY_MP3); break; ++ case 0x048: map_key_clear(KEY_DVD); break; ++ case 0x049: map_key_clear(KEY_MEDIA); break; ++ case 0x04a: map_key_clear(KEY_VIDEO); break; ++ case 0x04b: map_key_clear(KEY_ANGLE); break; ++ case 0x04c: map_key_clear(KEY_LANGUAGE); break; ++ case 0x04d: map_key_clear(KEY_SUBTITLE); break; ++ case 0x051: map_key_clear(KEY_RED); break; ++ case 0x052: map_key_clear(KEY_CLOSE); break; ++ default: goto ignore; ++ } ++ break; + + case HID_UP_PID: + switch (usage->hid & HID_USAGE) { diff --git a/SOURCES/centos-linux-3.10-ipv6refcnt-bug12711.patch b/SOURCES/centos-linux-3.10-ipv6refcnt-bug12711.patch new file mode 100644 index 0000000..18539c9 --- /dev/null +++ b/SOURCES/centos-linux-3.10-ipv6refcnt-bug12711.patch @@ -0,0 +1,59 @@ +centosplus patch [bug#12711] + +commit 751eb6b6042a596b0080967c1a529a9fe98dac1d +Author: Wei Yongjun +Date: Mon Sep 5 16:06:31 2016 +0800 + + ipv6: addrconf: fix dev refcont leak when DAD failed + + In general, when DAD detected IPv6 duplicate address, ifp->state + will be set to INET6_IFADDR_STATE_ERRDAD and DAD is stopped by a + delayed work, the call tree should be like this: + + ndisc_recv_ns + -> addrconf_dad_failure <- missing ifp put + -> addrconf_mod_dad_work + -> schedule addrconf_dad_work() + -> addrconf_dad_stop() <- missing ifp hold before call it + + addrconf_dad_failure() called with ifp refcont holding but not put. + addrconf_dad_work() call addrconf_dad_stop() without extra holding + refcount. This will not cause any issue normally. + + But the race between addrconf_dad_failure() and addrconf_dad_work() + may cause ifp refcount leak and netdevice can not be unregister, + dmesg show the following messages: + + IPv6: eth0: IPv6 duplicate address fe80::XX:XXXX:XXXX:XX detected! + ... + unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + + Cc: stable@vger.kernel.org + Fixes: c15b1ccadb32 ("ipv6: move DAD and addrconf_verify processing + to workqueue") + Signed-off-by: Wei Yongjun + Signed-off-by: David S. Miller + + Submitted-by: alfredo + Applied-by: Akemi Yagi + +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index b7d5ce6..dc65579 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1656,6 +1656,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp) + spin_unlock_bh(&ifp->state_lock); + + addrconf_mod_dad_work(ifp, 0); ++ in6_ifa_put(ifp); + } + + /* Join to solicited addr multicast group. +@@ -3300,6 +3301,7 @@ static void addrconf_dad_work(struct work_struct *w) + addrconf_dad_begin(ifp); + goto out; + } else if (action == DAD_ABORT) { ++ in6_ifa_hold(ifp); + addrconf_dad_stop(ifp, 1); + goto out; + } diff --git a/SOURCES/centos-linux-3.10-ixgbe-force-VLNCTRL_VFE-bug12653.patch b/SOURCES/centos-linux-3.10-ixgbe-force-VLNCTRL_VFE-bug12653.patch new file mode 100644 index 0000000..97588c6 --- /dev/null +++ b/SOURCES/centos-linux-3.10-ixgbe-force-VLNCTRL_VFE-bug12653.patch @@ -0,0 +1,76 @@ +centosplus patch [bug#12653] + +commit f60439bc21e3337429838e477903214f5bd8277f + +ixgbe: Force VLNCTRL.VFE to be set in all VMDq paths +When I was adding the code for enabling VLAN promiscuous mode with SR-IOV +enabled I had inadvertently left the VLNCTRL.VFE bit unchanged as I has +assumed there was code in another path that was setting it when we enabled +SR-IOV. This wasn't the case and as a result we were just disabling VLAN +filtering for all the VFs apparently. + +Also the previous patches were always clearing CFIEN which was always set +to 0 by the hardware anyway so I am dropping the redundant bit clearing. + +Fixes: 16369564915a ("ixgbe: Add support for VLAN promiscuous with SR-IOV") +Signed-off-by: Alexander Duyck +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher + +Applied-by: Akemi Yagi + +--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 2016-11-16 09:52:06.000000000 -0800 ++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c 2017-01-14 07:54:51.280709835 -0800 +@@ -4066,6 +4066,8 @@ static void ixgbe_vlan_promisc_enable(st + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl, i; + ++ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); ++ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: +@@ -4078,8 +4080,7 @@ static void ixgbe_vlan_promisc_enable(st + /* fall through */ + case ixgbe_mac_82598EB: + /* legacy case, we can just disable VLAN filtering */ +- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); +- vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); ++ vlnctrl &= ~IXGBE_VLNCTRL_VFE; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + return; + } +@@ -4091,6 +4092,10 @@ static void ixgbe_vlan_promisc_enable(st + /* Set flag so we don't redo unnecessary work */ + adapter->flags2 |= IXGBE_FLAG2_VLAN_PROMISC; + ++ /* For VMDq and SR-IOV we must leave VLAN filtering enabled */ ++ vlnctrl |= IXGBE_VLNCTRL_VFE; ++ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); ++ + /* Add PF to all active pools */ + for (i = IXGBE_VLVF_ENTRIES; --i;) { + u32 reg_offset = IXGBE_VLVFB(i * 2 + VMDQ_P(0) / 32); +@@ -4157,6 +4162,11 @@ static void ixgbe_vlan_promisc_disable(s + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl, i; + ++ /* Set VLAN filtering to enabled */ ++ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); ++ vlnctrl |= IXGBE_VLNCTRL_VFE; ++ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); ++ + switch (hw->mac.type) { + case ixgbe_mac_82599EB: + case ixgbe_mac_X540: +@@ -4168,10 +4178,6 @@ static void ixgbe_vlan_promisc_disable(s + break; + /* fall through */ + case ixgbe_mac_82598EB: +- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); +- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; +- vlnctrl |= IXGBE_VLNCTRL_VFE; +- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); + return; + } + diff --git a/SOURCES/centos-linux-3.10-reiserfs-fix-redefine-error.patch b/SOURCES/centos-linux-3.10-reiserfs-fix-redefine-error.patch new file mode 100644 index 0000000..5a61e68 --- /dev/null +++ b/SOURCES/centos-linux-3.10-reiserfs-fix-redefine-error.patch @@ -0,0 +1,25 @@ +centosplus patch + +Building reiserfs.ko under EL7.1 produces error: + +In file included from fs/reiserfs/bitmap.c:7:0: +fs/reiserfs/reiserfs.h:1957:0: error: "U32_MAX" redefined [-Werror] + #define U32_MAX (~(__u32)0) + +Solution: + +In EL7.1 kernels (>= 210), U32_MAX is defined in include/linux/kernel.h +This define now needs to be deleted from reiserfs.h + +Applied-by: Akemi Yagi + +--- a/fs/reiserfs/reiserfs.h 2014-11-24 14:38:58.000000000 -0800 ++++ b/fs/reiserfs/reiserfs.h 2015-01-12 15:34:40.187297040 -0800 +@@ -1954,7 +1954,6 @@ struct treepath var = {.path_length = IL + #define MAX_US_INT 0xffff + + // reiserfs version 2 has max offset 60 bits. Version 1 - 32 bit offset +-#define U32_MAX (~(__u32)0) + + static inline loff_t max_reiserfs_offset(struct inode *inode) + { diff --git a/SOURCES/centos-linux-3.10-support-MacBookPro-bug10447.patch b/SOURCES/centos-linux-3.10-support-MacBookPro-bug10447.patch new file mode 100644 index 0000000..4081205 --- /dev/null +++ b/SOURCES/centos-linux-3.10-support-MacBookPro-bug10447.patch @@ -0,0 +1,466 @@ +centosplus patch (bug#10447) +support for touchpad and fn key support for MacBookPro 12,1 + +https://kernel.googlesource.com/pub/scm/linux/kernel/git/groeck/linux-staging/+/dbe08116b87cdc2217f11a78b5b70e29068b7efd%5E1..dbe08116b87cdc2217f11a78b5b70e29068b7efd/ + +Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input + +Pull input fixes from Dmitry Torokhov: + "The main change is support for keyboards and touchpads found in 2015 + editions of Macbooks" + +* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: + Revert "Input: zforce - don't overwrite the stack" + Input: bcm5974 - add support for the 2015 Macbook Pro + HID: apple: Add support for the 2015 Macbook Pro + Input: bcm5974 - prepare for a new trackpad generation + Input: synaptics - dump ext10 capabilities as well + +Applied-by Akemi Yagi + +--- a/drivers/hid/hid-apple.c 2016-01-23 00:53:07.000000000 -0800 ++++ b/drivers/hid/hid-apple.c 2016-03-08 12:41:27.147368677 -0800 +@@ -552,6 +552,12 @@ static const struct hid_device_id apple_ + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI), ++ .driver_data = APPLE_HAS_FN }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO), ++ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), ++ .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), + .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), +--- a/drivers/hid/hid-core.c 2016-01-23 00:53:07.000000000 -0800 ++++ b/drivers/hid/hid-core.c 2016-03-08 12:45:44.846880469 -0800 +@@ -1643,6 +1643,9 @@ static const struct hid_device_id hid_ha + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, +@@ -2284,6 +2287,9 @@ static const struct hid_device_id hid_mo + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING8_JIS) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_ISO) }, ++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, + { } +--- a/drivers/hid/hid-ids.h 2016-01-23 00:53:07.000000000 -0800 ++++ b/drivers/hid/hid-ids.h 2016-03-08 12:48:25.532198900 -0800 +@@ -138,6 +138,9 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 + #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 + #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 ++#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 ++#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 ++#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 + #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a + #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b + #define USB_DEVICE_ID_APPLE_IRCONTROL 0x8240 +--- a/drivers/input/mouse/bcm5974.c 2016-01-23 00:53:07.000000000 -0800 ++++ b/drivers/input/mouse/bcm5974.c 2016-03-08 13:37:14.906154047 -0800 +@@ -2,6 +2,7 @@ + * Apple USB BCM5974 (Macbook Air and Penryn Macbook Pro) multitouch driver + * + * Copyright (C) 2008 Henrik Rydberg (rydberg@euromail.se) ++ * Copyright (C) 2015 John Horan (knasher@gmail.com) + * + * The USB initialization and package decoding was made by + * Scott Shawcroft as part of the touchd user-space driver project: +@@ -92,6 +93,10 @@ + #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 + #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 + #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 ++/* MacbookPro12,1 (2015) */ ++#define USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI 0x0272 ++#define USB_DEVICE_ID_APPLE_WELLSPRING9_ISO 0x0273 ++#define USB_DEVICE_ID_APPLE_WELLSPRING9_JIS 0x0274 + + #define BCM5974_DEVICE(prod) { \ + .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ +@@ -153,6 +158,10 @@ static const struct usb_device_id bcm597 + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING8_JIS), ++ /* MacbookPro12,1 */ ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI), ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_ISO), ++ BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), + /* Terminating entry */ + {} + }; +@@ -181,21 +190,47 @@ struct bt_data { + enum tp_type { + TYPE1, /* plain trackpad */ + TYPE2, /* button integrated in trackpad */ +- TYPE3 /* additional header fields since June 2013 */ ++ TYPE3, /* additional header fields since June 2013 */ ++ TYPE4 /* additional header field for pressure data */ + }; + + /* trackpad finger data offsets, le16-aligned */ +-#define FINGER_TYPE1 (13 * sizeof(__le16)) +-#define FINGER_TYPE2 (15 * sizeof(__le16)) +-#define FINGER_TYPE3 (19 * sizeof(__le16)) ++#define HEADER_TYPE1 (13 * sizeof(__le16)) ++#define HEADER_TYPE2 (15 * sizeof(__le16)) ++#define HEADER_TYPE3 (19 * sizeof(__le16)) ++#define HEADER_TYPE4 (23 * sizeof(__le16)) + + /* trackpad button data offsets */ ++#define BUTTON_TYPE1 0 + #define BUTTON_TYPE2 15 + #define BUTTON_TYPE3 23 ++#define BUTTON_TYPE4 31 + + /* list of device capability bits */ + #define HAS_INTEGRATED_BUTTON 1 + ++/* trackpad finger data block size */ ++#define FSIZE_TYPE1 (14 * sizeof(__le16)) ++#define FSIZE_TYPE2 (14 * sizeof(__le16)) ++#define FSIZE_TYPE3 (14 * sizeof(__le16)) ++#define FSIZE_TYPE4 (15 * sizeof(__le16)) ++ ++/* offset from header to finger struct */ ++#define DELTA_TYPE1 (0 * sizeof(__le16)) ++#define DELTA_TYPE2 (0 * sizeof(__le16)) ++#define DELTA_TYPE3 (0 * sizeof(__le16)) ++#define DELTA_TYPE4 (1 * sizeof(__le16)) ++ ++/* usb control message mode switch data */ ++#define USBMSG_TYPE1 8, 0x300, 0, 0, 0x1, 0x8 ++#define USBMSG_TYPE2 8, 0x300, 0, 0, 0x1, 0x8 ++#define USBMSG_TYPE3 8, 0x300, 0, 0, 0x1, 0x8 ++#define USBMSG_TYPE4 2, 0x302, 2, 1, 0x1, 0x0 ++ ++/* Wellspring initialization constants */ ++#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1 ++#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9 ++ + /* trackpad finger structure, le16-aligned */ + struct tp_finger { + __le16 origin; /* zero when switching track finger */ +@@ -208,14 +243,13 @@ struct tp_finger { + __le16 orientation; /* 16384 when point, else 15 bit angle */ + __le16 touch_major; /* touch area, major axis */ + __le16 touch_minor; /* touch area, minor axis */ +- __le16 unused[3]; /* zeros */ ++ __le16 unused[2]; /* zeros */ ++ __le16 pressure; /* pressure on forcetouch touchpad */ + __le16 multi; /* one finger: varies, more fingers: constant */ + } __attribute__((packed,aligned(2))); + + /* trackpad finger data size, empirically at least ten fingers */ + #define MAX_FINGERS 16 +-#define SIZEOF_FINGER sizeof(struct tp_finger) +-#define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) + #define MAX_FINGER_ORIENTATION 16384 + + /* device-specific parameters */ +@@ -233,8 +267,17 @@ struct bcm5974_config { + int bt_datalen; /* data length of the button interface */ + int tp_ep; /* the endpoint of the trackpad interface */ + enum tp_type tp_type; /* type of trackpad interface */ +- int tp_offset; /* offset to trackpad finger data */ ++ int tp_header; /* bytes in header block */ + int tp_datalen; /* data length of the trackpad interface */ ++ int tp_button; /* offset to button data */ ++ int tp_fsize; /* bytes in single finger block */ ++ int tp_delta; /* offset from header to finger struct */ ++ int um_size; /* usb control message length */ ++ int um_req_val; /* usb control message value */ ++ int um_req_idx; /* usb control message index */ ++ int um_switch_idx; /* usb control message mode switch index */ ++ int um_switch_on; /* usb control message mode switch on */ ++ int um_switch_off; /* usb control message mode switch off */ + struct bcm5974_param p; /* finger pressure limits */ + struct bcm5974_param w; /* finger width limits */ + struct bcm5974_param x; /* horizontal limits */ +@@ -260,6 +303,24 @@ struct bcm5974 { + int slots[MAX_FINGERS]; /* slot assignments */ + }; + ++/* trackpad finger block data, le16-aligned */ ++static const struct tp_finger *get_tp_finger(const struct bcm5974 *dev, int i) ++{ ++ const struct bcm5974_config *c = &dev->cfg; ++ u8 *f_base = dev->tp_data + c->tp_header + c->tp_delta; ++ ++ return (const struct tp_finger *)(f_base + i * c->tp_fsize); ++} ++ ++#define DATAFORMAT(type) \ ++ type, \ ++ HEADER_##type, \ ++ HEADER_##type + (MAX_FINGERS) * (FSIZE_##type), \ ++ BUTTON_##type, \ ++ FSIZE_##type, \ ++ DELTA_##type, \ ++ USBMSG_##type ++ + /* logical signal quality */ + #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ + #define SN_WIDTH 25 /* width signal-to-noise ratio */ +@@ -274,7 +335,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING_JIS, + 0, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE1), + { SN_PRESSURE, 0, 256 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4824, 5342 }, +@@ -287,7 +348,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, + 0, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE1), + { SN_PRESSURE, 0, 256 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4824, 4824 }, +@@ -300,7 +361,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING3_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4460, 5166 }, +@@ -313,7 +374,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, +@@ -326,7 +387,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4616, 5112 }, +@@ -339,7 +400,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING5_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4415, 5050 }, +@@ -352,7 +413,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING6_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, +@@ -365,7 +426,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4750, 5280 }, +@@ -378,7 +439,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, +@@ -391,7 +452,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4750, 5280 }, +@@ -404,7 +465,7 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING7A_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), +- 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, ++ 0x81, DATAFORMAT(TYPE2), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4750, 5280 }, +@@ -417,13 +478,26 @@ static const struct bcm5974_config bcm59 + USB_DEVICE_ID_APPLE_WELLSPRING8_JIS, + HAS_INTEGRATED_BUTTON, + 0, sizeof(struct bt_data), +- 0x83, TYPE3, FINGER_TYPE3, FINGER_TYPE3 + SIZEOF_ALL_FINGERS, ++ 0x83, DATAFORMAT(TYPE3), + { SN_PRESSURE, 0, 300 }, + { SN_WIDTH, 0, 2048 }, + { SN_COORD, -4620, 5140 }, + { SN_COORD, -150, 6600 }, + { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } + }, ++ { ++ USB_DEVICE_ID_APPLE_WELLSPRING9_ANSI, ++ USB_DEVICE_ID_APPLE_WELLSPRING9_ISO, ++ USB_DEVICE_ID_APPLE_WELLSPRING9_JIS, ++ HAS_INTEGRATED_BUTTON, ++ 0, sizeof(struct bt_data), ++ 0x83, DATAFORMAT(TYPE4), ++ { SN_PRESSURE, 0, 300 }, ++ { SN_WIDTH, 0, 2048 }, ++ { SN_COORD, -4828, 5345 }, ++ { SN_COORD, -203, 6803 }, ++ { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } ++ }, + {} + }; + +@@ -550,19 +624,18 @@ static int report_tp_state(struct bcm597 + struct input_dev *input = dev->input; + int raw_n, i, n = 0; + +- if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) ++ if (size < c->tp_header || (size - c->tp_header) % c->tp_fsize != 0) + return -EIO; + +- /* finger data, le16-aligned */ +- f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); +- raw_n = (size - c->tp_offset) / SIZEOF_FINGER; ++ raw_n = (size - c->tp_header) / c->tp_fsize; + + for (i = 0; i < raw_n; i++) { +- if (raw2int(f[i].touch_major) == 0) ++ f = get_tp_finger(dev, i); ++ if (raw2int(f->touch_major) == 0) + continue; +- dev->pos[n].x = raw2int(f[i].abs_x); +- dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); +- dev->index[n++] = &f[i]; ++ dev->pos[n].x = raw2int(f->abs_x); ++ dev->pos[n].y = c->y.min + c->y.max - raw2int(f->abs_y); ++ dev->index[n++] = f; + } + + input_mt_assign_slots(input, dev->slots, dev->pos, n); +@@ -573,32 +646,22 @@ static int report_tp_state(struct bcm597 + + input_mt_sync_frame(input); + +- report_synaptics_data(input, c, f, raw_n); ++ report_synaptics_data(input, c, get_tp_finger(dev, 0), raw_n); + +- /* type 2 reports button events via ibt only */ +- if (c->tp_type == TYPE2) { +- int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); ++ /* later types report button events via integrated button only */ ++ if (c->caps & HAS_INTEGRATED_BUTTON) { ++ int ibt = raw2int(dev->tp_data[c->tp_button]); + input_report_key(input, BTN_LEFT, ibt); + } + +- if (c->tp_type == TYPE3) +- input_report_key(input, BTN_LEFT, dev->tp_data[BUTTON_TYPE3]); +- + input_sync(input); + + return 0; + } + +-/* Wellspring initialization constants */ +-#define BCM5974_WELLSPRING_MODE_READ_REQUEST_ID 1 +-#define BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID 9 +-#define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300 +-#define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0 +-#define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01 +-#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE 0x08 +- + static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) + { ++ const struct bcm5974_config *c = &dev->cfg; + int retval = 0, size; + char *data; + +@@ -606,7 +669,7 @@ static int bcm5974_wellspring_mode(struc + if (dev->cfg.tp_type == TYPE3) + return 0; + +- data = kmalloc(8, GFP_KERNEL); ++ data = kmalloc(c->um_size, GFP_KERNEL); + if (!data) { + dev_err(&dev->intf->dev, "out of memory\n"); + retval = -ENOMEM; +@@ -617,28 +680,24 @@ static int bcm5974_wellspring_mode(struc + size = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), + BCM5974_WELLSPRING_MODE_READ_REQUEST_ID, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, +- BCM5974_WELLSPRING_MODE_REQUEST_VALUE, +- BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); ++ c->um_req_val, c->um_req_idx, data, c->um_size, 5000); + +- if (size != 8) { ++ if (size != c->um_size) { + dev_err(&dev->intf->dev, "could not read from device\n"); + retval = -EIO; + goto out; + } + + /* apply the mode switch */ +- data[0] = on ? +- BCM5974_WELLSPRING_MODE_VENDOR_VALUE : +- BCM5974_WELLSPRING_MODE_NORMAL_VALUE; ++ data[c->um_switch_idx] = on ? c->um_switch_on : c->um_switch_off; + + /* write configuration */ + size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), + BCM5974_WELLSPRING_MODE_WRITE_REQUEST_ID, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, +- BCM5974_WELLSPRING_MODE_REQUEST_VALUE, +- BCM5974_WELLSPRING_MODE_REQUEST_INDEX, data, 8, 5000); ++ c->um_req_val, c->um_req_idx, data, c->um_size, 5000); + +- if (size != 8) { ++ if (size != c->um_size) { + dev_err(&dev->intf->dev, "could not write to device\n"); + retval = -EIO; + goto out; +--- a/drivers/input/mouse/synaptics.c 2016-01-23 00:53:07.000000000 -0800 ++++ b/drivers/input/mouse/synaptics.c 2016-03-08 13:50:00.835861449 -0800 +@@ -1724,12 +1724,12 @@ static int __synaptics_init(struct psmou + priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; + + psmouse_info(psmouse, +- "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", ++ "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", + SYN_ID_MODEL(priv->identity), + SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), + priv->model_id, + priv->capabilities, priv->ext_cap, priv->ext_cap_0c, +- priv->board_id, priv->firmware_id); ++ priv->ext_cap_10, priv->board_id, priv->firmware_id); + + set_input_params(psmouse, priv); + diff --git a/SOURCES/centos-linux-scsi-storvsc-fix-bug12841.patch b/SOURCES/centos-linux-scsi-storvsc-fix-bug12841.patch new file mode 100644 index 0000000..80bca4f --- /dev/null +++ b/SOURCES/centos-linux-scsi-storvsc-fix-bug12841.patch @@ -0,0 +1,35 @@ +centosplus kernel patch [bug#12841] + +commit b0120d9906253570f593daf82016a5331bbee2b8 +Author: Cathy Avery +Date: Wed Nov 23 08:46:33 2016 -0500 + + scsi: storvsc: Payload buffer incorrectly sized for 32 bit kernels. + + On a 32 bit kernel sizeof(void *) is not 64 bits as hv_mpb_array + requires. Also the buffer needs to be cleared or the upper bytes will + contain junk. + + Suggested-by: Vitaly Kuznetsov + Signed-off-by: Cathy Avery + Reviewed-by: K. Y. Srinivasan + Signed-off-by: Martin K. Petersen + + Applied-by: Akemi Yagi + +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index 8ccfc9e..05526b7 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1495,9 +1495,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) + if (sg_count) { + if (sg_count > MAX_PAGE_BUFFER_COUNT) { + +- payload_sz = (sg_count * sizeof(void *) + ++ payload_sz = (sg_count * sizeof(u64) + + sizeof(struct vmbus_packet_mpb_array)); +- payload = kmalloc(payload_sz, GFP_ATOMIC); ++ payload = kzalloc(payload_sz, GFP_ATOMIC); + if (!payload) + return SCSI_MLQUEUE_DEVICE_BUSY; + } diff --git a/SOURCES/centos-linux-x86-perf-uncore-Avoid-kernel-panic-on-missing-topolo-bug12818.patch b/SOURCES/centos-linux-x86-perf-uncore-Avoid-kernel-panic-on-missing-topolo-bug12818.patch new file mode 100644 index 0000000..4cc9105 --- /dev/null +++ b/SOURCES/centos-linux-x86-perf-uncore-Avoid-kernel-panic-on-missing-topolo-bug12818.patch @@ -0,0 +1,44 @@ +centosplus kernel patch [bug#12818] + +From ac68351410df683a149e7eea09df178884cf2419 Mon Sep 17 00:00:00 2001 +From: Marcus Sundberg +Date: Mon, 13 Feb 2017 22:57:11 +0100 +Subject: [PATCH] [x86] perf: uncore: Avoid kernel panic on missing topology + +The uncore code is heavily dependent on the CPU topology mapping code, +so if we do not even have a working topology for the boot CPU we just +give up. +This happens for example on HPE DL360 Gen9 servers with x2APIC enabled +in the firmware settings, where the kernel only finds a single core. +--- + arch/x86/events/intel/uncore.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c +index 77ec6c0..88d79f6 100644 +--- a/arch/x86/events/intel/uncore.c ++++ b/arch/x86/events/intel/uncore.c +@@ -1394,6 +1394,20 @@ static int __init intel_uncore_init(void) + if (is_kdump_kernel()) + return -ENODEV; + ++ /* Sanity check - do not even try to proceed if we have no ++ working topology mapping for the boot CPU. */ ++ if (rh_boot_cpu_data.logical_proc_id < 0 || ++ topology_phys_to_logical_pkg(boot_cpu_data.phys_proc_id) < 0) { ++ printk(KERN_ERR ++ "no mapping between physical and logical CPU, " ++ "boot CPU phys: %d, logical: %d/%d\n", ++ (int)boot_cpu_data.phys_proc_id, ++ (int)rh_boot_cpu_data.logical_proc_id, ++ (int)topology_phys_to_logical_pkg( ++ boot_cpu_data.phys_proc_id)); ++ return -ENODEV; ++ } ++ + max_packages = topology_max_packages(); + + pret = uncore_pci_init(); +-- +2.5.0 + diff --git a/SOURCES/clear-32bit-Werror-warnings.patch b/SOURCES/clear-32bit-Werror-warnings.patch new file mode 100644 index 0000000..a8b6583 --- /dev/null +++ b/SOURCES/clear-32bit-Werror-warnings.patch @@ -0,0 +1,27 @@ +From 87a5a3683110ec3d30d95036c57f5cfa330ca9d9 Mon Sep 17 00:00:00 2001 +From: Marcus Sundberg +Date: Fri, 16 Dec 2016 22:53:51 +0100 +Subject: [PATCH] gpt: Use correct type for gpt->gdp. + +It should be a pointer to gte_t, to avoid warnings when +CONFIG_HIGHMEM64G is enabled. +--- + include/linux/gpt.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/gpt.h b/include/linux/gpt.h +index 134e02b..56715f1 100644 +--- a/include/linux/gpt.h ++++ b/include/linux/gpt.h +@@ -45,7 +45,7 @@ + struct gpt { + unsigned long start; + unsigned long end; +- unsigned long *gdp; ++ gte_t *gdp; + atomic_t refcount; + spinlock_t lock; + uint8_t nlevels; +-- +1.8.3.1 + diff --git a/SOURCES/cpufreq.patch b/SOURCES/cpufreq.patch new file mode 100644 index 0000000..beabf01 --- /dev/null +++ b/SOURCES/cpufreq.patch @@ -0,0 +1,394 @@ +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/cpufreq-nforce2.c linux-3.10.0-229.el7/drivers/cpufreq/cpufreq-nforce2.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/cpufreq-nforce2.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/cpufreq-nforce2.c 2015-03-09 09:22:18.376023945 -0400 +@@ -270,7 +270,7 @@ + pr_debug("Old CPU frequency %d kHz, new %d kHz\n", + freqs.old, freqs.new); + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + /* Disable IRQs */ + /* local_irq_save(flags); */ +@@ -285,7 +285,7 @@ + /* Enable IRQs */ + /* local_irq_restore(flags); */ + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + return 0; + } +Binary files linux-3.10.0-229.el7.original/drivers/cpufreq/.cpufreq-nforce2.c.swp and linux-3.10.0-229.el7/drivers/cpufreq/.cpufreq-nforce2.c.swp differ +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/exynos5440-cpufreq.c linux-3.10.0-229.el7/drivers/cpufreq/exynos5440-cpufreq.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/exynos5440-cpufreq.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/exynos5440-cpufreq.c 2015-03-09 09:22:18.377023945 -0400 +@@ -238,7 +238,7 @@ + freqs.old = dvfs_info->cur_frequency; + freqs.new = freq_table[index].frequency; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + /* Set the target frequency in all C0_3_PSTATE register */ + for_each_cpu(i, policy->cpus) { +@@ -279,7 +279,7 @@ + dev_crit(dvfs_info->dev, "New frequency out of range\n"); + freqs.new = dvfs_info->cur_frequency; + } +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + cpufreq_cpu_put(policy); + mutex_unlock(&cpufreq_lock); +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/gx-suspmod.c linux-3.10.0-229.el7/drivers/cpufreq/gx-suspmod.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/gx-suspmod.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/gx-suspmod.c 2015-03-09 09:22:18.377023945 -0400 +@@ -265,7 +265,7 @@ + + freqs.new = new_khz; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + local_irq_save(flags); + + if (new_khz != stock_freq) { +@@ -314,7 +314,7 @@ + + gx_params->pci_suscfg = suscfg; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n", + gx_params->on_duration * 32, gx_params->off_duration * 32); +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/integrator-cpufreq.c linux-3.10.0-229.el7/drivers/cpufreq/integrator-cpufreq.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/integrator-cpufreq.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/integrator-cpufreq.c 2015-03-09 09:22:18.377023945 -0400 +@@ -121,7 +121,7 @@ + return 0; + } + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + cm_osc = __raw_readl(CM_OSC); + +@@ -142,7 +142,7 @@ + */ + set_cpus_allowed(current, cpus_allowed); + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + return 0; + } +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/longhaul.c linux-3.10.0-229.el7/drivers/cpufreq/longhaul.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/longhaul.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/longhaul.c 2015-03-09 09:22:18.377023945 -0400 +@@ -269,7 +269,7 @@ + freqs.old = calc_speed(longhaul_get_cpu_mult()); + freqs.new = speed; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", + fsb, mult/10, mult%10, print_speed(speed/1000)); +@@ -386,7 +386,7 @@ + } + } + /* Report true CPU frequency */ +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + if (!bm_timeout) + printk(KERN_INFO PFX "Warning: Timeout while waiting for " +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/powernow-k6.c linux-3.10.0-229.el7/drivers/cpufreq/powernow-k6.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/powernow-k6.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/powernow-k6.c 2015-03-09 09:23:09.182024898 -0400 +@@ -83,7 +83,7 @@ + freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); + freqs.new = busfreq * clock_ratio[best_i].driver_data; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + /* we now need to transform best_i to the BVC format, see AMD#23446 */ + +@@ -98,7 +98,7 @@ + msrval = POWERNOW_IOPORT + 0x0; + wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */ + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + return; + } +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/powernow-k7.c linux-3.10.0-229.el7/drivers/cpufreq/powernow-k7.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/powernow-k7.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/powernow-k7.c 2015-03-09 09:23:52.126025704 -0400 +@@ -269,7 +269,7 @@ + + freqs.new = powernow_table[index].frequency; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + /* Now do the magic poking into the MSRs. */ + +@@ -290,7 +290,7 @@ + if (have_a0 == 1) + local_irq_enable(); + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + } + + +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/sh-cpufreq.c linux-3.10.0-229.el7/drivers/cpufreq/sh-cpufreq.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/sh-cpufreq.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/sh-cpufreq.c 2015-03-09 09:22:18.378023945 -0400 +@@ -68,10 +68,10 @@ + freqs.new = (freq + 500) / 1000; + freqs.flags = 0; + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + set_cpus_allowed_ptr(current, &cpus_allowed); + clk_set_rate(cpuclk, freq); +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, 0); + + dev_dbg(dev, "set frequency %lu Hz\n", freq); + +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/speedstep-centrino.c linux-3.10.0-229.el7/drivers/cpufreq/speedstep-centrino.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/speedstep-centrino.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/speedstep-centrino.c 2015-03-09 09:58:30.112064688 -0400 +@@ -345,7 +345,6 @@ + struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu); + unsigned freq; + unsigned l, h; +- int ret; + int i; + + /* Only Intel makes Enhanced Speedstep-capable CPUs */ +@@ -402,15 +401,8 @@ + + pr_debug("centrino_cpu_init: cur=%dkHz\n", policy->cur); + +- ret = cpufreq_frequency_table_cpuinfo(policy, ++ return cpufreq_table_validate_and_show(policy, + per_cpu(centrino_model, policy->cpu)->op_points); +- if (ret) +- return (ret); +- +- cpufreq_frequency_table_get_attr( +- per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu); +- +- return 0; + } + + static int centrino_cpu_exit(struct cpufreq_policy *policy) +@@ -428,19 +420,6 @@ + } + + /** +- * centrino_verify - verifies a new CPUFreq policy +- * @policy: new policy +- * +- * Limit must be within this model's frequency range at least one +- * border included. +- */ +-static int centrino_verify (struct cpufreq_policy *policy) +-{ +- return cpufreq_frequency_table_verify(policy, +- per_cpu(centrino_model, policy->cpu)->op_points); +-} +- +-/** + * centrino_setpolicy - set a new CPUFreq policy + * @policy: new policy + * @target_freq: the target frequency +@@ -561,20 +540,15 @@ + return retval; + } + +-static struct freq_attr* centrino_attr[] = { +- &cpufreq_freq_attr_scaling_available_freqs, +- NULL, +-}; +- + static struct cpufreq_driver centrino_driver = { + .name = "centrino", /* should be speedstep-centrino, + but there's a 16 char limit */ + .init = centrino_cpu_init, + .exit = centrino_cpu_exit, +- .verify = centrino_verify, ++ .verify = cpufreq_generic_frequency_table_verify, + .target = centrino_target, + .get = get_cur_freq, +- .attr = centrino_attr, ++ .attr = cpufreq_generic_attr, + }; + + /* +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/speedstep-ich.c linux-3.10.0-229.el7/drivers/cpufreq/speedstep-ich.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/speedstep-ich.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/speedstep-ich.c 2015-03-09 09:58:30.113064688 -0400 +@@ -289,18 +289,6 @@ + } + + +-/** +- * speedstep_verify - verifies a new CPUFreq policy +- * @policy: new policy +- * +- * Limit must be within speedstep_low_freq and speedstep_high_freq, with +- * at least one border included. +- */ +-static int speedstep_verify(struct cpufreq_policy *policy) +-{ +- return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); +-} +- + struct get_freqs { + struct cpufreq_policy *policy; + int ret; +@@ -320,7 +308,6 @@ + + static int speedstep_cpu_init(struct cpufreq_policy *policy) + { +- int result; + unsigned int policy_cpu, speed; + struct get_freqs gf; + +@@ -349,36 +336,18 @@ + /* cpuinfo and default policy values */ + policy->cur = speed; + +- result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); +- if (result) +- return result; +- +- cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); +- +- return 0; ++ return cpufreq_table_validate_and_show(policy, speedstep_freqs); + } + + +-static int speedstep_cpu_exit(struct cpufreq_policy *policy) +-{ +- cpufreq_frequency_table_put_attr(policy->cpu); +- return 0; +-} +- +-static struct freq_attr *speedstep_attr[] = { +- &cpufreq_freq_attr_scaling_available_freqs, +- NULL, +-}; +- +- + static struct cpufreq_driver speedstep_driver = { + .name = "speedstep-ich", +- .verify = speedstep_verify, ++ .verify = cpufreq_generic_frequency_table_verify, + .target = speedstep_target, + .init = speedstep_cpu_init, +- .exit = speedstep_cpu_exit, ++ .exit = cpufreq_generic_exit, + .get = speedstep_get, +- .attr = speedstep_attr, ++ .attr = cpufreq_generic_attr, + }; + + static const struct x86_cpu_id ss_smi_ids[] = { +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/speedstep-smi.c linux-3.10.0-229.el7/drivers/cpufreq/speedstep-smi.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/speedstep-smi.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/speedstep-smi.c 2015-03-09 09:58:30.113064688 -0400 +@@ -264,19 +264,6 @@ + } + + +-/** +- * speedstep_verify - verifies a new CPUFreq policy +- * @policy: new policy +- * +- * Limit must be within speedstep_low_freq and speedstep_high_freq, with +- * at least one border included. +- */ +-static int speedstep_verify(struct cpufreq_policy *policy) +-{ +- return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]); +-} +- +- + static int speedstep_cpu_init(struct cpufreq_policy *policy) + { + int result; +@@ -329,19 +316,7 @@ + policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; + policy->cur = speed; + +- result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs); +- if (result) +- return result; +- +- cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu); +- +- return 0; +-} +- +-static int speedstep_cpu_exit(struct cpufreq_policy *policy) +-{ +- cpufreq_frequency_table_put_attr(policy->cpu); +- return 0; ++ return cpufreq_table_validate_and_show(policy, speedstep_freqs); + } + + static unsigned int speedstep_get(unsigned int cpu) +@@ -362,20 +337,15 @@ + return result; + } + +-static struct freq_attr *speedstep_attr[] = { +- &cpufreq_freq_attr_scaling_available_freqs, +- NULL, +-}; +- + static struct cpufreq_driver speedstep_driver = { + .name = "speedstep-smi", +- .verify = speedstep_verify, ++ .verify = cpufreq_generic_frequency_table_verify, + .target = speedstep_target, + .init = speedstep_cpu_init, +- .exit = speedstep_cpu_exit, ++ .exit = cpufreq_generic_exit, + .get = speedstep_get, + .resume = speedstep_resume, +- .attr = speedstep_attr, ++ .attr = cpufreq_generic_attr, + }; + + static const struct x86_cpu_id ss_smi_ids[] = { +diff -urN linux-3.10.0-229.el7.original/drivers/cpufreq/unicore2-cpufreq.c linux-3.10.0-229.el7/drivers/cpufreq/unicore2-cpufreq.c +--- linux-3.10.0-229.el7.original/drivers/cpufreq/unicore2-cpufreq.c 2015-01-29 18:15:53.000000000 -0500 ++++ linux-3.10.0-229.el7/drivers/cpufreq/unicore2-cpufreq.c 2015-03-09 09:24:33.053026472 -0400 +@@ -50,14 +50,14 @@ + struct cpufreq_freqs freqs; + struct clk *mclk = clk_get(NULL, "MAIN_CLK"); + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); ++ cpufreq_freq_transition_begin(policy, &freqs); + + if (!clk_set_rate(mclk, target_freq * 1000)) { + freqs.old = cur; + freqs.new = target_freq; + } + +- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); ++ cpufreq_freq_transition_end(policy, &freqs, ret); + + return 0; + } diff --git a/SOURCES/i386-audit-stop-scri-stack-frame.patch b/SOURCES/i386-audit-stop-scri-stack-frame.patch new file mode 100644 index 0000000..48393aa --- /dev/null +++ b/SOURCES/i386-audit-stop-scri-stack-frame.patch @@ -0,0 +1,31 @@ +Note: this bug was taken from Commit-ID: 26c2d2b39128adba276d140eefa2745591b88536 +and corrected for white space differences between the RHEL-7.1 3.10.0-229 upstream +kernel. +--- +diff -uNrp a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S +--- a/arch/x86/kernel/entry_32.S 2015-05-17 07:39:14.371778177 -0500 ++++ b/arch/x86/kernel/entry_32.S 2015-05-17 07:36:13.654610869 -0500 +@@ -457,15 +457,14 @@ sysenter_exit: + sysenter_audit: + testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags(%ebp) + jnz syscall_trace_entry +- addl $4,%esp +- CFI_ADJUST_CFA_OFFSET -4 +- movl %esi,4(%esp) /* 5th arg: 4th syscall arg */ +- movl %edx,(%esp) /* 4th arg: 3rd syscall arg */ +- /* %ecx already in %ecx 3rd arg: 2nd syscall arg */ +- movl %ebx,%edx /* 2nd arg: 1st syscall arg */ +- /* %eax already in %eax 1st arg: syscall number */ ++ /* movl PT_EAX(%esp), %eax already set, syscall number: 1st arg to audit */ ++ movl PT_EBX(%esp), %edx /* ebx/a0: 2nd arg to audit */ ++ /* movl PT_ECX(%esp), %ecx already set, a1: 3nd arg to audit */ ++ pushl_cfi PT_ESI(%esp) /* a3: 5th arg */ ++ pushl_cfi PT_EDX+4(%esp) /* a2: 4th arg */ + call __audit_syscall_entry +- pushl_cfi %ebx ++ popl_cfi %ecx /* get that remapped edx off the stack */ ++ popl_cfi %ecx /* get that remapped esi off the stack */ + movl PT_EAX(%esp),%eax /* reload syscall number */ + jmp sysenter_do_call + +--- diff --git a/SOURCES/morefixes.patch b/SOURCES/morefixes.patch new file mode 100644 index 0000000..a294350 --- /dev/null +++ b/SOURCES/morefixes.patch @@ -0,0 +1,84 @@ +diff -up linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/cpufeature.h.morefixes linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/cpufeature.h +--- linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/cpufeature.h.morefixes 2016-10-19 10:16:25.000000000 -0400 ++++ linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/cpufeature.h 2016-11-05 08:30:46.276033474 -0400 +@@ -354,6 +354,7 @@ extern const char * const x86_power_flag + #define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX) + #define cpu_has_avx2 boot_cpu_has(X86_FEATURE_AVX2) + #define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) ++#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) + #define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) + #define cpu_has_xstore boot_cpu_has(X86_FEATURE_XSTORE) + #define cpu_has_xstore_enabled boot_cpu_has(X86_FEATURE_XSTORE_EN) +diff -up linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/irq_remapping.h.morefixes linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/irq_remapping.h +--- linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/irq_remapping.h.morefixes 2016-10-19 10:16:25.000000000 -0400 ++++ linux-3.10.0-514.sdl7.i686/arch/x86/include/asm/irq_remapping.h 2016-11-05 09:39:38.425043476 -0400 +@@ -110,7 +110,7 @@ static inline bool setup_remapped_irq(in + return false; + } + +-int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info) ++static inline int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info) + { + return -ENOSYS; + } +diff -up linux-3.10.0-514.sdl7.i686/arch/x86/kernel/irq_32.c.morefixes linux-3.10.0-514.sdl7.i686/arch/x86/kernel/irq_32.c +--- linux-3.10.0-514.sdl7.i686/arch/x86/kernel/irq_32.c.morefixes 2016-10-19 10:16:25.000000000 -0400 ++++ linux-3.10.0-514.sdl7.i686/arch/x86/kernel/irq_32.c 2016-11-05 09:49:59.371055125 -0400 +@@ -24,9 +24,12 @@ + DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); + EXPORT_PER_CPU_SYMBOL(irq_stat); + ++DEFINE_PER_CPU_SHARED_ALIGNED(rh_irq_cpustat_t, rh_irq_stat); ++ + DEFINE_PER_CPU(struct pt_regs *, irq_regs); + EXPORT_PER_CPU_SYMBOL(irq_regs); + ++ + #ifdef CONFIG_DEBUG_STACKOVERFLOW + + int sysctl_panic_on_stackoverflow __read_mostly; +diff -up linux-3.10.0-514.sdl7.i686/include/linux/pps_kernel.h.morefixes linux-3.10.0-514.sdl7.i686/include/linux/pps_kernel.h +--- linux-3.10.0-514.sdl7.i686/include/linux/pps_kernel.h.morefixes 2016-10-19 10:16:25.000000000 -0400 ++++ linux-3.10.0-514.sdl7.i686/include/linux/pps_kernel.h 2016-11-05 10:44:41.492049162 -0400 +@@ -115,10 +115,17 @@ static inline void pps_get_ts(struct pps + { + struct system_time_snapshot snap; + ktime_get_snapshot(&snap); ++#if defined CONFIG_X86_64 + ts->ts_real = ktime_to_timespec64(snap.real); + #ifdef CONFIG_NTP_PPS + ts->ts_raw = ktime_to_timespec64(snap.raw); + #endif ++#else ++ ts->ts_real = ktime_to_timespec(snap.real); ++#ifdef CONFIG_NTP_PPS ++ ts->ts_raw = ktime_to_timespec(snap.raw); ++#endif ++#endif + } + + /* Subtract known time delay from PPS event time(s) */ +diff -up linux-3.10.0-514.sdl7.i686/kernel/hrtimer.c.morefixes linux-3.10.0-514.sdl7.i686/kernel/hrtimer.c +--- linux-3.10.0-514.sdl7.i686/kernel/hrtimer.c.morefixes 2016-10-19 10:16:25.000000000 -0400 ++++ linux-3.10.0-514.sdl7.i686/kernel/hrtimer.c 2016-11-05 10:58:56.726065206 -0400 +@@ -328,6 +328,7 @@ u64 ktime_divns(const ktime_t kt, s64 di + + return dclc; + } ++EXPORT_SYMBOL_GPL(ktime_divns); + #endif /* BITS_PER_LONG >= 64 */ + + /* +diff -up linux-3.10.0-514.sdl7.i686/mm/swap.c.morefixes linux-3.10.0-514.sdl7.i686/mm/swap.c +--- linux-3.10.0-514.sdl7.i686/mm/swap.c.morefixes 2016-10-19 10:16:25.000000000 -0400 ++++ linux-3.10.0-514.sdl7.i686/mm/swap.c 2016-11-05 08:55:41.521061525 -0400 +@@ -972,9 +972,6 @@ void release_pages(struct page **pages, + if (!put_page_testzero(page)) + continue; + +- VM_BUG_ON_PAGE(check_mmu_gather && +- trans_huge_mmu_gather_count(page), page); +- + if (PageLRU(page)) { + if (!was_thp) + zone = zone_lru_lock(zone, page, &lock_batch, diff --git a/SOURCES/removejiffies.patch b/SOURCES/removejiffies.patch new file mode 100644 index 0000000..71da335 --- /dev/null +++ b/SOURCES/removejiffies.patch @@ -0,0 +1,12 @@ +diff -up linux-3.10.0-123.6.3.el7.x86_64/include/asm-generic/cputime_jiffies.h.removejiffies linux-3.10.0-123.6.3.el7.x86_64/include/asm-generic/cputime_jiffies.h +--- linux-3.10.0-123.6.3.el7.x86_64/include/asm-generic/cputime_jiffies.h.removejiffies 2014-07-16 14:25:31.000000000 -0400 ++++ linux-3.10.0-123.6.3.el7.x86_64/include/asm-generic/cputime_jiffies.h 2014-08-07 10:57:42.702063799 -0400 +@@ -17,8 +17,6 @@ typedef u64 __nocast cputime64_t; + /* + * Convert nanoseconds <-> cputime + */ +-#define cputime_to_nsecs(__ct) \ +- jiffies_to_nsecs(cputime_to_jiffies(__ct)) + #define nsecs_to_cputime64(__nsec) \ + jiffies64_to_cputime64(nsecs_to_jiffies64(__nsec)) + #define nsecs_to_cputime(__nsec) \ diff --git a/SOURCES/undorhirqstat.patch b/SOURCES/undorhirqstat.patch new file mode 100644 index 0000000..f8340fc --- /dev/null +++ b/SOURCES/undorhirqstat.patch @@ -0,0 +1,84 @@ +diff -up linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/hardirq.h.undorhirqstat linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/hardirq.h +--- linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/hardirq.h.undorhirqstat 2015-10-29 16:56:51.000000000 -0400 ++++ linux-3.10.0-327.sdl7.x86_64/arch/x86/include/asm/hardirq.h 2015-11-21 23:57:10.330063191 -0500 +@@ -37,18 +37,13 @@ typedef struct { + + DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); + +-typedef struct { +- unsigned int irq_hv_callback_count; +-} ____cacheline_aligned rh_irq_cpustat_t; +- +-DECLARE_PER_CPU_SHARED_ALIGNED(rh_irq_cpustat_t, rh_irq_stat); ++/* We can have at most NR_VECTORS irqs routed to a cpu at a time */ ++#define MAX_HARDIRQS_PER_CPU NR_VECTORS + + #define __ARCH_IRQ_STAT + + #define inc_irq_stat(member) this_cpu_inc(irq_stat.member) + +-#define rh_inc_irq_stat(member) this_cpu_inc(rh_irq_stat.member) +- + #define local_softirq_pending() this_cpu_read(irq_stat.__softirq_pending) + + #define __ARCH_SET_SOFTIRQ_PENDING +diff -up linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/cpu/mshyperv.c.undorhirqstat linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/cpu/mshyperv.c +--- linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/cpu/mshyperv.c.undorhirqstat 2015-10-29 16:56:51.000000000 -0400 ++++ linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/cpu/mshyperv.c 2015-11-22 00:03:55.131003266 -0500 +@@ -46,7 +46,6 @@ void hyperv_vector_handler(struct pt_reg + irq_enter(); + exit_idle(); + +- rh_inc_irq_stat(irq_hv_callback_count); + if (vmbus_handler) + vmbus_handler(); + +diff -up linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq.c.undorhirqstat linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq.c +--- linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq.c.undorhirqstat 2015-10-29 16:56:51.000000000 -0400 ++++ linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq.c 2015-11-21 23:58:02.526064171 -0500 +@@ -48,7 +48,6 @@ void ack_bad_irq(unsigned int irq) + } + + #define irq_stats(x) (&per_cpu(irq_stat, x)) +-#define rh_irq_stats(x) (&per_cpu(rh_irq_stat, x)) + /* + * /proc/interrupts printing for arch specific interrupts + */ +@@ -126,13 +125,6 @@ int arch_show_interrupts(struct seq_file + seq_printf(p, "%10u ", per_cpu(mce_poll_count, j)); + seq_printf(p, " Machine check polls\n"); + #endif +- if (test_bit(HYPERVISOR_CALLBACK_VECTOR, used_vectors)) { +- seq_printf(p, "%*s: ", prec, "HYP"); +- for_each_online_cpu(j) +- seq_printf(p, "%10u ", +- rh_irq_stats(j)->irq_hv_callback_count); +- seq_printf(p, " Hypervisor callback interrupts\n"); +- } + seq_printf(p, "%*s: %10u\n", prec, "ERR", atomic_read(&irq_err_count)); + #if defined(CONFIG_X86_IO_APIC) + seq_printf(p, "%*s: %10u\n", prec, "MIS", atomic_read(&irq_mis_count)); +diff -up linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq_64.c.undorhirqstat linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq_64.c +--- linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq_64.c.undorhirqstat 2015-10-29 16:56:51.000000000 -0400 ++++ linux-3.10.0-327.sdl7.x86_64/arch/x86/kernel/irq_64.c 2015-11-21 23:58:27.650064642 -0500 +@@ -23,8 +23,6 @@ + DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); + EXPORT_PER_CPU_SYMBOL(irq_stat); + +-DEFINE_PER_CPU_SHARED_ALIGNED(rh_irq_cpustat_t, rh_irq_stat); +- + DEFINE_PER_CPU(struct pt_regs *, irq_regs); + EXPORT_PER_CPU_SYMBOL(irq_regs); + +diff -up linux-3.10.0-327.sdl7.x86_64/drivers/xen/events.c.undorhirqstat linux-3.10.0-327.sdl7.x86_64/drivers/xen/events.c +--- linux-3.10.0-327.sdl7.x86_64/drivers/xen/events.c.undorhirqstat 2015-10-29 16:56:51.000000000 -0400 ++++ linux-3.10.0-327.sdl7.x86_64/drivers/xen/events.c 2015-11-22 00:04:18.032003696 -0500 +@@ -1446,8 +1446,6 @@ void xen_evtchn_do_upcall(struct pt_regs + #ifdef CONFIG_X86 + exit_idle(); + #endif +- rh_inc_irq_stat(irq_hv_callback_count); +- + __xen_evtchn_do_upcall(); + + irq_exit(); diff --git a/SOURCES/upstream-32bit-fixes.patch b/SOURCES/upstream-32bit-fixes.patch new file mode 100644 index 0000000..cb759ed --- /dev/null +++ b/SOURCES/upstream-32bit-fixes.patch @@ -0,0 +1,224 @@ +From 5265f6ea5a6643c5b2aa13e8e4664962251b37ea Mon Sep 17 00:00:00 2001 +From: Chad Dupuis +Date: Thu, 13 Mar 2014 14:16:40 -0400 +Subject: [PATCH] qla2xxx: Fix build errors related to invalid print fields on + some architectures. + +Fixes some build warnings such as: +drivers/scsi/qla2xxx/qla_attr.c:162:6: warning: format '%lx' expects argument of +type 'long unsigned int', but argument 6 has type 'size_t'" +and +drivers/scsi/qla2xxx/qla_init.c:5198:7: warning: format '%lx' expects argument +of type 'long unsigned int', but argument 5 has type 'uint32_t' [-Wformat] + +Signed-off-by: Chad Dupuis +Signed-off-by: Saurav Kashyap +Signed-off-by: James Bottomley +--- + drivers/scsi/qla2xxx/qla_attr.c | 6 +++--- + drivers/scsi/qla2xxx/qla_init.c | 12 ++++++------ + 2 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c +index da5ae11..1a976c0 100644 +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -159,7 +159,7 @@ qla2x00_sysfs_read_fw_dump_template(struct file *filp, struct kobject *kobj, + return 0; + + ql_dbg(ql_dbg_user, vha, 0x70e2, +- "chunk <- off=%llx count=%lx\n", off, count); ++ "chunk <- off=%llx count=%zx\n", off, count); + return memory_read_from_buffer(buf, count, &off, + ha->fw_dump_template, ha->fw_dump_template_len); + } +@@ -200,11 +200,11 @@ qla2x00_sysfs_write_fw_dump_template(struct file *filp, struct kobject *kobj, + if (off + count > ha->fw_dump_template_len) { + count = ha->fw_dump_template_len - off; + ql_dbg(ql_dbg_user, vha, 0x70d3, +- "chunk -> truncating to %lx bytes.\n", count); ++ "chunk -> truncating to %zx bytes.\n", count); + } + + ql_dbg(ql_dbg_user, vha, 0x70d4, +- "chunk -> off=%llx count=%lx\n", off, count); ++ "chunk -> off=%llx count=%zx\n", off, count); + memcpy(ha->fw_dump_template + off, buf, count); + + if (off + count == ha->fw_dump_template_len) { +diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c +index c64ee86..462836c 100644 +--- a/drivers/scsi/qla2xxx/qla_init.c ++++ b/drivers/scsi/qla2xxx/qla_init.c +@@ -5452,8 +5452,8 @@ qla24xx_load_risc_flash(scsi_qla_host_t *vha, uint32_t *srisc_addr, + "-> template size %x bytes\n", dlen); + if (dlen > risc_size * sizeof(*dcode)) { + ql_log(ql_log_warn, vha, 0x0167, +- "Failed fwdump template exceeds array by %lx bytes\n", +- dlen - risc_size * sizeof(*dcode)); ++ "Failed fwdump template exceeds array by %x bytes\n", ++ (uint32_t)(dlen - risc_size * sizeof(*dcode))); + goto default_template; + } + ha->fw_dump_template_len = dlen; +@@ -5719,8 +5719,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) + ha->fw_dump_template_len = 0; + + ql_dbg(ql_dbg_init, vha, 0x171, +- "Loading fwdump template from %lx\n", +- (void *)fwcode - (void *)blob->fw->data); ++ "Loading fwdump template from %x\n", ++ (uint32_t)((void *)fwcode - (void *)blob->fw->data)); + risc_size = be32_to_cpu(fwcode[2]); + ql_dbg(ql_dbg_init, vha, 0x172, + "-> array size %x dwords\n", risc_size); +@@ -5754,8 +5754,8 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) + "-> template size %x bytes\n", dlen); + if (dlen > risc_size * sizeof(*fwcode)) { + ql_log(ql_log_warn, vha, 0x0177, +- "Failed fwdump template exceeds array by %lx bytes\n", +- dlen - risc_size * sizeof(*fwcode)); ++ "Failed fwdump template exceeds array by %x bytes\n", ++ (uint32_t)(dlen - risc_size * sizeof(*fwcode))); + goto default_template; + } + ha->fw_dump_template_len = dlen; +-- +1.8.3.1 + +From b9469523631bd376a5f877d4e816f3a81c12b790 Mon Sep 17 00:00:00 2001 +From: Paul Bolle +Date: Mon, 30 Jun 2014 16:32:29 +0200 +Subject: [PATCH] x86: Remove unused variable "polling" + +Compile tested. "polling" is unused since commit f80c5b39b80a +("sched/idle, x86: Switch from TS_POLLING to TIF_POLLING_NRFLAG"). + +Signed-off-by: Paul Bolle +Signed-off-by: Peter Zijlstra +Cc: Jiri Kosina +Link: http://lkml.kernel.org/r/1404138749.2978.6.camel@x41 +Signed-off-by: Ingo Molnar +--- + arch/x86/kernel/apm_32.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c +index 8fdcec6..66d3b1f 100644 +--- a/arch/x86/kernel/apm_32.c ++++ b/arch/x86/kernel/apm_32.c +@@ -841,7 +841,6 @@ static int apm_do_idle(void) + u32 eax; + u8 ret = 0; + int idled = 0; +- int polling; + int err = 0; + + if (!need_resched()) { +-- +1.8.3.1 + +From 75c2e0e53d2fb5df66b8fe162d71930348ac0b96 Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Wed, 16 Jul 2014 21:03:56 +0000 +Subject: [PATCH] ktime: Change ktime_set() to take 64bit seconds value + +In order to support dates past 2038 on 32bit systems, ktime_set() +needs to handle 64bit second values. + +[ tglx: Removed the BITS_PER_LONG check ] + +Signed-off-by: John Stultz +Signed-off-by: Thomas Gleixner +Signed-off-by: John Stultz +--- + include/linux/ktime.h | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/include/linux/ktime.h b/include/linux/ktime.h +index e4e9a9f..6950c96 100644 +--- a/include/linux/ktime.h ++++ b/include/linux/ktime.h +@@ -71,13 +71,12 @@ typedef union ktime ktime_t; /* Kill this */ + * + * Return the ktime_t representation of the value + */ +-static inline ktime_t ktime_set(const long secs, const unsigned long nsecs) ++static inline ktime_t ktime_set(const s64 secs, const unsigned long nsecs) + { +-#if (BITS_PER_LONG == 64) + if (unlikely(secs >= KTIME_SEC_MAX)) + return (ktime_t){ .tv64 = KTIME_MAX }; +-#endif +- return (ktime_t) { .tv64 = (s64)secs * NSEC_PER_SEC + (s64)nsecs }; ++ ++ return (ktime_t) { .tv64 = secs * NSEC_PER_SEC + (s64)nsecs }; + } + + /* Subtract two ktime_t variables. rem = lhs -rhs: */ +-- +1.8.3.1 + +From 80a667f7ab1beee42b31e263ba4681fdfe00a0b6 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 17 Jun 2015 23:58:28 +0200 +Subject: [PATCH] netfilter: xtables: fix warnings on 32bit platforms + +On 32bit archs gcc complains due to cast from void* to u64. +Add intermediate casts to long to silence these warnings. + +include/linux/netfilter/x_tables.h:376:10: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] +include/linux/netfilter/x_tables.h:384:15: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] +include/linux/netfilter/x_tables.h:391:23: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] +include/linux/netfilter/x_tables.h:400:22: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] + +Fixes: 71ae0dff02d756e ("netfilter: xtables: use percpu rule counters") +Reported-by: kbuild test robot +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +--- + include/linux/netfilter/x_tables.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h +index d08f0ed..781b6fe 100644 +--- a/include/linux/netfilter/x_tables.h ++++ b/include/linux/netfilter/x_tables.h +@@ -390,7 +390,7 @@ static inline u64 xt_percpu_counter_alloc(void) + if (res == NULL) + return (u64) -ENOMEM; + +- return (__force u64) res; ++ return (u64) (__force unsigned long) res; + } + + return 0; +@@ -398,14 +398,14 @@ static inline u64 xt_percpu_counter_alloc(void) + static inline void xt_percpu_counter_free(u64 pcnt) + { + if (nr_cpu_ids > 1) +- free_percpu((void __percpu *) pcnt); ++ free_percpu((void __percpu *) (unsigned long) pcnt); + } + + static inline struct xt_counters * + xt_get_this_cpu_counter(struct xt_counters *cnt) + { + if (nr_cpu_ids > 1) +- return this_cpu_ptr((void __percpu *) cnt->pcnt); ++ return this_cpu_ptr((void __percpu *) (unsigned long) cnt->pcnt); + + return cnt; + } +@@ -414,7 +414,7 @@ static inline struct xt_counters * + xt_get_per_cpu_counter(struct xt_counters *cnt, unsigned int cpu) + { + if (nr_cpu_ids > 1) +- return per_cpu_ptr((void __percpu *) cnt->pcnt, cpu); ++ return per_cpu_ptr((void __percpu *) (unsigned long) cnt->pcnt, cpu); + + return cnt; + } +-- +1.8.3.1 +