From patchwork Fri Dec 4 23:00:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338631 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07BCFC433FE for ; Fri, 4 Dec 2020 23:02:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C73B022C9E for ; Fri, 4 Dec 2020 23:02:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726147AbgLDXCD (ORCPT ); Fri, 4 Dec 2020 18:02:03 -0500 Received: from esa6.microchip.iphmx.com ([216.71.154.253]:21231 "EHLO esa6.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725960AbgLDXCD (ORCPT ); Fri, 4 Dec 2020 18:02:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122922; x=1638658922; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sEiAodSF5h6RWBEkpXfCRMMnzVx5hcszxvTEhuu/XlY=; b=gjNVGGLNA9klCed5ltT+A7+LO2HDCX11KOUW82GSKiRl3SJHY8mhkHfd rAiXO2p9j4n/s/XVbf9Bw9OoV5h87l+A+YENL05BdqSAY6hJQb8Qc4g5r WGxLebkvULimueDOBdUxAUsucnZDdQTW+e0RnShprbu5/AG14Cg6N8/O8 zJlaVNmzXi9nFK4c6jfx9sVCmwlWxsqThvLhGSHAk+PUaFhfsDc30pdYL Xk0pbo+XwXsYr3P+uWHdhEf0pBl+GHtqPreEyJE9gqpcl5HQu22Pvqtnr moCcGoyZOwgyJRpwimsxE07vCLGXmrSDiDi3Cxz8YXTC4NZxcmRwjQNTS Q==; IronPort-SDR: QVWDFXrz+S1hPkb1MveFcT18EccMrvBtOogoiYm9ZkE2OaGdbHlqdagI/3RDjgv380s9JVcEVS DTQxtS4M/JgwC8ve4YzGJfklPNqQu/SsAhS6mdm7T1iTM5wr+7x5AqAIDOcmap+IQfJvHOAYzQ R2/7Uxc3EcazcRn4OR/vVcipOwBOEzcRJNsOmPlYiWdPKr3+OYTr3jwkoIuhofTexElPflK7+D bSJ156jF0uQ8fd7VjiUZhE4kJnOMgxIGtDp5ai6K0fflqJwVYbN6l0HB29Or6fqmUhgfecErwv KfU= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="36192742" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:00:57 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:00:57 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:00:56 -0700 Subject: [PATCH 01/25] smartpqi: add support for product id From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:00:56 -0600 Message-ID: <160712285637.21372.13661852121258610588.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 11 ++++++++++- drivers/scsi/smartpqi/smartpqi_init.c | 11 +++++++++-- drivers/scsi/smartpqi/smartpqi_sis.c | 5 +++++ drivers/scsi/smartpqi/smartpqi_sis.h | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 3e54590e6e92..7d3f956e949f 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -79,7 +79,8 @@ struct pqi_ctrl_registers { __le32 sis_ctrl_to_host_doorbell_clear; /* A0h */ u8 reserved4[0xb0 - (0xa0 + sizeof(__le32))]; __le32 sis_driver_scratch; /* B0h */ - u8 reserved5[0xbc - (0xb0 + sizeof(__le32))]; + __le32 sis_product_identifier; /* B4h */ + u8 reserved5[0xbc - (0xb4 + sizeof(__le32))]; __le32 sis_firmware_status; /* BCh */ u8 reserved6[0x1000 - (0xbc + sizeof(__le32))]; __le32 sis_mailbox[8]; /* 1000h */ @@ -585,6 +586,7 @@ struct pqi_raid_error_info { /* these values are defined by the PQI spec */ #define PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE 255 #define PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE 65535 + #define PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT 64 #define PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT 16 #define PQI_ADMIN_INDEX_ALIGNMENT 64 @@ -1082,6 +1084,11 @@ struct pqi_event { (PQI_RESERVED_IO_SLOTS_LUN_RESET + PQI_RESERVED_IO_SLOTS_EVENT_ACK + \ PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS) +#define PQI_CTRL_PRODUCT_ID_GEN1 0 +#define PQI_CTRL_PRODUCT_ID_GEN2 7 +#define PQI_CTRL_PRODUCT_REVISION_A 0 +#define PQI_CTRL_PRODUCT_REVISION_B 1 + struct pqi_ctrl_info { unsigned int ctrl_id; struct pci_dev *pci_dev; @@ -1089,6 +1096,8 @@ struct pqi_ctrl_info { char serial_number[17]; char model[17]; char vendor[9]; + u8 product_id; + u8 product_revision; void __iomem *iomem_base; struct pqi_ctrl_registers __iomem *registers; struct pqi_device_registers __iomem *pqi_registers; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index c53f456fbd09..68fc4327944e 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6259,8 +6259,8 @@ static DEVICE_ATTR(model, 0444, pqi_model_show, NULL); static DEVICE_ATTR(serial_number, 0444, pqi_serial_number_show, NULL); static DEVICE_ATTR(vendor, 0444, pqi_vendor_show, NULL); static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store); -static DEVICE_ATTR(lockup_action, 0644, - pqi_lockup_action_show, pqi_lockup_action_store); +static DEVICE_ATTR(lockup_action, 0644, pqi_lockup_action_show, + pqi_lockup_action_store); static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_driver_version, @@ -7146,6 +7146,7 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info) static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) { int rc; + u32 product_id; if (reset_devices) { sis_soft_reset(ctrl_info); @@ -7182,6 +7183,10 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) return rc; } + product_id = sis_get_product_id(ctrl_info); + ctrl_info->product_id = (u8)product_id; + ctrl_info->product_revision = (u8)(product_id >> 8); + if (reset_devices) { if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS_KDUMP) @@ -8602,6 +8607,8 @@ static void __attribute__((unused)) verify_structures(void) sis_ctrl_to_host_doorbell_clear) != 0xa0); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, sis_driver_scratch) != 0xb0); + BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, + sis_product_identifier) != 0xb4); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, sis_firmware_status) != 0xbc); BUILD_BUG_ON(offsetof(struct pqi_ctrl_registers, diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index 26ea6b9d4199..f0199bd87dd1 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -149,6 +149,11 @@ bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info) SIS_CTRL_KERNEL_UP; } +u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info) +{ + return readl(&ctrl_info->registers->sis_product_identifier); +} + /* used for passing command parameters/results when issuing SIS commands */ struct sis_sync_cmd_params { u32 mailbox[6]; /* mailboxes 0-5 */ diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h index 878d34ca6532..12cd2ab1aead 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.h +++ b/drivers/scsi/smartpqi/smartpqi_sis.h @@ -27,5 +27,6 @@ int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info); void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value); u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info); void sis_soft_reset(struct pqi_ctrl_info *ctrl_info); +u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info); #endif /* _SMARTPQI_SIS_H */ From patchwork Fri Dec 4 23:01:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338143 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 225CFC4361A for ; Fri, 4 Dec 2020 23:02:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E4E3722D01 for ; Fri, 4 Dec 2020 23:02:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726294AbgLDXCK (ORCPT ); Fri, 4 Dec 2020 18:02:10 -0500 Received: from esa2.microchip.iphmx.com ([68.232.149.84]:45753 "EHLO esa2.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725960AbgLDXCK (ORCPT ); Fri, 4 Dec 2020 18:02:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122929; x=1638658929; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SkZpuKQLM+gM32cFQhRmC2YIjTDAlqRus7vYfonSnLU=; b=i32lsrB6ZtHshxhig3NZvEGeMxaqn3k1xsQ/p4BZnPqWGBlLfFseUgcW iI1cfTATcyXwNM6yhcH3+WmN4/GswgUvMA5uLm/3zWngvG4wg8DvGTFdD VH8Z2yPWAQJerKw322IrXMtrU8o8Uw4HlQwrBwk7obPMPYpTTeS4x9FyP 7+4/kdYlqCI2ByflGXo+FRHH2ohRTYGO403qfG0OHnlMyB+fDZHwO2DdK TkuCBjcHdIm/nNilvpWvmHoN4IK+a8fIMETT9a+ZhHXEs12unAhCNnCYL qjXHnPEJg5YLWq7n+PBD0gpBC4GGZNIJZ1b/WwZ29y7Gj48uld0+RCwJG w==; IronPort-SDR: fUdBRQIolWo7f13BFvgj5+ay9f1LvRE4y4p54S5MQOIgMZCbyejo5+BgEwx1YoijbU5smD5b7h zTeqQq2w48CyIpYs5lC6jNOxgXR7lZFfsrq0YIK91tGfeN1/lgwS+LJJw3ICMr+uMNs7kXqTpt /OYTriAob4pIcRuE3PWBNPifPCg7FtNDwlmepbCxKO4GloUalIXn7p9CV5yEFdHtLtd6GbwgLI SH+BVTM6DDH8F56KVAGb/6O5Iwb1q+zKiBk5EDHzEjuUG5+hTpGobTwvPUYRjX6XC0+rceFNcr MQY= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="98683787" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:03 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:02 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:02 -0700 Subject: [PATCH 02/25] smartpqi: refactor aio submission code From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:02 -0600 Message-ID: <160712286220.21372.7483811214753573704.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * No functional changes. * Refactor aio submission code: 1. remove 32-bit calculations. 2. break-up function into smaller functions. 3. add common block of data to carry around into newly added functions. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 52 +++ drivers/scsi/smartpqi/smartpqi_init.c | 515 ++++++++++++++++----------------- 2 files changed, 309 insertions(+), 258 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 7d3f956e949f..d486a2ec3045 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -908,6 +908,58 @@ struct raid_map { #pragma pack() +struct pqi_scsi_dev_raid_map_data { + bool is_write; + u8 raid_level; + u32 map_index; + u64 first_block; + u64 last_block; + u32 data_length; + u32 block_cnt; + u32 blocks_per_row; + u64 first_row; + u64 last_row; + u32 first_row_offset; + u32 last_row_offset; + u32 first_column; + u32 last_column; + u64 r5or6_first_row; + u64 r5or6_last_row; + u32 r5or6_first_row_offset; + u32 r5or6_last_row_offset; + u32 r5or6_first_column; + u32 r5or6_last_column; + u16 data_disks_per_row; + u32 total_disks_per_row; + u16 layout_map_count; + u32 stripesize; + u16 strip_size; + u32 first_group; + u32 last_group; + u32 current_group; + u32 map_row; + u32 aio_handle; + u64 disk_block; + u32 disk_block_cnt; + u8 cdb[16]; + u8 cdb_length; + int offload_to_mirror; + + /* RAID1 specific */ +#define NUM_RAID1_MAP_ENTRIES 3 + u32 num_it_nexus_entries; + u32 it_nexus[NUM_RAID1_MAP_ENTRIES]; + + /* RAID5 RAID6 specific */ + u32 p_parity_it_nexus; /* aio_handle */ + u32 q_parity_it_nexus; /* aio_handle */ + u8 xor_mult; + u64 row; + u64 stripe_lba; + u32 p_index; + u32 q_index; +}; + #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" struct pqi_scsi_dev { diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 68fc4327944e..99ea384d8211 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -2237,332 +2237,331 @@ static inline void pqi_set_encryption_info( * Attempt to perform RAID bypass mapping for a logical volume I/O. */ +static bool pqi_aio_raid_level_supported(struct pqi_scsi_dev_raid_map_data *rmd) +{ + bool is_supported = true; + + switch (rmd->raid_level) { + case SA_RAID_0: + break; + case SA_RAID_1: + if (rmd->is_write) + is_supported = false; + break; + case SA_RAID_5: + fallthrough; + case SA_RAID_6: + if (rmd->is_write) + is_supported = false; + break; + case SA_RAID_ADM: + if (rmd->is_write) + is_supported = false; + break; + default: + is_supported = false; + } + + return is_supported; +} + #define PQI_RAID_BYPASS_INELIGIBLE 1 -static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, - struct pqi_queue_group *queue_group) +static int pqi_get_aio_lba_and_block_count(struct scsi_cmnd *scmd, + struct pqi_scsi_dev_raid_map_data *rmd) { - struct raid_map *raid_map; - bool is_write = false; - u32 map_index; - u64 first_block; - u64 last_block; - u32 block_cnt; - u32 blocks_per_row; - u64 first_row; - u64 last_row; - u32 first_row_offset; - u32 last_row_offset; - u32 first_column; - u32 last_column; - u64 r0_first_row; - u64 r0_last_row; - u32 r5or6_blocks_per_row; - u64 r5or6_first_row; - u64 r5or6_last_row; - u32 r5or6_first_row_offset; - u32 r5or6_last_row_offset; - u32 r5or6_first_column; - u32 r5or6_last_column; - u16 data_disks_per_row; - u32 total_disks_per_row; - u16 layout_map_count; - u32 stripesize; - u16 strip_size; - u32 first_group; - u32 last_group; - u32 current_group; - u32 map_row; - u32 aio_handle; - u64 disk_block; - u32 disk_block_cnt; - u8 cdb[16]; - u8 cdb_length; - int offload_to_mirror; - struct pqi_encryption_info *encryption_info_ptr; - struct pqi_encryption_info encryption_info; -#if BITS_PER_LONG == 32 - u64 tmpdiv; -#endif - /* Check for valid opcode, get LBA and block count. */ switch (scmd->cmnd[0]) { case WRITE_6: - is_write = true; + rmd->is_write = true; fallthrough; case READ_6: - first_block = (u64)(((scmd->cmnd[1] & 0x1f) << 16) | + rmd->first_block = (u64)(((scmd->cmnd[1] & 0x1f) << 16) | (scmd->cmnd[2] << 8) | scmd->cmnd[3]); - block_cnt = (u32)scmd->cmnd[4]; - if (block_cnt == 0) - block_cnt = 256; + rmd->block_cnt = (u32)scmd->cmnd[4]; + if (rmd->block_cnt == 0) + rmd->block_cnt = 256; break; case WRITE_10: - is_write = true; + rmd->is_write = true; fallthrough; case READ_10: - first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); - block_cnt = (u32)get_unaligned_be16(&scmd->cmnd[7]); + rmd->first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); + rmd->block_cnt = (u32)get_unaligned_be16(&scmd->cmnd[7]); break; case WRITE_12: - is_write = true; + rmd->is_write = true; fallthrough; case READ_12: - first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); - block_cnt = get_unaligned_be32(&scmd->cmnd[6]); + rmd->first_block = (u64)get_unaligned_be32(&scmd->cmnd[2]); + rmd->block_cnt = get_unaligned_be32(&scmd->cmnd[6]); break; case WRITE_16: - is_write = true; + rmd->is_write = true; fallthrough; case READ_16: - first_block = get_unaligned_be64(&scmd->cmnd[2]); - block_cnt = get_unaligned_be32(&scmd->cmnd[10]); + rmd->first_block = get_unaligned_be64(&scmd->cmnd[2]); + rmd->block_cnt = get_unaligned_be32(&scmd->cmnd[10]); break; default: /* Process via normal I/O path. */ return PQI_RAID_BYPASS_INELIGIBLE; } - /* Check for write to non-RAID-0. */ - if (is_write && device->raid_level != SA_RAID_0) - return PQI_RAID_BYPASS_INELIGIBLE; + put_unaligned_le32(scsi_bufflen(scmd), &rmd->data_length); - if (unlikely(block_cnt == 0)) - return PQI_RAID_BYPASS_INELIGIBLE; + return 0; +} - last_block = first_block + block_cnt - 1; - raid_map = device->raid_map; +static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev_raid_map_data *rmd, + struct raid_map *raid_map) +{ + rmd->last_block = rmd->first_block + rmd->block_cnt - 1; /* Check for invalid block or wraparound. */ - if (last_block >= get_unaligned_le64(&raid_map->volume_blk_cnt) || - last_block < first_block) + if (rmd->last_block >= + get_unaligned_le64(&raid_map->volume_blk_cnt) || + rmd->last_block < rmd->first_block) return PQI_RAID_BYPASS_INELIGIBLE; - data_disks_per_row = get_unaligned_le16(&raid_map->data_disks_per_row); - strip_size = get_unaligned_le16(&raid_map->strip_size); - layout_map_count = get_unaligned_le16(&raid_map->layout_map_count); + rmd->data_disks_per_row = + get_unaligned_le16(&raid_map->data_disks_per_row); + rmd->strip_size = get_unaligned_le16(&raid_map->strip_size); + rmd->layout_map_count = get_unaligned_le16(&raid_map->layout_map_count); /* Calculate stripe information for the request. */ - blocks_per_row = data_disks_per_row * strip_size; -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - do_div(tmpdiv, blocks_per_row); - first_row = tmpdiv; - tmpdiv = last_block; - do_div(tmpdiv, blocks_per_row); - last_row = tmpdiv; - first_row_offset = (u32)(first_block - (first_row * blocks_per_row)); - last_row_offset = (u32)(last_block - (last_row * blocks_per_row)); - tmpdiv = first_row_offset; - do_div(tmpdiv, strip_size); - first_column = tmpdiv; - tmpdiv = last_row_offset; - do_div(tmpdiv, strip_size); - last_column = tmpdiv; -#else - first_row = first_block / blocks_per_row; - last_row = last_block / blocks_per_row; - first_row_offset = (u32)(first_block - (first_row * blocks_per_row)); - last_row_offset = (u32)(last_block - (last_row * blocks_per_row)); - first_column = first_row_offset / strip_size; - last_column = last_row_offset / strip_size; -#endif + rmd->blocks_per_row = rmd->data_disks_per_row * rmd->strip_size; + rmd->first_row = rmd->first_block / rmd->blocks_per_row; + rmd->last_row = rmd->last_block / rmd->blocks_per_row; + rmd->first_row_offset = (u32)(rmd->first_block - + (rmd->first_row * rmd->blocks_per_row)); + rmd->last_row_offset = (u32)(rmd->last_block - (rmd->last_row * + rmd->blocks_per_row)); + rmd->first_column = rmd->first_row_offset / rmd->strip_size; + rmd->last_column = rmd->last_row_offset / rmd->strip_size; /* If this isn't a single row/column then give to the controller. */ - if (first_row != last_row || first_column != last_column) + if (rmd->first_row != rmd->last_row || + rmd->first_column != rmd->last_column) return PQI_RAID_BYPASS_INELIGIBLE; /* Proceeding with driver mapping. */ - total_disks_per_row = data_disks_per_row + + rmd->total_disks_per_row = rmd->data_disks_per_row + get_unaligned_le16(&raid_map->metadata_disks_per_row); - map_row = ((u32)(first_row >> raid_map->parity_rotation_shift)) % + rmd->map_row = ((u32)(rmd->first_row >> + raid_map->parity_rotation_shift)) % + get_unaligned_le16(&raid_map->row_cnt); + rmd->map_index = (rmd->map_row * rmd->total_disks_per_row) + + rmd->first_column; + + return 0; +} + +static int pqi_calc_aio_raid_adm(struct pqi_scsi_dev_raid_map_data *rmd, + struct pqi_scsi_dev *device) +{ + /* RAID ADM */ + /* + * Handles N-way mirrors (R1-ADM) and R10 with # of drives + * divisible by 3. + */ + rmd->offload_to_mirror = device->offload_to_mirror; + + if (rmd->offload_to_mirror == 0) { + /* use physical disk in the first mirrored group. */ + rmd->map_index %= rmd->data_disks_per_row; + } else { + do { + /* + * Determine mirror group that map_index + * indicates. + */ + rmd->current_group = + rmd->map_index / rmd->data_disks_per_row; + + if (rmd->offload_to_mirror != + rmd->current_group) { + if (rmd->current_group < + rmd->layout_map_count - 1) { + /* + * Select raid index from + * next group. + */ + rmd->map_index += rmd->data_disks_per_row; + rmd->current_group++; + } else { + /* + * Select raid index from first + * group. + */ + rmd->map_index %= rmd->data_disks_per_row; + rmd->current_group = 0; + } + } + } while (rmd->offload_to_mirror != rmd->current_group); + } + + /* Set mirror group to use next time. */ + rmd->offload_to_mirror = + (rmd->offload_to_mirror >= rmd->layout_map_count - 1) ? + 0 : rmd->offload_to_mirror + 1; + device->offload_to_mirror = rmd->offload_to_mirror; + /* + * Avoid direct use of device->offload_to_mirror within this + * function since multiple threads might simultaneously + * increment it beyond the range of device->layout_map_count -1. + */ + + return 0; +} + +static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, + struct raid_map *raid_map) +{ + /* RAID 50/60 */ + /* Verify first and last block are in same RAID group */ + rmd->stripesize = rmd->blocks_per_row * rmd->layout_map_count; + rmd->first_group = (rmd->first_block % + rmd->stripesize) / rmd->blocks_per_row; + rmd->last_group = (rmd->last_block % + rmd->stripesize) / rmd->blocks_per_row; + if (rmd->first_group != rmd->last_group) + return PQI_RAID_BYPASS_INELIGIBLE; + + /* Verify request is in a single row of RAID 5/6 */ + rmd->first_row = rmd->r5or6_first_row = + rmd->first_block / rmd->stripesize; + rmd->r5or6_last_row = rmd->last_block / rmd->stripesize; + if (rmd->r5or6_first_row != rmd->r5or6_last_row) + return PQI_RAID_BYPASS_INELIGIBLE; + + /* Verify request is in a single column */ + rmd->first_row_offset = rmd->r5or6_first_row_offset = + (u32)((rmd->first_block % + rmd->stripesize) % + rmd->blocks_per_row); + + rmd->r5or6_last_row_offset = + (u32)((rmd->last_block % rmd->stripesize) % + rmd->blocks_per_row); + + rmd->first_column = + rmd->r5or6_first_row_offset / rmd->strip_size; + rmd->r5or6_first_column = rmd->first_column; + rmd->r5or6_last_column = rmd->r5or6_last_row_offset / rmd->strip_size; + if (rmd->r5or6_first_column != rmd->r5or6_last_column) + return PQI_RAID_BYPASS_INELIGIBLE; + + /* Request is eligible */ + rmd->map_row = + ((u32)(rmd->first_row >> raid_map->parity_rotation_shift)) % get_unaligned_le16(&raid_map->row_cnt); - map_index = (map_row * total_disks_per_row) + first_column; + + rmd->map_index = (rmd->first_group * + (get_unaligned_le16(&raid_map->row_cnt) * + rmd->total_disks_per_row)) + + (rmd->map_row * rmd->total_disks_per_row) + rmd->first_column; + + return 0; +} + +static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd) +{ + /* Build the new CDB for the physical disk I/O. */ + if (rmd->disk_block > 0xffffffff) { + rmd->cdb[0] = rmd->is_write ? WRITE_16 : READ_16; + rmd->cdb[1] = 0; + put_unaligned_be64(rmd->disk_block, &rmd->cdb[2]); + put_unaligned_be32(rmd->disk_block_cnt, &rmd->cdb[10]); + rmd->cdb[14] = 0; + rmd->cdb[15] = 0; + rmd->cdb_length = 16; + } else { + rmd->cdb[0] = rmd->is_write ? WRITE_10 : READ_10; + rmd->cdb[1] = 0; + put_unaligned_be32((u32)rmd->disk_block, &rmd->cdb[2]); + rmd->cdb[6] = 0; + put_unaligned_be16((u16)rmd->disk_block_cnt, &rmd->cdb[7]); + rmd->cdb[9] = 0; + rmd->cdb_length = 10; + } +} + +static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, + struct pqi_queue_group *queue_group) +{ + struct raid_map *raid_map; + int rc; + struct pqi_encryption_info *encryption_info_ptr; + struct pqi_encryption_info encryption_info; + struct pqi_scsi_dev_raid_map_data rmd = {0}; + + rc = pqi_get_aio_lba_and_block_count(scmd, &rmd); + if (rc) + return PQI_RAID_BYPASS_INELIGIBLE; + + rmd.raid_level = device->raid_level; + + if (!pqi_aio_raid_level_supported(&rmd)) + return PQI_RAID_BYPASS_INELIGIBLE; + + if (unlikely(rmd.block_cnt == 0)) + return PQI_RAID_BYPASS_INELIGIBLE; + + raid_map = device->raid_map; + + rc = pci_get_aio_common_raid_map_values(ctrl_info, &rmd, raid_map); + if (rc) + return PQI_RAID_BYPASS_INELIGIBLE; /* RAID 1 */ if (device->raid_level == SA_RAID_1) { if (device->offload_to_mirror) - map_index += data_disks_per_row; + rmd.map_index += rmd.data_disks_per_row; device->offload_to_mirror = !device->offload_to_mirror; } else if (device->raid_level == SA_RAID_ADM) { - /* RAID ADM */ - /* - * Handles N-way mirrors (R1-ADM) and R10 with # of drives - * divisible by 3. - */ - offload_to_mirror = device->offload_to_mirror; - if (offload_to_mirror == 0) { - /* use physical disk in the first mirrored group. */ - map_index %= data_disks_per_row; - } else { - do { - /* - * Determine mirror group that map_index - * indicates. - */ - current_group = map_index / data_disks_per_row; - - if (offload_to_mirror != current_group) { - if (current_group < - layout_map_count - 1) { - /* - * Select raid index from - * next group. - */ - map_index += data_disks_per_row; - current_group++; - } else { - /* - * Select raid index from first - * group. - */ - map_index %= data_disks_per_row; - current_group = 0; - } - } - } while (offload_to_mirror != current_group); - } - - /* Set mirror group to use next time. */ - offload_to_mirror = - (offload_to_mirror >= layout_map_count - 1) ? - 0 : offload_to_mirror + 1; - device->offload_to_mirror = offload_to_mirror; - /* - * Avoid direct use of device->offload_to_mirror within this - * function since multiple threads might simultaneously - * increment it beyond the range of device->layout_map_count -1. - */ + rc = pqi_calc_aio_raid_adm(&rmd, device); } else if ((device->raid_level == SA_RAID_5 || - device->raid_level == SA_RAID_6) && layout_map_count > 1) { - /* RAID 50/60 */ - /* Verify first and last block are in same RAID group */ - r5or6_blocks_per_row = strip_size * data_disks_per_row; - stripesize = r5or6_blocks_per_row * layout_map_count; -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - first_group = do_div(tmpdiv, stripesize); - tmpdiv = first_group; - do_div(tmpdiv, r5or6_blocks_per_row); - first_group = tmpdiv; - tmpdiv = last_block; - last_group = do_div(tmpdiv, stripesize); - tmpdiv = last_group; - do_div(tmpdiv, r5or6_blocks_per_row); - last_group = tmpdiv; -#else - first_group = (first_block % stripesize) / r5or6_blocks_per_row; - last_group = (last_block % stripesize) / r5or6_blocks_per_row; -#endif - if (first_group != last_group) - return PQI_RAID_BYPASS_INELIGIBLE; - - /* Verify request is in a single row of RAID 5/6 */ -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - do_div(tmpdiv, stripesize); - first_row = r5or6_first_row = r0_first_row = tmpdiv; - tmpdiv = last_block; - do_div(tmpdiv, stripesize); - r5or6_last_row = r0_last_row = tmpdiv; -#else - first_row = r5or6_first_row = r0_first_row = - first_block / stripesize; - r5or6_last_row = r0_last_row = last_block / stripesize; -#endif - if (r5or6_first_row != r5or6_last_row) - return PQI_RAID_BYPASS_INELIGIBLE; - - /* Verify request is in a single column */ -#if BITS_PER_LONG == 32 - tmpdiv = first_block; - first_row_offset = do_div(tmpdiv, stripesize); - tmpdiv = first_row_offset; - first_row_offset = (u32)do_div(tmpdiv, r5or6_blocks_per_row); - r5or6_first_row_offset = first_row_offset; - tmpdiv = last_block; - r5or6_last_row_offset = do_div(tmpdiv, stripesize); - tmpdiv = r5or6_last_row_offset; - r5or6_last_row_offset = do_div(tmpdiv, r5or6_blocks_per_row); - tmpdiv = r5or6_first_row_offset; - do_div(tmpdiv, strip_size); - first_column = r5or6_first_column = tmpdiv; - tmpdiv = r5or6_last_row_offset; - do_div(tmpdiv, strip_size); - r5or6_last_column = tmpdiv; -#else - first_row_offset = r5or6_first_row_offset = - (u32)((first_block % stripesize) % - r5or6_blocks_per_row); - - r5or6_last_row_offset = - (u32)((last_block % stripesize) % - r5or6_blocks_per_row); - - first_column = r5or6_first_row_offset / strip_size; - r5or6_first_column = first_column; - r5or6_last_column = r5or6_last_row_offset / strip_size; -#endif - if (r5or6_first_column != r5or6_last_column) + device->raid_level == SA_RAID_6) && rmd.layout_map_count > 1) { + rc = pqi_calc_aio_r5_or_r6(&rmd, raid_map); + if (rc) return PQI_RAID_BYPASS_INELIGIBLE; - - /* Request is eligible */ - map_row = - ((u32)(first_row >> raid_map->parity_rotation_shift)) % - get_unaligned_le16(&raid_map->row_cnt); - - map_index = (first_group * - (get_unaligned_le16(&raid_map->row_cnt) * - total_disks_per_row)) + - (map_row * total_disks_per_row) + first_column; } - aio_handle = raid_map->disk_data[map_index].aio_handle; - disk_block = get_unaligned_le64(&raid_map->disk_starting_blk) + - first_row * strip_size + - (first_row_offset - first_column * strip_size); - disk_block_cnt = block_cnt; + if (unlikely(rmd.map_index >= RAID_MAP_MAX_ENTRIES)) + return PQI_RAID_BYPASS_INELIGIBLE; + + rmd.aio_handle = raid_map->disk_data[rmd.map_index].aio_handle; + rmd.disk_block = get_unaligned_le64(&raid_map->disk_starting_blk) + + rmd.first_row * rmd.strip_size + + (rmd.first_row_offset - rmd.first_column * rmd.strip_size); + rmd.disk_block_cnt = rmd.block_cnt; /* Handle differing logical/physical block sizes. */ if (raid_map->phys_blk_shift) { - disk_block <<= raid_map->phys_blk_shift; - disk_block_cnt <<= raid_map->phys_blk_shift; + rmd.disk_block <<= raid_map->phys_blk_shift; + rmd.disk_block_cnt <<= raid_map->phys_blk_shift; } - if (unlikely(disk_block_cnt > 0xffff)) + if (unlikely(rmd.disk_block_cnt > 0xffff)) return PQI_RAID_BYPASS_INELIGIBLE; - /* Build the new CDB for the physical disk I/O. */ - if (disk_block > 0xffffffff) { - cdb[0] = is_write ? WRITE_16 : READ_16; - cdb[1] = 0; - put_unaligned_be64(disk_block, &cdb[2]); - put_unaligned_be32(disk_block_cnt, &cdb[10]); - cdb[14] = 0; - cdb[15] = 0; - cdb_length = 16; - } else { - cdb[0] = is_write ? WRITE_10 : READ_10; - cdb[1] = 0; - put_unaligned_be32((u32)disk_block, &cdb[2]); - cdb[6] = 0; - put_unaligned_be16((u16)disk_block_cnt, &cdb[7]); - cdb[9] = 0; - cdb_length = 10; - } + pqi_set_aio_cdb(&rmd); if (get_unaligned_le16(&raid_map->flags) & RAID_MAP_ENCRYPTION_ENABLED) { pqi_set_encryption_info(&encryption_info, raid_map, - first_block); + rmd.first_block); encryption_info_ptr = &encryption_info; } else { encryption_info_ptr = NULL; } - return pqi_aio_submit_io(ctrl_info, scmd, aio_handle, - cdb, cdb_length, queue_group, encryption_info_ptr, true); + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); } #define PQI_STATUS_IDLE 0x0 From patchwork Fri Dec 4 23:01:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 35666C433FE for ; Fri, 4 Dec 2020 23:02:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1005C22D01 for ; Fri, 4 Dec 2020 23:02:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726780AbgLDXCn (ORCPT ); Fri, 4 Dec 2020 18:02:43 -0500 Received: from esa6.microchip.iphmx.com ([216.71.154.253]:21231 "EHLO esa6.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726296AbgLDXCn (ORCPT ); Fri, 4 Dec 2020 18:02:43 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122963; x=1638658963; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JDLY+/Z0WqZwPscaiXoly3dC+qxR+BHbvdoWrmgmWo0=; b=uct5d5dZY06xzvp/sUa0LMBxM8Jv/ibE3S6psh/X5HOSLT3tTs4HW2wK 5KhUDpuTgMVRdDeohBI1lwC/3/N9bRwsCBoP4HM2BrgDAWnC3mb3dkHK+ yY/2Tqg5ePfCQks4+wc/GpNcXn/OnMbEKINDhUiM2yK8lwYgNlVeYumH1 BWP9ral5Er0h4doKtqf+Mh0Iyok4E8ELKUJKfwx0wPk5M6OigZmrpXV6W hf/0ODCsqjB7XU/HjQzTbOTgyLY5DsuV8SUFSFz9f3o+BDjmIf9gu1WcL vMeQp/+Y5FPDx+66cQlrqxhnvbMKgwdOS5j9TsFM2TfNUhPik5UrbkayQ w==; IronPort-SDR: te07XTUooOpFfVicMEJNOyMyHgxhV0cr0j0FTaotcanDgsSdkC1/FkEhIfHCcfe1B4GWXgaTPj PyCKdQItjCYYylu8hVdCOmqqyVy4okAztj9e3e7gRUS1Isjkm+pVepFZsfa7wHk4rTwLLQ7gEi dvEI5o2n2nsliYNnoKHwQvP7bZOEt/MRFZX7avGm9V6zk7ukvs/byAfEJzbVbCgRrJG0Uoczax T1j0zljQMTECQnnb5qDLCcdMKQrahGfUgANupZ20+X80R1cfQVmgE0IhVjZ839aSJGorvHWt5P lUE= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="36192813" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:08 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:08 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:08 -0700 Subject: [PATCH 03/25] smartpqi: refactor build sg list code From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:08 -0600 Message-ID: <160712286807.21372.1703523876231635148.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * No functional changes. * Factor out code common to all s/g list building. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 101 ++++++++++++++------------------- 1 file changed, 42 insertions(+), 59 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 99ea384d8211..553284a40d00 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -4794,16 +4794,52 @@ static inline void pqi_set_sg_descriptor( put_unaligned_le32(0, &sg_descriptor->flags); } +static unsigned int pqi_build_sg_list(struct pqi_sg_descriptor *sg_descriptor, + struct scatterlist *sg, int sg_count, struct pqi_io_request *io_request, + int max_sg_per_iu, bool *chained) +{ + int i; + unsigned int num_sg_in_iu; + + *chained = false; + i = 0; + num_sg_in_iu = 0; + max_sg_per_iu--; /* Subtract 1 to leave room for chain marker. */ + + while (1) { + pqi_set_sg_descriptor(sg_descriptor, sg); + if (!*chained) + num_sg_in_iu++; + i++; + if (i == sg_count) + break; + sg_descriptor++; + if (i == max_sg_per_iu) { + put_unaligned_le64((u64)io_request->sg_chain_buffer_dma_handle, + &sg_descriptor->address); + put_unaligned_le32((sg_count - num_sg_in_iu) * sizeof(*sg_descriptor), + &sg_descriptor->length); + put_unaligned_le32(CISS_SG_CHAIN, &sg_descriptor->flags); + *chained = true; + num_sg_in_iu++; + sg_descriptor = io_request->sg_chain_buffer; + } + sg = sg_next(sg); + } + + put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); + + return num_sg_in_iu; +} + static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_raid_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) { - int i; u16 iu_length; int sg_count; bool chained; unsigned int num_sg_in_iu; - unsigned int max_sg_per_iu; struct scatterlist *sg; struct pqi_sg_descriptor *sg_descriptor; @@ -4819,36 +4855,10 @@ static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info, sg = scsi_sglist(scmd); sg_descriptor = request->sg_descriptors; - max_sg_per_iu = ctrl_info->max_sg_per_iu - 1; - chained = false; - num_sg_in_iu = 0; - i = 0; - while (1) { - pqi_set_sg_descriptor(sg_descriptor, sg); - if (!chained) - num_sg_in_iu++; - i++; - if (i == sg_count) - break; - sg_descriptor++; - if (i == max_sg_per_iu) { - put_unaligned_le64( - (u64)io_request->sg_chain_buffer_dma_handle, - &sg_descriptor->address); - put_unaligned_le32((sg_count - num_sg_in_iu) - * sizeof(*sg_descriptor), - &sg_descriptor->length); - put_unaligned_le32(CISS_SG_CHAIN, - &sg_descriptor->flags); - chained = true; - num_sg_in_iu++; - sg_descriptor = io_request->sg_chain_buffer; - } - sg = sg_next(sg); - } + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_iu, &chained); - put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); request->partial = chained; iu_length += num_sg_in_iu * sizeof(*sg_descriptor); @@ -4862,12 +4872,10 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_aio_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) { - int i; u16 iu_length; int sg_count; bool chained; unsigned int num_sg_in_iu; - unsigned int max_sg_per_iu; struct scatterlist *sg; struct pqi_sg_descriptor *sg_descriptor; @@ -4884,35 +4892,10 @@ static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, sg = scsi_sglist(scmd); sg_descriptor = request->sg_descriptors; - max_sg_per_iu = ctrl_info->max_sg_per_iu - 1; - chained = false; - i = 0; - while (1) { - pqi_set_sg_descriptor(sg_descriptor, sg); - if (!chained) - num_sg_in_iu++; - i++; - if (i == sg_count) - break; - sg_descriptor++; - if (i == max_sg_per_iu) { - put_unaligned_le64( - (u64)io_request->sg_chain_buffer_dma_handle, - &sg_descriptor->address); - put_unaligned_le32((sg_count - num_sg_in_iu) - * sizeof(*sg_descriptor), - &sg_descriptor->length); - put_unaligned_le32(CISS_SG_CHAIN, - &sg_descriptor->flags); - chained = true; - num_sg_in_iu++; - sg_descriptor = io_request->sg_chain_buffer; - } - sg = sg_next(sg); - } + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_iu, &chained); - put_unaligned_le32(CISS_SG_LAST, &sg_descriptor->flags); request->partial = chained; iu_length += num_sg_in_iu * sizeof(*sg_descriptor); From patchwork Fri Dec 4 23:01:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338630 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B364AC433FE for ; Fri, 4 Dec 2020 23:02:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7C26522D01 for ; Fri, 4 Dec 2020 23:02:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726510AbgLDXC2 (ORCPT ); Fri, 4 Dec 2020 18:02:28 -0500 Received: from esa1.microchip.iphmx.com ([68.232.147.91]:4901 "EHLO esa1.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725960AbgLDXC0 (ORCPT ); Fri, 4 Dec 2020 18:02:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122945; x=1638658945; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DUE9XyoT2qERn6Svv81sUmGAXZq5o1gbcaebqRKbigc=; b=MQYcKeZB5IPFdiMvX4IMFHdmN0Xwst3c25LTnFwFz7iDR+P+VaAaIqGm /RYjqSLxN/uV8JloupzC9neJuAWwKG3MCNalzg3oLJLrGXkSFc7lb0f1E 8h1Nxy5DUAjQGzK4/cWRfJZEOHj1x4REnHOhtLdOfBZV0O5svuOJd1diz 5GLfwQToop4nTfSVinp93ODQfD0AqS91CIUT+ob1ynEM6QM2em9HLWYh5 Tn+59yoFx9aTMdYQNCCaQ+cxZpw7qXQwt4Kw/Fo9RkQVmdiIAiLUjOSiB pbPxEV71QqTaZjLv+uQR6o3xTQfo4QXVh8qVRfQ8SLl9rlQB28CY7E3XS Q==; IronPort-SDR: RCgbuISP/FspMoAFoZGKn4A6gc46gcW6879VOImzKbKB9kywIosZIIMB2pQIILIUrRnRpSHOaU vDiSzg7diRwDht4OURt6tdjKm9XVTeSrf1GhrmnQdfTPopXu76QhpidrNz3FhFJQaXci2EMelo ruv68XTzWCyScvCFk3Xr0baXnf5BmbbzDOZWYiSRks3ihi8qKn/qyNf0DRTyHRyufabYWnwRsZ NOGgjmdOhjPdPy7tYEqclJnGrLcb9UsQAtheSgJbrTA9HvIMlZT6m1/JVd4eamUhwpJeRrWdxA Luc= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="106272857" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:14 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:14 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:14 -0700 Subject: [PATCH 04/25] smartpqi: add support for raid5 and raid6 writes From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:13 -0600 Message-ID: <160712287386.21372.11961555423060868820.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * Add in new IU definition. * Add in support raid5 and raid6 writes. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 39 +++++ drivers/scsi/smartpqi/smartpqi_init.c | 241 ++++++++++++++++++++++++++++++++- 2 files changed, 272 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index d486a2ec3045..e9844210c4a0 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -257,6 +257,7 @@ struct pqi_device_capability { }; #define PQI_MAX_EMBEDDED_SG_DESCRIPTORS 4 +#define PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS 3 struct pqi_raid_path_request { struct pqi_iu_header header; @@ -312,6 +313,39 @@ struct pqi_aio_path_request { sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; +#define PQI_RAID56_XFER_LIMIT_4K 0x1000 /* 4Kib */ +#define PQI_RAID56_XFER_LIMIT_8K 0x2000 /* 8Kib */ +struct pqi_aio_r56_path_request { + struct pqi_iu_header header; + __le16 request_id; + __le16 volume_id; /* ID of the RAID volume */ + __le32 data_it_nexus; /* IT nexus for the data drive */ + __le32 p_parity_it_nexus; /* IT nexus for the P parity drive */ + __le32 q_parity_it_nexus; /* IT nexus for the Q parity drive */ + __le32 data_length; /* total bytes to read/write */ + u8 data_direction : 2; + u8 partial : 1; + u8 mem_type : 1; /* 0b: PCIe, 1b: DDR */ + u8 fence : 1; + u8 encryption_enable : 1; + u8 reserved : 2; + u8 task_attribute : 3; + u8 command_priority : 4; + u8 reserved1 : 1; + __le16 data_encryption_key_index; + u8 cdb[16]; + __le16 error_index; + u8 num_sg_descriptors; + u8 cdb_length; + u8 xor_multiplier; + u8 reserved2[3]; + __le32 encrypt_tweak_lower; + __le32 encrypt_tweak_upper; + u8 row; /* row = logical lba/blocks per row */ + u8 reserved3[8]; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS]; +}; + struct pqi_io_response { struct pqi_iu_header header; __le16 request_id; @@ -484,6 +518,8 @@ struct pqi_raid_error_info { #define PQI_REQUEST_IU_TASK_MANAGEMENT 0x13 #define PQI_REQUEST_IU_RAID_PATH_IO 0x14 #define PQI_REQUEST_IU_AIO_PATH_IO 0x15 +#define PQI_REQUEST_IU_AIO_PATH_RAID5_IO 0x18 +#define PQI_REQUEST_IU_AIO_PATH_RAID6_IO 0x19 #define PQI_REQUEST_IU_GENERAL_ADMIN 0x60 #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72 #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73 @@ -1179,6 +1215,7 @@ struct pqi_ctrl_info { u16 max_inbound_iu_length_per_firmware; u16 max_inbound_iu_length; unsigned int max_sg_per_iu; + unsigned int max_sg_per_r56_iu; void *admin_queue_memory_base; u32 admin_queue_memory_length; dma_addr_t admin_queue_memory_base_dma_handle; @@ -1210,6 +1247,8 @@ struct pqi_ctrl_info { u8 soft_reset_handshake_supported : 1; u8 raid_iu_timeout_supported: 1; u8 tmf_iu_timeout_supported: 1; + u8 enable_r5_writes : 1; + u8 enable_r6_writes : 1; struct list_head scsi_device_list; spinlock_t scsi_device_list_lock; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 553284a40d00..555d821e72ce 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -67,6 +67,10 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb, unsigned int cdb_length, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, bool raid_bypass); +static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd); static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info); static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info); @@ -2237,7 +2241,8 @@ static inline void pqi_set_encryption_info( * Attempt to perform RAID bypass mapping for a logical volume I/O. */ -static bool pqi_aio_raid_level_supported(struct pqi_scsi_dev_raid_map_data *rmd) +static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev_raid_map_data *rmd) { bool is_supported = true; @@ -2245,13 +2250,14 @@ static bool pqi_aio_raid_level_supported(struct pqi_scsi_dev_raid_map_data *rmd) case SA_RAID_0: break; case SA_RAID_1: - if (rmd->is_write) - is_supported = false; + is_supported = false; break; case SA_RAID_5: - fallthrough; + if (rmd->is_write && !ctrl_info->enable_r5_writes) + is_supported = false; + break; case SA_RAID_6: - if (rmd->is_write) + if (rmd->is_write && !ctrl_info->enable_r6_writes) is_supported = false; break; case SA_RAID_ADM: @@ -2463,6 +2469,20 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, rmd->total_disks_per_row)) + (rmd->map_row * rmd->total_disks_per_row) + rmd->first_column; + if (rmd->is_write) { + rmd->p_index = (rmd->map_row * rmd->total_disks_per_row) + rmd->data_disks_per_row; + rmd->p_parity_it_nexus = raid_map->disk_data[rmd->p_index].aio_handle; + if (rmd->raid_level == SA_RAID_6) { + rmd->q_index = (rmd->map_row * rmd->total_disks_per_row) + + (rmd->data_disks_per_row + 1); + rmd->q_parity_it_nexus = raid_map->disk_data[rmd->q_index].aio_handle; + rmd->xor_mult = raid_map->disk_data[rmd->map_index].xor_mult[1]; + } + if (rmd->blocks_per_row == 0) + return PQI_RAID_BYPASS_INELIGIBLE; + rmd->row = rmd->first_block / rmd->blocks_per_row; + } + return 0; } @@ -2504,7 +2524,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, rmd.raid_level = device->raid_level; - if (!pqi_aio_raid_level_supported(&rmd)) + if (!pqi_aio_raid_level_supported(ctrl_info, &rmd)) return PQI_RAID_BYPASS_INELIGIBLE; if (unlikely(rmd.block_cnt == 0)) @@ -2524,7 +2544,8 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, } else if (device->raid_level == SA_RAID_ADM) { rc = pqi_calc_aio_raid_adm(&rmd, device); } else if ((device->raid_level == SA_RAID_5 || - device->raid_level == SA_RAID_6) && rmd.layout_map_count > 1) { + device->raid_level == SA_RAID_6) && + (rmd.layout_map_count > 1 || rmd.is_write)) { rc = pqi_calc_aio_r5_or_r6(&rmd, raid_map); if (rc) return PQI_RAID_BYPASS_INELIGIBLE; @@ -2559,9 +2580,27 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, encryption_info_ptr = NULL; } - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + if (rmd.is_write) { + switch (device->raid_level) { + case SA_RAID_0: + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, rmd.cdb, rmd.cdb_length, queue_group, encryption_info_ptr, true); + case SA_RAID_5: + case SA_RAID_6: + return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, + encryption_info_ptr, device, &rmd); + default: + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); + } + } else { + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); + } + } #define PQI_STATUS_IDLE 0x0 @@ -4781,6 +4820,12 @@ static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info) PQI_OPERATIONAL_IQ_ELEMENT_LENGTH) / sizeof(struct pqi_sg_descriptor)) + PQI_MAX_EMBEDDED_SG_DESCRIPTORS; + + ctrl_info->max_sg_per_r56_iu = + ((ctrl_info->max_inbound_iu_length - + PQI_OPERATIONAL_IQ_ELEMENT_LENGTH) / + sizeof(struct pqi_sg_descriptor)) + + PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS; } static inline void pqi_set_sg_descriptor( @@ -4868,6 +4913,44 @@ static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info, return 0; } +static int pqi_build_aio_r56_sg_list(struct pqi_ctrl_info *ctrl_info, + struct pqi_aio_r56_path_request *request, struct scsi_cmnd *scmd, + struct pqi_io_request *io_request) +{ + u16 iu_length; + int sg_count; + bool chained; + unsigned int num_sg_in_iu; + struct scatterlist *sg; + struct pqi_sg_descriptor *sg_descriptor; + + sg_count = scsi_dma_map(scmd); + if (sg_count < 0) + return sg_count; + + iu_length = offsetof(struct pqi_aio_r56_path_request, sg_descriptors) - + PQI_REQUEST_HEADER_LENGTH; + num_sg_in_iu = 0; + + if (sg_count == 0) + goto out; + + sg = scsi_sglist(scmd); + sg_descriptor = request->sg_descriptors; + + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_r56_iu, &chained); + + request->partial = chained; + iu_length += num_sg_in_iu * sizeof(*sg_descriptor); + +out: + put_unaligned_le16(iu_length, &request->header.iu_length); + request->num_sg_descriptors = num_sg_in_iu; + + return 0; +} + static int pqi_build_aio_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_aio_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) @@ -5272,6 +5355,88 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, return 0; } +static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd) +{ + int rc; + struct pqi_io_request *io_request; + struct pqi_aio_r56_path_request *r56_request; + + io_request = pqi_alloc_io_request(ctrl_info); + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = true; + + r56_request = io_request->iu; + memset(r56_request, 0, offsetof(struct pqi_aio_r56_path_request, sg_descriptors)); + + if (device->raid_level == SA_RAID_5 || device->raid_level == SA_RAID_51) + r56_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID5_IO; + else + r56_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID6_IO; + + put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r56_request->volume_id); + put_unaligned_le32(rmd->aio_handle, &r56_request->data_it_nexus); + put_unaligned_le32(rmd->p_parity_it_nexus, &r56_request->p_parity_it_nexus); + if (rmd->raid_level == SA_RAID_6) { + put_unaligned_le32(rmd->q_parity_it_nexus, &r56_request->q_parity_it_nexus); + r56_request->xor_multiplier = rmd->xor_mult; + } + put_unaligned_le32(scsi_bufflen(scmd), &r56_request->data_length); + r56_request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; + put_unaligned_le64(rmd->row, &r56_request->row); + + put_unaligned_le16(io_request->index, &r56_request->request_id); + r56_request->error_index = r56_request->request_id; + + if (rmd->cdb_length > sizeof(r56_request->cdb)) + rmd->cdb_length = sizeof(r56_request->cdb); + r56_request->cdb_length = rmd->cdb_length; + memcpy(r56_request->cdb, rmd->cdb, rmd->cdb_length); + + switch (scmd->sc_data_direction) { + case DMA_TO_DEVICE: + r56_request->data_direction = SOP_READ_FLAG; + break; + case DMA_FROM_DEVICE: + r56_request->data_direction = SOP_WRITE_FLAG; + break; + case DMA_NONE: + r56_request->data_direction = SOP_NO_DIRECTION_FLAG; + break; + case DMA_BIDIRECTIONAL: + r56_request->data_direction = SOP_BIDIRECTIONAL; + break; + default: + dev_err(&ctrl_info->pci_dev->dev, + "unknown data direction: %d\n", + scmd->sc_data_direction); + break; + } + + if (encryption_info) { + r56_request->encryption_enable = true; + put_unaligned_le16(encryption_info->data_encryption_key_index, + &r56_request->data_encryption_key_index); + put_unaligned_le32(encryption_info->encrypt_tweak_lower, + &r56_request->encrypt_tweak_lower); + put_unaligned_le32(encryption_info->encrypt_tweak_upper, + &r56_request->encrypt_tweak_upper); + } + + rc = pqi_build_aio_r56_sg_list(ctrl_info, r56_request, scmd, io_request); + if (rc) { + pqi_free_io_request(io_request); + return SCSI_MLQUEUE_HOST_BUSY; + } + + pqi_start_io(ctrl_info, queue_group, AIO_PATH, io_request); + + return 0; +} + static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) { @@ -6235,6 +6400,60 @@ static ssize_t pqi_lockup_action_store(struct device *dev, return -EINVAL; } +static ssize_t pqi_host_enable_r5_writes_show(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + + return scnprintf(buffer, 10, "%hhx\n", ctrl_info->enable_r5_writes); +} + +static ssize_t pqi_host_enable_r5_writes_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + u8 set_r5_writes = 0; + + if (kstrtou8(buffer, 0, &set_r5_writes)) + return -EINVAL; + + if (set_r5_writes > 0) + set_r5_writes = 1; + + ctrl_info->enable_r5_writes = set_r5_writes; + + return count; +} + +static ssize_t pqi_host_enable_r6_writes_show(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + + return scnprintf(buffer, 10, "%hhx\n", ctrl_info->enable_r6_writes); +} + +static ssize_t pqi_host_enable_r6_writes_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + u8 set_r6_writes = 0; + + if (kstrtou8(buffer, 0, &set_r6_writes)) + return -EINVAL; + + if (set_r6_writes > 0) + set_r6_writes = 1; + + ctrl_info->enable_r6_writes = set_r6_writes; + + return count; +} + static DEVICE_ATTR(driver_version, 0444, pqi_driver_version_show, NULL); static DEVICE_ATTR(firmware_version, 0444, pqi_firmware_version_show, NULL); static DEVICE_ATTR(model, 0444, pqi_model_show, NULL); @@ -6243,6 +6462,10 @@ static DEVICE_ATTR(vendor, 0444, pqi_vendor_show, NULL); static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store); static DEVICE_ATTR(lockup_action, 0644, pqi_lockup_action_show, pqi_lockup_action_store); +static DEVICE_ATTR(enable_r5_writes, 0644, + pqi_host_enable_r5_writes_show, pqi_host_enable_r5_writes_store); +static DEVICE_ATTR(enable_r6_writes, 0644, + pqi_host_enable_r6_writes_show, pqi_host_enable_r6_writes_store); static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_driver_version, @@ -6252,6 +6475,8 @@ static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_vendor, &dev_attr_rescan, &dev_attr_lockup_action, + &dev_attr_enable_r5_writes, + &dev_attr_enable_r6_writes, NULL }; From patchwork Fri Dec 4 23:01:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91FB8C4361A for ; Fri, 4 Dec 2020 23:02:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 49EAC22C9E for ; Fri, 4 Dec 2020 23:02:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726467AbgLDXC1 (ORCPT ); Fri, 4 Dec 2020 18:02:27 -0500 Received: from esa4.microchip.iphmx.com ([68.232.154.123]:48973 "EHLO esa4.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726296AbgLDXC0 (ORCPT ); Fri, 4 Dec 2020 18:02:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122946; x=1638658946; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8dwWX2L3/9VmL7PtVYB/NWgSO4aRCl/LgYNKCJetvLM=; b=NqvZXGQk4LGp638orlddmJJ1bXpjDgq1o6irRn+iKlv9jWuwHHNTf9xm +t4AZj3F3nXDG0iCUqxpmF3y5BlDmuEAmCdVn8iWQ4H1PW1HukV9rq1KM RVsxGj/9q+WPxrS1g13vJBYF37ojehb7ljT+LrFX8hypaXLerCESMajEZ HaUSUTS1lAZesH2XTs4KAXELqdls45j/ZuGGZwjRzXLeQFjP5BBiFZQEm CFcUXeYI+WHSCi7H64iz91MDaJDVL5U7Qh6q0w8JvGDQ/O9/ez1ckY7QG mo5WxFtcFXon3FpRH2eYiTUMWoZMFpX4/GfxGaV+LjFqHBPKeh+Q6BAVQ g==; IronPort-SDR: 0fAnWO+S32bQP4KXwwN3k1ja0WnKvpC1p2pxf1d9ZRZaiW+tVLCpdmdJ5BKc5QMYSbgqCI1S0e T84JvyvCmhIB+ETyqMudYuVeVkRj1kdt0+KD8He+GSELfSTFrs+Rhonj18xtRrFuPXzFbYayim +HJ24s3Aq0yTmsBL3Us+mELAoN29cJBBW9uIYM1oe/t0VmyFQXHISUzda9lOvHiHQMA2lbjDiM s9HlrWmeXwSGzbfuwxUpUeAKtimvjNAUB7DwLVyw3cfKi2Uph2hCzlCEiKGWT12Mia9KI8F1DI 1no= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="95934564" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:20 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:20 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:19 -0700 Subject: [PATCH 05/25] smartpqi: add support for raid1 writes From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:19 -0600 Message-ID: <160712287970.21372.16965959498935407325.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * Add raid1 write IU. * Add in raid1 write support. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 37 +++++ drivers/scsi/smartpqi/smartpqi_init.c | 235 +++++++++++++++++++++++---------- 2 files changed, 196 insertions(+), 76 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index e9844210c4a0..225ec6843c68 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -313,6 +313,36 @@ struct pqi_aio_path_request { sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; +#define PQI_RAID1_NVME_XFER_LIMIT (32 * 1024) /* 32 KiB */ +struct pqi_aio_r1_path_request { + struct pqi_iu_header header; + __le16 request_id; + __le16 volume_id; /* ID of the RAID volume */ + __le32 it_nexus_1; /* IT nexus of the 1st drive in the RAID volume */ + __le32 it_nexus_2; /* IT nexus of the 2nd drive in the RAID volume */ + __le32 it_nexus_3; /* IT nexus of the 3rd drive in the RAID volume */ + __le32 data_length; /* total bytes to read/write */ + u8 data_direction : 2; + u8 partial : 1; + u8 memory_type : 1; + u8 fence : 1; + u8 encryption_enable : 1; + u8 reserved : 2; + u8 task_attribute : 3; + u8 command_priority : 4; + u8 reserved2 : 1; + __le16 data_encryption_key_index; + u8 cdb[16]; + __le16 error_index; + u8 num_sg_descriptors; + u8 cdb_length; + u8 num_drives; /* number of drives in the RAID volume (2 or 3) */ + u8 reserved3[3]; + __le32 encrypt_tweak_lower; + __le32 encrypt_tweak_upper; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; +}; + #define PQI_RAID56_XFER_LIMIT_4K 0x1000 /* 4Kib */ #define PQI_RAID56_XFER_LIMIT_8K 0x2000 /* 8Kib */ struct pqi_aio_r56_path_request { @@ -520,6 +550,7 @@ struct pqi_raid_error_info { #define PQI_REQUEST_IU_AIO_PATH_IO 0x15 #define PQI_REQUEST_IU_AIO_PATH_RAID5_IO 0x18 #define PQI_REQUEST_IU_AIO_PATH_RAID6_IO 0x19 +#define PQI_REQUEST_IU_AIO_PATH_RAID1_IO 0x1A #define PQI_REQUEST_IU_GENERAL_ADMIN 0x60 #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72 #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73 @@ -972,14 +1003,12 @@ struct pqi_scsi_dev_raid_map_data { u16 strip_size; u32 first_group; u32 last_group; - u32 current_group; u32 map_row; u32 aio_handle; u64 disk_block; u32 disk_block_cnt; u8 cdb[16]; u8 cdb_length; - int offload_to_mirror; /* RAID1 specific */ #define NUM_RAID1_MAP_ENTRIES 3 @@ -1040,8 +1069,7 @@ struct pqi_scsi_dev { u16 phys_connector[8]; bool raid_bypass_configured; /* RAID bypass configured */ bool raid_bypass_enabled; /* RAID bypass enabled */ - int offload_to_mirror; /* Send next RAID bypass request */ - /* to mirror drive. */ + u32 next_bypass_group; struct raid_map *raid_map; /* RAID bypass map */ struct pqi_sas_port *sas_port; @@ -1247,6 +1275,7 @@ struct pqi_ctrl_info { u8 soft_reset_handshake_supported : 1; u8 raid_iu_timeout_supported: 1; u8 tmf_iu_timeout_supported: 1; + u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 555d821e72ce..2bceea7b8dc7 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -67,6 +67,10 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb, unsigned int cdb_length, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, bool raid_bypass); +static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd); static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, @@ -1717,7 +1721,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, sizeof(existing_device->box)); memcpy(existing_device->phys_connector, new_device->phys_connector, sizeof(existing_device->phys_connector)); - existing_device->offload_to_mirror = 0; + existing_device->next_bypass_group = 0; kfree(existing_device->raid_map); existing_device->raid_map = new_device->raid_map; existing_device->raid_bypass_configured = @@ -2250,7 +2254,10 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, case SA_RAID_0: break; case SA_RAID_1: - is_supported = false; + fallthrough; + case SA_RAID_ADM: + if (rmd->is_write && !ctrl_info->enable_r1_writes) + is_supported = false; break; case SA_RAID_5: if (rmd->is_write && !ctrl_info->enable_r5_writes) @@ -2260,10 +2267,6 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, if (rmd->is_write && !ctrl_info->enable_r6_writes) is_supported = false; break; - case SA_RAID_ADM: - if (rmd->is_write) - is_supported = false; - break; default: is_supported = false; } @@ -2364,64 +2367,6 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, return 0; } -static int pqi_calc_aio_raid_adm(struct pqi_scsi_dev_raid_map_data *rmd, - struct pqi_scsi_dev *device) -{ - /* RAID ADM */ - /* - * Handles N-way mirrors (R1-ADM) and R10 with # of drives - * divisible by 3. - */ - rmd->offload_to_mirror = device->offload_to_mirror; - - if (rmd->offload_to_mirror == 0) { - /* use physical disk in the first mirrored group. */ - rmd->map_index %= rmd->data_disks_per_row; - } else { - do { - /* - * Determine mirror group that map_index - * indicates. - */ - rmd->current_group = - rmd->map_index / rmd->data_disks_per_row; - - if (rmd->offload_to_mirror != - rmd->current_group) { - if (rmd->current_group < - rmd->layout_map_count - 1) { - /* - * Select raid index from - * next group. - */ - rmd->map_index += rmd->data_disks_per_row; - rmd->current_group++; - } else { - /* - * Select raid index from first - * group. - */ - rmd->map_index %= rmd->data_disks_per_row; - rmd->current_group = 0; - } - } - } while (rmd->offload_to_mirror != rmd->current_group); - } - - /* Set mirror group to use next time. */ - rmd->offload_to_mirror = - (rmd->offload_to_mirror >= rmd->layout_map_count - 1) ? - 0 : rmd->offload_to_mirror + 1; - device->offload_to_mirror = rmd->offload_to_mirror; - /* - * Avoid direct use of device->offload_to_mirror within this - * function since multiple threads might simultaneously - * increment it beyond the range of device->layout_map_count -1. - */ - - return 0; -} - static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, struct raid_map *raid_map) { @@ -2508,12 +2453,34 @@ static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd) } } +static void pqi_calc_aio_r1_nexus(struct raid_map *raid_map, + struct pqi_scsi_dev_raid_map_data *rmd) +{ + u32 index; + u32 group; + + group = rmd->map_index / rmd->data_disks_per_row; + + index = rmd->map_index - (group * rmd->data_disks_per_row); + rmd->it_nexus[0] = raid_map->disk_data[index].aio_handle; + index += rmd->data_disks_per_row; + rmd->it_nexus[1] = raid_map->disk_data[index].aio_handle; + if (rmd->layout_map_count > 2) { + index += rmd->data_disks_per_row; + rmd->it_nexus[2] = raid_map->disk_data[index].aio_handle; + } + + rmd->num_it_nexus_entries = rmd->layout_map_count; +} + static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group) { - struct raid_map *raid_map; int rc; + struct raid_map *raid_map; + u32 group; + u32 next_bypass_group; struct pqi_encryption_info *encryption_info_ptr; struct pqi_encryption_info encryption_info; struct pqi_scsi_dev_raid_map_data rmd = {0}; @@ -2536,13 +2503,18 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, if (rc) return PQI_RAID_BYPASS_INELIGIBLE; - /* RAID 1 */ - if (device->raid_level == SA_RAID_1) { - if (device->offload_to_mirror) - rmd.map_index += rmd.data_disks_per_row; - device->offload_to_mirror = !device->offload_to_mirror; - } else if (device->raid_level == SA_RAID_ADM) { - rc = pqi_calc_aio_raid_adm(&rmd, device); + if (device->raid_level == SA_RAID_1 || + device->raid_level == SA_RAID_ADM) { + if (rmd.is_write) { + pqi_calc_aio_r1_nexus(raid_map, &rmd); + } else { + group = device->next_bypass_group; + next_bypass_group = group + 1; + if (next_bypass_group >= rmd.layout_map_count) + next_bypass_group = 0; + device->next_bypass_group = next_bypass_group; + rmd.map_index += group * rmd.data_disks_per_row; + } } else if ((device->raid_level == SA_RAID_5 || device->raid_level == SA_RAID_6) && (rmd.layout_map_count > 1 || rmd.is_write)) { @@ -2586,6 +2558,10 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, rmd.cdb, rmd.cdb_length, queue_group, encryption_info_ptr, true); + case SA_RAID_1: + case SA_RAID_ADM: + return pqi_aio_submit_r1_write_io(ctrl_info, scmd, queue_group, + encryption_info_ptr, device, &rmd); case SA_RAID_5: case SA_RAID_6: return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, @@ -4913,6 +4889,44 @@ static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info, return 0; } +static int pqi_build_aio_r1_sg_list(struct pqi_ctrl_info *ctrl_info, + struct pqi_aio_r1_path_request *request, struct scsi_cmnd *scmd, + struct pqi_io_request *io_request) +{ + u16 iu_length; + int sg_count; + bool chained; + unsigned int num_sg_in_iu; + struct scatterlist *sg; + struct pqi_sg_descriptor *sg_descriptor; + + sg_count = scsi_dma_map(scmd); + if (sg_count < 0) + return sg_count; + + iu_length = offsetof(struct pqi_aio_r1_path_request, sg_descriptors) - + PQI_REQUEST_HEADER_LENGTH; + num_sg_in_iu = 0; + + if (sg_count == 0) + goto out; + + sg = scsi_sglist(scmd); + sg_descriptor = request->sg_descriptors; + + num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request, + ctrl_info->max_sg_per_iu, &chained); + + request->partial = chained; + iu_length += num_sg_in_iu * sizeof(*sg_descriptor); + +out: + put_unaligned_le16(iu_length, &request->header.iu_length); + request->num_sg_descriptors = num_sg_in_iu; + + return 0; +} + static int pqi_build_aio_r56_sg_list(struct pqi_ctrl_info *ctrl_info, struct pqi_aio_r56_path_request *request, struct scsi_cmnd *scmd, struct pqi_io_request *io_request) @@ -5355,6 +5369,83 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, return 0; } +static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, + struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, + struct pqi_scsi_dev_raid_map_data *rmd) + +{ + int rc; + struct pqi_io_request *io_request; + struct pqi_aio_r1_path_request *r1_request; + + io_request = pqi_alloc_io_request(ctrl_info); + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = true; + + r1_request = io_request->iu; + memset(r1_request, 0, offsetof(struct pqi_aio_r1_path_request, sg_descriptors)); + + r1_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID1_IO; + + put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r1_request->volume_id); + r1_request->num_drives = rmd->num_it_nexus_entries; + put_unaligned_le32(rmd->it_nexus[0], &r1_request->it_nexus_1); + put_unaligned_le32(rmd->it_nexus[1], &r1_request->it_nexus_2); + if (rmd->num_it_nexus_entries == 3) + put_unaligned_le32(rmd->it_nexus[2], &r1_request->it_nexus_3); + + put_unaligned_le32(scsi_bufflen(scmd), &r1_request->data_length); + r1_request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; + put_unaligned_le16(io_request->index, &r1_request->request_id); + r1_request->error_index = r1_request->request_id; + if (rmd->cdb_length > sizeof(r1_request->cdb)) + rmd->cdb_length = sizeof(r1_request->cdb); + r1_request->cdb_length = rmd->cdb_length; + memcpy(r1_request->cdb, rmd->cdb, rmd->cdb_length); + + switch (scmd->sc_data_direction) { + case DMA_TO_DEVICE: + r1_request->data_direction = SOP_READ_FLAG; + break; + case DMA_FROM_DEVICE: + r1_request->data_direction = SOP_WRITE_FLAG; + break; + case DMA_NONE: + r1_request->data_direction = SOP_NO_DIRECTION_FLAG; + break; + case DMA_BIDIRECTIONAL: + r1_request->data_direction = SOP_BIDIRECTIONAL; + break; + default: + dev_err(&ctrl_info->pci_dev->dev, + "unknown data direction: %d\n", + scmd->sc_data_direction); + break; + } + + if (encryption_info) { + r1_request->encryption_enable = true; + put_unaligned_le16(encryption_info->data_encryption_key_index, + &r1_request->data_encryption_key_index); + put_unaligned_le32(encryption_info->encrypt_tweak_lower, + &r1_request->encrypt_tweak_lower); + put_unaligned_le32(encryption_info->encrypt_tweak_upper, + &r1_request->encrypt_tweak_upper); + } + + rc = pqi_build_aio_r1_sg_list(ctrl_info, r1_request, scmd, io_request); + if (rc) { + pqi_free_io_request(io_request); + return SCSI_MLQUEUE_HOST_BUSY; + } + + pqi_start_io(ctrl_info, queue_group, AIO_PATH, io_request); + + return 0; +} + static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, From patchwork Fri Dec 4 23:01:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338139 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D2930C4361A for ; Fri, 4 Dec 2020 23:03:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 94C2222D01 for ; Fri, 4 Dec 2020 23:03:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727132AbgLDXDF (ORCPT ); Fri, 4 Dec 2020 18:03:05 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1456 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDF (ORCPT ); Fri, 4 Dec 2020 18:03:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122984; x=1638658984; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cxEkOG0E071kpWKS0nsffM2UNZ/AIR3SV1ByQ435eE8=; b=xKoOcRm2+3M57pKXfiMd+zDn1rhwEZs+8f2OwiXIiC1zRrq2ngWKBgkR az8rdPgmUpfOQuShRT+ea82LpxE+bOtQ6uQ5ZCOM15BDi3j2pUBYa/iNZ s558WP0vRs2VAxpN4orCuqI4jIlrFYQyiNfHJv3+PwV9gGUXeOIekDZJI 6s66zfUUICo+Aeuohiu4r8E7dyDZti6MxWptL/fiSyYlDrPYqdriJ1U0T vQc4eejDQUX4wh0bysKSZ0v8L/cBiacFuPLDNwzru2nsQYdjF95hpA20J snl/Pj4w01m9dX5PHivkFukwpmiuR8jSUBETgzqaXEohSPr9tXDJGaG8f Q==; IronPort-SDR: SteIAeq7dEgwqP/SiX4839dbE77nHpblgFyZGoQxwpKXONChsnzuocH04TuTIU9vFaKkkD8q0q 9VUPnKKO+6HUupc4y8Vsfgo08Vd1r2tRFku+uTifdrexD0SOpoI7ts0VCYvko4n8RssZcxJCG4 DzK/RM2HiCzrt5UP7IPakyAykaWF7ONe8zgMovZYKamjamGKU/QKvxB4KZPaLfqJ2jhmBtSy6W L4T+JdfoooXNCpA1rCh2EzJ5Fw4AU+RbaFy9rAfRrarRwctpYdlFSoyX8SzHfY4SUAKm7mCZ+E Ia0= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548418" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:26 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:26 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:25 -0700 Subject: [PATCH 06/25] smartpqi: add support for BMIC sense feature cmd and feature bits From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:25 -0600 Message-ID: <160712288548.21372.18384773215966260644.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Determine support for supported features from BMIC sense feature command instead of config table. Reviewed-by: Scott Teel Reviewed-by: Scott Benesh Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 77 +++++++- drivers/scsi/smartpqi/smartpqi_init.c | 328 +++++++++++++++++++++++++++++---- 2 files changed, 363 insertions(+), 42 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 225ec6843c68..31281cddadfe 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -314,6 +314,7 @@ struct pqi_aio_path_request { }; #define PQI_RAID1_NVME_XFER_LIMIT (32 * 1024) /* 32 KiB */ + struct pqi_aio_r1_path_request { struct pqi_iu_header header; __le16 request_id; @@ -343,8 +344,10 @@ struct pqi_aio_r1_path_request { struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; -#define PQI_RAID56_XFER_LIMIT_4K 0x1000 /* 4Kib */ -#define PQI_RAID56_XFER_LIMIT_8K 0x2000 /* 8Kib */ +#define PQI_DEFAULT_MAX_WRITE_RAID_5_6 (8 * 1024U) +#define PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_SAS_SATA (~0U) +#define PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_NVME (32 * 1024U) + struct pqi_aio_r56_path_request { struct pqi_iu_header header; __le16 request_id; @@ -355,7 +358,7 @@ struct pqi_aio_r56_path_request { __le32 data_length; /* total bytes to read/write */ u8 data_direction : 2; u8 partial : 1; - u8 mem_type : 1; /* 0b: PCIe, 1b: DDR */ + u8 mem_type : 1; /* 0 = PCIe, 1 = DDR */ u8 fence : 1; u8 encryption_enable : 1; u8 reserved : 2; @@ -371,7 +374,7 @@ struct pqi_aio_r56_path_request { u8 reserved2[3]; __le32 encrypt_tweak_lower; __le32 encrypt_tweak_upper; - u8 row; /* row = logical lba/blocks per row */ + __le64 row; /* row = logical LBA/blocks per row */ u8 reserved3[8]; struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS]; }; @@ -828,13 +831,27 @@ struct pqi_config_table_firmware_features { u8 features_supported[]; /* u8 features_requested_by_host[]; */ /* u8 features_enabled[]; */ +/* The 2 fields below are only valid if the MAX_KNOWN_FEATURE bit is set. */ +/* __le16 firmware_max_known_feature; */ +/* __le16 host_max_known_feature; */ }; #define PQI_FIRMWARE_FEATURE_OFA 0 #define PQI_FIRMWARE_FEATURE_SMP 1 +#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2 +#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3 +#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4 +#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5 +#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6 +#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7 +#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8 +#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9 +#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10 #define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 +#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 #define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 #define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 14 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -1010,12 +1027,12 @@ struct pqi_scsi_dev_raid_map_data { u8 cdb[16]; u8 cdb_length; - /* RAID1 specific */ + /* RAID 1 specific */ #define NUM_RAID1_MAP_ENTRIES 3 u32 num_it_nexus_entries; u32 it_nexus[NUM_RAID1_MAP_ENTRIES]; - /* RAID5 RAID6 specific */ + /* RAID 5 / RAID 6 specific */ u32 p_parity_it_nexus; /* aio_handle */ u32 q_parity_it_nexus; /* aio_handle */ u8 xor_mult; @@ -1071,6 +1088,7 @@ struct pqi_scsi_dev { bool raid_bypass_enabled; /* RAID bypass enabled */ u32 next_bypass_group; struct raid_map *raid_map; /* RAID bypass map */ + u32 max_transfer_encrypted; struct pqi_sas_port *sas_port; struct scsi_device *sdev; @@ -1278,6 +1296,13 @@ struct pqi_ctrl_info { u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; + u8 lv_drive_type_mix_valid : 1; + + u8 ciss_report_log_flags; + u32 max_transfer_encrypted_sas_sata; + u32 max_transfer_encrypted_nvme; + u32 max_write_raid_5_6; + struct list_head scsi_device_list; spinlock_t scsi_device_list_lock; @@ -1338,6 +1363,7 @@ enum pqi_ctrl_mode { #define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15 #define BMIC_READ 0x26 #define BMIC_WRITE 0x27 +#define BMIC_SENSE_FEATURE 0x61 #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64 #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 #define BMIC_CSMI_PASSTHRU 0x68 @@ -1357,6 +1383,19 @@ enum pqi_ctrl_mode { (((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \ CISS_GET_LEVEL_2_TARGET((lunid))) +#define LV_GET_DRIVE_TYPE_MIX(lunid) ((lunid)[6]) + +#define LV_DRIVE_TYPE_MIX_UNKNOWN 0 +#define LV_DRIVE_TYPE_MIX_NO_RESTRICTION 1 +#define LV_DRIVE_TYPE_MIX_SAS_HDD_ONLY 2 +#define LV_DRIVE_TYPE_MIX_SATA_HDD_ONLY 3 +#define LV_DRIVE_TYPE_MIX_SAS_OR_SATA_SSD_ONLY 4 +#define LV_DRIVE_TYPE_MIX_SAS_SSD_ONLY 5 +#define LV_DRIVE_TYPE_MIX_SATA_SSD_ONLY 6 +#define LV_DRIVE_TYPE_MIX_SAS_ONLY 7 +#define LV_DRIVE_TYPE_MIX_SATA_ONLY 8 +#define LV_DRIVE_TYPE_MIX_NVME_ONLY 9 + #define NO_TIMEOUT ((unsigned long) -1) #pragma pack(1) @@ -1470,6 +1509,32 @@ struct bmic_identify_physical_device { u8 padding_to_multiple_of_512[9]; }; +#define BMIC_SENSE_FEATURE_IO_PAGE 0x8 +#define BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE 0x2 + +struct bmic_sense_feature_buffer_header { + u8 page_code; + u8 subpage_code; + __le16 buffer_length; +}; + +struct bmic_sense_feature_page_header { + u8 page_code; + u8 subpage_code; + __le16 page_length; +}; + +struct bmic_sense_feature_io_page_aio_subpage { + struct bmic_sense_feature_page_header header; + u8 firmware_read_support; + u8 driver_read_support; + u8 firmware_write_support; + u8 driver_write_support; + __le16 max_transfer_encrypted_sas_sata; + __le16 max_transfer_encrypted_nvme; + __le16 max_write_raid_5_6; +}; + struct bmic_smp_request { u8 frame_type; u8 function; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 2bceea7b8dc7..25a3aa763bba 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -506,7 +506,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, if (cmd == CISS_REPORT_PHYS) cdb[1] = CISS_REPORT_PHYS_FLAG_OTHER; else - cdb[1] = CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID; + cdb[1] = ctrl_info->ciss_report_log_flags; put_unaligned_be32(cdb_length, &cdb[6]); break; case CISS_GET_RAID_MAP: @@ -527,6 +527,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, case BMIC_IDENTIFY_CONTROLLER: case BMIC_IDENTIFY_PHYSICAL_DEVICE: case BMIC_SENSE_SUBSYSTEM_INFORMATION: + case BMIC_SENSE_FEATURE: request->data_direction = SOP_READ_FLAG; cdb[0] = BMIC_READ; cdb[6] = cmd; @@ -695,6 +696,97 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, return rc; } +#pragma pack(1) + +struct bmic_sense_feature_buffer { + struct bmic_sense_feature_buffer_header header; + struct bmic_sense_feature_io_page_aio_subpage aio_subpage; +}; + +#pragma pack() + +#define MINIMUM_AIO_SUBPAGE_BUFFER_LENGTH \ + offsetofend(struct bmic_sense_feature_buffer, \ + aio_subpage.max_write_raid_5_6) + +#define MINIMUM_AIO_SUBPAGE_LENGTH \ + (offsetofend(struct bmic_sense_feature_io_page_aio_subpage, \ + max_write_raid_5_6) - \ + sizeof_field(struct bmic_sense_feature_io_page_aio_subpage, header)) + +static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) +{ + int rc; + enum dma_data_direction dir; + struct pqi_raid_path_request request; + struct bmic_sense_feature_buffer *buffer; + + buffer = kmalloc(sizeof(*buffer), GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + rc = pqi_build_raid_path_request(ctrl_info, &request, + BMIC_SENSE_FEATURE, RAID_CTLR_LUNID, buffer, + sizeof(*buffer), 0, &dir); + if (rc) + goto error; + + request.cdb[2] = BMIC_SENSE_FEATURE_IO_PAGE; + request.cdb[3] = BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE; + + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, + 0, NULL, NO_TIMEOUT); + + pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); + + if (rc) + goto error; + + if (buffer->header.page_code != BMIC_SENSE_FEATURE_IO_PAGE || + buffer->header.subpage_code != + BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE || + get_unaligned_le16(&buffer->header.buffer_length) < + MINIMUM_AIO_SUBPAGE_BUFFER_LENGTH || + buffer->aio_subpage.header.page_code != + BMIC_SENSE_FEATURE_IO_PAGE || + buffer->aio_subpage.header.subpage_code != + BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE || + get_unaligned_le16(&buffer->aio_subpage.header.page_length) < + MINIMUM_AIO_SUBPAGE_LENGTH) { + rc = -EINVAL; + goto error; + } + + ctrl_info->max_transfer_encrypted_sas_sata = + get_unaligned_le16( + &buffer->aio_subpage.max_transfer_encrypted_sas_sata); + if (ctrl_info->max_transfer_encrypted_sas_sata) + ctrl_info->max_transfer_encrypted_sas_sata *= 1024; + else + ctrl_info->max_transfer_encrypted_sas_sata = ~0; + + ctrl_info->max_transfer_encrypted_nvme = + get_unaligned_le16( + &buffer->aio_subpage.max_transfer_encrypted_nvme); + if (ctrl_info->max_transfer_encrypted_nvme) + ctrl_info->max_transfer_encrypted_nvme *= 1024; + else + ctrl_info->max_transfer_encrypted_nvme = ~0; + + ctrl_info->max_write_raid_5_6 = + get_unaligned_le16( + &buffer->aio_subpage.max_write_raid_5_6); + if (ctrl_info->max_write_raid_5_6) + ctrl_info->max_write_raid_5_6 *= 1024; + else + ctrl_info->max_write_raid_5_6 = ~0; + +error: + kfree(buffer); + + return rc; +} + static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info, enum bmic_flush_cache_shutdown_event shutdown_event) { @@ -1232,6 +1324,39 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, return rc; } +static void pqi_set_max_transfer_encrypted(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device) +{ + if (!ctrl_info->lv_drive_type_mix_valid) { + device->max_transfer_encrypted = ~0; + return; + } + + switch (LV_GET_DRIVE_TYPE_MIX(device->scsi3addr)) { + case LV_DRIVE_TYPE_MIX_SAS_HDD_ONLY: + case LV_DRIVE_TYPE_MIX_SATA_HDD_ONLY: + case LV_DRIVE_TYPE_MIX_SAS_OR_SATA_SSD_ONLY: + case LV_DRIVE_TYPE_MIX_SAS_SSD_ONLY: + case LV_DRIVE_TYPE_MIX_SATA_SSD_ONLY: + case LV_DRIVE_TYPE_MIX_SAS_ONLY: + case LV_DRIVE_TYPE_MIX_SATA_ONLY: + device->max_transfer_encrypted = + ctrl_info->max_transfer_encrypted_sas_sata; + break; + case LV_DRIVE_TYPE_MIX_NVME_ONLY: + device->max_transfer_encrypted = + ctrl_info->max_transfer_encrypted_nvme; + break; + case LV_DRIVE_TYPE_MIX_UNKNOWN: + case LV_DRIVE_TYPE_MIX_NO_RESTRICTION: + default: + device->max_transfer_encrypted = + min(ctrl_info->max_transfer_encrypted_sas_sata, + ctrl_info->max_transfer_encrypted_nvme); + break; + } +} + static void pqi_get_raid_bypass_status(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { @@ -1257,8 +1382,12 @@ static void pqi_get_raid_bypass_status(struct pqi_ctrl_info *ctrl_info, (bypass_status & RAID_BYPASS_CONFIGURED) != 0; if (device->raid_bypass_configured && (bypass_status & RAID_BYPASS_ENABLED) && - pqi_get_raid_map(ctrl_info, device) == 0) + pqi_get_raid_map(ctrl_info, device) == 0) { device->raid_bypass_enabled = true; + if (get_unaligned_le16(&device->raid_map->flags) & + RAID_MAP_ENCRYPTION_ENABLED) + pqi_set_max_transfer_encrypted(ctrl_info, device); + } out: kfree(buffer); @@ -2028,6 +2157,10 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) } } + if (num_logicals && + (logdev_list->header.flags & CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX)) + ctrl_info->lv_drive_type_mix_valid = true; + num_new_devices = num_physicals + num_logicals; new_device_list = kmalloc_array(num_new_devices, @@ -2260,15 +2393,18 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, is_supported = false; break; case SA_RAID_5: - if (rmd->is_write && !ctrl_info->enable_r5_writes) + if (rmd->is_write && (!ctrl_info->enable_r5_writes || + rmd->data_length > ctrl_info->max_write_raid_5_6)) is_supported = false; break; case SA_RAID_6: - if (rmd->is_write && !ctrl_info->enable_r6_writes) + if (rmd->is_write && (!ctrl_info->enable_r6_writes || + rmd->data_length > ctrl_info->max_write_raid_5_6)) is_supported = false; break; default: is_supported = false; + break; } return is_supported; @@ -2277,7 +2413,7 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, #define PQI_RAID_BYPASS_INELIGIBLE 1 static int pqi_get_aio_lba_and_block_count(struct scsi_cmnd *scmd, - struct pqi_scsi_dev_raid_map_data *rmd) + struct pqi_scsi_dev_raid_map_data *rmd) { /* Check for valid opcode, get LBA and block count. */ switch (scmd->cmnd[0]) { @@ -2323,8 +2459,7 @@ static int pqi_get_aio_lba_and_block_count(struct scsi_cmnd *scmd, } static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev_raid_map_data *rmd, - struct raid_map *raid_map) + struct pqi_scsi_dev_raid_map_data *rmd, struct raid_map *raid_map) { rmd->last_block = rmd->first_block + rmd->block_cnt - 1; @@ -2335,7 +2470,7 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, return PQI_RAID_BYPASS_INELIGIBLE; rmd->data_disks_per_row = - get_unaligned_le16(&raid_map->data_disks_per_row); + get_unaligned_le16(&raid_map->data_disks_per_row); rmd->strip_size = get_unaligned_le16(&raid_map->strip_size); rmd->layout_map_count = get_unaligned_le16(&raid_map->layout_map_count); @@ -2344,15 +2479,15 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, rmd->first_row = rmd->first_block / rmd->blocks_per_row; rmd->last_row = rmd->last_block / rmd->blocks_per_row; rmd->first_row_offset = (u32)(rmd->first_block - - (rmd->first_row * rmd->blocks_per_row)); + (rmd->first_row * rmd->blocks_per_row)); rmd->last_row_offset = (u32)(rmd->last_block - (rmd->last_row * - rmd->blocks_per_row)); + rmd->blocks_per_row)); rmd->first_column = rmd->first_row_offset / rmd->strip_size; rmd->last_column = rmd->last_row_offset / rmd->strip_size; /* If this isn't a single row/column then give to the controller. */ if (rmd->first_row != rmd->last_row || - rmd->first_column != rmd->last_column) + rmd->first_column != rmd->last_column) return PQI_RAID_BYPASS_INELIGIBLE; /* Proceeding with driver mapping. */ @@ -2362,16 +2497,16 @@ static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info, raid_map->parity_rotation_shift)) % get_unaligned_le16(&raid_map->row_cnt); rmd->map_index = (rmd->map_row * rmd->total_disks_per_row) + - rmd->first_column; + rmd->first_column; return 0; } static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, - struct raid_map *raid_map) + struct raid_map *raid_map) { /* RAID 50/60 */ - /* Verify first and last block are in same RAID group */ + /* Verify first and last block are in same RAID group. */ rmd->stripesize = rmd->blocks_per_row * rmd->layout_map_count; rmd->first_group = (rmd->first_block % rmd->stripesize) / rmd->blocks_per_row; @@ -2380,31 +2515,30 @@ static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd, if (rmd->first_group != rmd->last_group) return PQI_RAID_BYPASS_INELIGIBLE; - /* Verify request is in a single row of RAID 5/6 */ + /* Verify request is in a single row of RAID 5/6. */ rmd->first_row = rmd->r5or6_first_row = rmd->first_block / rmd->stripesize; rmd->r5or6_last_row = rmd->last_block / rmd->stripesize; if (rmd->r5or6_first_row != rmd->r5or6_last_row) return PQI_RAID_BYPASS_INELIGIBLE; - /* Verify request is in a single column */ + /* Verify request is in a single column. */ rmd->first_row_offset = rmd->r5or6_first_row_offset = - (u32)((rmd->first_block % - rmd->stripesize) % - rmd->blocks_per_row); + (u32)((rmd->first_block % rmd->stripesize) % + rmd->blocks_per_row); rmd->r5or6_last_row_offset = (u32)((rmd->last_block % rmd->stripesize) % rmd->blocks_per_row); rmd->first_column = - rmd->r5or6_first_row_offset / rmd->strip_size; + rmd->r5or6_first_row_offset / rmd->strip_size; rmd->r5or6_first_column = rmd->first_column; rmd->r5or6_last_column = rmd->r5or6_last_row_offset / rmd->strip_size; if (rmd->r5or6_first_column != rmd->r5or6_last_column) return PQI_RAID_BYPASS_INELIGIBLE; - /* Request is eligible */ + /* Request is eligible. */ rmd->map_row = ((u32)(rmd->first_row >> raid_map->parity_rotation_shift)) % get_unaligned_le16(&raid_map->row_cnt); @@ -2454,7 +2588,7 @@ static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd) } static void pqi_calc_aio_r1_nexus(struct raid_map *raid_map, - struct pqi_scsi_dev_raid_map_data *rmd) + struct pqi_scsi_dev_raid_map_data *rmd) { u32 index; u32 group; @@ -2483,7 +2617,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, u32 next_bypass_group; struct pqi_encryption_info *encryption_info_ptr; struct pqi_encryption_info encryption_info; - struct pqi_scsi_dev_raid_map_data rmd = {0}; + struct pqi_scsi_dev_raid_map_data rmd = { 0 }; rc = pqi_get_aio_lba_and_block_count(scmd, &rmd); if (rc) @@ -2544,7 +2678,9 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, pqi_set_aio_cdb(&rmd); if (get_unaligned_le16(&raid_map->flags) & - RAID_MAP_ENCRYPTION_ENABLED) { + RAID_MAP_ENCRYPTION_ENABLED) { + if (rmd.data_length > device->max_transfer_encrypted) + return PQI_RAID_BYPASS_INELIGIBLE; pqi_set_encryption_info(&encryption_info, raid_map, rmd.first_block); encryption_info_ptr = &encryption_info; @@ -2554,10 +2690,6 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, if (rmd.is_write) { switch (device->raid_level) { - case SA_RAID_0: - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, - rmd.cdb, rmd.cdb_length, queue_group, - encryption_info_ptr, true); case SA_RAID_1: case SA_RAID_ADM: return pqi_aio_submit_r1_write_io(ctrl_info, scmd, queue_group, @@ -2566,17 +2698,12 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, case SA_RAID_6: return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, encryption_info_ptr, device, &rmd); - default: - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, - rmd.cdb, rmd.cdb_length, queue_group, - encryption_info_ptr, true); } - } else { - return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, - rmd.cdb, rmd.cdb_length, queue_group, - encryption_info_ptr, true); } + return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle, + rmd.cdb, rmd.cdb_length, queue_group, + encryption_info_ptr, true); } #define PQI_STATUS_IDLE 0x0 @@ -7140,6 +7267,7 @@ static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info, { void *features_requested; void __iomem *features_requested_iomem_addr; + void __iomem *host_max_known_feature_iomem_addr; features_requested = firmware_features->features_supported + le16_to_cpu(firmware_features->num_elements); @@ -7150,6 +7278,16 @@ static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info, memcpy_toio(features_requested_iomem_addr, features_requested, le16_to_cpu(firmware_features->num_elements)); + if (pqi_is_firmware_feature_supported(firmware_features, + PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE)) { + host_max_known_feature_iomem_addr = + features_requested_iomem_addr + + (le16_to_cpu(firmware_features->num_elements) * 2) + + sizeof(__le16); + writew(PQI_FIRMWARE_FEATURE_MAXIMUM, + host_max_known_feature_iomem_addr); + } + return pqi_config_table_update(ctrl_info, PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES, PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES); @@ -7187,6 +7325,15 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, struct pqi_firmware_feature *firmware_feature) { switch (firmware_feature->feature_bit) { + case PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS: + ctrl_info->enable_r1_writes = firmware_feature->enabled; + break; + case PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS: + ctrl_info->enable_r5_writes = firmware_feature->enabled; + break; + case PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS: + ctrl_info->enable_r6_writes = firmware_feature->enabled; + break; case PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE: ctrl_info->soft_reset_handshake_supported = firmware_feature->enabled; @@ -7224,6 +7371,51 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_SMP, .feature_status = pqi_firmware_feature_status, }, + { + .feature_name = "Maximum Known Feature", + .feature_bit = PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 0 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 1 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 5 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 6 Read Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 0 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS, + .feature_status = pqi_firmware_feature_status, + }, + { + .feature_name = "RAID 1 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS, + .feature_status = pqi_ctrl_update_feature_flags, + }, + { + .feature_name = "RAID 5 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS, + .feature_status = pqi_ctrl_update_feature_flags, + }, + { + .feature_name = "RAID 6 Write Bypass", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS, + .feature_status = pqi_ctrl_update_feature_flags, + }, { .feature_name = "New Soft Reset Handshake", .feature_bit = PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE, @@ -7598,6 +7790,17 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) pqi_start_heartbeat_timer(ctrl_info); + if (ctrl_info->enable_r5_writes || ctrl_info->enable_r6_writes) { + rc = pqi_get_advanced_raid_bypass_config(ctrl_info); + if (rc) { + dev_err(&ctrl_info->pci_dev->dev, + "error obtaining advanced RAID bypass configuration\n"); + return rc; + } + ctrl_info->ciss_report_log_flags |= + CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX; + } + rc = pqi_enable_events(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, @@ -7753,6 +7956,17 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) pqi_start_heartbeat_timer(ctrl_info); + if (ctrl_info->enable_r5_writes || ctrl_info->enable_r6_writes) { + rc = pqi_get_advanced_raid_bypass_config(ctrl_info); + if (rc) { + dev_err(&ctrl_info->pci_dev->dev, + "error obtaining advanced RAID bypass configuration\n"); + return rc; + } + ctrl_info->ciss_report_log_flags |= + CISS_REPORT_LOG_FLAG_DRIVE_TYPE_MIX; + } + rc = pqi_enable_events(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, @@ -7916,6 +8130,13 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) ctrl_info->irq_mode = IRQ_MODE_NONE; ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS; + ctrl_info->ciss_report_log_flags = CISS_REPORT_LOG_FLAG_UNIQUE_LUN_ID; + ctrl_info->max_transfer_encrypted_sas_sata = + PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_SAS_SATA; + ctrl_info->max_transfer_encrypted_nvme = + PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_NVME; + ctrl_info->max_write_raid_5_6 = PQI_DEFAULT_MAX_WRITE_RAID_5_6; + return ctrl_info; } @@ -9327,6 +9548,41 @@ static void __attribute__((unused)) verify_structures(void) current_queue_depth_limit) != 1796); BUILD_BUG_ON(sizeof(struct bmic_identify_physical_device) != 2560); + BUILD_BUG_ON(sizeof(struct bmic_sense_feature_buffer_header) != 4); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_buffer_header, + page_code) != 0); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_buffer_header, + subpage_code) != 1); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_buffer_header, + buffer_length) != 2); + + BUILD_BUG_ON(sizeof(struct bmic_sense_feature_page_header) != 4); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_page_header, + page_code) != 0); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_page_header, + subpage_code) != 1); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_page_header, + page_length) != 2); + + BUILD_BUG_ON(sizeof(struct bmic_sense_feature_io_page_aio_subpage) + != 14); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + header) != 0); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + firmware_read_support) != 4); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + driver_read_support) != 5); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + firmware_write_support) != 6); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + driver_write_support) != 7); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_transfer_encrypted_sas_sata) != 8); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_transfer_encrypted_nvme) != 10); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_write_raid_5_6) != 12); + BUILD_BUG_ON(PQI_ADMIN_IQ_NUM_ELEMENTS > 255); BUILD_BUG_ON(PQI_ADMIN_OQ_NUM_ELEMENTS > 255); BUILD_BUG_ON(PQI_ADMIN_IQ_ELEMENT_LENGTH % From patchwork Fri Dec 4 23:01:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338137 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7205C433FE for ; Fri, 4 Dec 2020 23:03:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C44AE22D01 for ; Fri, 4 Dec 2020 23:03:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727230AbgLDXDK (ORCPT ); Fri, 4 Dec 2020 18:03:10 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1374 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDJ (ORCPT ); Fri, 4 Dec 2020 18:03:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122989; x=1638658989; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=votB9wXp5KI1r3R9o1Wg6925asMQ2aoSjMqDU7bBlDY=; b=JJiuHyE88w5x0IWwf8JEAqPxCVnDg/RJ5xqZAqwXSSHDXZ8yGE+uuBo7 Aw33TH9BMv9EaluTuiyjbdKH5Eq0GkhLCysJ/v/KtOKHLTUBbkhpVh7ex ieLUs8IlshbOLm/CzKjYlvMv1vus5WHkehHsS+ep8Jjg5QquHcdOYOB27 ED8goiGfuADnjoRDo6JLlBU5TeKbhmaqNMSB19fvoCFexvjhIIfNGuZdR U34XTN/x+vNkOqjmtP0aBs0T+7L9ESL/f/1j3IzIOltCAQqt/vyAQH6KM za2PxQuH++xesUH8oZl5OHuAs9lz8zH5f2YAkWsxsuSWdFKzrxchVYghz g==; IronPort-SDR: jMXEpSCEnWdDBqAbVwLBRj37BMqDDcEDiKJvOmB8AFdoTfI9xGe1j/5AccYycxgpyuO3ie96M/ nwiC7zmis74jkDIglC4xND2hcogCeUpFt13RYfELDALCZuomPQJHdftfuy9PfvwEArkyjPu5Gp Sg3X8CWv1UuEOogyUd+rpmZ0rreiCyOdG3HY/PJxuplSqVwjKkFPy63ZjEtSZzYW2bYk5P2IxS TC4ywJllCLEeGbjWsoD7RHxgmHF/wdATN/3k2Pqc420f0lEx8/iJvNldXwVThCcSMVm3f2oggK mqY= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548508" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:34 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:31 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:31 -0700 Subject: [PATCH 07/25] smartpqi: update AIO Sub Page 0x02 support From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:31 -0600 Message-ID: <160712289129.21372.649253271818958012.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett The specification for AIO Sub-Page (0x02) has changed slightly. * bring the driver into conformance with the spec. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 12 ++++--- drivers/scsi/smartpqi/smartpqi_init.c | 60 +++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 31281cddadfe..eb23c3cf59c0 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1028,13 +1028,13 @@ struct pqi_scsi_dev_raid_map_data { u8 cdb_length; /* RAID 1 specific */ -#define NUM_RAID1_MAP_ENTRIES 3 +#define NUM_RAID1_MAP_ENTRIES 3 u32 num_it_nexus_entries; u32 it_nexus[NUM_RAID1_MAP_ENTRIES]; /* RAID 5 / RAID 6 specific */ - u32 p_parity_it_nexus; /* aio_handle */ - u32 q_parity_it_nexus; /* aio_handle */ + u32 p_parity_it_nexus; /* aio_handle */ + u32 q_parity_it_nexus; /* aio_handle */ u8 xor_mult; u64 row; u64 stripe_lba; @@ -1044,6 +1044,7 @@ struct pqi_scsi_dev_raid_map_data { #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" + struct pqi_scsi_dev { int devtype; /* as reported by INQUIRY commmand */ u8 device_type; /* as reported by */ @@ -1302,7 +1303,8 @@ struct pqi_ctrl_info { u32 max_transfer_encrypted_sas_sata; u32 max_transfer_encrypted_nvme; u32 max_write_raid_5_6; - + u32 max_write_raid_1_10_2drive; + u32 max_write_raid_1_10_3drive; struct list_head scsi_device_list; spinlock_t scsi_device_list_lock; @@ -1533,6 +1535,8 @@ struct bmic_sense_feature_io_page_aio_subpage { __le16 max_transfer_encrypted_sas_sata; __le16 max_transfer_encrypted_nvme; __le16 max_write_raid_5_6; + __le16 max_write_raid_1_10_2drive; + __le16 max_write_raid_1_10_3drive; }; struct bmic_smp_request { diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 25a3aa763bba..34ff1b3679f1 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -696,6 +696,19 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, return rc; } +static inline u32 pqi_aio_limit_to_bytes(__le16 *limit) +{ + u32 bytes; + + bytes = get_unaligned_le16(limit); + if (bytes == 0) + bytes = ~0; + else + bytes *= 1024; + + return bytes; +} + #pragma pack(1) struct bmic_sense_feature_buffer { @@ -707,11 +720,11 @@ struct bmic_sense_feature_buffer { #define MINIMUM_AIO_SUBPAGE_BUFFER_LENGTH \ offsetofend(struct bmic_sense_feature_buffer, \ - aio_subpage.max_write_raid_5_6) + aio_subpage.max_write_raid_1_10_3drive) #define MINIMUM_AIO_SUBPAGE_LENGTH \ (offsetofend(struct bmic_sense_feature_io_page_aio_subpage, \ - max_write_raid_5_6) - \ + max_write_raid_1_10_3drive) - \ sizeof_field(struct bmic_sense_feature_io_page_aio_subpage, header)) static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) @@ -753,33 +766,28 @@ static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE || get_unaligned_le16(&buffer->aio_subpage.header.page_length) < MINIMUM_AIO_SUBPAGE_LENGTH) { - rc = -EINVAL; goto error; } ctrl_info->max_transfer_encrypted_sas_sata = - get_unaligned_le16( + pqi_aio_limit_to_bytes( &buffer->aio_subpage.max_transfer_encrypted_sas_sata); - if (ctrl_info->max_transfer_encrypted_sas_sata) - ctrl_info->max_transfer_encrypted_sas_sata *= 1024; - else - ctrl_info->max_transfer_encrypted_sas_sata = ~0; ctrl_info->max_transfer_encrypted_nvme = - get_unaligned_le16( + pqi_aio_limit_to_bytes( &buffer->aio_subpage.max_transfer_encrypted_nvme); - if (ctrl_info->max_transfer_encrypted_nvme) - ctrl_info->max_transfer_encrypted_nvme *= 1024; - else - ctrl_info->max_transfer_encrypted_nvme = ~0; ctrl_info->max_write_raid_5_6 = - get_unaligned_le16( + pqi_aio_limit_to_bytes( &buffer->aio_subpage.max_write_raid_5_6); - if (ctrl_info->max_write_raid_5_6) - ctrl_info->max_write_raid_5_6 *= 1024; - else - ctrl_info->max_write_raid_5_6 = ~0; + + ctrl_info->max_write_raid_1_10_2drive = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_write_raid_1_10_2drive); + + ctrl_info->max_write_raid_1_10_3drive = + pqi_aio_limit_to_bytes( + &buffer->aio_subpage.max_write_raid_1_10_3drive); error: kfree(buffer); @@ -2387,9 +2395,13 @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info, case SA_RAID_0: break; case SA_RAID_1: - fallthrough; + if (rmd->is_write && (!ctrl_info->enable_r1_writes || + rmd->data_length > ctrl_info->max_write_raid_1_10_2drive)) + is_supported = false; + break; case SA_RAID_ADM: - if (rmd->is_write && !ctrl_info->enable_r1_writes) + if (rmd->is_write && (!ctrl_info->enable_r1_writes || + rmd->data_length > ctrl_info->max_write_raid_1_10_3drive)) is_supported = false; break; case SA_RAID_5: @@ -8136,6 +8148,8 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) ctrl_info->max_transfer_encrypted_nvme = PQI_DEFAULT_MAX_TRANSFER_ENCRYPTED_NVME; ctrl_info->max_write_raid_5_6 = PQI_DEFAULT_MAX_WRITE_RAID_5_6; + ctrl_info->max_write_raid_1_10_2drive = ~0; + ctrl_info->max_write_raid_1_10_3drive = ~0; return ctrl_info; } @@ -9565,7 +9579,7 @@ static void __attribute__((unused)) verify_structures(void) page_length) != 2); BUILD_BUG_ON(sizeof(struct bmic_sense_feature_io_page_aio_subpage) - != 14); + != 18); BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, header) != 0); BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, @@ -9582,6 +9596,10 @@ static void __attribute__((unused)) verify_structures(void) max_transfer_encrypted_nvme) != 10); BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, max_write_raid_5_6) != 12); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_write_raid_1_10_2drive) != 14); + BUILD_BUG_ON(offsetof(struct bmic_sense_feature_io_page_aio_subpage, + max_write_raid_1_10_3drive) != 16); BUILD_BUG_ON(PQI_ADMIN_IQ_NUM_ELEMENTS > 255); BUILD_BUG_ON(PQI_ADMIN_OQ_NUM_ELEMENTS > 255); From patchwork Fri Dec 4 23:01:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338626 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 11764C4361B for ; Fri, 4 Dec 2020 23:03:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D9B3222D01 for ; Fri, 4 Dec 2020 23:03:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727179AbgLDXDG (ORCPT ); Fri, 4 Dec 2020 18:03:06 -0500 Received: from esa1.microchip.iphmx.com ([68.232.147.91]:5002 "EHLO esa1.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDG (ORCPT ); Fri, 4 Dec 2020 18:03:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122985; x=1638658985; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZJHuAHuA39KgPLxn7KQtSeOXyftvbYd+tIZUinHUgcU=; b=Lcu5HunJJIJOTR4376k2TfVlhz6WSb7tfE2i/X5xXwnlPSkCrzH21QJo ZzwMrCN7Qzw9qXgJlRmmBz3D+PjvMi0+8SelK2otxjaThsxGh2XqLdtFf VTbjyiqsF4r6XSw9AN6CnDwvBCZZcner93AYjJdtNgbCH7XJUAE6ZyttJ iSQoBEB4fWKb6w8oYe0H1AeJPWAz2lbSlBuvMUPI6pGzK8ygZ7YBxe0D1 /afb2Ta2L+bUEyn6xjRArGl7CmOLfOq5bMZK466YifjwYcrLVWTX8U5JB rYFTP0mBZ3cX5WZLAZyWDRVXBebkRDolBZwVqdih2l3hLIHbP7nIXXhUX Q==; IronPort-SDR: E3Wl0I7h7wIWPIzKQGliINGJ67ySER+JkKEVbBJlKftfUTA8AOmW15AiqUUH534XkmR/OHrHA4 3wYdS+5Hjh2BmglHzBUtsGzTse+iwcsUmyoMRCxvQyLMmdbHS9CU9RNNw8mHG78zhgASrMhLSg 0tXIQ4iT+GxOQkfNTTNm/nNNB5qzfGI6adOvhAxf101P82oRfHMz4g7ucDM+rvrLV1WGxJExJe Zg+8AVmA6RoPd6ChYNISl2I0ZwdPKA+y7vfMQzUp4cqaDAsN0XF3BetD7HTprbWO6syEBE1yJA oQQ= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="106272993" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:41 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:37 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:37 -0700 Subject: [PATCH 08/25] smartpqi: add support for long firmware version From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:37 -0600 Message-ID: <160712289713.21372.11962145772698586911.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Add support for new "long" firmware version which requires minor driver changes to expose. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 14 ++++++++--- drivers/scsi/smartpqi/smartpqi_init.c | 42 ++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index eb23c3cf59c0..f33244def944 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1227,7 +1227,7 @@ struct pqi_event { struct pqi_ctrl_info { unsigned int ctrl_id; struct pci_dev *pci_dev; - char firmware_version[11]; + char firmware_version[32]; char serial_number[17]; char model[17]; char vendor[9]; @@ -1405,7 +1405,7 @@ enum pqi_ctrl_mode { struct bmic_identify_controller { u8 configured_logical_drive_count; __le32 configuration_signature; - u8 firmware_version[4]; + u8 firmware_version_short[4]; u8 reserved[145]; __le16 extended_logical_unit_count; u8 reserved1[34]; @@ -1413,11 +1413,17 @@ struct bmic_identify_controller { u8 reserved2[8]; u8 vendor_id[8]; u8 product_id[16]; - u8 reserved3[68]; + u8 reserved3[62]; + __le32 extra_controller_flags; + u8 reserved4[2]; u8 controller_mode; - u8 reserved4[32]; + u8 spare_part_number[32]; + u8 firmware_version_long[32]; }; +/* constants for extra_controller_flags field of bmic_identify_controller */ +#define BMIC_IDENTIFY_EXTRA_FLAGS_LONG_FW_VERSION_SUPPORTED 0x20000000 + struct bmic_sense_subsystem_info { u8 reserved[44]; u8 ctrl_serial_number[16]; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 34ff1b3679f1..15f07df91a8c 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -998,14 +998,12 @@ static void pqi_update_time_worker(struct work_struct *work) PQI_UPDATE_TIME_WORK_INTERVAL); } -static inline void pqi_schedule_update_time_worker( - struct pqi_ctrl_info *ctrl_info) +static inline void pqi_schedule_update_time_worker(struct pqi_ctrl_info *ctrl_info) { schedule_delayed_work(&ctrl_info->update_time_work, 0); } -static inline void pqi_cancel_update_time_worker( - struct pqi_ctrl_info *ctrl_info) +static inline void pqi_cancel_update_time_worker(struct pqi_ctrl_info *ctrl_info) { cancel_delayed_work_sync(&ctrl_info->update_time_work); } @@ -7176,13 +7174,23 @@ static int pqi_get_ctrl_product_details(struct pqi_ctrl_info *ctrl_info) if (rc) goto out; - memcpy(ctrl_info->firmware_version, identify->firmware_version, - sizeof(identify->firmware_version)); - ctrl_info->firmware_version[sizeof(identify->firmware_version)] = '\0'; - snprintf(ctrl_info->firmware_version + - strlen(ctrl_info->firmware_version), - sizeof(ctrl_info->firmware_version), - "-%u", get_unaligned_le16(&identify->firmware_build_number)); + if (get_unaligned_le32(&identify->extra_controller_flags) & + BMIC_IDENTIFY_EXTRA_FLAGS_LONG_FW_VERSION_SUPPORTED) { + memcpy(ctrl_info->firmware_version, + identify->firmware_version_long, + sizeof(identify->firmware_version_long)); + } else { + memcpy(ctrl_info->firmware_version, + identify->firmware_version_short, + sizeof(identify->firmware_version_short)); + ctrl_info->firmware_version + [sizeof(identify->firmware_version_short)] = '\0'; + snprintf(ctrl_info->firmware_version + + strlen(ctrl_info->firmware_version), + sizeof(ctrl_info->firmware_version), + "-%u", + get_unaligned_le16(&identify->firmware_build_number)); + } memcpy(ctrl_info->model, identify->product_id, sizeof(identify->product_id)); @@ -9538,13 +9546,23 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct bmic_identify_controller, configuration_signature) != 1); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, - firmware_version) != 5); + firmware_version_short) != 5); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, extended_logical_unit_count) != 154); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, firmware_build_number) != 190); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + vendor_id) != 200); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + product_id) != 208); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + extra_controller_flags) != 286); BUILD_BUG_ON(offsetof(struct bmic_identify_controller, controller_mode) != 292); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + spare_part_number) != 293); + BUILD_BUG_ON(offsetof(struct bmic_identify_controller, + firmware_version_long) != 325); BUILD_BUG_ON(offsetof(struct bmic_identify_physical_device, phys_bay_in_box) != 115); From patchwork Fri Dec 4 23:01:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338140 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E1CB9C433FE for ; Fri, 4 Dec 2020 23:02:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A238122D01 for ; Fri, 4 Dec 2020 23:02:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726920AbgLDXCv (ORCPT ); Fri, 4 Dec 2020 18:02:51 -0500 Received: from esa6.microchip.iphmx.com ([216.71.154.253]:21357 "EHLO esa6.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726296AbgLDXCv (ORCPT ); Fri, 4 Dec 2020 18:02:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122969; x=1638658969; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zATmGYzTr/c20Cousm9+QT8PROh+O+5lwsKMTNpKrqU=; b=qhHBVW0sbbjLoKOYWJJTRq+ID6GeBu2GcaehL2kGo7B8FSMfWojHlYey cuDJ5rZZ+EHv+qJRqJ2+uZAZA0PmnIc/SuXaTPBiyhIbs0LETr/t4fKsZ WnxG37/7VG3are/hUp1UPJTO5zLghky5Gno+kKqko9DONrBvSRCb7l7m7 dr2uqSsbVK37zR0cq5OaxT+/dNMMc3ty8XiZNzc7CG3HtC5E8eqiwl2U2 soi3A07Lsd1YnH0u2SjSTOIIblmJJF5eFNiI569zyy9vQhmKUBNoIxNKO +NQDJ5ESqUQFdekcZoIGwsHR0tCDMTce5/0JTL2dqb6Q6W4zVYPx5gUaV w==; IronPort-SDR: W1QthwC5dNBDtFFixKCjDT+ef7WTlbGvHUNPXezhZgoHjwu1O/qT0pjyBtfqQ41rJ9xsAfFmQj 4PCMe8b75H4B+ANZUNUB30c0S4bACcPU6I91CQJ9FqCURICV6FatjfMZ70cZBRgE6nJVPVo1fI zkNoLLBLVtL8QfDrNU5530qOoCPUbY4PpEPdyotisiAre2bkf6bt+bKbsWCR+FVmhJ/w4/7JTP tdRD3+tmYWwPCzTyB+NqqBbCI/OgQykqSNDxGsWzHqvlcBURnnC8X4Qb1ii79OlUyAQZ//976F M/0= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="36193035" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:44 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:43 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:43 -0700 Subject: [PATCH 09/25] smartpqi: align code with oob driver From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:42 -0600 Message-ID: <160712290293.21372.10543821844870220439.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Non-functional changes. * Reduce differences between out-of-box driver and kernel.org driver. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 54 +++--- drivers/scsi/smartpqi/smartpqi_init.c | 232 +++++++++--------------- drivers/scsi/smartpqi/smartpqi_sas_transport.c | 10 + drivers/scsi/smartpqi/smartpqi_sis.c | 4 4 files changed, 119 insertions(+), 181 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index f33244def944..a5e271dd2742 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -129,7 +129,7 @@ struct pqi_iu_header { __le16 iu_length; /* in bytes - does not include the length */ /* of this header */ __le16 response_queue_id; /* specifies the OQ where the */ - /* response IU is to be delivered */ + /* response IU is to be delivered */ u8 work_area[2]; /* reserved for driver use */ }; @@ -281,8 +281,7 @@ struct pqi_raid_path_request { u8 cdb[16]; u8 reserved6[12]; __le32 timeout; - struct pqi_sg_descriptor - sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; struct pqi_aio_path_request { @@ -309,8 +308,7 @@ struct pqi_aio_path_request { u8 cdb_length; u8 lun_number[8]; u8 reserved4[4]; - struct pqi_sg_descriptor - sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; + struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; }; #define PQI_RAID1_NVME_XFER_LIMIT (32 * 1024) /* 32 KiB */ @@ -421,7 +419,7 @@ struct pqi_event_config { #define PQI_EVENT_OFA_MEMORY_ALLOCATION 0x0 #define PQI_EVENT_OFA_QUIESCE 0x1 -#define PQI_EVENT_OFA_CANCELLED 0x2 +#define PQI_EVENT_OFA_CANCELED 0x2 struct pqi_event_response { struct pqi_iu_header header; @@ -726,7 +724,7 @@ struct pqi_admin_queues_aligned { struct pqi_admin_queues { void *iq_element_array; void *oq_element_array; - pqi_index_t *iq_ci; + pqi_index_t __iomem *iq_ci; pqi_index_t __iomem *oq_pi; dma_addr_t iq_element_array_bus_addr; dma_addr_t oq_element_array_bus_addr; @@ -751,8 +749,8 @@ struct pqi_queue_group { dma_addr_t oq_element_array_bus_addr; __le32 __iomem *iq_pi[2]; pqi_index_t iq_pi_copy[2]; - pqi_index_t __iomem *iq_ci[2]; - pqi_index_t __iomem *oq_pi; + pqi_index_t __iomem *iq_ci[2]; + pqi_index_t __iomem *oq_pi; dma_addr_t iq_ci_bus_addr[2]; dma_addr_t oq_pi_bus_addr; __le32 __iomem *oq_ci; @@ -765,7 +763,7 @@ struct pqi_event_queue { u16 oq_id; u16 int_msg_num; void *oq_element_array; - pqi_index_t __iomem *oq_pi; + pqi_index_t __iomem *oq_pi; dma_addr_t oq_element_array_bus_addr; dma_addr_t oq_pi_bus_addr; __le32 __iomem *oq_ci; @@ -836,22 +834,22 @@ struct pqi_config_table_firmware_features { /* __le16 host_max_known_feature; */ }; -#define PQI_FIRMWARE_FEATURE_OFA 0 -#define PQI_FIRMWARE_FEATURE_SMP 1 -#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2 -#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3 -#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4 -#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5 -#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6 -#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7 -#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8 -#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9 -#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10 -#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 -#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 -#define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 -#define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 -#define PQI_FIRMWARE_FEATURE_MAXIMUM 14 +#define PQI_FIRMWARE_FEATURE_OFA 0 +#define PQI_FIRMWARE_FEATURE_SMP 1 +#define PQI_FIRMWARE_FEATURE_MAX_KNOWN_FEATURE 2 +#define PQI_FIRMWARE_FEATURE_RAID_0_READ_BYPASS 3 +#define PQI_FIRMWARE_FEATURE_RAID_1_READ_BYPASS 4 +#define PQI_FIRMWARE_FEATURE_RAID_5_READ_BYPASS 5 +#define PQI_FIRMWARE_FEATURE_RAID_6_READ_BYPASS 6 +#define PQI_FIRMWARE_FEATURE_RAID_0_WRITE_BYPASS 7 +#define PQI_FIRMWARE_FEATURE_RAID_1_WRITE_BYPASS 8 +#define PQI_FIRMWARE_FEATURE_RAID_5_WRITE_BYPASS 9 +#define PQI_FIRMWARE_FEATURE_RAID_6_WRITE_BYPASS 10 +#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11 +#define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 +#define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 +#define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 14 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -1292,8 +1290,8 @@ struct pqi_ctrl_info { u8 pqi_mode_enabled : 1; u8 pqi_reset_quiesce_supported : 1; u8 soft_reset_handshake_supported : 1; - u8 raid_iu_timeout_supported: 1; - u8 tmf_iu_timeout_supported: 1; + u8 raid_iu_timeout_supported : 1; + u8 tmf_iu_timeout_supported : 1; u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 15f07df91a8c..ddd2ed8f4283 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -156,14 +156,12 @@ MODULE_PARM_DESC(lockup_action, "Action to take when controller locked up.\n" static int pqi_expose_ld_first; module_param_named(expose_ld_first, pqi_expose_ld_first, int, 0644); -MODULE_PARM_DESC(expose_ld_first, - "Expose logical drives before physical drives."); +MODULE_PARM_DESC(expose_ld_first, "Expose logical drives before physical drives."); static int pqi_hide_vsep; module_param_named(hide_vsep, pqi_hide_vsep, int, 0644); -MODULE_PARM_DESC(hide_vsep, - "Hide the virtual SEP for direct attached drives."); +MODULE_PARM_DESC(hide_vsep, "Hide the virtual SEP for direct attached drives."); static char *raid_levels[] = { "RAID-0", @@ -236,8 +234,7 @@ static inline bool pqi_is_hba_lunid(u8 *scsi3addr) return pqi_scsi3addr_equal(scsi3addr, RAID_CTLR_LUNID); } -static inline enum pqi_ctrl_mode pqi_get_ctrl_mode( - struct pqi_ctrl_info *ctrl_info) +static inline enum pqi_ctrl_mode pqi_get_ctrl_mode(struct pqi_ctrl_info *ctrl_info) { return sis_read_driver_scratch(ctrl_info); } @@ -368,8 +365,8 @@ static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info) return ctrl_info->in_shutdown; } -static inline void pqi_schedule_rescan_worker_with_delay( - struct pqi_ctrl_info *ctrl_info, unsigned long delay) +static inline void pqi_schedule_rescan_worker_with_delay(struct pqi_ctrl_info *ctrl_info, + unsigned long delay) { if (pqi_ctrl_offline(ctrl_info)) return; @@ -386,8 +383,7 @@ static inline void pqi_schedule_rescan_worker(struct pqi_ctrl_info *ctrl_info) #define PQI_RESCAN_WORK_DELAY (10 * PQI_HZ) -static inline void pqi_schedule_rescan_worker_delayed( - struct pqi_ctrl_info *ctrl_info) +static inline void pqi_schedule_rescan_worker_delayed(struct pqi_ctrl_info *ctrl_info) { pqi_schedule_rescan_worker_with_delay(ctrl_info, PQI_RESCAN_WORK_DELAY); } @@ -616,9 +612,8 @@ static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, struct pqi_raid_path_request request; enum dma_data_direction dir; - rc = pqi_build_raid_path_request(ctrl_info, &request, - cmd, scsi3addr, buffer, - buffer_length, vpd_page, &dir); + rc = pqi_build_raid_path_request(ctrl_info, &request, cmd, scsi3addr, + buffer, buffer_length, vpd_page, &dir); if (rc) return rc; @@ -738,17 +733,15 @@ static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) if (!buffer) return -ENOMEM; - rc = pqi_build_raid_path_request(ctrl_info, &request, - BMIC_SENSE_FEATURE, RAID_CTLR_LUNID, buffer, - sizeof(*buffer), 0, &dir); + rc = pqi_build_raid_path_request(ctrl_info, &request, BMIC_SENSE_FEATURE, RAID_CTLR_LUNID, + buffer, sizeof(*buffer), 0, &dir); if (rc) goto error; request.cdb[2] = BMIC_SENSE_FEATURE_IO_PAGE; request.cdb[3] = BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL, NO_TIMEOUT); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -1008,15 +1001,13 @@ static inline void pqi_cancel_update_time_worker(struct pqi_ctrl_info *ctrl_info cancel_delayed_work_sync(&ctrl_info->update_time_work); } -static inline int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, - void *buffer, size_t buffer_length) +static inline int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, void *buffer, + size_t buffer_length) { - return pqi_send_ctrl_raid_request(ctrl_info, cmd, buffer, - buffer_length); + return pqi_send_ctrl_raid_request(ctrl_info, cmd, buffer, buffer_length); } -static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, - void **buffer) +static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, void **buffer) { int rc; size_t lun_list_length; @@ -1031,8 +1022,7 @@ static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, goto out; } - rc = pqi_report_luns(ctrl_info, cmd, report_lun_header, - sizeof(*report_lun_header)); + rc = pqi_report_luns(ctrl_info, cmd, report_lun_header, sizeof(*report_lun_header)); if (rc) goto out; @@ -1056,8 +1046,8 @@ static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, if (rc) goto out; - new_lun_list_length = get_unaligned_be32( - &((struct report_lun_header *)lun_data)->list_length); + new_lun_list_length = + get_unaligned_be32(&((struct report_lun_header *)lun_data)->list_length); if (new_lun_list_length > lun_list_length) { lun_list_length = new_lun_list_length; @@ -1078,15 +1068,12 @@ static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, return rc; } -static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, - void **buffer) +static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, void **buffer) { - return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_PHYS, - buffer); + return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_PHYS, buffer); } -static inline int pqi_report_logical_luns(struct pqi_ctrl_info *ctrl_info, - void **buffer) +static inline int pqi_report_logical_luns(struct pqi_ctrl_info *ctrl_info, void **buffer) { return pqi_report_phys_logical_luns(ctrl_info, CISS_REPORT_LOG, buffer); } @@ -1309,7 +1296,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, if (get_unaligned_le32(&raid_map->structure_size) != raid_map_size) { dev_warn(&ctrl_info->pci_dev->dev, - "Requested %d bytes, received %d bytes", + "requested %u bytes, received %u bytes\n", raid_map_size, get_unaligned_le32(&raid_map->structure_size)); goto error; @@ -1666,8 +1653,7 @@ static int pqi_add_device(struct pqi_ctrl_info *ctrl_info, #define PQI_PENDING_IO_TIMEOUT_SECS 20 -static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device) +static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { int rc; @@ -1701,8 +1687,7 @@ static struct pqi_scsi_dev *pqi_find_scsi_dev(struct pqi_ctrl_info *ctrl_info, return NULL; } -static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, - struct pqi_scsi_dev *dev2) +static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, struct pqi_scsi_dev *dev2) { if (dev1->is_physical_device != dev2->is_physical_device) return false; @@ -1710,8 +1695,7 @@ static inline bool pqi_device_equal(struct pqi_scsi_dev *dev1, if (dev1->is_physical_device) return dev1->wwid == dev2->wwid; - return memcmp(dev1->volume_id, dev2->volume_id, - sizeof(dev1->volume_id)) == 0; + return memcmp(dev1->volume_id, dev2->volume_id, sizeof(dev1->volume_id)) == 0; } enum pqi_find_result { @@ -1850,8 +1834,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, existing_device->bay = new_device->bay; existing_device->box_index = new_device->box_index; existing_device->phys_box_on_bus = new_device->phys_box_on_bus; - existing_device->phy_connected_dev_type = - new_device->phy_connected_dev_type; + existing_device->phy_connected_dev_type = new_device->phy_connected_dev_type; memcpy(existing_device->box, new_device->box, sizeof(existing_device->box)); memcpy(existing_device->phys_connector, new_device->phys_connector, @@ -2054,7 +2037,7 @@ static inline bool pqi_is_supported_device(struct pqi_scsi_dev *device) */ if (device->device_type == SA_DEVICE_TYPE_CONTROLLER && !pqi_is_hba_lunid(device->scsi3addr)) - return false; + return false; return true; } @@ -2087,8 +2070,7 @@ static inline bool pqi_is_device_with_sas_address(struct pqi_scsi_dev *device) static inline bool pqi_expose_device(struct pqi_scsi_dev *device) { - return !device->is_physical_device || - !pqi_skip_device(device->scsi3addr); + return !device->is_physical_device || !pqi_skip_device(device->scsi3addr); } static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) @@ -2152,11 +2134,8 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) for (i = num_physicals - 1; i >= 0; i--) { phys_lun_ext_entry = &physdev_list->lun_entries[i]; - if (CISS_GET_DRIVE_NUMBER( - phys_lun_ext_entry->lunid) == - PQI_VSEP_CISS_BTL) { - pqi_mask_device( - phys_lun_ext_entry->lunid); + if (CISS_GET_DRIVE_NUMBER(phys_lun_ext_entry->lunid) == PQI_VSEP_CISS_BTL) { + pqi_mask_device(phys_lun_ext_entry->lunid); break; } } @@ -2246,8 +2225,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if (device->is_physical_device) dev_warn(&ctrl_info->pci_dev->dev, "obtaining device info failed, skipping physical device %016llx\n", - get_unaligned_be64( - &phys_lun_ext_entry->wwid)); + get_unaligned_be64(&phys_lun_ext_entry->wwid)); else dev_warn(&ctrl_info->pci_dev->dev, "obtaining device info failed, skipping logical device %08x%08x\n", @@ -2264,9 +2242,9 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) if ((phys_lun_ext_entry->device_flags & CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) && phys_lun_ext_entry->aio_handle) { - device->aio_enabled = true; - device->aio_handle = - phys_lun_ext_entry->aio_handle; + device->aio_enabled = true; + device->aio_handle = + phys_lun_ext_entry->aio_handle; } } else { memcpy(device->volume_id, log_lun_ext_entry->volume_id, @@ -2687,12 +2665,10 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, pqi_set_aio_cdb(&rmd); - if (get_unaligned_le16(&raid_map->flags) & - RAID_MAP_ENCRYPTION_ENABLED) { + if (get_unaligned_le16(&raid_map->flags) & RAID_MAP_ENCRYPTION_ENABLED) { if (rmd.data_length > device->max_transfer_encrypted) return PQI_RAID_BYPASS_INELIGIBLE; - pqi_set_encryption_info(&encryption_info, raid_map, - rmd.first_block); + pqi_set_encryption_info(&encryption_info, raid_map, rmd.first_block); encryption_info_ptr = &encryption_info; } else { encryption_info_ptr = NULL; @@ -2707,7 +2683,7 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, case SA_RAID_5: case SA_RAID_6: return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group, - encryption_info_ptr, device, &rmd); + encryption_info_ptr, device, &rmd); } } @@ -3093,8 +3069,7 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue case PQI_RESPONSE_IU_VENDOR_GENERAL: io_request->status = get_unaligned_le16( - &((struct pqi_vendor_general_response *) - response)->status); + &((struct pqi_vendor_general_response *)response)->status); break; case PQI_RESPONSE_IU_TASK_MANAGEMENT: io_request->status = @@ -3306,7 +3281,7 @@ static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, pqi_ofa_setup_host_buffer(ctrl_info, le32_to_cpu(event->ofa_bytes_requested)); pqi_ofa_host_memory_update(ctrl_info); - } else if (event_id == PQI_EVENT_OFA_CANCELLED) { + } else if (event_id == PQI_EVENT_OFA_CANCELED) { pqi_ofa_free_host_buffer(ctrl_info); pqi_acknowledge_event(ctrl_info, event); dev_info(&ctrl_info->pci_dev->dev, @@ -3356,8 +3331,7 @@ static void pqi_heartbeat_timer_handler(struct timer_list *t) { int num_interrupts; u32 heartbeat_count; - struct pqi_ctrl_info *ctrl_info = from_timer(ctrl_info, t, - heartbeat_timer); + struct pqi_ctrl_info *ctrl_info = from_timer(ctrl_info, t, heartbeat_timer); pqi_check_ctrl_health(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) @@ -3430,7 +3404,7 @@ static void pqi_ofa_capture_event_payload(struct pqi_event *event, if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { event->ofa_bytes_requested = response->data.ofa_memory_allocation.bytes_requested; - } else if (event_id == PQI_EVENT_OFA_CANCELLED) { + } else if (event_id == PQI_EVENT_OFA_CANCELED) { event->ofa_cancel_reason = response->data.ofa_cancelled.reason; } @@ -3572,8 +3546,7 @@ static inline bool pqi_is_valid_irq(struct pqi_ctrl_info *ctrl_info) valid_irq = true; break; case IRQ_MODE_INTX: - intx_status = - readl(&ctrl_info->pqi_registers->legacy_intx_status); + intx_status = readl(&ctrl_info->pqi_registers->legacy_intx_status); if (intx_status & PQI_LEGACY_INTX_PENDING) valid_irq = true; else @@ -3894,7 +3867,8 @@ static int pqi_alloc_admin_queues(struct pqi_ctrl_info *ctrl_info) &admin_queues_aligned->iq_element_array; admin_queues->oq_element_array = &admin_queues_aligned->oq_element_array; - admin_queues->iq_ci = &admin_queues_aligned->iq_ci; + admin_queues->iq_ci = + (pqi_index_t __iomem *)&admin_queues_aligned->iq_ci; admin_queues->oq_pi = (pqi_index_t __iomem *)&admin_queues_aligned->oq_pi; @@ -3908,8 +3882,8 @@ static int pqi_alloc_admin_queues(struct pqi_ctrl_info *ctrl_info) ctrl_info->admin_queue_memory_base); admin_queues->iq_ci_bus_addr = ctrl_info->admin_queue_memory_base_dma_handle + - ((void *)admin_queues->iq_ci - - ctrl_info->admin_queue_memory_base); + ((void __iomem *)admin_queues->iq_ci - + (void __iomem *)ctrl_info->admin_queue_memory_base); admin_queues->oq_pi_bus_addr = ctrl_info->admin_queue_memory_base_dma_handle + ((void __iomem *)admin_queues->oq_pi - @@ -3945,6 +3919,7 @@ static int pqi_create_admin_queues(struct pqi_ctrl_info *ctrl_info) (PQI_ADMIN_OQ_NUM_ELEMENTS << 8) | (admin_queues->int_msg_num << 16); writel(reg, &pqi_registers->admin_iq_num_elements); + writel(PQI_CREATE_ADMIN_QUEUE_PAIR, &pqi_registers->function_and_status_code); @@ -4241,8 +4216,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, io_request->io_complete_callback = pqi_raid_synchronous_complete; io_request->context = &wait; - pqi_start_io(ctrl_info, - &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, + pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); pqi_ctrl_unbusy(ctrl_info); @@ -4260,13 +4234,11 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, if (error_info) { if (io_request->error_info) - memcpy(error_info, io_request->error_info, - sizeof(*error_info)); + memcpy(error_info, io_request->error_info, sizeof(*error_info)); else memset(error_info, 0, sizeof(*error_info)); } else if (rc == 0 && io_request->error_info) { - rc = pqi_process_raid_io_error_synchronous( - io_request->error_info); + rc = pqi_process_raid_io_error_synchronous(io_request->error_info); } pqi_free_io_request(io_request); @@ -4344,8 +4316,7 @@ static int pqi_report_device_capability(struct pqi_ctrl_info *ctrl_info) if (rc) goto out; - rc = pqi_submit_admin_request_synchronous(ctrl_info, &request, - &response); + rc = pqi_submit_admin_request_synchronous(ctrl_info, &request, &response); pqi_pci_unmap(ctrl_info->pci_dev, &request.data.report_device_capability.sg_descriptor, 1, @@ -4694,7 +4665,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, event_descriptor = &event_config->descriptors[i]; if (enable_events && pqi_is_supported_event(event_descriptor->event_type)) - put_unaligned_le16(ctrl_info->event_queue.oq_id, + put_unaligned_le16(ctrl_info->event_queue.oq_id, &event_descriptor->oq_id); else put_unaligned_le16(0, &event_descriptor->oq_id); @@ -4769,7 +4740,6 @@ static void pqi_free_all_io_requests(struct pqi_ctrl_info *ctrl_info) static inline int pqi_alloc_error_buffer(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->error_buffer = dma_alloc_coherent(&ctrl_info->pci_dev->dev, ctrl_info->error_buffer_length, &ctrl_info->error_buffer_dma_handle, @@ -4789,9 +4759,8 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) struct device *dev; struct pqi_io_request *io_request; - ctrl_info->io_request_pool = - kcalloc(ctrl_info->max_io_slots, - sizeof(ctrl_info->io_request_pool[0]), GFP_KERNEL); + ctrl_info->io_request_pool = kcalloc(ctrl_info->max_io_slots, + sizeof(ctrl_info->io_request_pool[0]), GFP_KERNEL); if (!ctrl_info->io_request_pool) { dev_err(&ctrl_info->pci_dev->dev, @@ -4804,8 +4773,7 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) io_request = ctrl_info->io_request_pool; for (i = 0; i < ctrl_info->max_io_slots; i++) { - io_request->iu = - kmalloc(ctrl_info->max_inbound_iu_length, GFP_KERNEL); + io_request->iu = kmalloc(ctrl_info->max_inbound_iu_length, GFP_KERNEL); if (!io_request->iu) { dev_err(&ctrl_info->pci_dev->dev, @@ -4825,8 +4793,7 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) io_request->index = i; io_request->sg_chain_buffer = sg_chain_buffer; - io_request->sg_chain_buffer_dma_handle = - sg_chain_buffer_dma_handle; + io_request->sg_chain_buffer_dma_handle = sg_chain_buffer_dma_handle; io_request++; } @@ -4941,8 +4908,8 @@ static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info) PQI_MAX_EMBEDDED_R56_SG_DESCRIPTORS; } -static inline void pqi_set_sg_descriptor( - struct pqi_sg_descriptor *sg_descriptor, struct scatterlist *sg) +static inline void pqi_set_sg_descriptor(struct pqi_sg_descriptor *sg_descriptor, + struct scatterlist *sg) { u64 address = (u64)sg_dma_address(sg); unsigned int length = sg_dma_len(sg); @@ -5164,16 +5131,14 @@ static int pqi_raid_submit_scsi_cmd_with_io_request( io_request->scmd = scmd; request = io_request->iu; - memset(request, 0, - offsetof(struct pqi_raid_path_request, sg_descriptors)); + memset(request, 0, offsetof(struct pqi_raid_path_request, sg_descriptors)); request->header.iu_type = PQI_REQUEST_IU_RAID_PATH_IO; put_unaligned_le32(scsi_bufflen(scmd), &request->buffer_length); request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE; put_unaligned_le16(io_request->index, &request->request_id); request->error_index = request->request_id; - memcpy(request->lun_number, device->scsi3addr, - sizeof(request->lun_number)); + memcpy(request->lun_number, device->scsi3addr, sizeof(request->lun_number)); cdb_length = min_t(size_t, scmd->cmd_len, sizeof(request->cdb)); memcpy(request->cdb, scmd->cmnd, cdb_length); @@ -5183,30 +5148,20 @@ static int pqi_raid_submit_scsi_cmd_with_io_request( case 10: case 12: case 16: - /* No bytes in the Additional CDB bytes field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_0; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_0; break; case 20: - /* 4 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_4; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_4; break; case 24: - /* 8 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_8; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_8; break; case 28: - /* 12 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_12; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_12; break; case 32: default: - /* 16 bytes in the Additional cdb field */ - request->additional_cdb_bytes_usage = - SOP_ADDITIONAL_CDB_BYTES_16; + request->additional_cdb_bytes_usage = SOP_ADDITIONAL_CDB_BYTES_16; break; } @@ -5451,8 +5406,7 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, io_request->raid_bypass = raid_bypass; request = io_request->iu; - memset(request, 0, - offsetof(struct pqi_raid_path_request, sg_descriptors)); + memset(request, 0, offsetof(struct pqi_raid_path_request, sg_descriptors)); request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_IO; put_unaligned_le32(aio_handle, &request->nexus_id); @@ -5510,7 +5464,6 @@ static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, struct pqi_scsi_dev_raid_map_data *rmd) - { int rc; struct pqi_io_request *io_request; @@ -5525,7 +5478,6 @@ static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, memset(r1_request, 0, offsetof(struct pqi_aio_r1_path_request, sg_descriptors)); r1_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID1_IO; - put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r1_request->volume_id); r1_request->num_drives = rmd->num_it_nexus_entries; put_unaligned_le32(rmd->it_nexus[0], &r1_request->it_nexus_1); @@ -5854,6 +5806,7 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, list_for_each_entry_safe(io_request, next, &queue_group->request_list[path], request_list_entry) { + scmd = io_request->scmd; if (!scmd) continue; @@ -6047,8 +6000,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, put_unaligned_le16(PQI_LUN_RESET_TIMEOUT_SECS, &request->timeout); - pqi_start_io(ctrl_info, - &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, + pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); rc = pqi_wait_for_lun_reset_completion(ctrl_info, device, &wait); @@ -6738,7 +6690,8 @@ static ssize_t pqi_unique_id_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); return snprintf(buffer, PAGE_SIZE, - "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", + "%02X%02X%02X%02X%02X%02X%02X%02X" + "%02X%02X%02X%02X%02X%02X%02X%02X\n", unique_id[0], unique_id[1], unique_id[2], unique_id[3], unique_id[4], unique_id[5], unique_id[6], unique_id[7], unique_id[8], unique_id[9], unique_id[10], unique_id[11], @@ -7038,17 +6991,13 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) rc = scsi_add_host(shost, &ctrl_info->pci_dev->dev); if (rc) { - dev_err(&ctrl_info->pci_dev->dev, - "scsi_add_host failed for controller %u\n", - ctrl_info->ctrl_id); + dev_err(&ctrl_info->pci_dev->dev, "scsi_add_host failed\n"); goto free_host; } rc = pqi_add_sas_host(shost, ctrl_info); if (rc) { - dev_err(&ctrl_info->pci_dev->dev, - "add SAS host failed for controller %u\n", - ctrl_info->ctrl_id); + dev_err(&ctrl_info->pci_dev->dev, "add SAS host failed\n"); goto remove_host; } @@ -7118,8 +7067,7 @@ static int pqi_reset(struct pqi_ctrl_info *ctrl_info) rc = sis_pqi_reset_quiesce(ctrl_info); if (rc) { dev_err(&ctrl_info->pci_dev->dev, - "PQI reset failed during quiesce with error %d\n", - rc); + "PQI reset failed during quiesce with error %d\n", rc); return rc; } } @@ -7359,12 +7307,10 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, firmware_feature->enabled; break; case PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT: - ctrl_info->raid_iu_timeout_supported = - firmware_feature->enabled; + ctrl_info->raid_iu_timeout_supported = firmware_feature->enabled; break; case PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT: - ctrl_info->tmf_iu_timeout_supported = - firmware_feature->enabled; + ctrl_info->tmf_iu_timeout_supported = firmware_feature->enabled; break; } @@ -7509,7 +7455,7 @@ static void pqi_process_firmware_features( if (pqi_is_firmware_feature_enabled(firmware_features, firmware_features_iomem_addr, pqi_firmware_features[i].feature_bit)) { - pqi_firmware_features[i].enabled = true; + pqi_firmware_features[i].enabled = true; } pqi_firmware_feature_update(ctrl_info, &pqi_firmware_features[i]); @@ -7559,21 +7505,18 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) * Copy the config table contents from I/O memory space into the * temporary buffer. */ - table_iomem_addr = ctrl_info->iomem_base + - ctrl_info->config_table_offset; + table_iomem_addr = ctrl_info->iomem_base + ctrl_info->config_table_offset; memcpy_fromio(config_table, table_iomem_addr, table_length); section_info.ctrl_info = ctrl_info; - section_offset = - get_unaligned_le32(&config_table->first_section_offset); + section_offset = get_unaligned_le32(&config_table->first_section_offset); while (section_offset) { section = (void *)config_table + section_offset; section_info.section = section; section_info.section_offset = section_offset; - section_info.section_iomem_addr = - table_iomem_addr + section_offset; + section_info.section_iomem_addr = table_iomem_addr + section_offset; switch (get_unaligned_le16(§ion->section_id)) { case PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES: @@ -7587,8 +7530,7 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) ctrl_info->heartbeat_counter = table_iomem_addr + section_offset + - offsetof( - struct pqi_config_table_heartbeat, + offsetof(struct pqi_config_table_heartbeat, heartbeat_counter); break; case PQI_CONFIG_TABLE_SECTION_SOFT_RESET: @@ -7600,8 +7542,7 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) break; } - section_offset = - get_unaligned_le16(§ion->next_section_offset); + section_offset = get_unaligned_le16(§ion->next_section_offset); } kfree(config_table); @@ -7700,12 +7641,12 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) if (reset_devices) { if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS_KDUMP) - ctrl_info->max_outstanding_requests = + ctrl_info->max_outstanding_requests = PQI_MAX_OUTSTANDING_REQUESTS_KDUMP; } else { if (ctrl_info->max_outstanding_requests > PQI_MAX_OUTSTANDING_REQUESTS) - ctrl_info->max_outstanding_requests = + ctrl_info->max_outstanding_requests = PQI_MAX_OUTSTANDING_REQUESTS; } @@ -8022,8 +7963,7 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) return 0; } -static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev, - u16 timeout) +static inline int pqi_set_pcie_completion_timeout(struct pci_dev *pci_dev, u16 timeout) { int rc; @@ -8275,8 +8215,8 @@ static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, break; mem_descriptor = &ofap->sg_descriptor[i]; - put_unaligned_le64 ((u64) dma_handle, &mem_descriptor->address); - put_unaligned_le32 (chunk_size, &mem_descriptor->length); + put_unaligned_le64((u64)dma_handle, &mem_descriptor->address); + put_unaligned_le32(chunk_size, &mem_descriptor->length); } if (!size || size < total_size) diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index c9b00b3368d7..77923c6ec2c6 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -107,8 +107,7 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, static struct sas_rphy *pqi_sas_rphy_alloc(struct pqi_sas_port *pqi_sas_port) { - if (pqi_sas_port->device && - pqi_sas_port->device->is_expander_smp_device) + if (pqi_sas_port->device && pqi_sas_port->device->is_expander_smp_device) return sas_expander_alloc(pqi_sas_port->port, SAS_FANOUT_EXPANDER_DEVICE); @@ -161,7 +160,7 @@ static void pqi_free_sas_port(struct pqi_sas_port *pqi_sas_port) list_for_each_entry_safe(pqi_sas_phy, next, &pqi_sas_port->phy_list_head, phy_list_entry) - pqi_free_sas_phy(pqi_sas_phy); + pqi_free_sas_phy(pqi_sas_phy); sas_port_delete(pqi_sas_port->port); list_del(&pqi_sas_port->port_list_entry); @@ -191,7 +190,7 @@ static void pqi_free_sas_node(struct pqi_sas_node *pqi_sas_node) list_for_each_entry_safe(pqi_sas_port, next, &pqi_sas_node->port_list_head, port_list_entry) - pqi_free_sas_port(pqi_sas_port); + pqi_free_sas_port(pqi_sas_port); kfree(pqi_sas_node); } @@ -498,7 +497,7 @@ static unsigned int pqi_build_sas_smp_handler_reply( job->reply_len = le16_to_cpu(error_info->sense_data_length); memcpy(job->reply, error_info->data, - le16_to_cpu(error_info->sense_data_length)); + le16_to_cpu(error_info->sense_data_length)); return job->reply_payload.payload_len - get_unaligned_le32(&error_info->data_in_transferred); @@ -547,6 +546,7 @@ void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, goto out; reslen = pqi_build_sas_smp_handler_reply(smp_buf, job, &error_info); + out: bsg_job_done(job, rc, reslen); } diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c index f0199bd87dd1..c954620628e0 100644 --- a/drivers/scsi/smartpqi/smartpqi_sis.c +++ b/drivers/scsi/smartpqi/smartpqi_sis.c @@ -71,7 +71,7 @@ struct sis_base_struct { /* error response data */ __le32 error_buffer_element_length; /* length of each PQI error */ /* response buffer element */ - /* in bytes */ + /* in bytes */ __le32 error_buffer_num_elements; /* total number of PQI error */ /* response buffers available */ }; @@ -146,7 +146,7 @@ bool sis_is_firmware_running(struct pqi_ctrl_info *ctrl_info) bool sis_is_kernel_up(struct pqi_ctrl_info *ctrl_info) { return readl(&ctrl_info->registers->sis_firmware_status) & - SIS_CTRL_KERNEL_UP; + SIS_CTRL_KERNEL_UP; } u32 sis_get_product_id(struct pqi_ctrl_info *ctrl_info) From patchwork Fri Dec 4 23:01:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338625 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DEB80C4361A for ; Fri, 4 Dec 2020 23:03:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B45E422C9E for ; Fri, 4 Dec 2020 23:03:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727219AbgLDXDJ (ORCPT ); Fri, 4 Dec 2020 18:03:09 -0500 Received: from esa1.microchip.iphmx.com ([68.232.147.91]:4901 "EHLO esa1.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDI (ORCPT ); Fri, 4 Dec 2020 18:03:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122987; x=1638658987; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yTJ/yR/sJyPKxTtb8oiP0CyUtZwvhCJcfxTURsmMWxU=; b=yNVhiyiA0faqCVQZq9O7Gd3xF7BgAISfNyazoQbxrLqq3fIVcwX4XEz2 rL9i/UldGaBVbIGo1YGH3Jkx+bDpUtE++C/Q67ntUlhpos6JD9cWkIpor Izzf1DKJawblTo15nBT5EzN4l0NjGd50CS8t/EbeOT03oaIpM7kyNno5I 8VHZwIGObByjOAvPp+kasPLIBEOZJv7vZLo/adw5KYHH9SJRur1Ro9KAT f6HRORlraXAxCVIVJxwz5rfHJ0enueAnafwThO++1EImwrcjU2tOd/Qtv 2rL2P+cR27rSbHVx4Tik+dN6Vry9ymlG1wxYzi7qip/RtmRwwVerR3Kwd g==; IronPort-SDR: 0r4jHZKo7FqxRfqziLbMpzadbIhIrIgloN7dJPE+FFrBTGnw0DOfGDbtVsyoqGQ6s1/GWM/h+J NzQ8TV6ghnBalcRVRn65CPYlBdTfnp8aJp7H0fEdQnLd5Px4kR8sNcUmxJGv0xrA5tx6G+KuBJ j60//BM7EVtsZ9atMl/u1aXSRT3s84xA1IL4dO8q2x1BpvEPRhR5JNGyp/5Bm3WSHmymyWXIX3 mMwhsQlRy3Kypt5eFE4o1eAB5NjwH1O5FeyIwLNEJbfp/evRODqpZAPAlXuziH2rxUpKp/O7sk +4o= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="106273061" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:50 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:49 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:48 -0700 Subject: [PATCH 10/25] smartpqi: add stream detection From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:48 -0600 Message-ID: <160712290881.21372.8579870523469517845.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * Enhance performance by adding sequential stream detection. for R5/R6 sequential write requests. * Reduce stripe lock contention with full-stripe write operations. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 8 +++ drivers/scsi/smartpqi/smartpqi_init.c | 87 +++++++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index a5e271dd2742..343f06e44220 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1042,6 +1042,12 @@ struct pqi_scsi_dev_raid_map_data { #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" +#define NUM_STREAMS_PER_LUN 8 + +struct pqi_stream_data { + u64 next_lba; + u32 last_accessed; +}; struct pqi_scsi_dev { int devtype; /* as reported by INQUIRY commmand */ @@ -1097,6 +1103,7 @@ struct pqi_scsi_dev { struct list_head add_list_entry; struct list_head delete_list_entry; + struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN]; atomic_t scsi_cmds_outstanding; atomic_t raid_bypass_cnt; }; @@ -1296,6 +1303,7 @@ struct pqi_ctrl_info { u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; u8 lv_drive_type_mix_valid : 1; + u8 enable_stream_detection : 1; u8 ciss_report_log_flags; u32 max_transfer_encrypted_sas_sata; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index ddd2ed8f4283..25896e7dbd1b 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5652,8 +5652,82 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd) atomic_dec(&device->scsi_cmds_outstanding); } -static int pqi_scsi_queue_command(struct Scsi_Host *shost, +static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) +{ + u32 oldest_jiffies; + u8 lru_index; + int i; + int rc; + struct pqi_scsi_dev *device; + struct pqi_stream_data *pqi_stream_data; + struct pqi_scsi_dev_raid_map_data rmd; + + if (!ctrl_info->enable_stream_detection) + return false; + + rc = pqi_get_aio_lba_and_block_count(scmd, &rmd); + if (rc) + return false; + + /* Check writes only. */ + if (!rmd.is_write) + return false; + + device = scmd->device->hostdata; + + /* Check for RAID 5/6 streams. */ + if (device->raid_level != SA_RAID_5 && device->raid_level != SA_RAID_6) + return false; + + /* + * If controller does not support AIO RAID{5,6} writes, need to send + * requests down non-AIO path. + */ + if ((device->raid_level == SA_RAID_5 && !ctrl_info->enable_r5_writes) || + (device->raid_level == SA_RAID_6 && !ctrl_info->enable_r6_writes)) + return true; + + lru_index = 0; + oldest_jiffies = INT_MAX; + for (i = 0; i < NUM_STREAMS_PER_LUN; i++) { + pqi_stream_data = &device->stream_data[i]; + /* + * Check for adjacent request or request is within + * the previous request. + */ + if ((pqi_stream_data->next_lba && + rmd.first_block >= pqi_stream_data->next_lba) && + rmd.first_block <= pqi_stream_data->next_lba + + rmd.block_cnt) { + pqi_stream_data->next_lba = rmd.first_block + + rmd.block_cnt; + pqi_stream_data->last_accessed = jiffies; + return true; + } + + /* unused entry */ + if (pqi_stream_data->last_accessed == 0) { + lru_index = i; + break; + } + + /* Find entry with oldest last accessed time. */ + if (pqi_stream_data->last_accessed <= oldest_jiffies) { + oldest_jiffies = pqi_stream_data->last_accessed; + lru_index = i; + } + } + + /* Set LRU entry. */ + pqi_stream_data = &device->stream_data[lru_index]; + pqi_stream_data->last_accessed = jiffies; + pqi_stream_data->next_lba = rmd.first_block + rmd.block_cnt; + + return false; +} + +static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd) { int rc; struct pqi_ctrl_info *ctrl_info; @@ -5699,11 +5773,12 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, raid_bypassed = false; if (device->raid_bypass_enabled && !blk_rq_is_passthrough(scmd->request)) { - rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, - scmd, queue_group); - if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { - raid_bypassed = true; - atomic_inc(&device->raid_bypass_cnt); + if (!pqi_is_parity_write_stream(ctrl_info, scmd)) { + rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); + if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { + raid_bypassed = true; + atomic_inc(&device->raid_bypass_cnt); + } } } if (!raid_bypassed) From patchwork Fri Dec 4 23:01:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338628 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9360BC4361A for ; Fri, 4 Dec 2020 23:02:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6BAAC22C9E for ; Fri, 4 Dec 2020 23:02:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726964AbgLDXCv (ORCPT ); Fri, 4 Dec 2020 18:02:51 -0500 Received: from esa2.microchip.iphmx.com ([68.232.149.84]:45753 "EHLO esa2.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726829AbgLDXCv (ORCPT ); Fri, 4 Dec 2020 18:02:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122970; x=1638658970; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BeGyAEb7MMOkxayLp9BSFwHQPHKdIa+beHKD1giNJSM=; b=qUHAnLrSmuOfobLnk/Av0tUM9UVAv7YJbj5OkH3gagqFrnoQspnQf2xZ tyiUUh/TAepoQRC37N8woiEFtcVTg9vgvfz9ncM6gSnH3ozJRBHfOjheS DHfWPQ/DYwq6ZVvCcuvLrlCRp/R7uo4T0ATF8lR8tEKA/byt6OgShAoYT lKSdn2dLa/G6p0Esz5hDcMhPBm0c7z7DGaPvnGUz5NLKSIStPVhrExT99 K4jb7o2CvgyQ8+d1WwHix3XTup9enJy+FgIThzvf7taa5Zs7mOrFm02lu Whng91DugctQdUu4p5z3+8OlbuEMYl6NjslMplC5z+J01iNvYK90BUcFA A==; IronPort-SDR: QcotMrK6wrMsg7PoY2GgjAfZE3jS6+7t9ei/Zdk7VSNipu7IKonabGnCjflnthBGa8R6zzCDLL N2XNfnTZD//LeeFLYbS25kbakGL8gS4vwOTtZsKXOkXJGUec2z49S6Q5gQZjmocwLw54B+H2Dl psiNh7rWaco/Pv993jxKX335e+50VtVmY+TAgtYA9lF2ZyHNt4xLDNQ8o1TsD1fl98aPMlft3g JwOSwr4WPdB/X90Z0rQl4rSrb9zSrugjIZviSEI78IsImDdijSGf4CwP5lDl48cd1kcXEpBFwE JOk= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="98684113" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:01:55 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:01:55 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:01:54 -0700 Subject: [PATCH 11/25] smartpqi: add host level stream detection enable From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:01:54 -0600 Message-ID: <160712291461.21372.5830547651591062444.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * Allow R5/R6 stream detection to be disabled/enabled. using sysfs entry enable_stream_detection. Example usage: lsscsi [2:2:0:0] storage Adaptec 3258P-32i /e 0010 ^ | +---- NOTE: here host is host2 find /sys -name \*enable_stream\* /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection /sys/devices/pci0000:5b/0000:5b:00.0/0000:5c:00.0/host3/scsi_host/host3/enable_stream_detection Current stream detection: cat /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection 1 Turn off stream detection: echo 0 > /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection Turn on stream detection: echo 1 > /sys/devices/pci0000:36/0000:36:00.0/0000:37:00.0/0000:38:00.0/0000:39:00.0/host2/scsi_host/host2/enable_stream_detection Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 25896e7dbd1b..9604e08e58cb 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6655,6 +6655,34 @@ static ssize_t pqi_lockup_action_store(struct device *dev, return -EINVAL; } +static ssize_t pqi_host_enable_stream_detection_show(struct device *dev, + struct device_attribute *attr, char *buffer) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + + return scnprintf(buffer, 10, "%hhx\n", + ctrl_info->enable_stream_detection); +} + +static ssize_t pqi_host_enable_stream_detection_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(dev); + struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + u8 set_stream_detection = 0; + + if (kstrtou8(buffer, 0, &set_stream_detection)) + return -EINVAL; + + if (set_stream_detection > 0) + set_stream_detection = 1; + + ctrl_info->enable_stream_detection = set_stream_detection; + + return count; +} + static ssize_t pqi_host_enable_r5_writes_show(struct device *dev, struct device_attribute *attr, char *buffer) { @@ -6717,6 +6745,9 @@ static DEVICE_ATTR(vendor, 0444, pqi_vendor_show, NULL); static DEVICE_ATTR(rescan, 0200, NULL, pqi_host_rescan_store); static DEVICE_ATTR(lockup_action, 0644, pqi_lockup_action_show, pqi_lockup_action_store); +static DEVICE_ATTR(enable_stream_detection, 0644, + pqi_host_enable_stream_detection_show, + pqi_host_enable_stream_detection_store); static DEVICE_ATTR(enable_r5_writes, 0644, pqi_host_enable_r5_writes_show, pqi_host_enable_r5_writes_store); static DEVICE_ATTR(enable_r6_writes, 0644, @@ -6730,6 +6761,7 @@ static struct device_attribute *pqi_shost_attrs[] = { &dev_attr_vendor, &dev_attr_rescan, &dev_attr_lockup_action, + &dev_attr_enable_stream_detection, &dev_attr_enable_r5_writes, &dev_attr_enable_r6_writes, NULL From patchwork Fri Dec 4 23:02:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 585BEC433FE for ; Fri, 4 Dec 2020 23:03:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 286D822D01 for ; Fri, 4 Dec 2020 23:03:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726829AbgLDXDB (ORCPT ); Fri, 4 Dec 2020 18:03:01 -0500 Received: from esa2.microchip.iphmx.com ([68.232.149.84]:45863 "EHLO esa2.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDB (ORCPT ); Fri, 4 Dec 2020 18:03:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122980; x=1638658980; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hU1czVExCD3fXvIWcdqtP2z0QNdElvuzaH8DBzttLxE=; b=YH2RoqUV4kP6z2WVWW4NF0wMroIpn5qRH+vMC9uYCy6q+0UIEkAq35LB KcumsaKq+Xkrl0TWB+6mq/KVhVpvKxfrr2gfUkGF2+nESFuEiLQsbg9aV RQISvkVr6iNf5Ijc/kLm0LSeBnuk6ht6g7vpK9vV8q6Z6BdZmvnl8vzP3 R6WWdABqfRnb0io/LtF0yRmAPA66CIRbI4N0/7HQok7d0O8j1UtLRFgm6 bUoMdixG8bAiHPeUNXMvzz2c4otCRpLWU2R/Gc2HTuU894Okf0zsD0b2D h7h917nqfEujXP5LGrrU+u31FfNIQLXmDMWxnc6xXVn0M9MMlqKxLtc5C w==; IronPort-SDR: vWuuS95NkFvclOLdCodR7YpZJRKUUKe09SiJxU30wR9dF6mNxiOvKGbWdtiJazhVhg3FAOPBNZ l7DNsA17Zo6n5IhJOavcPKveuMh6Hz655q0UX8aeBGKWnCpU70Iulcloc58uReTyic8Scgo27l xNuG8R6/NMPSVM39TAzlzeVagfyrRIXbzy9u2aIQOXw14zFgblc8jBbmqhDN9dbCXBzhcZl3rq dv6XrBYkmOtkfIwqfcz9cfoa3XhgnVZRNtQP4zPjCtxQLs1lGuFhSrs+8tvWmBKsHhvW4HW9ZH 27M= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="98684130" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa2.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:04 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:01 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:00 -0700 Subject: [PATCH 12/25] smartpqi: enable support for NVMe encryption From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:00 -0600 Message-ID: <160712292038.21372.12259646828427195105.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Support new FW feature bit that enables NVMe encryption. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 3 ++- drivers/scsi/smartpqi/smartpqi_init.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 343f06e44220..976bfd8c5192 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -849,7 +849,8 @@ struct pqi_config_table_firmware_features { #define PQI_FIRMWARE_FEATURE_UNIQUE_SATA_WWN 12 #define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 #define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 -#define PQI_FIRMWARE_FEATURE_MAXIMUM 14 +#define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 15 struct pqi_config_table_debug { struct pqi_config_table_section_header header; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 9604e08e58cb..be2f177b3a21 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -7504,6 +7504,11 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT, .feature_status = pqi_ctrl_update_feature_flags, }, + { + .feature_name = "RAID Bypass on encrypted logical volumes on NVMe", + .feature_bit = PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME, + .feature_status = pqi_firmware_feature_status, + }, }; static void pqi_process_firmware_features( From patchwork Fri Dec 4 23:02:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338624 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DC5F4C4361A for ; Fri, 4 Dec 2020 23:03:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AD7AA22D01 for ; Fri, 4 Dec 2020 23:03:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727243AbgLDXDO (ORCPT ); Fri, 4 Dec 2020 18:03:14 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1478 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDO (ORCPT ); Fri, 4 Dec 2020 18:03:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122993; x=1638658993; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lmIw3y1p92HnugvLiKGMzPtRIyxOEMgXAXE21Epvo8Y=; b=mpacBSnHPRt6ehh2B0Urtc2OO6jl0mCNMwknBAlmXuykW4OVs1hsRRFh KEFrB8YLH11aliubmYJqFKsx7axZPkZ75tCmWuLtCcsGIx7z4xDBOR/F+ 8Ww0R/aSKICUOt3TxBnIGTEypcSrmXscfYG+N2zB3G4ZJvwtNqd3jYU6z UGbo99cS3pcV/WCi3cjxElc0nyDXajtHPTNk081IKSg5LXpqxl4mpERXB VyXOZUMf3Hb7Jdd5P1+dLW5a3P5eA/P8moBjH4StKzk03PjRFJNIgBfwL 2FjtGgVTnYP8QlDYucdDVdAXAFp617FeemkqHaFnJlaghtIwpy1E+144I Q==; IronPort-SDR: bew/MqZIDjg91ngy0odT9ZVJrGoKjb6vY9E/yoMp9M0wsWjIvBfYxTPAXtH6VcsZD1dYqlsju4 nVkUkkyX9z1/JHqa18TDTzfNlUyjIwYckrqwy3evMYA0DOdTgA267dNQZmrGbM2hPyGeEkDghe PQF3a7VjA+mtfVm07NJkP5cFfAaq1aoXLA4bbWBRVrfP3+b+c469AxrEnh0I0AbM0tdMesWvu4 ogcq+zo+QQka3vZ/xvatEP56jvZbDgA+3ddm+KKNI8SazXJrbeEd63jp0xU4o813koqNTyQTLR GD8= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548671" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:09 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:06 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:06 -0700 Subject: [PATCH 13/25] smartpqi: disable write_same for nvme hba disks From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:06 -0600 Message-ID: <160712292615.21372.15639957017242633419.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Controller do not support SCSI WRITE SAME for NVMe drives in HBA mode Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index be2f177b3a21..8148a270854e 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6211,10 +6211,13 @@ static int pqi_slave_alloc(struct scsi_device *sdev) scsi_change_queue_depth(sdev, device->advertised_queue_depth); } - if (pqi_is_logical_device(device)) + if (pqi_is_logical_device(device)) { pqi_disable_write_same(sdev); - else + } else { sdev->allow_restart = 1; + if (device->device_type == SA_DEVICE_TYPE_NVME) + pqi_disable_write_same(sdev); + } } spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); From patchwork Fri Dec 4 23:02:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338134 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7C60C4361A for ; Fri, 4 Dec 2020 23:03:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 922C822D01 for ; Fri, 4 Dec 2020 23:03:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727303AbgLDXDq (ORCPT ); Fri, 4 Dec 2020 18:03:46 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1456 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727281AbgLDXDp (ORCPT ); Fri, 4 Dec 2020 18:03:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123025; x=1638659025; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zcCUVYgnYiMLqO37EPXUlfW3vL8agdFT8HecNCeQ+bM=; b=DsxU76qFzZr8ERRFAFRP+aX9sRDJtkMv7CHhkzww3b7x7gkSZse0jZyn tyEmWwIKPbjYTKeMkpXmYVwJ59QqPMNEmFv1/iM0N6wqibOiqpgpI/xlf cnLADvQK0PPE1ZO0XnglfPM1+bFT8+Vji9AaTf+lUCqsxfeQFGk/cV8a2 LClIbaBdGDx2Jh6PR/yj3ZmAEqbo/pXHwVbzr1/XtvfHc1h4iBmKktyzG YkBQITJ9KWBrItU7PJ1QgADXc5q9evxqg+931dh44G8bDi6pX9N5hbT9/ p6/5FwoplTsLuok7YXzuj5An/n5C+nlV/QpnpHOgfVXqMnONZSB7e6Gu6 Q==; IronPort-SDR: oPdkddk5TgywnpQBDyYXY6E+YRCdQxp6A2tpIlgKPU/JSb5O9hn+Hx20gVcl3GE5DZfSqiP+em r0ZnwK+EZZTq/frqPSzZoY4n5+hMP1l6LfjbqfjQqpL/CLmlNQfStTn2xBlU6BYAZfbrt91ge+ uzIOs0CI3aheyEu5S/8HBdPcxyaGI0tQ8eSBru6DOd/eAY1+ArCcSZCn2/TMudCQqWlr7NK3Dv RQfZWMW2kpvdHx+Yu0Aaiv+er5aUhJJtOMEScGV0L0wGPGst4c2FWtZAdwZ0JSkQse/dbDWH8T JME= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548717" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:13 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:12 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:12 -0700 Subject: [PATCH 14/25] smartpqi: fix driver synchronization issues From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:11 -0600 Message-ID: <160712293190.21372.8193896733647433880.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * synchronize: LUN resets, shutdowns, suspend, hibernate, OFA, and controller offline events. * prevent I/O during the the above conditions. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 48 - drivers/scsi/smartpqi/smartpqi_init.c | 1157 +++++++++++++-------------------- 2 files changed, 474 insertions(+), 731 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 976bfd8c5192..0b94c755a74c 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -130,9 +130,12 @@ struct pqi_iu_header { /* of this header */ __le16 response_queue_id; /* specifies the OQ where the */ /* response IU is to be delivered */ - u8 work_area[2]; /* reserved for driver use */ + u16 driver_flags; /* reserved for driver use */ }; +/* manifest constants for pqi_iu_header.driver_flags */ +#define PQI_DRIVER_NONBLOCKABLE_REQUEST 0x1 + /* * According to the PQI spec, the IU header is only the first 4 bytes of our * pqi_iu_header structure. @@ -508,10 +511,6 @@ struct pqi_vendor_general_response { #define PQI_OFA_SIGNATURE "OFA_QRM" #define PQI_OFA_MAX_SG_DESCRIPTORS 64 -#define PQI_OFA_MEMORY_DESCRIPTOR_LENGTH \ - (offsetof(struct pqi_ofa_memory, sg_descriptor) + \ - (PQI_OFA_MAX_SG_DESCRIPTORS * sizeof(struct pqi_sg_descriptor))) - struct pqi_ofa_memory { __le64 signature; /* "OFA_QRM" */ __le16 version; /* version of this struct (1 = 1st version) */ @@ -519,7 +518,7 @@ struct pqi_ofa_memory { __le32 bytes_allocated; /* total allocated memory in bytes */ __le16 num_memory_descriptors; u8 reserved1[2]; - struct pqi_sg_descriptor sg_descriptor[1]; + struct pqi_sg_descriptor sg_descriptor[PQI_OFA_MAX_SG_DESCRIPTORS]; }; struct pqi_aio_error_info { @@ -850,7 +849,8 @@ struct pqi_config_table_firmware_features { #define PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT 13 #define PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT 14 #define PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME 15 -#define PQI_FIRMWARE_FEATURE_MAXIMUM 15 +#define PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN 16 +#define PQI_FIRMWARE_FEATURE_MAXIMUM 16 struct pqi_config_table_debug { struct pqi_config_table_section_header header; @@ -1071,7 +1071,6 @@ struct pqi_scsi_dev { u8 volume_offline : 1; u8 rescan : 1; bool aio_enabled; /* only valid for physical disks */ - bool in_reset; bool in_remove; bool device_offline; u8 vendor[8]; /* bytes 8-15 of inquiry data */ @@ -1107,6 +1106,7 @@ struct pqi_scsi_dev { struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN]; atomic_t scsi_cmds_outstanding; atomic_t raid_bypass_cnt; + u8 page_83_identifier[16]; }; /* VPD inquiry pages */ @@ -1212,10 +1212,8 @@ struct pqi_io_request { struct pqi_event { bool pending; u8 event_type; - __le16 event_id; - __le32 additional_event_id; - __le32 ofa_bytes_requested; - __le16 ofa_cancel_reason; + u16 event_id; + u32 additional_event_id; }; #define PQI_RESERVED_IO_SLOTS_LUN_RESET 1 @@ -1287,12 +1285,9 @@ struct pqi_ctrl_info { struct mutex scan_mutex; struct mutex lun_reset_mutex; - struct mutex ofa_mutex; /* serialize ofa */ bool controller_online; bool block_requests; - bool block_device_reset; - bool in_ofa; - bool in_shutdown; + bool scan_blocked; u8 inbound_spanning_supported : 1; u8 outbound_spanning_supported : 1; u8 pqi_mode_enabled : 1; @@ -1300,6 +1295,7 @@ struct pqi_ctrl_info { u8 soft_reset_handshake_supported : 1; u8 raid_iu_timeout_supported : 1; u8 tmf_iu_timeout_supported : 1; + u8 unique_wwid_in_report_phys_lun_supported : 1; u8 enable_r1_writes : 1; u8 enable_r5_writes : 1; u8 enable_r6_writes : 1; @@ -1341,14 +1337,14 @@ struct pqi_ctrl_info { atomic_t num_blocked_threads; wait_queue_head_t block_requests_wait; - struct list_head raid_bypass_retry_list; - spinlock_t raid_bypass_retry_list_lock; - struct work_struct raid_bypass_retry_work; - + struct mutex ofa_mutex; struct pqi_ofa_memory *pqi_ofa_mem_virt_addr; dma_addr_t pqi_ofa_mem_dma_handle; void **pqi_ofa_chunk_virt_addr; - atomic_t sync_cmds_outstanding; + struct work_struct ofa_memory_alloc_work; + struct work_struct ofa_quiesce_work; + u32 ofa_bytes_requested; + u16 ofa_cancel_reason; }; enum pqi_ctrl_mode { @@ -1619,16 +1615,6 @@ struct bmic_diag_options { #pragma pack() -static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info) -{ - atomic_inc(&ctrl_info->num_busy_threads); -} - -static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info) -{ - atomic_dec(&ctrl_info->num_busy_threads); -} - static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost) { void *hostdata = shost_priv(shost); diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 8148a270854e..0472ba6de43b 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -45,6 +45,9 @@ #define PQI_EXTRA_SGL_MEMORY (12 * sizeof(struct pqi_sg_descriptor)) +#define PQI_POST_RESET_DELAY_SECS 5 +#define PQI_POST_OFA_RESET_DELAY_UPON_TIMEOUT_SECS 10 + MODULE_AUTHOR("Microsemi"); MODULE_DESCRIPTION("Driver for Microsemi Smart Family Controller version " DRIVER_VERSION); @@ -54,7 +57,6 @@ MODULE_LICENSE("GPL"); static void pqi_take_ctrl_offline(struct pqi_ctrl_info *ctrl_info); static void pqi_ctrl_offline_worker(struct work_struct *work); -static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info); static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info); static void pqi_scan_start(struct Scsi_Host *shost); static void pqi_start_io(struct pqi_ctrl_info *ctrl_info, @@ -62,7 +64,7 @@ static void pqi_start_io(struct pqi_ctrl_info *ctrl_info, struct pqi_io_request *io_request); static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, struct pqi_iu_header *request, unsigned int flags, - struct pqi_raid_error_info *error_info, unsigned long timeout_msecs); + struct pqi_raid_error_info *error_info); static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb, unsigned int cdb_length, struct pqi_queue_group *queue_group, @@ -77,9 +79,8 @@ static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev_raid_map_data *rmd); static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info); -static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info); -static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info, - u32 bytes_requested); +static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int delay_secs); +static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info); static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info); static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, @@ -245,14 +246,66 @@ static inline void pqi_save_ctrl_mode(struct pqi_ctrl_info *ctrl_info, sis_write_driver_scratch(ctrl_info, mode); } +static inline void pqi_ctrl_block_scan(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->scan_blocked = true; + mutex_lock(&ctrl_info->scan_mutex); +} + +static inline void pqi_ctrl_unblock_scan(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->scan_blocked = false; + mutex_unlock(&ctrl_info->scan_mutex); +} + +static inline bool pqi_ctrl_scan_blocked(struct pqi_ctrl_info *ctrl_info) +{ + return ctrl_info->scan_blocked; +} + static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->block_device_reset = true; + mutex_lock(&ctrl_info->lun_reset_mutex); +} + +static inline void pqi_ctrl_unblock_device_reset(struct pqi_ctrl_info *ctrl_info) +{ + mutex_unlock(&ctrl_info->lun_reset_mutex); +} + +static inline void pqi_scsi_block_requests(struct pqi_ctrl_info *ctrl_info) +{ + struct Scsi_Host *shost; + unsigned int num_loops; + int msecs_sleep; + + shost = ctrl_info->scsi_host; + + scsi_block_requests(shost); + + num_loops = 0; + msecs_sleep = 20; + while (scsi_host_busy(shost)) { + num_loops++; + if (num_loops == 10) + msecs_sleep = 500; + msleep(msecs_sleep); + } +} + +static inline void pqi_scsi_unblock_requests(struct pqi_ctrl_info *ctrl_info) +{ + scsi_unblock_requests(ctrl_info->scsi_host); +} + +static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info) +{ + atomic_inc(&ctrl_info->num_busy_threads); } -static inline bool pqi_device_reset_blocked(struct pqi_ctrl_info *ctrl_info) +static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info) { - return ctrl_info->block_device_reset; + atomic_dec(&ctrl_info->num_busy_threads); } static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) @@ -263,44 +316,23 @@ static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) static inline void pqi_ctrl_block_requests(struct pqi_ctrl_info *ctrl_info) { ctrl_info->block_requests = true; - scsi_block_requests(ctrl_info->scsi_host); } static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info) { ctrl_info->block_requests = false; wake_up_all(&ctrl_info->block_requests_wait); - pqi_retry_raid_bypass_requests(ctrl_info); - scsi_unblock_requests(ctrl_info->scsi_host); } -static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info, - unsigned long timeout_msecs) +static void pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) { - unsigned long remaining_msecs; - if (!pqi_ctrl_blocked(ctrl_info)) - return timeout_msecs; + return; atomic_inc(&ctrl_info->num_blocked_threads); - - if (timeout_msecs == NO_TIMEOUT) { - wait_event(ctrl_info->block_requests_wait, - !pqi_ctrl_blocked(ctrl_info)); - remaining_msecs = timeout_msecs; - } else { - unsigned long remaining_jiffies; - - remaining_jiffies = - wait_event_timeout(ctrl_info->block_requests_wait, - !pqi_ctrl_blocked(ctrl_info), - msecs_to_jiffies(timeout_msecs)); - remaining_msecs = jiffies_to_msecs(remaining_jiffies); - } - + wait_event(ctrl_info->block_requests_wait, + !pqi_ctrl_blocked(ctrl_info)); atomic_dec(&ctrl_info->num_blocked_threads); - - return remaining_msecs; } static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info) @@ -315,34 +347,25 @@ static inline bool pqi_device_offline(struct pqi_scsi_dev *device) return device->device_offline; } -static inline void pqi_device_reset_start(struct pqi_scsi_dev *device) -{ - device->in_reset = true; -} - -static inline void pqi_device_reset_done(struct pqi_scsi_dev *device) -{ - device->in_reset = false; -} - -static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device) +static inline void pqi_ctrl_ofa_start(struct pqi_ctrl_info *ctrl_info) { - return device->in_reset; + mutex_lock(&ctrl_info->ofa_mutex); } -static inline void pqi_ctrl_ofa_start(struct pqi_ctrl_info *ctrl_info) +static inline void pqi_ctrl_ofa_done(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->in_ofa = true; + mutex_unlock(&ctrl_info->ofa_mutex); } -static inline void pqi_ctrl_ofa_done(struct pqi_ctrl_info *ctrl_info) +static inline void pqi_wait_until_ofa_finished(struct pqi_ctrl_info *ctrl_info) { - ctrl_info->in_ofa = false; + mutex_lock(&ctrl_info->ofa_mutex); + mutex_unlock(&ctrl_info->ofa_mutex); } -static inline bool pqi_ctrl_in_ofa(struct pqi_ctrl_info *ctrl_info) +static inline bool pqi_ofa_in_progress(struct pqi_ctrl_info *ctrl_info) { - return ctrl_info->in_ofa; + return mutex_is_locked(&ctrl_info->ofa_mutex); } static inline void pqi_device_remove_start(struct pqi_scsi_dev *device) @@ -355,14 +378,20 @@ static inline bool pqi_device_in_remove(struct pqi_scsi_dev *device) return device->in_remove; } -static inline void pqi_ctrl_shutdown_start(struct pqi_ctrl_info *ctrl_info) +static inline int pqi_event_type_to_event_index(unsigned int event_type) { - ctrl_info->in_shutdown = true; + int index; + + for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++) + if (event_type == pqi_supported_event_types[index]) + return index; + + return -1; } -static inline bool pqi_ctrl_in_shutdown(struct pqi_ctrl_info *ctrl_info) +static inline bool pqi_is_supported_event(unsigned int event_type) { - return ctrl_info->in_shutdown; + return pqi_event_type_to_event_index(event_type) != -1; } static inline void pqi_schedule_rescan_worker_with_delay(struct pqi_ctrl_info *ctrl_info, @@ -370,8 +399,6 @@ static inline void pqi_schedule_rescan_worker_with_delay(struct pqi_ctrl_info *c { if (pqi_ctrl_offline(ctrl_info)) return; - if (pqi_ctrl_in_ofa(ctrl_info)) - return; schedule_delayed_work(&ctrl_info->rescan_work, delay); } @@ -408,22 +435,15 @@ static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info) static inline u8 pqi_read_soft_reset_status(struct pqi_ctrl_info *ctrl_info) { - if (!ctrl_info->soft_reset_status) - return 0; - return readb(ctrl_info->soft_reset_status); } -static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info, - u8 clear) +static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info) { u8 status; - if (!ctrl_info->soft_reset_status) - return; - status = pqi_read_soft_reset_status(ctrl_info); - status &= ~clear; + status &= ~PQI_SOFT_RESET_ABORT; writeb(status, ctrl_info->soft_reset_status); } @@ -512,6 +532,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info, put_unaligned_be32(cdb_length, &cdb[6]); break; case SA_FLUSH_CACHE: + request->header.driver_flags = PQI_DRIVER_NONBLOCKABLE_REQUEST; request->data_direction = SOP_WRITE_FLAG; cdb[0] = BMIC_WRITE; cdb[6] = BMIC_FLUSH_CACHE; @@ -606,7 +627,7 @@ static void pqi_free_io_request(struct pqi_io_request *io_request) static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, u8 *scsi3addr, void *buffer, size_t buffer_length, u16 vpd_page, - struct pqi_raid_error_info *error_info, unsigned long timeout_msecs) + struct pqi_raid_error_info *error_info) { int rc; struct pqi_raid_path_request request; @@ -618,7 +639,7 @@ static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, return rc; rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, - error_info, timeout_msecs); + error_info); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -631,7 +652,7 @@ static inline int pqi_send_ctrl_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd, void *buffer, size_t buffer_length) { return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID, - buffer, buffer_length, 0, NULL, NO_TIMEOUT); + buffer, buffer_length, 0, NULL); } static inline int pqi_send_ctrl_raid_with_error(struct pqi_ctrl_info *ctrl_info, @@ -639,7 +660,7 @@ static inline int pqi_send_ctrl_raid_with_error(struct pqi_ctrl_info *ctrl_info, struct pqi_raid_error_info *error_info) { return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID, - buffer, buffer_length, 0, error_info, NO_TIMEOUT); + buffer, buffer_length, 0, error_info); } static inline int pqi_identify_controller(struct pqi_ctrl_info *ctrl_info, @@ -661,7 +682,7 @@ static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info, u8 *scsi3addr, u16 vpd_page, void *buffer, size_t buffer_length) { return pqi_send_scsi_raid_request(ctrl_info, INQUIRY, scsi3addr, - buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT); + buffer, buffer_length, vpd_page, NULL); } static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, @@ -683,8 +704,7 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info, request.cdb[2] = (u8)bmic_device_index; request.cdb[9] = (u8)(bmic_device_index >> 8); - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -741,7 +761,7 @@ static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) request.cdb[2] = BMIC_SENSE_FEATURE_IO_PAGE; request.cdb[3] = BMIC_SENSE_FEATURE_IO_PAGE_AIO_SUBPAGE; - rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL, NO_TIMEOUT); + rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir); @@ -794,13 +814,6 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info, int rc; struct bmic_flush_cache *flush_cache; - /* - * Don't bother trying to flush the cache if the controller is - * locked up. - */ - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - flush_cache = kzalloc(sizeof(*flush_cache), GFP_KERNEL); if (!flush_cache) return -ENOMEM; @@ -979,9 +992,6 @@ static void pqi_update_time_worker(struct work_struct *work) ctrl_info = container_of(to_delayed_work(work), struct pqi_ctrl_info, update_time_work); - if (pqi_ctrl_offline(ctrl_info)) - return; - rc = pqi_write_current_time_to_host_wellness(ctrl_info); if (rc) dev_warn(&ctrl_info->pci_dev->dev, @@ -1271,9 +1281,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, return -ENOMEM; rc = pqi_send_scsi_raid_request(ctrl_info, CISS_GET_RAID_MAP, - device->scsi3addr, raid_map, sizeof(*raid_map), - 0, NULL, NO_TIMEOUT); - + device->scsi3addr, raid_map, sizeof(*raid_map), 0, NULL); if (rc) goto error; @@ -1288,8 +1296,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, return -ENOMEM; rc = pqi_send_scsi_raid_request(ctrl_info, CISS_GET_RAID_MAP, - device->scsi3addr, raid_map, raid_map_size, - 0, NULL, NO_TIMEOUT); + device->scsi3addr, raid_map, raid_map_size, 0, NULL); if (rc) goto error; @@ -1464,6 +1471,9 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info, sizeof(device->phys_connector)); device->bay = id_phys->phys_bay_in_box; + memcpy(&device->page_83_identifier, &id_phys->page_83_identifier, + sizeof(device->page_83_identifier)); + return 0; } @@ -1970,8 +1980,13 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - if (pqi_ctrl_in_ofa(ctrl_info)) - pqi_ctrl_ofa_done(ctrl_info); + if (pqi_ofa_in_progress(ctrl_info)) { + list_for_each_entry_safe(device, next, &delete_list, delete_list_entry) + if (pqi_is_device_added(device)) + pqi_device_remove_start(device); + pqi_ctrl_unblock_device_reset(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + } /* Remove all devices that have gone away. */ list_for_each_entry_safe(device, next, &delete_list, delete_list_entry) { @@ -1993,19 +2008,14 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, * Notify the SCSI ML if the queue depth of any existing device has * changed. */ - list_for_each_entry(device, &ctrl_info->scsi_device_list, - scsi_device_list_entry) { - if (device->sdev) { - if (device->queue_depth != - device->advertised_queue_depth) { - device->advertised_queue_depth = device->queue_depth; - scsi_change_queue_depth(device->sdev, - device->advertised_queue_depth); - } - if (device->rescan) { - scsi_rescan_device(&device->sdev->sdev_gendev); - device->rescan = false; - } + list_for_each_entry(device, &ctrl_info->scsi_device_list, scsi_device_list_entry) { + if (device->sdev && device->queue_depth != device->advertised_queue_depth) { + device->advertised_queue_depth = device->queue_depth; + scsi_change_queue_depth(device->sdev, device->advertised_queue_depth); + } + if (device->rescan) { + scsi_rescan_device(&device->sdev->sdev_gendev); + device->rescan = false; } } @@ -2073,6 +2083,16 @@ static inline bool pqi_expose_device(struct pqi_scsi_dev *device) return !device->is_physical_device || !pqi_skip_device(device->scsi3addr); } +static inline void pqi_set_physical_device_wwid(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, struct report_phys_lun_extended_entry *phys_lun_ext_entry) +{ + if (ctrl_info->unique_wwid_in_report_phys_lun_supported || + pqi_is_device_with_sas_address(device)) + device->wwid = phys_lun_ext_entry->wwid; + else + device->wwid = cpu_to_be64(get_unaligned_be64(&device->page_83_identifier)); +} + static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) { int i; @@ -2238,7 +2258,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) pqi_assign_bus_target_lun(device); if (device->is_physical_device) { - device->wwid = phys_lun_ext_entry->wwid; + pqi_set_physical_device_wwid(ctrl_info, device, phys_lun_ext_entry); if ((phys_lun_ext_entry->device_flags & CISS_REPORT_PHYS_DEV_FLAG_AIO_ENABLED) && phys_lun_ext_entry->aio_handle) { @@ -2278,21 +2298,27 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) static int pqi_scan_scsi_devices(struct pqi_ctrl_info *ctrl_info) { - int rc = 0; + int rc; + int mutex_acquired; if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; - if (!mutex_trylock(&ctrl_info->scan_mutex)) { + mutex_acquired = mutex_trylock(&ctrl_info->scan_mutex); + + if (!mutex_acquired) { + if (pqi_ctrl_scan_blocked(ctrl_info)) + return -EBUSY; pqi_schedule_rescan_worker_delayed(ctrl_info); - rc = -EINPROGRESS; - } else { - rc = pqi_update_scsi_devices(ctrl_info); - if (rc) - pqi_schedule_rescan_worker_delayed(ctrl_info); - mutex_unlock(&ctrl_info->scan_mutex); + return -EINPROGRESS; } + rc = pqi_update_scsi_devices(ctrl_info); + if (rc && !pqi_ctrl_scan_blocked(ctrl_info)) + pqi_schedule_rescan_worker_delayed(ctrl_info); + + mutex_unlock(&ctrl_info->scan_mutex); + return rc; } @@ -2301,8 +2327,6 @@ static void pqi_scan_start(struct Scsi_Host *shost) struct pqi_ctrl_info *ctrl_info; ctrl_info = shost_to_hba(shost); - if (pqi_ctrl_in_ofa(ctrl_info)) - return; pqi_scan_scsi_devices(ctrl_info); } @@ -2319,27 +2343,8 @@ static int pqi_scan_finished(struct Scsi_Host *shost, return !mutex_is_locked(&ctrl_info->scan_mutex); } -static void pqi_wait_until_scan_finished(struct pqi_ctrl_info *ctrl_info) -{ - mutex_lock(&ctrl_info->scan_mutex); - mutex_unlock(&ctrl_info->scan_mutex); -} - -static void pqi_wait_until_lun_reset_finished(struct pqi_ctrl_info *ctrl_info) -{ - mutex_lock(&ctrl_info->lun_reset_mutex); - mutex_unlock(&ctrl_info->lun_reset_mutex); -} - -static void pqi_wait_until_ofa_finished(struct pqi_ctrl_info *ctrl_info) -{ - mutex_lock(&ctrl_info->ofa_mutex); - mutex_unlock(&ctrl_info->ofa_mutex); -} - -static inline void pqi_set_encryption_info( - struct pqi_encryption_info *encryption_info, struct raid_map *raid_map, - u64 first_block) +static inline void pqi_set_encryption_info(struct pqi_encryption_info *encryption_info, + struct raid_map *raid_map, u64 first_block) { u32 volume_blk_size; @@ -3182,8 +3187,8 @@ static void pqi_acknowledge_event(struct pqi_ctrl_info *ctrl_info, put_unaligned_le16(sizeof(request) - PQI_REQUEST_HEADER_LENGTH, &request.header.iu_length); request.event_type = event->event_type; - request.event_id = event->event_id; - request.additional_event_id = event->additional_event_id; + put_unaligned_le16(event->event_id, &request.event_id); + put_unaligned_le16(event->additional_event_id, &request.additional_event_id); pqi_send_event_ack(ctrl_info, &request, sizeof(request)); } @@ -3194,8 +3199,8 @@ static void pqi_acknowledge_event(struct pqi_ctrl_info *ctrl_info, static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status( struct pqi_ctrl_info *ctrl_info) { - unsigned long timeout; u8 status; + unsigned long timeout; timeout = (PQI_SOFT_RESET_STATUS_TIMEOUT_SECS * PQI_HZ) + jiffies; @@ -3207,120 +3212,169 @@ static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status( if (status & PQI_SOFT_RESET_ABORT) return RESET_ABORT; + if (!sis_is_firmware_running(ctrl_info)) + return RESET_NORESPONSE; + if (time_after(jiffies, timeout)) { - dev_err(&ctrl_info->pci_dev->dev, + dev_warn(&ctrl_info->pci_dev->dev, "timed out waiting for soft reset status\n"); return RESET_TIMEDOUT; } - if (!sis_is_firmware_running(ctrl_info)) - return RESET_NORESPONSE; - ssleep(PQI_SOFT_RESET_STATUS_POLL_INTERVAL_SECS); } } -static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info, - enum pqi_soft_reset_status reset_status) +static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) { int rc; + unsigned int delay_secs; + enum pqi_soft_reset_status reset_status; + + if (ctrl_info->soft_reset_handshake_supported) + reset_status = pqi_poll_for_soft_reset_status(ctrl_info); + else + reset_status = RESET_INITIATE_FIRMWARE; + + pqi_ofa_free_host_buffer(ctrl_info); + + delay_secs = PQI_POST_RESET_DELAY_SECS; switch (reset_status) { - case RESET_INITIATE_DRIVER: case RESET_TIMEDOUT: + delay_secs = PQI_POST_OFA_RESET_DELAY_UPON_TIMEOUT_SECS; + fallthrough; + case RESET_INITIATE_DRIVER: dev_info(&ctrl_info->pci_dev->dev, - "resetting controller %u\n", ctrl_info->ctrl_id); + "Online Firmware Activation: resetting controller\n"); sis_soft_reset(ctrl_info); fallthrough; case RESET_INITIATE_FIRMWARE: - rc = pqi_ofa_ctrl_restart(ctrl_info); - pqi_ofa_free_host_buffer(ctrl_info); + ctrl_info->pqi_mode_enabled = false; + pqi_save_ctrl_mode(ctrl_info, SIS_MODE); + rc = pqi_ofa_ctrl_restart(ctrl_info, delay_secs); + pqi_ctrl_ofa_done(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation for controller %u: %s\n", - ctrl_info->ctrl_id, rc == 0 ? "SUCCESS" : "FAILED"); + "Online Firmware Activation: %s\n", + rc == 0 ? "SUCCESS" : "FAILED"); break; case RESET_ABORT: - pqi_ofa_ctrl_unquiesce(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation for controller %u: %s\n", - ctrl_info->ctrl_id, "ABORTED"); + "Online Firmware Activation ABORTED\n"); + if (ctrl_info->soft_reset_handshake_supported) + pqi_clear_soft_reset_status(ctrl_info); + pqi_ctrl_ofa_done(ctrl_info); + pqi_ofa_ctrl_unquiesce(ctrl_info); break; case RESET_NORESPONSE: - pqi_ofa_free_host_buffer(ctrl_info); + fallthrough; + default: + dev_err(&ctrl_info->pci_dev->dev, + "unexpected Online Firmware Activation reset status: 0x%x\n", + reset_status); + pqi_ctrl_ofa_done(ctrl_info); + pqi_ofa_ctrl_unquiesce(ctrl_info); pqi_take_ctrl_offline(ctrl_info); break; } } -static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, - struct pqi_event *event) +static void pqi_ofa_memory_alloc_worker(struct work_struct *work) { - u16 event_id; - enum pqi_soft_reset_status status; + struct pqi_ctrl_info *ctrl_info; - event_id = get_unaligned_le16(&event->event_id); + ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_memory_alloc_work); - mutex_lock(&ctrl_info->ofa_mutex); + pqi_ctrl_ofa_start(ctrl_info); + pqi_ofa_setup_host_buffer(ctrl_info); + pqi_ofa_host_memory_update(ctrl_info); +} - if (event_id == PQI_EVENT_OFA_QUIESCE) { - dev_info(&ctrl_info->pci_dev->dev, - "Received Online Firmware Activation quiesce event for controller %u\n", - ctrl_info->ctrl_id); - pqi_ofa_ctrl_quiesce(ctrl_info); - pqi_acknowledge_event(ctrl_info, event); - if (ctrl_info->soft_reset_handshake_supported) { - status = pqi_poll_for_soft_reset_status(ctrl_info); - pqi_process_soft_reset(ctrl_info, status); - } else { - pqi_process_soft_reset(ctrl_info, - RESET_INITIATE_FIRMWARE); - } +static void pqi_ofa_quiesce_worker(struct work_struct *work) +{ + struct pqi_ctrl_info *ctrl_info; + struct pqi_event *event; - } else if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { - pqi_acknowledge_event(ctrl_info, event); - pqi_ofa_setup_host_buffer(ctrl_info, - le32_to_cpu(event->ofa_bytes_requested)); - pqi_ofa_host_memory_update(ctrl_info); - } else if (event_id == PQI_EVENT_OFA_CANCELED) { - pqi_ofa_free_host_buffer(ctrl_info); - pqi_acknowledge_event(ctrl_info, event); + ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_quiesce_work); + + event = &ctrl_info->events[pqi_event_type_to_event_index(PQI_EVENT_TYPE_OFA)]; + + pqi_ofa_ctrl_quiesce(ctrl_info); + pqi_acknowledge_event(ctrl_info, event); + pqi_process_soft_reset(ctrl_info); +} + +static bool pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, + struct pqi_event *event) +{ + bool ack_event; + + ack_event = true; + + switch (event->event_id) { + case PQI_EVENT_OFA_MEMORY_ALLOCATION: + dev_info(&ctrl_info->pci_dev->dev, + "received Online Firmware Activation memory allocation request\n"); + schedule_work(&ctrl_info->ofa_memory_alloc_work); + break; + case PQI_EVENT_OFA_QUIESCE: dev_info(&ctrl_info->pci_dev->dev, - "Online Firmware Activation(%u) cancel reason : %u\n", - ctrl_info->ctrl_id, event->ofa_cancel_reason); + "received Online Firmware Activation quiesce request\n"); + schedule_work(&ctrl_info->ofa_quiesce_work); + ack_event = false; + break; + case PQI_EVENT_OFA_CANCELED: + dev_info(&ctrl_info->pci_dev->dev, + "received Online Firmware Activation cancel request: reason: %u\n", + ctrl_info->ofa_cancel_reason); + pqi_ofa_free_host_buffer(ctrl_info); + pqi_ctrl_ofa_done(ctrl_info); + break; + default: + dev_err(&ctrl_info->pci_dev->dev, + "received unknown Online Firmware Activation request: event ID: %u\n", + event->event_id); + break; } - mutex_unlock(&ctrl_info->ofa_mutex); + return ack_event; } static void pqi_event_worker(struct work_struct *work) { unsigned int i; + bool rescan_needed; struct pqi_ctrl_info *ctrl_info; struct pqi_event *event; + bool ack_event; ctrl_info = container_of(work, struct pqi_ctrl_info, event_work); pqi_ctrl_busy(ctrl_info); - pqi_wait_if_ctrl_blocked(ctrl_info, NO_TIMEOUT); + pqi_wait_if_ctrl_blocked(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) goto out; - pqi_schedule_rescan_worker_delayed(ctrl_info); - + rescan_needed = false; event = ctrl_info->events; for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) { if (event->pending) { event->pending = false; if (event->event_type == PQI_EVENT_TYPE_OFA) { - pqi_ctrl_unbusy(ctrl_info); - pqi_ofa_process_event(ctrl_info, event); - return; + ack_event = pqi_ofa_process_event(ctrl_info, event); + } else { + ack_event = true; + rescan_needed = true; } - pqi_acknowledge_event(ctrl_info, event); + if (ack_event) + pqi_acknowledge_event(ctrl_info, event); } event++; } + if (rescan_needed) + pqi_schedule_rescan_worker_delayed(ctrl_info); + out: pqi_ctrl_unbusy(ctrl_info); } @@ -3377,37 +3431,18 @@ static inline void pqi_stop_heartbeat_timer(struct pqi_ctrl_info *ctrl_info) del_timer_sync(&ctrl_info->heartbeat_timer); } -static inline int pqi_event_type_to_event_index(unsigned int event_type) -{ - int index; - - for (index = 0; index < ARRAY_SIZE(pqi_supported_event_types); index++) - if (event_type == pqi_supported_event_types[index]) - return index; - - return -1; -} - -static inline bool pqi_is_supported_event(unsigned int event_type) -{ - return pqi_event_type_to_event_index(event_type) != -1; -} - -static void pqi_ofa_capture_event_payload(struct pqi_event *event, - struct pqi_event_response *response) +static void pqi_ofa_capture_event_payload(struct pqi_ctrl_info *ctrl_info, + struct pqi_event *event, struct pqi_event_response *response) { - u16 event_id; - - event_id = get_unaligned_le16(&event->event_id); - - if (event->event_type == PQI_EVENT_TYPE_OFA) { - if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) { - event->ofa_bytes_requested = - response->data.ofa_memory_allocation.bytes_requested; - } else if (event_id == PQI_EVENT_OFA_CANCELED) { - event->ofa_cancel_reason = - response->data.ofa_cancelled.reason; - } + switch (event->event_id) { + case PQI_EVENT_OFA_MEMORY_ALLOCATION: + ctrl_info->ofa_bytes_requested = + get_unaligned_le32(&response->data.ofa_memory_allocation.bytes_requested); + break; + case PQI_EVENT_OFA_CANCELED: + ctrl_info->ofa_cancel_reason = + get_unaligned_le16(&response->data.ofa_cancelled.reason); + break; } } @@ -3441,17 +3476,17 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) num_events++; response = event_queue->oq_element_array + (oq_ci * PQI_EVENT_OQ_ELEMENT_LENGTH); - event_index = - pqi_event_type_to_event_index(response->event_type); + event_index = pqi_event_type_to_event_index(response->event_type); if (event_index >= 0 && response->request_acknowledge) { event = &ctrl_info->events[event_index]; event->pending = true; event->event_type = response->event_type; - event->event_id = response->event_id; - event->additional_event_id = response->additional_event_id; + event->event_id = get_unaligned_le16(&response->event_id); + event->additional_event_id = + get_unaligned_le32(&response->additional_event_id); if (event->event_type == PQI_EVENT_TYPE_OFA) - pqi_ofa_capture_event_payload(event, response); + pqi_ofa_capture_event_payload(ctrl_info, event, response); } oq_ci = (oq_ci + 1) % PQI_NUM_EVENT_QUEUE_ELEMENTS; @@ -3468,8 +3503,7 @@ static int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info) #define PQI_LEGACY_INTX_MASK 0x1 -static inline void pqi_configure_legacy_intx(struct pqi_ctrl_info *ctrl_info, - bool enable_intx) +static inline void pqi_configure_legacy_intx(struct pqi_ctrl_info *ctrl_info, bool enable_intx) { u32 intx_mask; struct pqi_device_registers __iomem *pqi_registers; @@ -4147,59 +4181,36 @@ static int pqi_process_raid_io_error_synchronous( return rc; } +static inline bool pqi_is_blockable_request(struct pqi_iu_header *request) +{ + return (request->driver_flags & PQI_DRIVER_NONBLOCKABLE_REQUEST) == 0; +} + static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, struct pqi_iu_header *request, unsigned int flags, - struct pqi_raid_error_info *error_info, unsigned long timeout_msecs) + struct pqi_raid_error_info *error_info) { int rc = 0; struct pqi_io_request *io_request; - unsigned long start_jiffies; - unsigned long msecs_blocked; size_t iu_length; DECLARE_COMPLETION_ONSTACK(wait); - /* - * Note that specifying PQI_SYNC_FLAGS_INTERRUPTABLE and a timeout value - * are mutually exclusive. - */ - if (flags & PQI_SYNC_FLAGS_INTERRUPTABLE) { if (down_interruptible(&ctrl_info->sync_request_sem)) return -ERESTARTSYS; } else { - if (timeout_msecs == NO_TIMEOUT) { - down(&ctrl_info->sync_request_sem); - } else { - start_jiffies = jiffies; - if (down_timeout(&ctrl_info->sync_request_sem, - msecs_to_jiffies(timeout_msecs))) - return -ETIMEDOUT; - msecs_blocked = - jiffies_to_msecs(jiffies - start_jiffies); - if (msecs_blocked >= timeout_msecs) { - rc = -ETIMEDOUT; - goto out; - } - timeout_msecs -= msecs_blocked; - } + down(&ctrl_info->sync_request_sem); } pqi_ctrl_busy(ctrl_info); - timeout_msecs = pqi_wait_if_ctrl_blocked(ctrl_info, timeout_msecs); - if (timeout_msecs == 0) { - pqi_ctrl_unbusy(ctrl_info); - rc = -ETIMEDOUT; - goto out; - } + if (pqi_is_blockable_request(request)) + pqi_wait_if_ctrl_blocked(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) { - pqi_ctrl_unbusy(ctrl_info); rc = -ENXIO; goto out; } - atomic_inc(&ctrl_info->sync_cmds_outstanding); - io_request = pqi_alloc_io_request(ctrl_info); put_unaligned_le16(io_request->index, @@ -4219,18 +4230,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); - pqi_ctrl_unbusy(ctrl_info); - - if (timeout_msecs == NO_TIMEOUT) { - pqi_wait_for_completion_io(ctrl_info, &wait); - } else { - if (!wait_for_completion_io_timeout(&wait, - msecs_to_jiffies(timeout_msecs))) { - dev_warn(&ctrl_info->pci_dev->dev, - "command timed out\n"); - rc = -ETIMEDOUT; - } - } + pqi_wait_for_completion_io(ctrl_info, &wait); if (error_info) { if (io_request->error_info) @@ -4243,8 +4243,8 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, pqi_free_io_request(io_request); - atomic_dec(&ctrl_info->sync_cmds_outstanding); out: + pqi_ctrl_unbusy(ctrl_info); up(&ctrl_info->sync_request_sem); return rc; @@ -4281,8 +4281,7 @@ static int pqi_submit_admin_request_synchronous( rc = pqi_poll_for_admin_response(ctrl_info, response); if (rc == 0) - rc = pqi_validate_admin_response(response, - request->function_code); + rc = pqi_validate_admin_response(response, request->function_code); return rc; } @@ -4652,7 +4651,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, goto out; rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + 0, NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.data.report_event_configuration.sg_descriptors, 1, @@ -4688,7 +4687,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info, goto out; rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0, - NULL, NO_TIMEOUT); + NULL); pqi_pci_unmap(ctrl_info->pci_dev, request.data.report_event_configuration.sg_descriptors, 1, @@ -5208,12 +5207,6 @@ static inline int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, device, scmd, queue_group); } -static inline void pqi_schedule_bypass_retry(struct pqi_ctrl_info *ctrl_info) -{ - if (!pqi_ctrl_blocked(ctrl_info)) - schedule_work(&ctrl_info->raid_bypass_retry_work); -} - static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request) { struct scsi_cmnd *scmd; @@ -5230,7 +5223,7 @@ static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request) return false; device = scmd->device->hostdata; - if (pqi_device_offline(device)) + if (pqi_device_offline(device) || pqi_device_in_remove(device)) return false; ctrl_info = shost_to_hba(scmd->device->host); @@ -5240,155 +5233,26 @@ static bool pqi_raid_bypass_retry_needed(struct pqi_io_request *io_request) return true; } -static inline void pqi_add_to_raid_bypass_retry_list( - struct pqi_ctrl_info *ctrl_info, - struct pqi_io_request *io_request, bool at_head) -{ - unsigned long flags; - - spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags); - if (at_head) - list_add(&io_request->request_list_entry, - &ctrl_info->raid_bypass_retry_list); - else - list_add_tail(&io_request->request_list_entry, - &ctrl_info->raid_bypass_retry_list); - spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags); -} - -static void pqi_queued_raid_bypass_complete(struct pqi_io_request *io_request, +static void pqi_aio_io_complete(struct pqi_io_request *io_request, void *context) { struct scsi_cmnd *scmd; scmd = io_request->scmd; + scsi_dma_unmap(scmd); + if (io_request->status == -EAGAIN || + pqi_raid_bypass_retry_needed(io_request)) + set_host_byte(scmd, DID_IMM_RETRY); pqi_free_io_request(io_request); pqi_scsi_done(scmd); } -static void pqi_queue_raid_bypass_retry(struct pqi_io_request *io_request) +static inline int pqi_aio_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, + struct pqi_queue_group *queue_group) { - struct scsi_cmnd *scmd; - struct pqi_ctrl_info *ctrl_info; - - io_request->io_complete_callback = pqi_queued_raid_bypass_complete; - scmd = io_request->scmd; - scmd->result = 0; - ctrl_info = shost_to_hba(scmd->device->host); - - pqi_add_to_raid_bypass_retry_list(ctrl_info, io_request, false); - pqi_schedule_bypass_retry(ctrl_info); -} - -static int pqi_retry_raid_bypass(struct pqi_io_request *io_request) -{ - struct scsi_cmnd *scmd; - struct pqi_scsi_dev *device; - struct pqi_ctrl_info *ctrl_info; - struct pqi_queue_group *queue_group; - - scmd = io_request->scmd; - device = scmd->device->hostdata; - if (pqi_device_in_reset(device)) { - pqi_free_io_request(io_request); - set_host_byte(scmd, DID_RESET); - pqi_scsi_done(scmd); - return 0; - } - - ctrl_info = shost_to_hba(scmd->device->host); - queue_group = io_request->queue_group; - - pqi_reinit_io_request(io_request); - - return pqi_raid_submit_scsi_cmd_with_io_request(ctrl_info, io_request, - device, scmd, queue_group); -} - -static inline struct pqi_io_request *pqi_next_queued_raid_bypass_request( - struct pqi_ctrl_info *ctrl_info) -{ - unsigned long flags; - struct pqi_io_request *io_request; - - spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags); - io_request = list_first_entry_or_null( - &ctrl_info->raid_bypass_retry_list, - struct pqi_io_request, request_list_entry); - if (io_request) - list_del(&io_request->request_list_entry); - spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags); - - return io_request; -} - -static void pqi_retry_raid_bypass_requests(struct pqi_ctrl_info *ctrl_info) -{ - int rc; - struct pqi_io_request *io_request; - - pqi_ctrl_busy(ctrl_info); - - while (1) { - if (pqi_ctrl_blocked(ctrl_info)) - break; - io_request = pqi_next_queued_raid_bypass_request(ctrl_info); - if (!io_request) - break; - rc = pqi_retry_raid_bypass(io_request); - if (rc) { - pqi_add_to_raid_bypass_retry_list(ctrl_info, io_request, - true); - pqi_schedule_bypass_retry(ctrl_info); - break; - } - } - - pqi_ctrl_unbusy(ctrl_info); -} - -static void pqi_raid_bypass_retry_worker(struct work_struct *work) -{ - struct pqi_ctrl_info *ctrl_info; - - ctrl_info = container_of(work, struct pqi_ctrl_info, - raid_bypass_retry_work); - pqi_retry_raid_bypass_requests(ctrl_info); -} - -static void pqi_clear_all_queued_raid_bypass_retries( - struct pqi_ctrl_info *ctrl_info) -{ - unsigned long flags; - - spin_lock_irqsave(&ctrl_info->raid_bypass_retry_list_lock, flags); - INIT_LIST_HEAD(&ctrl_info->raid_bypass_retry_list); - spin_unlock_irqrestore(&ctrl_info->raid_bypass_retry_list_lock, flags); -} - -static void pqi_aio_io_complete(struct pqi_io_request *io_request, - void *context) -{ - struct scsi_cmnd *scmd; - - scmd = io_request->scmd; - scsi_dma_unmap(scmd); - if (io_request->status == -EAGAIN) - set_host_byte(scmd, DID_IMM_RETRY); - else if (pqi_raid_bypass_retry_needed(io_request)) { - pqi_queue_raid_bypass_retry(io_request); - return; - } - pqi_free_io_request(io_request); - pqi_scsi_done(scmd); -} - -static inline int pqi_aio_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, struct scsi_cmnd *scmd, - struct pqi_queue_group *queue_group) -{ - return pqi_aio_submit_io(ctrl_info, scmd, device->aio_handle, - scmd->cmnd, scmd->cmd_len, queue_group, NULL, false); + return pqi_aio_submit_io(ctrl_info, scmd, device->aio_handle, + scmd->cmnd, scmd->cmd_len, queue_group, NULL, false); } static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, @@ -5629,6 +5493,14 @@ static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, return hw_queue; } +static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd) +{ + if (blk_rq_is_passthrough(scmd->request)) + return false; + + return scmd->retries == 0; +} + /* * This function gets called just before we hand the completed SCSI request * back to the SML. @@ -5737,7 +5609,6 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm bool raid_bypassed; device = scmd->device->hostdata; - ctrl_info = shost_to_hba(shost); if (!device) { set_host_byte(scmd, DID_NO_CONNECT); @@ -5747,15 +5618,15 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm atomic_inc(&device->scsi_cmds_outstanding); + ctrl_info = shost_to_hba(shost); + if (pqi_ctrl_offline(ctrl_info) || pqi_device_in_remove(device)) { set_host_byte(scmd, DID_NO_CONNECT); pqi_scsi_done(scmd); return 0; } - pqi_ctrl_busy(ctrl_info); - if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device) || - pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) { + if (pqi_ctrl_blocked(ctrl_info)) { rc = SCSI_MLQUEUE_HOST_BUSY; goto out; } @@ -5772,13 +5643,12 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm if (pqi_is_logical_device(device)) { raid_bypassed = false; if (device->raid_bypass_enabled && - !blk_rq_is_passthrough(scmd->request)) { - if (!pqi_is_parity_write_stream(ctrl_info, scmd)) { - rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); - if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { - raid_bypassed = true; - atomic_inc(&device->raid_bypass_cnt); - } + pqi_is_bypass_eligible_request(scmd) && + !pqi_is_parity_write_stream(ctrl_info, scmd)) { + rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); + if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { + raid_bypassed = true; + atomic_inc(&device->raid_bypass_cnt); } } if (!raid_bypassed) @@ -5791,7 +5661,6 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm } out: - pqi_ctrl_unbusy(ctrl_info); if (rc) atomic_dec(&device->scsi_cmds_outstanding); @@ -5901,100 +5770,22 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, } } -static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info) -{ - unsigned int i; - unsigned int path; - struct pqi_queue_group *queue_group; - unsigned long flags; - struct pqi_io_request *io_request; - struct pqi_io_request *next; - struct scsi_cmnd *scmd; - - for (i = 0; i < ctrl_info->num_queue_groups; i++) { - queue_group = &ctrl_info->queue_groups[i]; - - for (path = 0; path < 2; path++) { - spin_lock_irqsave(&queue_group->submit_lock[path], - flags); - - list_for_each_entry_safe(io_request, next, - &queue_group->request_list[path], - request_list_entry) { - - scmd = io_request->scmd; - if (!scmd) - continue; - - list_del(&io_request->request_list_entry); - set_host_byte(scmd, DID_RESET); - pqi_scsi_done(scmd); - } - - spin_unlock_irqrestore( - &queue_group->submit_lock[path], flags); - } - } -} - static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, unsigned long timeout_secs) { unsigned long timeout; - timeout = (timeout_secs * PQI_HZ) + jiffies; - - while (atomic_read(&device->scsi_cmds_outstanding)) { - pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - if (timeout_secs != NO_TIMEOUT) { - if (time_after(jiffies, timeout)) { - dev_err(&ctrl_info->pci_dev->dev, - "timed out waiting for pending IO\n"); - return -ETIMEDOUT; - } - } - usleep_range(1000, 2000); - } - - return 0; -} - -static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, - unsigned long timeout_secs) -{ - bool io_pending; - unsigned long flags; - unsigned long timeout; - struct pqi_scsi_dev *device; timeout = (timeout_secs * PQI_HZ) + jiffies; - while (1) { - io_pending = false; - - spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); - list_for_each_entry(device, &ctrl_info->scsi_device_list, - scsi_device_list_entry) { - if (atomic_read(&device->scsi_cmds_outstanding)) { - io_pending = true; - break; - } - } - spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, - flags); - - if (!io_pending) - break; + while (atomic_read(&device->scsi_cmds_outstanding)) { pqi_check_ctrl_health(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; - if (timeout_secs != NO_TIMEOUT) { if (time_after(jiffies, timeout)) { dev_err(&ctrl_info->pci_dev->dev, - "timed out waiting for pending IO\n"); + "timed out waiting for pending I/O\n"); return -ETIMEDOUT; } } @@ -6004,18 +5795,6 @@ static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, return 0; } -static int pqi_ctrl_wait_for_pending_sync_cmds(struct pqi_ctrl_info *ctrl_info) -{ - while (atomic_read(&ctrl_info->sync_cmds_outstanding)) { - pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info)) - return -ENXIO; - usleep_range(1000, 2000); - } - - return 0; -} - static void pqi_lun_reset_complete(struct pqi_io_request *io_request, void *context) { @@ -6087,13 +5866,11 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, return rc; } -/* Performs a reset at the LUN level. */ - #define PQI_LUN_RESET_RETRIES 3 #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 #define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120 -static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info, +static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { int rc; @@ -6119,23 +5896,15 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, { int rc; - mutex_lock(&ctrl_info->lun_reset_mutex); - pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); pqi_fail_io_queued_for_device(ctrl_info, device); rc = pqi_wait_until_inbound_queues_empty(ctrl_info); - pqi_device_reset_start(device); - pqi_ctrl_unblock_requests(ctrl_info); - if (rc) rc = FAILED; else - rc = _pqi_device_reset(ctrl_info, device); - - pqi_device_reset_done(device); - - mutex_unlock(&ctrl_info->lun_reset_mutex); + rc = pqi_lun_reset_with_retries(ctrl_info, device); + pqi_ctrl_unblock_requests(ctrl_info); return rc; } @@ -6151,29 +5920,25 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) ctrl_info = shost_to_hba(shost); device = scmd->device->hostdata; + mutex_lock(&ctrl_info->lun_reset_mutex); + dev_err(&ctrl_info->pci_dev->dev, "resetting scsi %d:%d:%d:%d\n", shost->host_no, device->bus, device->target, device->lun); pqi_check_ctrl_health(ctrl_info); - if (pqi_ctrl_offline(ctrl_info) || - pqi_device_reset_blocked(ctrl_info)) { + if (pqi_ctrl_offline(ctrl_info)) rc = FAILED; - goto out; - } - - pqi_wait_until_ofa_finished(ctrl_info); - - atomic_inc(&ctrl_info->sync_cmds_outstanding); - rc = pqi_device_reset(ctrl_info, device); - atomic_dec(&ctrl_info->sync_cmds_outstanding); + else + rc = pqi_device_reset(ctrl_info, device); -out: dev_err(&ctrl_info->pci_dev->dev, "reset of scsi %d:%d:%d:%d: %s\n", shost->host_no, device->bus, device->target, device->lun, rc == SUCCESS ? "SUCCESS" : "FAILED"); + mutex_unlock(&ctrl_info->lun_reset_mutex); + return rc; } @@ -6475,7 +6240,7 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) put_unaligned_le32(iocommand.Request.Timeout, &request.timeout); rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - PQI_SYNC_FLAGS_INTERRUPTABLE, &pqi_error_info, NO_TIMEOUT); + PQI_SYNC_FLAGS_INTERRUPTABLE, &pqi_error_info); if (iocommand.buf_size > 0) pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, @@ -6527,9 +6292,6 @@ static int pqi_ioctl(struct scsi_device *sdev, unsigned int cmd, ctrl_info = shost_to_hba(sdev->host); - if (pqi_ctrl_in_ofa(ctrl_info) || pqi_ctrl_in_shutdown(ctrl_info)) - return -EBUSY; - switch (cmd) { case CCISS_DEREGDISK: case CCISS_REGNEWDISK: @@ -7076,9 +6838,7 @@ static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info) shost = scsi_host_alloc(&pqi_driver_template, sizeof(ctrl_info)); if (!shost) { - dev_err(&ctrl_info->pci_dev->dev, - "scsi_host_alloc failed for controller %u\n", - ctrl_info->ctrl_id); + dev_err(&ctrl_info->pci_dev->dev, "scsi_host_alloc failed\n"); return -ENOMEM; } @@ -7336,7 +7096,7 @@ static int pqi_config_table_update(struct pqi_ctrl_info *ctrl_info, &request.data.config_table_update.last_section); return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + 0, NULL); } static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info, @@ -7414,7 +7174,8 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, break; case PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE: ctrl_info->soft_reset_handshake_supported = - firmware_feature->enabled; + firmware_feature->enabled && + ctrl_info->soft_reset_status; break; case PQI_FIRMWARE_FEATURE_RAID_IU_TIMEOUT: ctrl_info->raid_iu_timeout_supported = firmware_feature->enabled; @@ -7422,6 +7183,10 @@ static void pqi_ctrl_update_feature_flags(struct pqi_ctrl_info *ctrl_info, case PQI_FIRMWARE_FEATURE_TMF_IU_TIMEOUT: ctrl_info->tmf_iu_timeout_supported = firmware_feature->enabled; break; + case PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN: + ctrl_info->unique_wwid_in_report_phys_lun_supported = + firmware_feature->enabled; + break; } pqi_firmware_feature_status(ctrl_info, firmware_feature); @@ -7512,6 +7277,11 @@ static struct pqi_firmware_feature pqi_firmware_features[] = { .feature_bit = PQI_FIRMWARE_FEATURE_RAID_BYPASS_ON_ENCRYPTED_NVME, .feature_status = pqi_firmware_feature_status, }, + { + .feature_name = "Unique WWID in Report Physical LUN", + .feature_bit = PQI_FIRMWARE_FEATURE_UNIQUE_WWID_IN_REPORT_PHYS_LUN, + .feature_status = pqi_ctrl_update_feature_flags, + }, }; static void pqi_process_firmware_features( @@ -7596,14 +7366,34 @@ static void pqi_process_firmware_features_section( mutex_unlock(&pqi_firmware_features_mutex); } +/* + * Reset all controller settings that can be initialized during the processing + * of the PQI Configuration Table. + */ + +static void pqi_ctrl_reset_config(struct pqi_ctrl_info *ctrl_info) +{ + ctrl_info->heartbeat_counter = NULL; + ctrl_info->soft_reset_status = NULL; + ctrl_info->soft_reset_handshake_supported = false; + ctrl_info->enable_r1_writes = false; + ctrl_info->enable_r5_writes = false; + ctrl_info->enable_r6_writes = false; + ctrl_info->raid_iu_timeout_supported = false; + ctrl_info->tmf_iu_timeout_supported = false; + ctrl_info->unique_wwid_in_report_phys_lun_supported = false; +} + static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) { u32 table_length; u32 section_offset; + bool firmware_feature_section_present; void __iomem *table_iomem_addr; struct pqi_config_table *config_table; struct pqi_config_table_section_header *section; struct pqi_config_table_section_info section_info; + struct pqi_config_table_section_info feature_section_info; table_length = ctrl_info->config_table_length; if (table_length == 0) @@ -7623,6 +7413,7 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) table_iomem_addr = ctrl_info->iomem_base + ctrl_info->config_table_offset; memcpy_fromio(config_table, table_iomem_addr, table_length); + firmware_feature_section_present = false; section_info.ctrl_info = ctrl_info; section_offset = get_unaligned_le32(&config_table->first_section_offset); @@ -7635,7 +7426,8 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) switch (get_unaligned_le16(§ion->section_id)) { case PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES: - pqi_process_firmware_features_section(§ion_info); + firmware_feature_section_present = true; + feature_section_info = section_info; break; case PQI_CONFIG_TABLE_SECTION_HEARTBEAT: if (pqi_disable_heartbeat) @@ -7653,13 +7445,21 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info) table_iomem_addr + section_offset + offsetof(struct pqi_config_table_soft_reset, - soft_reset_status); + soft_reset_status); break; } section_offset = get_unaligned_le16(§ion->next_section_offset); } + /* + * We process the firmware feature section after all other sections + * have been processed so that the feature bit callbacks can take + * into account the settings configured by other sections. + */ + if (firmware_feature_section_present) + pqi_process_firmware_features_section(&feature_section_info); + kfree(config_table); return 0; @@ -7707,8 +7507,6 @@ static int pqi_force_sis_mode(struct pqi_ctrl_info *ctrl_info) return pqi_revert_to_sis_mode(ctrl_info); } -#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000 - static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) { int rc; @@ -7716,7 +7514,7 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info) if (reset_devices) { sis_soft_reset(ctrl_info); - msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); + msleep(PQI_POST_RESET_DELAY_SECS * PQI_HZ); } else { rc = pqi_force_sis_mode(ctrl_info); if (rc) @@ -8026,6 +7824,8 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) ctrl_info->controller_online = true; pqi_ctrl_unblock_requests(ctrl_info); + pqi_ctrl_reset_config(ctrl_info); + rc = pqi_process_config_table(ctrl_info); if (rc) return rc; @@ -8071,7 +7871,8 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) return rc; } - pqi_schedule_update_time_worker(ctrl_info); + if (pqi_ofa_in_progress(ctrl_info)) + pqi_ctrl_unblock_scan(ctrl_info); pqi_scan_scsi_devices(ctrl_info); @@ -8184,7 +7985,6 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) INIT_WORK(&ctrl_info->event_work, pqi_event_worker); atomic_set(&ctrl_info->num_interrupts, 0); - atomic_set(&ctrl_info->sync_cmds_outstanding, 0); INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker); INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker); @@ -8192,15 +7992,13 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) timer_setup(&ctrl_info->heartbeat_timer, pqi_heartbeat_timer_handler, 0); INIT_WORK(&ctrl_info->ctrl_offline_work, pqi_ctrl_offline_worker); + INIT_WORK(&ctrl_info->ofa_memory_alloc_work, pqi_ofa_memory_alloc_worker); + INIT_WORK(&ctrl_info->ofa_quiesce_work, pqi_ofa_quiesce_worker); + sema_init(&ctrl_info->sync_request_sem, PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS); init_waitqueue_head(&ctrl_info->block_requests_wait); - INIT_LIST_HEAD(&ctrl_info->raid_bypass_retry_list); - spin_lock_init(&ctrl_info->raid_bypass_retry_list_lock); - INIT_WORK(&ctrl_info->raid_bypass_retry_work, - pqi_raid_bypass_retry_worker); - ctrl_info->ctrl_id = atomic_inc_return(&pqi_controller_count) - 1; ctrl_info->irq_mode = IRQ_MODE_NONE; ctrl_info->max_msix_vectors = PQI_MAX_MSIX_VECTORS; @@ -8265,81 +8063,57 @@ static void pqi_remove_ctrl(struct pqi_ctrl_info *ctrl_info) static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info) { - pqi_cancel_update_time_worker(ctrl_info); - pqi_cancel_rescan_worker(ctrl_info); - pqi_wait_until_lun_reset_finished(ctrl_info); - pqi_wait_until_scan_finished(ctrl_info); - pqi_ctrl_ofa_start(ctrl_info); + pqi_ctrl_block_scan(ctrl_info); + pqi_scsi_block_requests(ctrl_info); + pqi_ctrl_block_device_reset(ctrl_info); pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); - pqi_ctrl_wait_for_pending_io(ctrl_info, PQI_PENDING_IO_TIMEOUT_SECS); - pqi_fail_io_queued_for_all_devices(ctrl_info); - pqi_wait_until_inbound_queues_empty(ctrl_info); pqi_stop_heartbeat_timer(ctrl_info); - ctrl_info->pqi_mode_enabled = false; - pqi_save_ctrl_mode(ctrl_info, SIS_MODE); } static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info) { - pqi_ofa_free_host_buffer(ctrl_info); - ctrl_info->pqi_mode_enabled = true; - pqi_save_ctrl_mode(ctrl_info, PQI_MODE); - ctrl_info->controller_online = true; - pqi_ctrl_unblock_requests(ctrl_info); pqi_start_heartbeat_timer(ctrl_info); - pqi_schedule_update_time_worker(ctrl_info); - pqi_clear_soft_reset_status(ctrl_info, - PQI_SOFT_RESET_ABORT); - pqi_scan_scsi_devices(ctrl_info); + pqi_ctrl_unblock_requests(ctrl_info); + pqi_ctrl_unblock_device_reset(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + pqi_ctrl_unblock_scan(ctrl_info); } -static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, - u32 total_size, u32 chunk_size) +static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, u32 total_size, u32 chunk_size) { - u32 sg_count; - u32 size; int i; - struct pqi_sg_descriptor *mem_descriptor = NULL; + u32 sg_count; struct device *dev; struct pqi_ofa_memory *ofap; - - dev = &ctrl_info->pci_dev->dev; - - sg_count = (total_size + chunk_size - 1); - sg_count /= chunk_size; + struct pqi_sg_descriptor *mem_descriptor; + dma_addr_t dma_handle; ofap = ctrl_info->pqi_ofa_mem_virt_addr; - if (sg_count*chunk_size < total_size) + sg_count = DIV_ROUND_UP(total_size, chunk_size); + if (sg_count == 0 || sg_count > PQI_OFA_MAX_SG_DESCRIPTORS) goto out; - ctrl_info->pqi_ofa_chunk_virt_addr = - kcalloc(sg_count, sizeof(void *), GFP_KERNEL); + ctrl_info->pqi_ofa_chunk_virt_addr = kmalloc_array(sg_count, sizeof(void *), GFP_KERNEL); if (!ctrl_info->pqi_ofa_chunk_virt_addr) goto out; - for (size = 0, i = 0; size < total_size; size += chunk_size, i++) { - dma_addr_t dma_handle; + dev = &ctrl_info->pci_dev->dev; + for (i = 0; i < sg_count; i++) { ctrl_info->pqi_ofa_chunk_virt_addr[i] = - dma_alloc_coherent(dev, chunk_size, &dma_handle, - GFP_KERNEL); - + dma_alloc_coherent(dev, chunk_size, &dma_handle, GFP_KERNEL); if (!ctrl_info->pqi_ofa_chunk_virt_addr[i]) - break; - + goto out_free_chunks; mem_descriptor = &ofap->sg_descriptor[i]; put_unaligned_le64((u64)dma_handle, &mem_descriptor->address); put_unaligned_le32(chunk_size, &mem_descriptor->length); } - if (!size || size < total_size) - goto out_free_chunks; - put_unaligned_le32(CISS_SG_LAST, &mem_descriptor->flags); put_unaligned_le16(sg_count, &ofap->num_memory_descriptors); - put_unaligned_le32(size, &ofap->bytes_allocated); + put_unaligned_le32(sg_count * chunk_size, &ofap->bytes_allocated); return 0; @@ -8347,82 +8121,87 @@ static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info, while (--i >= 0) { mem_descriptor = &ofap->sg_descriptor[i]; dma_free_coherent(dev, chunk_size, - ctrl_info->pqi_ofa_chunk_virt_addr[i], - get_unaligned_le64(&mem_descriptor->address)); + ctrl_info->pqi_ofa_chunk_virt_addr[i], + get_unaligned_le64(&mem_descriptor->address)); } kfree(ctrl_info->pqi_ofa_chunk_virt_addr); out: - put_unaligned_le32 (0, &ofap->bytes_allocated); return -ENOMEM; } static int pqi_ofa_alloc_host_buffer(struct pqi_ctrl_info *ctrl_info) { u32 total_size; + u32 chunk_size; u32 min_chunk_size; - u32 chunk_sz; - total_size = le32_to_cpu( - ctrl_info->pqi_ofa_mem_virt_addr->bytes_allocated); - min_chunk_size = total_size / PQI_OFA_MAX_SG_DESCRIPTORS; + if (ctrl_info->ofa_bytes_requested == 0) + return 0; - for (chunk_sz = total_size; chunk_sz >= min_chunk_size; chunk_sz /= 2) - if (!pqi_ofa_alloc_mem(ctrl_info, total_size, chunk_sz)) + total_size = PAGE_ALIGN(ctrl_info->ofa_bytes_requested); + min_chunk_size = DIV_ROUND_UP(total_size, PQI_OFA_MAX_SG_DESCRIPTORS); + min_chunk_size = PAGE_ALIGN(min_chunk_size); + + for (chunk_size = total_size; chunk_size >= min_chunk_size;) { + if (pqi_ofa_alloc_mem(ctrl_info, total_size, chunk_size) == 0) return 0; + chunk_size /= 2; + chunk_size = PAGE_ALIGN(chunk_size); + } return -ENOMEM; } -static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info, - u32 bytes_requested) +static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info) { - struct pqi_ofa_memory *pqi_ofa_memory; struct device *dev; + struct pqi_ofa_memory *ofap; dev = &ctrl_info->pci_dev->dev; - pqi_ofa_memory = dma_alloc_coherent(dev, - PQI_OFA_MEMORY_DESCRIPTOR_LENGTH, - &ctrl_info->pqi_ofa_mem_dma_handle, - GFP_KERNEL); - if (!pqi_ofa_memory) + ofap = dma_alloc_coherent(dev, sizeof(*ofap), + &ctrl_info->pqi_ofa_mem_dma_handle, GFP_KERNEL); + if (!ofap) return; - put_unaligned_le16(PQI_OFA_VERSION, &pqi_ofa_memory->version); - memcpy(&pqi_ofa_memory->signature, PQI_OFA_SIGNATURE, - sizeof(pqi_ofa_memory->signature)); - pqi_ofa_memory->bytes_allocated = cpu_to_le32(bytes_requested); - - ctrl_info->pqi_ofa_mem_virt_addr = pqi_ofa_memory; + ctrl_info->pqi_ofa_mem_virt_addr = ofap; if (pqi_ofa_alloc_host_buffer(ctrl_info) < 0) { - dev_err(dev, "Failed to allocate host buffer of size = %u", - bytes_requested); + dev_err(dev, + "failed to allocate host buffer for Online Firmware Activation\n"); + dma_free_coherent(dev, sizeof(*ofap), ofap, ctrl_info->pqi_ofa_mem_dma_handle); + ctrl_info->pqi_ofa_mem_virt_addr = NULL; + return; } - return; + put_unaligned_le16(PQI_OFA_VERSION, &ofap->version); + memcpy(&ofap->signature, PQI_OFA_SIGNATURE, sizeof(ofap->signature)); } static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info) { - int i; - struct pqi_sg_descriptor *mem_descriptor; + unsigned int i; + struct device *dev; struct pqi_ofa_memory *ofap; + struct pqi_sg_descriptor *mem_descriptor; + unsigned int num_memory_descriptors; ofap = ctrl_info->pqi_ofa_mem_virt_addr; - if (!ofap) return; - if (!ofap->bytes_allocated) + dev = &ctrl_info->pci_dev->dev; + + if (get_unaligned_le32(&ofap->bytes_allocated) == 0) goto out; mem_descriptor = ofap->sg_descriptor; + num_memory_descriptors = + get_unaligned_le16(&ofap->num_memory_descriptors); - for (i = 0; i < get_unaligned_le16(&ofap->num_memory_descriptors); - i++) { - dma_free_coherent(&ctrl_info->pci_dev->dev, + for (i = 0; i < num_memory_descriptors; i++) { + dma_free_coherent(dev, get_unaligned_le32(&mem_descriptor[i].length), ctrl_info->pqi_ofa_chunk_virt_addr[i], get_unaligned_le64(&mem_descriptor[i].address)); @@ -8430,47 +8209,46 @@ static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info) kfree(ctrl_info->pqi_ofa_chunk_virt_addr); out: - dma_free_coherent(&ctrl_info->pci_dev->dev, - PQI_OFA_MEMORY_DESCRIPTOR_LENGTH, ofap, - ctrl_info->pqi_ofa_mem_dma_handle); + dma_free_coherent(dev, sizeof(*ofap), ofap, + ctrl_info->pqi_ofa_mem_dma_handle); ctrl_info->pqi_ofa_mem_virt_addr = NULL; } static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info) { + u32 buffer_length; struct pqi_vendor_general_request request; - size_t size; struct pqi_ofa_memory *ofap; memset(&request, 0, sizeof(request)); - ofap = ctrl_info->pqi_ofa_mem_virt_addr; - request.header.iu_type = PQI_REQUEST_IU_VENDOR_GENERAL; put_unaligned_le16(sizeof(request) - PQI_REQUEST_HEADER_LENGTH, &request.header.iu_length); put_unaligned_le16(PQI_VENDOR_GENERAL_HOST_MEMORY_UPDATE, &request.function_code); + ofap = ctrl_info->pqi_ofa_mem_virt_addr; + if (ofap) { - size = offsetof(struct pqi_ofa_memory, sg_descriptor) + + buffer_length = offsetof(struct pqi_ofa_memory, sg_descriptor) + get_unaligned_le16(&ofap->num_memory_descriptors) * sizeof(struct pqi_sg_descriptor); put_unaligned_le64((u64)ctrl_info->pqi_ofa_mem_dma_handle, &request.data.ofa_memory_allocation.buffer_address); - put_unaligned_le32(size, + put_unaligned_le32(buffer_length, &request.data.ofa_memory_allocation.buffer_length); - } return pqi_submit_raid_request_synchronous(ctrl_info, &request.header, - 0, NULL, NO_TIMEOUT); + 0, NULL); } -static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info) +static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int delay_secs) { - msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY); + ssleep(delay_secs); + return pqi_ctrl_init_resume(ctrl_info); } @@ -8528,7 +8306,6 @@ static void pqi_take_ctrl_offline_deferred(struct pqi_ctrl_info *ctrl_info) pqi_cancel_update_time_worker(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); pqi_fail_all_outstanding_requests(ctrl_info); - pqi_clear_all_queued_raid_bypass_retries(ctrl_info); pqi_ctrl_unblock_requests(ctrl_info); } @@ -8661,24 +8438,12 @@ static void pqi_shutdown(struct pci_dev *pci_dev) return; } - pqi_disable_events(ctrl_info); pqi_wait_until_ofa_finished(ctrl_info); - pqi_cancel_update_time_worker(ctrl_info); - pqi_cancel_rescan_worker(ctrl_info); - pqi_cancel_event_worker(ctrl_info); - - pqi_ctrl_shutdown_start(ctrl_info); - pqi_ctrl_wait_until_quiesced(ctrl_info); - - rc = pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT); - if (rc) { - dev_err(&pci_dev->dev, - "wait for pending I/O failed\n"); - return; - } + pqi_scsi_block_requests(ctrl_info); pqi_ctrl_block_device_reset(ctrl_info); - pqi_wait_until_lun_reset_finished(ctrl_info); + pqi_ctrl_block_requests(ctrl_info); + pqi_ctrl_wait_until_quiesced(ctrl_info); /* * Write all data in the controller's battery-backed cache to @@ -8689,15 +8454,6 @@ static void pqi_shutdown(struct pci_dev *pci_dev) dev_err(&pci_dev->dev, "unable to flush controller cache\n"); - pqi_ctrl_block_requests(ctrl_info); - - rc = pqi_ctrl_wait_for_pending_sync_cmds(ctrl_info); - if (rc) { - dev_err(&pci_dev->dev, - "wait for pending sync cmds failed\n"); - return; - } - pqi_crash_if_pending_command(ctrl_info); pqi_reset(ctrl_info); } @@ -8732,19 +8488,18 @@ static __maybe_unused int pqi_suspend(struct pci_dev *pci_dev, pm_message_t stat ctrl_info = pci_get_drvdata(pci_dev); - pqi_disable_events(ctrl_info); - pqi_cancel_update_time_worker(ctrl_info); - pqi_cancel_rescan_worker(ctrl_info); - pqi_wait_until_scan_finished(ctrl_info); - pqi_wait_until_lun_reset_finished(ctrl_info); pqi_wait_until_ofa_finished(ctrl_info); - pqi_flush_cache(ctrl_info, SUSPEND); + + pqi_ctrl_block_scan(ctrl_info); + pqi_scsi_block_requests(ctrl_info); + pqi_ctrl_block_device_reset(ctrl_info); pqi_ctrl_block_requests(ctrl_info); pqi_ctrl_wait_until_quiesced(ctrl_info); - pqi_wait_until_inbound_queues_empty(ctrl_info); - pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT); + pqi_flush_cache(ctrl_info, SUSPEND); pqi_stop_heartbeat_timer(ctrl_info); + pqi_crash_if_pending_command(ctrl_info); + if (state.event == PM_EVENT_FREEZE) return 0; @@ -8777,8 +8532,10 @@ static __maybe_unused int pqi_resume(struct pci_dev *pci_dev) pci_dev->irq, rc); return rc; } - pqi_start_heartbeat_timer(ctrl_info); + pqi_ctrl_unblock_device_reset(ctrl_info); pqi_ctrl_unblock_requests(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + pqi_ctrl_unblock_scan(ctrl_info); return 0; } @@ -9219,7 +8976,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_iu_header, response_queue_id) != 0x4); BUILD_BUG_ON(offsetof(struct pqi_iu_header, - work_area) != 0x6); + driver_flags) != 0x6); BUILD_BUG_ON(sizeof(struct pqi_iu_header) != 0x8); BUILD_BUG_ON(offsetof(struct pqi_aio_error_info, @@ -9317,7 +9074,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, header.iu_length) != 2); BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_general_admin_request, @@ -9373,7 +9130,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, header.iu_length) != 2); BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_general_admin_response, @@ -9397,7 +9154,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, header.response_queue_id) != 4); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_raid_path_request, @@ -9426,7 +9183,7 @@ static void __attribute__((unused)) verify_structures(void) BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, header.response_queue_id) != 4); BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, - header.work_area) != 6); + header.driver_flags) != 6); BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, request_id) != 8); BUILD_BUG_ON(offsetof(struct pqi_aio_path_request, From patchwork Fri Dec 4 23:02:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2680FC433FE for ; Fri, 4 Dec 2020 23:03:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EFC2122D01 for ; Fri, 4 Dec 2020 23:03:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727883AbgLDXDu (ORCPT ); Fri, 4 Dec 2020 18:03:50 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1374 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727348AbgLDXDu (ORCPT ); Fri, 4 Dec 2020 18:03:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123030; x=1638659030; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=pjfu8r41g7xridLJ0i98fuv1C0sQXap513gkj+n0C0U=; b=rs2u2irvubLQ+tj4MNLTTB29c1LX6ND4DtHquUXA3OyXTc08Ze8H/ClQ IETGUtBYJlicMUJpLSCAgkJfU07akrCG2MhEsZ53fpjx8yedzoctlkWxC 62BIivno6Jkh+06tT9UgPH/JiKg4SP13CtJUP+WZ8ZJxC2EpgrmHOXww3 z9zVjsIKsv1dQbkkE6n1ZBJx2AbNcO5baOGqUtTHivnq344O+tKjzwofY NTh2dOEAzpH8P6b8521QoGYlHx/Cvu2AI6thUEC24MfLcpBO8I9l1iys8 7LXoshgouD1zLDNptbYl1xF3qe1pM3wdjjxoiuxUDTR9lLXxdIV63lmXe w==; IronPort-SDR: VlnmJrKOkz0xcXXor1YBRJp0bDt+WSY/eKU4GKIIqPMo3XFVo1lHHULUrxg4GJ+5RgISNMCMIo dbdoI5Nkh6IG5Qi2Wbl6vXuuuz3uLx82dW73Fx3DKqOHaSzyhIWXcgGP4kMavOpbl9MdyhtFWx gRFb4/Gd2MvUeEXr8bQOihm+ysEIp1rY2HGGKZnFL1mMC+L1W2FVo+zT42LcZT7FRSDV0shHkK yWA9eNlxTvMPpUoEXHgE7HBb1t+9vFMugYbe2rhaGWn7ntZAY/a3sOyB1iODcQEarmozl0jPU7 IG0= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548802" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:20 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:18 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:17 -0700 Subject: [PATCH 15/25] smartpqi: fix host qdepth limit From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:17 -0600 Message-ID: <160712293782.21372.12605446472261001024.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Mahesh Rajashekhara * Correct scsi-mid-layer sending more requests than exposed host Q depth causing firmware ASSERT issue. * Add host Qdepth counter. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Mahesh Rajashekhara Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 2 ++ drivers/scsi/smartpqi/smartpqi_init.c | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index 0b94c755a74c..c3b103b15924 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1345,6 +1345,8 @@ struct pqi_ctrl_info { struct work_struct ofa_quiesce_work; u32 ofa_bytes_requested; u16 ofa_cancel_reason; + + atomic_t total_scmds_outstanding; }; enum pqi_ctrl_mode { diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 0472ba6de43b..a9856cc9a951 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5509,6 +5509,8 @@ static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd) void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd) { struct pqi_scsi_dev *device; + struct pqi_ctrl_info *ctrl_info; + struct Scsi_Host *shost; if (!scmd->device) { set_host_byte(scmd, DID_NO_CONNECT); @@ -5521,7 +5523,11 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd) return; } + shost = scmd->device->host; + ctrl_info = shost_to_hba(shost); + atomic_dec(&device->scsi_cmds_outstanding); + atomic_dec(&ctrl_info->total_scmds_outstanding); } static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info, @@ -5609,6 +5615,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm bool raid_bypassed; device = scmd->device->hostdata; + ctrl_info = shost_to_hba(shost); if (!device) { set_host_byte(scmd, DID_NO_CONNECT); @@ -5617,8 +5624,11 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm } atomic_inc(&device->scsi_cmds_outstanding); - - ctrl_info = shost_to_hba(shost); + if (atomic_inc_return(&ctrl_info->total_scmds_outstanding) > + ctrl_info->scsi_ml_can_queue) { + rc = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } if (pqi_ctrl_offline(ctrl_info) || pqi_device_in_remove(device)) { set_host_byte(scmd, DID_NO_CONNECT); @@ -5661,8 +5671,10 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm } out: - if (rc) + if (rc) { atomic_dec(&device->scsi_cmds_outstanding); + atomic_dec(&ctrl_info->total_scmds_outstanding); + } return rc; } @@ -7985,6 +7997,7 @@ static struct pqi_ctrl_info *pqi_alloc_ctrl_info(int numa_node) INIT_WORK(&ctrl_info->event_work, pqi_event_worker); atomic_set(&ctrl_info->num_interrupts, 0); + atomic_set(&ctrl_info->total_scmds_outstanding, 0); INIT_DELAYED_WORK(&ctrl_info->rescan_work, pqi_rescan_worker); INIT_DELAYED_WORK(&ctrl_info->update_time_work, pqi_update_time_worker); From patchwork Fri Dec 4 23:02:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338138 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E4CAC433FE for ; Fri, 4 Dec 2020 23:03:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 40A5222D01 for ; Fri, 4 Dec 2020 23:03:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727195AbgLDXDI (ORCPT ); Fri, 4 Dec 2020 18:03:08 -0500 Received: from esa4.microchip.iphmx.com ([68.232.154.123]:48973 "EHLO esa4.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727186AbgLDXDH (ORCPT ); Fri, 4 Dec 2020 18:03:07 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607122987; x=1638658987; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=sXUcvXC/ZItNl9JW38wnQSR4IGVQomuEtqjH5+B5Iog=; b=m+BJvASZqzdAAq3f3JcYsL+dMTh/sd004ArftWdwgc84zmG/AYqMQkiz FArKEz9qBzV60YvuLmxCMAX6npuAq2+fpAfweyHvvzpxks8Ope5xFwCeW Fjfyf/KsNfmppD/z06bDbk2m3rtosy+B0nS4A3bgGV02G4UEeDfcIWSFU ZTDZUJsaZpbTil67PEZEzioLvikLY4xIG37adcgSXRUOZId/fMGXLEkUv g4a8700D5pIOB5FYywFdpVOaXprMkTsUQHcv2O+QXP7kdeEFAgW0tZb18 m5IR9TBVGRMxKwoE6jI7DNRRBGare+jnO9lYUQva5gLKKjC9bXHHobz1h g==; IronPort-SDR: o59hvk7e7adDJf2581LcyBwZKgnaXCpInG/jEMeYTG0XohSnVLnCMQg93lios/C9B7Mbx8dk+X vK6XR2CED9pW4DfiwOQXYW/LBqIma1JjVPAI3abBYLlKcI1aJCjhz9IAOEWIvf4jZXnyii5Wz/ ffC3FTFnK/cehXljsOPw85ySCAtPziUARbvXmYBXtxmGyvwpxC8C8b/Am+7/w4qWPSKowxfDoL DMvte66Lq2iPkpp8LAoxf3LsH7FkAW5QU4oPZRvBiaJBzSnrJnaadPvFQNJxJv7WuayNMcccmq AJc= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="95934650" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:24 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:24 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:23 -0700 Subject: [PATCH 16/25] smartpqi: convert snprintf to scnprintf From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:23 -0600 Message-ID: <160712294365.21372.18410124969166927118.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett The entire Linux kernel has been slowly migrating from snprintf to scnprintf, so we are doing our part. This article explains the rationale for this change: https: //lwn.net/Articles/69419/ Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index a9856cc9a951..f96b8ce2edba 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1750,7 +1750,7 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info, ssize_t count; char buffer[PQI_DEV_INFO_BUFFER_LENGTH]; - count = snprintf(buffer, PQI_DEV_INFO_BUFFER_LENGTH, + count = scnprintf(buffer, PQI_DEV_INFO_BUFFER_LENGTH, "%d:%d:", ctrl_info->scsi_host->host_no, device->bus); if (device->target_lun_valid) @@ -6336,14 +6336,13 @@ static ssize_t pqi_firmware_version_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->firmware_version); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->firmware_version); } static ssize_t pqi_driver_version_show(struct device *dev, struct device_attribute *attr, char *buffer) { - return snprintf(buffer, PAGE_SIZE, "%s\n", - DRIVER_VERSION BUILD_TIMESTAMP); + return scnprintf(buffer, PAGE_SIZE, "%s\n", DRIVER_VERSION BUILD_TIMESTAMP); } static ssize_t pqi_serial_number_show(struct device *dev, @@ -6355,7 +6354,7 @@ static ssize_t pqi_serial_number_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->serial_number); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->serial_number); } static ssize_t pqi_model_show(struct device *dev, @@ -6367,7 +6366,7 @@ static ssize_t pqi_model_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->model); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->model); } static ssize_t pqi_vendor_show(struct device *dev, @@ -6379,7 +6378,7 @@ static ssize_t pqi_vendor_show(struct device *dev, shost = class_to_shost(dev); ctrl_info = shost_to_hba(shost); - return snprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->vendor); + return scnprintf(buffer, PAGE_SIZE, "%s\n", ctrl_info->vendor); } static ssize_t pqi_host_rescan_store(struct device *dev, @@ -6573,7 +6572,7 @@ static ssize_t pqi_unique_id_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, + return scnprintf(buffer, PAGE_SIZE, "%02X%02X%02X%02X%02X%02X%02X%02X" "%02X%02X%02X%02X%02X%02X%02X%02X\n", unique_id[0], unique_id[1], unique_id[2], unique_id[3], @@ -6606,7 +6605,7 @@ static ssize_t pqi_lunid_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid); + return scnprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid); } #define MAX_PATHS 8 @@ -6718,7 +6717,7 @@ static ssize_t pqi_sas_address_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "0x%016llx\n", sas_address); + return scnprintf(buffer, PAGE_SIZE, "0x%016llx\n", sas_address); } static ssize_t pqi_ssd_smart_path_enabled_show(struct device *dev, @@ -6776,7 +6775,7 @@ static ssize_t pqi_raid_level_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "%s\n", raid_level); + return scnprintf(buffer, PAGE_SIZE, "%s\n", raid_level); } static ssize_t pqi_raid_bypass_cnt_show(struct device *dev, @@ -6803,7 +6802,7 @@ static ssize_t pqi_raid_bypass_cnt_show(struct device *dev, spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); - return snprintf(buffer, PAGE_SIZE, "0x%x\n", raid_bypass_cnt); + return scnprintf(buffer, PAGE_SIZE, "0x%x\n", raid_bypass_cnt); } static DEVICE_ATTR(lunid, 0444, pqi_lunid_show, NULL); From patchwork Fri Dec 4 23:02:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338620 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E406C4361A for ; Fri, 4 Dec 2020 23:03:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EAE5C22C9E for ; Fri, 4 Dec 2020 23:03:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728623AbgLDXDy (ORCPT ); Fri, 4 Dec 2020 18:03:54 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1478 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727348AbgLDXDy (ORCPT ); Fri, 4 Dec 2020 18:03:54 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123034; x=1638659034; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=EAW0KLglLv6Sbl5qFiNslj10+GLqM/6dOaN0YY8QieI=; b=OThHDZVCA7t/ZWCQ9lk218sQc16z5D1TAYoHuCfr2A+S7tZ1UjZ9rKie qBi5HAFuFv9KeSUvG2ISqNska6WVx14NrvyWQ8pV06CI6TVaRx85Imchx 1pYg7Q/M8ZvGAOgvxcNpNCHTXvbBtV7ftN+eP6pgSuuOD3tglo/5VejUO 4VTseQm+3BCaYpR9YlsxkNmWLTiCSYOYEjl7C29L14hKajRZrBkqD2rkJ iY2x7ZQu/UkR3TJ4S+vNFKTqi5OV856PjhCDNetwmqghPiQqPfj6ep2eC HXHrPhB3OXKeYZrXz53LcXi3JOaYUjc/THLGoAiuG0mmlyUt8AxYCFnCg Q==; IronPort-SDR: 9xCAEen3VfUoeLoaywkR4/c7OlYO2i4vF18wWZ3t6aAKiXavBqkHNx0OAZ5MVyQFVRI7/cAhYV X32QRq7Xw/eVF/PczMs68Eqz/eaUzVCgc4oyJu4YXHWbXmiB49kHsNtwef5UZl1HD6mRWSt9kM FA+CdMZ9s6kfBPSTsehtvQE/7L2UtAbt4Vxd8NeVwLTpb+0W0meUFE1jPUoA0WvcdzQQ/Uh/FF UfmaS0mLNi0NTlR3KoOPo32ypwY/O4q1fPpYTLua2wmEnbE1iDWhbAdzP5qCVoYthq0iQ/e+vx UpA= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548884" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:30 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:30 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:29 -0700 Subject: [PATCH 17/25] smartpqi: change timing of release of QRM memory during OFA From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:29 -0600 Message-ID: <160712294945.21372.4369424711794317420.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Release QRM memory (OFA buffer) on OFA error conditions. * Controller is left in a bad state which can cause a kernel panic upon reboot after an unsuccessful OFA. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index f96b8ce2edba..52f59ae50fda 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -3236,8 +3236,6 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) else reset_status = RESET_INITIATE_FIRMWARE; - pqi_ofa_free_host_buffer(ctrl_info); - delay_secs = PQI_POST_RESET_DELAY_SECS; switch (reset_status) { @@ -3253,6 +3251,7 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) ctrl_info->pqi_mode_enabled = false; pqi_save_ctrl_mode(ctrl_info, SIS_MODE); rc = pqi_ofa_ctrl_restart(ctrl_info, delay_secs); + pqi_ofa_free_host_buffer(ctrl_info); pqi_ctrl_ofa_done(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, "Online Firmware Activation: %s\n", @@ -3263,6 +3262,7 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) "Online Firmware Activation ABORTED\n"); if (ctrl_info->soft_reset_handshake_supported) pqi_clear_soft_reset_status(ctrl_info); + pqi_ofa_free_host_buffer(ctrl_info); pqi_ctrl_ofa_done(ctrl_info); pqi_ofa_ctrl_unquiesce(ctrl_info); break; @@ -3272,6 +3272,7 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) dev_err(&ctrl_info->pci_dev->dev, "unexpected Online Firmware Activation reset status: 0x%x\n", reset_status); + pqi_ofa_free_host_buffer(ctrl_info); pqi_ctrl_ofa_done(ctrl_info); pqi_ofa_ctrl_unquiesce(ctrl_info); pqi_take_ctrl_offline(ctrl_info); From patchwork Fri Dec 4 23:02:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C4CAC4361A for ; Fri, 4 Dec 2020 23:03:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C74DF22C9E for ; Fri, 4 Dec 2020 23:03:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727266AbgLDXDY (ORCPT ); Fri, 4 Dec 2020 18:03:24 -0500 Received: from esa6.microchip.iphmx.com ([216.71.154.253]:21231 "EHLO esa6.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725885AbgLDXDY (ORCPT ); Fri, 4 Dec 2020 18:03:24 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123003; x=1638659003; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jK8Ao6vti47kIYtZeEfaypWBis8c7YLbSL2H2Sqzbmw=; b=w8nWH9VctVHv2m7dk+r9WUfH5bCYPd1V0q4wlear+cDlRKm9vztOoVgF Li+s2RybB3aJdDyYs1RNdCzBWbtmTpq9WHD+hPFdUkB4fEwuwsjVMK/hL x1Yj9ESU/Nm0+6iq/NM1JocpOmoHLtRMQhAbn2njqB2O8fCxjN7sVIISy PlWGXXtvaXqzkl4FZqV+DP5O7/aMN5omssdfyuqxJMC+hbXYV7LhC5Zg8 C1682cYBmep5M3KfS+yxjfRJj1YcpNVsdR+3cBt+s/Gbb8QlD2EPLikJK BKovVXHYxvEwQppxYcNML0QycLvcUxAx4K1klO3o9JSPXNqTOC3iC/pOD g==; IronPort-SDR: pb3D0iBal8yJhK91GJn0N0L5JPX3KmwawSND2IIXRAtuNlOfDfk6vZwsU88VEQAMnLwX4G7g2x p5aEPqSAAFxYOrgf8RSSrOCH9Ni7AVmsKyQU0R4KyMX2LprexOf5CRrQzpQ3fFVt7lkAEsUZaH crfEhu+vJ9Vj+2zvmocCvQhw/WFXenKG2Yyun+53WYZKhnmP4Lb5+2Y3lEj4jQtfhYWNUA3yS4 OFNSem8g2u7aHQDDGCP9tO2CUFFgP5OcEOopnC0XEUg0XdwWepnpctxgpJ0yFR9sY+yx2C2wnF nm8= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="36193302" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:35 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.87.72) by chn-vm-ex02.mchp-main.com (10.10.87.72) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:35 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:35 -0700 Subject: [PATCH 18/25] smartpqi: return busy indication for IOCTLs when ofa is active From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:35 -0600 Message-ID: <160712295524.21372.17275357939433334592.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Prevent Kernel crashes while issuing ioctl during OFA. * Before this fix, the driver returned busy indication for pass-through IOCTLs throughout all stages of OFA. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 52f59ae50fda..748735d71464 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -6169,6 +6169,8 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; + if (pqi_ofa_in_progress(ctrl_info) && pqi_ctrl_blocked(ctrl_info)) + return -EBUSY; if (!arg) return -EINVAL; if (!capable(CAP_SYS_RAWIO)) From patchwork Fri Dec 4 23:02:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BFD88C4361B for ; Fri, 4 Dec 2020 23:03:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9872822D49 for ; Fri, 4 Dec 2020 23:03:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727333AbgLDXDr (ORCPT ); Fri, 4 Dec 2020 18:03:47 -0500 Received: from esa1.microchip.iphmx.com ([68.232.147.91]:5002 "EHLO esa1.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727281AbgLDXDr (ORCPT ); Fri, 4 Dec 2020 18:03:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123026; x=1638659026; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=dyUwGWM8h9A0H0neVeGhBqagcjisxhVZ4ImqZkSlN/k=; b=if2XGfv6Mw4lwH9bS0ol0CiUYXUpk9ySoua4qBBt2YqbfRrhzCtXT9en TA5yuXFhk5/4iK1/AW5yckv4ay/KBt+ZtK5MDzUHbrCeMaWoVrshUDteK bk/hQyyNQ8jGpSRbxSSGlFLFI/qQnapkbjl47ZetRPAU55mDgeumqv/Qo g4U7HCfhpbF1dHaX6BdO8cNG8kesKW1uxWgnwuk49XeMLrmNQ3x+4+sRP iXKDTBZsa8LlJT18PBgqeRoYNg/pZt9ZkEN25DjU7UpiydpEqAViUrWB4 elAMSOJrZeEZNQcSmPlpvrIoOdLwKe+74LnNbKagkKoDxEkGrm1vWPzYq A==; IronPort-SDR: 906txNOwydQmtczgLZjKcdRHfcO5QTjSlBu6FuwXXsiGVBJQq2h1hCNLQALiFoG8hb0YxggI17 NKW5lk9RcxWClOoDaKcP+txz8Yo89T896yq8ytscIAUqAP5ZChC4TvpGqruT1Bz/0YoC7at6AV CU93V3BKOm+laoCNQs/0G1l0k+5CdefdjWYoEjeRrPMIS0KcGCzRJpf0+ueQ/Ge6jXSi4lAP0b NqWcHM78WaBi8b+96hx6XMNzTxMfK8ZJwHBsRhbxZi6lhs0V17OlOAg/zv6eJONkjyMW/IpjjZ ymQ= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="106273244" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:42 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:41 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:41 -0700 Subject: [PATCH 19/25] smartpqi: add phy id support for the physical drives From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:41 -0600 Message-ID: <160712296106.21372.12338709679674654994.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Murthy Bhat * Display topology using PHY numbers. * PHY(both local and remote) numbers corresponding to physical drives are read from BMIC_IDENTIFY_PHYSICAL_DEVICE. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Murthy Bhat Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi.h | 1 + drivers/scsi/smartpqi/smartpqi_init.c | 10 ++++++++++ drivers/scsi/smartpqi/smartpqi_sas_transport.c | 1 + 3 files changed, 12 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h index c3b103b15924..8220957bc69b 100644 --- a/drivers/scsi/smartpqi/smartpqi.h +++ b/drivers/scsi/smartpqi/smartpqi.h @@ -1089,6 +1089,7 @@ struct pqi_scsi_dev { u8 phy_connected_dev_type; u8 box[8]; u16 phys_connector[8]; + u8 phy_id; bool raid_bypass_configured; /* RAID bypass configured */ bool raid_bypass_enabled; /* RAID bypass enabled */ u32 next_bypass_group; diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 748735d71464..52ae3e7f75e1 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1435,6 +1435,8 @@ static void pqi_get_volume_status(struct pqi_ctrl_info *ctrl_info, device->volume_offline = volume_offline; } +#define PQI_DEVICE_PHY_MAP_SUPPORTED 0x10 + static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct bmic_identify_physical_device *id_phys) @@ -1474,6 +1476,13 @@ static int pqi_get_physical_device_info(struct pqi_ctrl_info *ctrl_info, memcpy(&device->page_83_identifier, &id_phys->page_83_identifier, sizeof(device->page_83_identifier)); + if ((id_phys->even_more_flags & PQI_DEVICE_PHY_MAP_SUPPORTED) && + id_phys->phy_count) + device->phy_id = + id_phys->phy_to_phy_map[device->active_path_index]; + else + device->phy_id = 0xFF; + return 0; } @@ -1840,6 +1849,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, existing_device->aio_handle = new_device->aio_handle; existing_device->volume_status = new_device->volume_status; existing_device->active_path_index = new_device->active_path_index; + existing_device->phy_id = new_device->phy_id; existing_device->path_map = new_device->path_map; existing_device->bay = new_device->bay; existing_device->box_index = new_device->box_index; diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index 77923c6ec2c6..71e83d5fdd02 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -92,6 +92,7 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, identify = &rphy->identify; identify->sas_address = pqi_sas_port->sas_address; + identify->phy_identifier = pqi_sas_port->device->phy_id; if (pqi_sas_port->device && pqi_sas_port->device->is_expander_smp_device) { From patchwork Fri Dec 4 23:02:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338622 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7BB69C4167B for ; Fri, 4 Dec 2020 23:03:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 53CD322D01 for ; Fri, 4 Dec 2020 23:03:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727351AbgLDXDt (ORCPT ); Fri, 4 Dec 2020 18:03:49 -0500 Received: from esa1.microchip.iphmx.com ([68.232.147.91]:5079 "EHLO esa1.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727281AbgLDXDs (ORCPT ); Fri, 4 Dec 2020 18:03:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123027; x=1638659027; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Y7+pBmuEvnH+XQCjqvFzRGxI3wOQmc/1Cb5tqqhd0lY=; b=OWyG9hiiAnJdJqMZj9ilc/zbg/AcVpwCU44Eh3uMayHNkbtwYl1g1kh0 THHAqBZLx6i7iiCZWHGjybYLFDfSTzPchiA1Y78GDIT+5EgzdxOirH+HJ H20CmTz8p4s3bA6sYVvorHa9ok1NavhzVNgDALPawtakOya9b8JQRbuSO wII5JVdypiJjqzum3SmtuNzGOnE/jLrYIh38tYcAZM8/byePwW09IGzby E3aCI2hlT9CYaaDbQP8z3WISCEDrHwCIu5/E89MMrqAXwMAhY/1vPP7ZH cQfDwsEGbp3cZWZ3bcrD/xcZkBi4KLtl91Rh8bKzNSl2yqmdEOTP6+dGG g==; IronPort-SDR: /S6UVkD0WgrKcRzMaDssF6dmgPx6zGDBoF+nBsPG7VMS3/dnPeWGtFE3X5uEDB45DuoPQtJdHC +9fLFpafDVsaD5bNsN7MehvLR5lzvGye6bE7dUeCPnhZUO3po+i9izURVDjIZNpj6fRmMNKiWK 2vV21TLrayyMN3qFxdptXyA+5O6xrONAs9Vy5XvYF48aKGHycaGtTipJM5QqtQf8iJcgZQKL96 BFoWHIFxx8Z96MbltBdWs0FP5vGi+lY0JvbG6wSIgVQWNyj0q8cSR3S4E7ijydUfy86HGAMxiL y0Y= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="106273262" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa1.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:47 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:47 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:46 -0700 Subject: [PATCH 20/25] smartpqi: update sas initiator_port_protocols and target_port_protocols From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:46 -0600 Message-ID: <160712296680.21372.13023212315335549812.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Murthy Bhat * Export valid sas initiator_port_protocols and target_port_protocols to sysfs. * lsscsi now shows correct values. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Murthy Bhat Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_sas_transport.c | 28 ++++++++++++++++-------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index 71e83d5fdd02..dd9b784792ef 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -65,8 +65,8 @@ static int pqi_sas_port_add_phy(struct pqi_sas_phy *pqi_sas_phy) memset(identify, 0, sizeof(*identify)); identify->sas_address = pqi_sas_port->sas_address; identify->device_type = SAS_END_DEVICE; - identify->initiator_port_protocols = SAS_PROTOCOL_STP; - identify->target_port_protocols = SAS_PROTOCOL_STP; + identify->initiator_port_protocols = SAS_PROTOCOL_ALL; + identify->target_port_protocols = SAS_PROTOCOL_ALL; phy->minimum_linkrate_hw = SAS_LINK_RATE_UNKNOWN; phy->maximum_linkrate_hw = SAS_LINK_RATE_UNKNOWN; phy->minimum_linkrate = SAS_LINK_RATE_UNKNOWN; @@ -94,13 +94,23 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port, identify->sas_address = pqi_sas_port->sas_address; identify->phy_identifier = pqi_sas_port->device->phy_id; - if (pqi_sas_port->device && - pqi_sas_port->device->is_expander_smp_device) { - identify->initiator_port_protocols = SAS_PROTOCOL_SMP; - identify->target_port_protocols = SAS_PROTOCOL_SMP; - } else { - identify->initiator_port_protocols = SAS_PROTOCOL_STP; - identify->target_port_protocols = SAS_PROTOCOL_STP; + identify->initiator_port_protocols = SAS_PROTOCOL_ALL; + identify->target_port_protocols = SAS_PROTOCOL_STP; + + if (pqi_sas_port->device) { + switch (pqi_sas_port->device->device_type) { + case SA_DEVICE_TYPE_SAS: + case SA_DEVICE_TYPE_SES: + case SA_DEVICE_TYPE_NVME: + identify->target_port_protocols = SAS_PROTOCOL_SSP; + break; + case SA_DEVICE_TYPE_EXPANDER_SMP: + identify->target_port_protocols = SAS_PROTOCOL_SMP; + break; + case SA_DEVICE_TYPE_SATA: + default: + break; + } } return sas_rphy_add(rphy); From patchwork Fri Dec 4 23:02:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 75782C433FE for ; Fri, 4 Dec 2020 23:03:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 47AEE22C9E for ; Fri, 4 Dec 2020 23:03:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727289AbgLDXDf (ORCPT ); Fri, 4 Dec 2020 18:03:35 -0500 Received: from esa6.microchip.iphmx.com ([216.71.154.253]:21357 "EHLO esa6.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727281AbgLDXDe (ORCPT ); Fri, 4 Dec 2020 18:03:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123013; x=1638659013; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=31FP8fKO8dPZbY6o/IMZDWH0RLTF7h4mX+vioY+p8QU=; b=AoZS1dD3DGWore4q6kuwvwIeomN1sZXh1abmjzcc7FT6dBdyQFVv02HY THvs8HfBd2ue4xhChzT8MZrR0HECkW9Etwa1qvxw8qVdfTK16m7b/uWMG 7xD3BmG+zCrU4ziP9SFvQwg3DnESJYGgrUkK2zK8Q+ZQFyTRJ93AYncQX Ktpcz8/f38tqQepZ9XtiK7paY9JXwlfhgo5YOSG/U3lH2386Qfr8QLyv+ +VUvBcgMTherH+7cWWgbEgqd512JrTr8hn1oUqlcGoQG2nMWrsENA6stO ijuJhbBAoY+MKI7Qcho/c31/OjmiKFpqAFBRDia65CR0b4/tzPrVFVwYh w==; IronPort-SDR: 8aS56Ep2roYobhwdqjOik7vC0gEc4PxayxQomM4DM2tRrcFov5xb6fYbAz/oJAXIcVAfRV4Qav qKEZYnh73FY923/Bn55Ra/QBcWd8EwiAIpLWg6mS7hU/dMHUEy2Z5CgZYVPC8kqTT0JWWXef3f GyILQoDWB1SENjYqSnzg3i71z9iMgyB68fE3jlG/8xL3Zay9Z6zlAaxs4lqL5QaeOZfT6naXMk BQBq6vLA/rLtlHsGI6Ea4A6nWIP95u8R93PNaqUha9/Mu+9f9lvCTJgVYOYQe6yxvZnYSQ3Jo6 ut4= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="36193356" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:53 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:53 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:52 -0700 Subject: [PATCH 21/25] smartpqi: add additional logging for LUN resets From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:52 -0600 Message-ID: <160712297258.21372.7512230442693942907.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Add additional logging to help in debugging issues with LUN resets. Reviewed-by: Mahesh Rajashekhara Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 125 +++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 52ae3e7f75e1..cfc5505e8234 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -84,7 +84,7 @@ static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info); static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info); static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info); static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, unsigned long timeout_secs); + struct pqi_scsi_dev *device, unsigned long timeout_msecs); /* for flags argument to pqi_submit_raid_request_synchronous() */ #define PQI_SYNC_FLAGS_INTERRUPTABLE 0x1 @@ -335,11 +335,34 @@ static void pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info) atomic_dec(&ctrl_info->num_blocked_threads); } +#define PQI_QUIESE_WARNING_TIMEOUT_SECS 10 + static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info) { + unsigned long start_jiffies; + unsigned long warning_timeout; + bool displayed_warning; + + displayed_warning = false; + start_jiffies = jiffies; + warning_timeout = (PQI_QUIESE_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies; + while (atomic_read(&ctrl_info->num_busy_threads) > - atomic_read(&ctrl_info->num_blocked_threads)) + atomic_read(&ctrl_info->num_blocked_threads)) { + if (time_after(jiffies, warning_timeout)) { + dev_warn(&ctrl_info->pci_dev->dev, + "waiting %u seconds for driver activity to quiesce\n", + jiffies_to_msecs(jiffies - start_jiffies) / 1000); + displayed_warning = true; + warning_timeout = (PQI_QUIESE_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies; + } usleep_range(1000, 2000); + } + + if (displayed_warning) + dev_warn(&ctrl_info->pci_dev->dev, + "driver activity quiesced after waiting for %u seconds\n", + jiffies_to_msecs(jiffies - start_jiffies) / 1000); } static inline bool pqi_device_offline(struct pqi_scsi_dev *device) @@ -1670,7 +1693,7 @@ static int pqi_add_device(struct pqi_ctrl_info *ctrl_info, return rc; } -#define PQI_PENDING_IO_TIMEOUT_SECS 20 +#define PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS (20 * 1000) static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { @@ -1678,7 +1701,8 @@ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info, struct pqi pqi_device_remove_start(device); - rc = pqi_device_wait_for_pending_io(ctrl_info, device, PQI_PENDING_IO_TIMEOUT_SECS); + rc = pqi_device_wait_for_pending_io(ctrl_info, device, + PQI_REMOVE_DEVICE_PENDING_IO_TIMEOUT_MSECS); if (rc) dev_err(&ctrl_info->pci_dev->dev, "scsi %d:%d:%d:%d removing device with %d outstanding command(s)\n", @@ -3001,7 +3025,7 @@ static void pqi_process_io_error(unsigned int iu_type, } } -static int pqi_interpret_task_management_response( +static int pqi_interpret_task_management_response(struct pqi_ctrl_info *ctrl_info, struct pqi_task_management_response *response) { int rc; @@ -3019,6 +3043,10 @@ static int pqi_interpret_task_management_response( break; } + if (rc) + dev_err(&ctrl_info->pci_dev->dev, + "Task Management Function error: %d (response code: %u)\n", rc, response->response_code); + return rc; } @@ -3087,9 +3115,8 @@ static int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info, struct pqi_queue &((struct pqi_vendor_general_response *)response)->status); break; case PQI_RESPONSE_IU_TASK_MANAGEMENT: - io_request->status = - pqi_interpret_task_management_response( - (void *)response); + io_request->status = pqi_interpret_task_management_response(ctrl_info, + (void *)response); break; case PQI_RESPONSE_IU_AIO_PATH_DISABLED: pqi_aio_path_disabled(io_request); @@ -5793,24 +5820,37 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, } } +#define PQI_PENDING_IO_WARNING_TIMEOUT_SECS 10 + static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device, unsigned long timeout_secs) + struct pqi_scsi_dev *device, unsigned long timeout_msecs) { - unsigned long timeout; + int cmds_outstanding; + unsigned long start_jiffies; + unsigned long warning_timeout; + unsigned long msecs_waiting; + start_jiffies = jiffies; + warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * PQI_HZ) + start_jiffies; - timeout = (timeout_secs * PQI_HZ) + jiffies; - - while (atomic_read(&device->scsi_cmds_outstanding)) { + while ((cmds_outstanding = atomic_read(&device->scsi_cmds_outstanding)) > 0) { pqi_check_ctrl_health(ctrl_info); if (pqi_ctrl_offline(ctrl_info)) return -ENXIO; - if (timeout_secs != NO_TIMEOUT) { - if (time_after(jiffies, timeout)) { - dev_err(&ctrl_info->pci_dev->dev, - "timed out waiting for pending I/O\n"); - return -ETIMEDOUT; - } + msecs_waiting = jiffies_to_msecs(jiffies - start_jiffies); + if (msecs_waiting > timeout_msecs) { + dev_err(&ctrl_info->pci_dev->dev, + "scsi %d:%d:%d:%d: timed out after %lu seconds waiting for %d outstanding command(s)\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, + device->lun, msecs_waiting / 1000, cmds_outstanding); + return -ETIMEDOUT; + } + if (time_after(jiffies, warning_timeout)) { + dev_warn(&ctrl_info->pci_dev->dev, + "scsi %d:%d:%d:%d: waiting %lu seconds for %d outstanding command(s)\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, + device->lun, msecs_waiting / 1000, cmds_outstanding); + warning_timeout = (PQI_PENDING_IO_WARNING_TIMEOUT_SECS * PQI_HZ) + jiffies; } usleep_range(1000, 2000); } @@ -5826,13 +5866,15 @@ static void pqi_lun_reset_complete(struct pqi_io_request *io_request, complete(waiting); } -#define PQI_LUN_RESET_TIMEOUT_SECS 30 #define PQI_LUN_RESET_POLL_COMPLETION_SECS 10 static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, struct completion *wait) { int rc; + unsigned int wait_secs; + + wait_secs = 0; while (1) { if (wait_for_completion_io_timeout(wait, @@ -5846,13 +5888,21 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, rc = -ENXIO; break; } + + wait_secs += PQI_LUN_RESET_POLL_COMPLETION_SECS; + + dev_warn(&ctrl_info->pci_dev->dev, + "scsi %d:%d:%d:%d: waiting %u seconds for LUN reset to complete\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun, + wait_secs); } return rc; } -static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device) +#define PQI_LUN_RESET_FIRMWARE_TIMEOUT_SECS 30 + +static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { int rc; struct pqi_io_request *io_request; @@ -5874,8 +5924,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, sizeof(request->lun_number)); request->task_management_function = SOP_TASK_MANAGEMENT_LUN_RESET; if (ctrl_info->tmf_iu_timeout_supported) - put_unaligned_le16(PQI_LUN_RESET_TIMEOUT_SECS, - &request->timeout); + put_unaligned_le16(PQI_LUN_RESET_FIRMWARE_TIMEOUT_SECS, &request->timeout); pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, io_request); @@ -5889,29 +5938,33 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, return rc; } -#define PQI_LUN_RESET_RETRIES 3 -#define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000 -#define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120 +#define PQI_LUN_RESET_RETRIES 3 +#define PQI_LUN_RESET_RETRY_INTERVAL_MSECS (10 * 1000) +#define PQI_LUN_RESET_PENDING_IO_TIMEOUT_MSECS (10 * 60 * 1000) +#define PQI_LUN_RESET_FAILED_PENDING_IO_TIMEOUT_MSECS (2 * 60 * 1000) -static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, - struct pqi_scsi_dev *device) +static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device) { - int rc; + int reset_rc; + int wait_rc; unsigned int retries; - unsigned long timeout_secs; + unsigned long timeout_msecs; for (retries = 0;;) { - rc = pqi_lun_reset(ctrl_info, device); - if (rc == 0 || ++retries > PQI_LUN_RESET_RETRIES) + reset_rc = pqi_lun_reset(ctrl_info, device); + if (reset_rc == 0 || ++retries > PQI_LUN_RESET_RETRIES) break; msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); } - timeout_secs = rc ? PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS : NO_TIMEOUT; + timeout_msecs = reset_rc ? PQI_LUN_RESET_FAILED_PENDING_IO_TIMEOUT_MSECS : + PQI_LUN_RESET_PENDING_IO_TIMEOUT_MSECS; - rc |= pqi_device_wait_for_pending_io(ctrl_info, device, timeout_secs); + wait_rc = pqi_device_wait_for_pending_io(ctrl_info, device, timeout_msecs); + if (wait_rc && reset_rc == 0) + reset_rc = wait_rc; - return rc == 0 ? SUCCESS : FAILED; + return reset_rc == 0 ? SUCCESS : FAILED; } static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, From patchwork Fri Dec 4 23:02:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338133 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C184C0018C for ; Fri, 4 Dec 2020 23:03:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CBD0B22D01 for ; Fri, 4 Dec 2020 23:03:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727517AbgLDXDt (ORCPT ); Fri, 4 Dec 2020 18:03:49 -0500 Received: from esa4.microchip.iphmx.com ([68.232.154.123]:48973 "EHLO esa4.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727348AbgLDXDs (ORCPT ); Fri, 4 Dec 2020 18:03:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123028; x=1638659028; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=V3ZFAee8kjnF5fem46YCVTq9Tu6zPg0HPIuxEfi3qMU=; b=t+XH9hp0Fbh/aFtNUGUrIbO/CnLB1JiH/AKXLXYR0TTErDpKBK8e8PzO ie1qAJP0gMHH2sD95KUKXfPfbZ/Suo6UsXRBPlidp/WGoJqJ27/DiktPU OfK0+UJGBdFNyKrlyLnmcGQr12wqki07Nx29oTi6Bgqz8sKh52OSNExm0 79i38GydGS5+xDTiUnhp06PTnPu3A3/+lHQnY+GJcsDWzipNKiryPdYzl YVMRV6VFBdbKEO63LeUv87TSdFmMLcw3hTcmQgENkktU5Nvv7kq0ts5PR ShP31PoU9/ojT4fmRo4hbAOuW1gHI0T03Us5hRxnKlZrJEw0iU/mBEzsE A==; IronPort-SDR: 7LT+VtB3CGeep+rRP7SU6ZS16lhK/LWRF9RtTp5n2BZLdSsjQqXaAJ3zfPXQqPQTQw5U9VCrQ6 wQj7lfN/llAl2wDovGgSz1igmpR+Tq+Le/0v1EJAqEV9EVPWRsL/Z92x8b51qar+Atvhv/Saoq FO9nFxvjEl26DdM78QCdBPHjCBNoLMllNnnP5n84Mto5ea9BkL1LRsejAweeFE3AQs5NIOuVae GZ8M32t+iaxRrC2mQymqXXHXu06jWFqkZ/5AYQ5gghoAvv41R/8btNshG00/Q+rv0EcElP+Xk4 2cc= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="95934708" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:02:59 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:02:59 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:02:58 -0700 Subject: [PATCH 22/25] smartpqi: update enclosure identifier in sysf From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:02:58 -0600 Message-ID: <160712297842.21372.14060743747106039439.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Murthy Bhat * Update enclosure identifier field corresponding to physical devices in lsscsi/sysfs. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Murthy Bhat Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index cfc5505e8234..01e62eb08583 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -1841,7 +1841,6 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info, static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device, struct pqi_scsi_dev *new_device) { - existing_device->devtype = new_device->devtype; existing_device->device_type = new_device->device_type; existing_device->bus = new_device->bus; if (new_device->target_lun_valid) { From patchwork Fri Dec 4 23:03:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338132 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54EB3C4361A for ; Fri, 4 Dec 2020 23:04:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1B7FC22D01 for ; Fri, 4 Dec 2020 23:04:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727357AbgLDXE0 (ORCPT ); Fri, 4 Dec 2020 18:04:26 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1456 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727348AbgLDXE0 (ORCPT ); Fri, 4 Dec 2020 18:04:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123066; x=1638659066; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=xYZN3FRbTMguNn3cxo8CKKBXr+jqAuoIaHF1KU+m+wc=; b=XclMlUHdMJ0y/D4vSPvgDpt5tzxHWRatuld6mU/+Dt20Gh2nw2K8RdRT OKSQQwbYtcZn06AzMLoXxjSCSv5dqlhSFxqMe52HfGZKzxnDa3c9ALDoV RRAMGoG+nDeLPBEKArqZ2c2UTCLrUaXfPCjsRN4H73cI6jRkbtoZw69ED 75wBJgJ8kb7PwfdYa2XBjagPLxyGU56/GK/Kxn9E92g+nIOPwzNSJrhc0 3Fbi5Yro1DqTkwF/zYP+UCpoTDJp+9kY00UV5wo/YeS7h1lKK59hzjtp1 Btk99QELK0h7grPBU0aixvP6uD0hR2ROJq/hk96Ag07yBjbW7k6gGndS3 Q==; IronPort-SDR: wsYeIkuZmASDyMRBU43BfkvgmjjLZdswCoFl3FfDD6oW5RltIqjjyApzeh0y+yLnIM4B49oVsX HyY6EpjMJbnjrqRZ1KcOkXbg9QyerWc99jQ+OngEMU8vFHldlzSva9VvhtD4wGhqKBfgcH5edi 2IJSyvXbkWwX3lepTSWwQnbBy4QQxzLHP05DaxgHtr/0NmeWf03njYJSPJWYe4FIwDce36n3QT wRUMLbphCfs8pS1nLx8nx4fvSjOPz+XDxqICOg6bBpsJ9Lv0NJKcBsPj23JLjWwvAcJJ58HSve mX4= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548931" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:03:05 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:03:04 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:03:04 -0700 Subject: [PATCH 23/25] smartpqi: correct system hangs when resuming from hibernation From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:03:04 -0600 Message-ID: <160712298422.21372.9624784570305531704.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Correct system hangs when resuming from hibernation after first successful hibernation/resume cycle. * Rare condition involving OFA. Reviewed-by: Scott Benesh Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 01e62eb08583..acfa57beb3c5 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8619,6 +8619,11 @@ static __maybe_unused int pqi_resume(struct pci_dev *pci_dev) pci_set_power_state(pci_dev, PCI_D0); pci_restore_state(pci_dev); + pqi_ctrl_unblock_device_reset(ctrl_info); + pqi_ctrl_unblock_requests(ctrl_info); + pqi_scsi_unblock_requests(ctrl_info); + pqi_ctrl_unblock_scan(ctrl_info); + return pqi_ctrl_init_resume(ctrl_info); } From patchwork Fri Dec 4 23:03:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, UPPERCASE_50_75, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D8D53C433FE for ; Fri, 4 Dec 2020 23:04:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DAEF22D01 for ; Fri, 4 Dec 2020 23:04:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728734AbgLDXEb (ORCPT ); Fri, 4 Dec 2020 18:04:31 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1374 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726057AbgLDXEb (ORCPT ); Fri, 4 Dec 2020 18:04:31 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123070; x=1638659070; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eDPYIavmP312Fjv2L6+Pfs948GGEL96Kzuu/4FUGH04=; b=XhHeoAm4DLkiGtufbtht/zfe32kBp8mwlvhmbWzHL1E+x9/4k31OKSkR h5aebl1M8Afkv7yDsWdBm0TNd0AtqsZ+9mKGze6qiOJiCIUW3nsF89p0E QtlTz8GFMYveC2W2Fk++Qw2dzRxBRIVbxTgT/ZxteFs843XF7EfKAmyln SfSKjgXajCXSJkoooiNfxl7gNv7+oH6/zeE9jCl+NWzmLhz/RKhsq2KvQ gawvKDmgN61Uk9lOKUXFQqiywutcxplN+61T1eJltdGWXXcGgM+C6OWCk 4/l6AghGCnJ+UXgMjnL40GiM3T3902KRZHuAHjInWWRUzjhVjxQbeuHRJ g==; IronPort-SDR: ak5xeDyfvdMMRTgxmbgA4qbduLKKgtFf/kotazy686qVB3ajt43PddGfdedgVEc5r/iQmwZYl7 SuEmnlitEf/PevFri964x90AXWs6VtgYboFASVB/KT45umpTG/mD9BKUj3rePydbenbNH/oU6/ 58m09ve+3UulAsAAUwC5u/DpUiAEyhChfDZ/E9AxtZQSsPL83z8BYWTvpFITemKRq2UT1iSkg4 vTcIMcFo2r3htoYLacI7FyuHEPV2U8fDAaMTLTduCghztvFDj2wzNuj1jmdK85c30IsYxGB6am 5oE= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548946" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:03:10 -0700 Received: from chn-vm-ex03.mchp-main.com (10.10.85.151) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:03:10 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:03:10 -0700 Subject: [PATCH 24/25] smartpqi: add new pci ids From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:03:10 -0600 Message-ID: <160712299001.21372.444900738652746693.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org From: Kevin Barnett * Add support for newer HW. Reviewed-by: Scott Benesh Reviewed-by: Scott Teel Signed-off-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 156 +++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index acfa57beb3c5..55f3c2d2c52c 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -8657,6 +8657,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x152d, 0x8a37) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x193d, 0x8460) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x193d, 0x1104) @@ -8729,6 +8733,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1bd4, 0x004f) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0051) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0052) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0053) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1bd4, 0x0054) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x19e5, 0xd227) @@ -8889,6 +8909,122 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADAPTEC2, 0x1380) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1400) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1402) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1410) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1411) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1412) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1420) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1430) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1440) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1441) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1450) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1452) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1460) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1461) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1462) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1470) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1471) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1472) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1480) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1490) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x1491) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14a1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14b1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14c1) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14d0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14e0) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_ADAPTEC2, 0x14f0) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_ADVANTECH, 0x8312) @@ -8953,6 +9089,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1001) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + PCI_VENDOR_ID_HP, 0x1002) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1100) @@ -8961,6 +9101,22 @@ static const struct pci_device_id pqi_pci_id_table[] = { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, PCI_VENDOR_ID_HP, 0x1101) }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x0294) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02db) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x02dc) + }, + { + PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, + 0x1590, 0x032e) + }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, 0x1d8d, 0x0800) From patchwork Fri Dec 4 23:03:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Don Brace X-Patchwork-Id: 338131 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D748C433FE for ; Fri, 4 Dec 2020 23:04:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6B5A022D01 for ; Fri, 4 Dec 2020 23:04:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728750AbgLDXEf (ORCPT ); Fri, 4 Dec 2020 18:04:35 -0500 Received: from esa3.microchip.iphmx.com ([68.232.153.233]:1478 "EHLO esa3.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725985AbgLDXEe (ORCPT ); Fri, 4 Dec 2020 18:04:34 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1607123074; x=1638659074; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RFHTOJk4jL1L+AndjkrMk4I5uYjcqb32AdpDg2Rd02w=; b=viKSNspFoUGOAuvWbhs2C7dRpI744UuDSm4WMz9lVLDe0QnNlpSzDv+Z YBbKCGjIXUQuf4afjrWLZg5uM3VcA2ZKf6CV+FiRiBtefogkOpsZQ8vuA 7SRndO0mHBmKEen3KQL5HtqLMoMD88ykplq4pSxTeRBuOrxVZvmGdr9+z 1BGjPdsSWYouf261gWrftyUioq8qkfectrxlgZiFBRSlMKmHXEmIAUOop 7FSfX0XZGt6fC1U1fjl2PXX/yPicYehujw5dVcBvwTLZAuatPX/+LZ7P6 +AYiwtzt8hKzJnwKJDTHpjBqdYSBGiAogbImjopCCBHse5sRKVwF6UMvV w==; IronPort-SDR: Lfe9yF4M96NeK4OjkZcurMVwBzanpttOeORHNHDBlkxbI1VN27wuvflDVVksgHwewDmMROXl2E X0vcrsPuQ74cOvNCtmFLB68uSxn77nldOaGeBJQhjJZ1+oJdKrXW3ZPWwiOF/2ejbtzJQBBGUE vwHgcMqznbUVITEk9i2PbzSPEj1s8h89rhK5LNjGN1jXnRnSNOeXctaKRII08qjkMIsgXR18JA oG3SSFgG3j0xeQkdWOJuw0X4RZJMCPlDAFj56xyNsDQRlNjodRdsNaKIkf0YBTMs6GwUIXzzex kXY= X-IronPort-AV: E=Sophos;i="5.78,393,1599548400"; d="scan'208";a="101548957" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 04 Dec 2020 16:03:16 -0700 Received: from chn-vm-ex01.mchp-main.com (10.10.85.143) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Fri, 4 Dec 2020 16:03:16 -0700 Received: from [127.0.1.1] (10.10.115.15) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Fri, 4 Dec 2020 16:03:16 -0700 Subject: [PATCH 25/25] smartpqi: update version to 2.1.6-005 From: Don Brace To: , , , , , , , , , CC: Date: Fri, 4 Dec 2020 17:03:15 -0600 Message-ID: <160712299585.21372.913012583816104187.stgit@brunhilda> In-Reply-To: <160712276179.21372.51526310810782843.stgit@brunhilda> References: <160712276179.21372.51526310810782843.stgit@brunhilda> User-Agent: StGit/0.23-dirty MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org * Update version for tracking Reviewed-by: Scott Benesh Reviewed-by: Gerry Morong Reviewed-by: Scott Teel Reviewed-by: Kevin Barnett Signed-off-by: Don Brace --- drivers/scsi/smartpqi/smartpqi_init.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 55f3c2d2c52c..2c13c6a19e4c 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -33,11 +33,11 @@ #define BUILD_TIMESTAMP #endif -#define DRIVER_VERSION "1.2.16-012" -#define DRIVER_MAJOR 1 -#define DRIVER_MINOR 2 -#define DRIVER_RELEASE 16 -#define DRIVER_REVISION 12 +#define DRIVER_VERSION "2.1.6-005" +#define DRIVER_MAJOR 2 +#define DRIVER_MINOR 1 +#define DRIVER_RELEASE 6 +#define DRIVER_REVISION 5 #define DRIVER_NAME "Microsemi PQI Driver (v" \ DRIVER_VERSION BUILD_TIMESTAMP ")"