All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ivan Mironov <mironov.ivan@gmail.com>
To: linux-scsi@vger.kernel.org, mironov.ivan@gmail.com
Cc: linux-kernel@vger.kernel.org, Don Brace <don.brace@microsemi.com>,
	"James E.J. Bottomley" <jejb@linux.vnet.ibm.com>,
	"Martin K. Petersen" <martin.petersen@oracle.com>,
	esc.storagedev@microsemi.com
Subject: [PATCH 2/6] scsi: hpsa: Support HBA mode on HP Smart Array P410i controllers
Date: Fri, 14 Dec 2018 18:21:11 +0500	[thread overview]
Message-ID: <20181214132115.21440-3-mironov.ivan@gmail.com> (raw)
In-Reply-To: <20181214132115.21440-1-mironov.ivan@gmail.com>

This patch is based on code from the 316b221, most of which was removed by
the b9092b7.

Originally, HBA mode on these controllers was supported only on
Itanium-based HP Integrity servers running HP-UX. Tool for switching
between RAID and HBA modes existed only in form of EFI binary for
ia64 architecture: saupdate.efi[1]. However, I guessed how to overwrite the
corresponding flags field in controller's NVRAM, and was able to
reimplement RAID/HBA mode switching tool for Linux[2].

This change was successfully tested using blktests[3] and xfstests[4] on
my hardware, with embedded P410i controller (PCI ID: 103c:3245, board
ID: 0x3245103c) with firmware version 6.64.

This may work with some other controllers, but it is not tested
(because I do not have the hardware) and it may be very dangerous. That is
why this functionality is disabled by default and may be enabled only
manually using the new module parameter.

[1] https://support.hpe.com/hpsc/swd/public/detail?swItemId=MTX_0b76aec489764aea9802a6d27b
[2] https://github.com/im-0/hpsahba
[3] https://github.com/osandov/blktests
[4] https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git

Signed-off-by: Ivan Mironov <mironov.ivan@gmail.com>
---
 drivers/scsi/hpsa.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
 drivers/scsi/hpsa.h |  3 ++
 2 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index fc06b790f16b..ee3d7c722a63 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -88,6 +88,11 @@ module_param(hpsa_simple_mode, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(hpsa_simple_mode,
 	"Use 'simple mode' rather than 'performant mode'");
 
+static bool hpsa_use_nvram_hba_flag;
+module_param(hpsa_use_nvram_hba_flag, bool, 0444);
+MODULE_PARM_DESC(hpsa_use_nvram_hba_flag,
+	"Use flag from NVRAM to enable HBA mode");
+
 /* define the PCI info for the cards we can control */
 static const struct pci_device_id hpsa_pci_device_id[] = {
 	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3241},
@@ -3039,6 +3044,37 @@ static int hpsa_scsi_do_inquiry(struct ctlr_info *h, unsigned char *scsi3addr,
 	return rc;
 }
 
+static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h,
+	struct bmic_controller_parameters *buf)
+{
+	int rc = IO_OK;
+	struct CommandList *c;
+	struct ErrorInfo *ei;
+
+	c = cmd_alloc(h);
+
+	if (fill_cmd(c, BMIC_SENSE_CONTROLLER_PARAMETERS, h, buf, sizeof(*buf),
+			0, RAID_CTLR_LUNID, TYPE_CMD)) {
+		rc = -1;
+		goto out;
+	}
+
+	rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
+		NO_TIMEOUT);
+	if (rc)
+		goto out;
+
+	ei = c->err_info;
+	if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
+		hpsa_scsi_interpret_error(h, c);
+		rc = -1;
+	}
+
+out:
+	cmd_free(h, c);
+	return rc;
+}
+
 static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
 	u8 reset_type, int reply_queue)
 {
@@ -4296,6 +4332,50 @@ static bool hpsa_skip_device(struct ctlr_info *h, u8 *lunaddrbytes,
 	return false;
 }
 
+static int hpsa_nvram_hba_flag_enabled(struct ctlr_info *h, bool *flag_enabled)
+{
+	int rc;
+	struct bmic_controller_parameters *ctlr_params;
+
+	ctlr_params = kzalloc(sizeof(*ctlr_params), GFP_KERNEL);
+	if (!ctlr_params) {
+		rc = -ENOMEM;
+		goto out;
+	}
+
+	rc = hpsa_bmic_ctrl_mode_sense(h, ctlr_params);
+	if (rc)
+		goto out;
+
+	*flag_enabled = ctlr_params->nvram_flags & HPSA_NVRAM_FLAG_HBA;
+
+out:
+	kfree(ctlr_params);
+	return rc;
+}
+
+static int hpsa_update_nvram_hba_mode(struct ctlr_info *h)
+{
+	int rc;
+	bool flag_enabled;
+
+	if (!hpsa_use_nvram_hba_flag)
+		return 0;
+
+	rc = hpsa_nvram_hba_flag_enabled(h, &flag_enabled);
+	if (rc == -ENOMEM)
+		dev_warn(&h->pdev->dev, "Out of memory.\n");
+	if (rc)
+		return rc;
+
+	dev_info(&h->pdev->dev, "NVRAM HBA flag: %s\n",
+		flag_enabled ? "enabled" : "disabled");
+
+	h->nvram_hba_mode_enabled = flag_enabled;
+
+	return 0;
+}
+
 static void hpsa_update_scsi_devices(struct ctlr_info *h)
 {
 	/* the idea here is we could get notified
@@ -4352,6 +4432,11 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
 			__func__);
 	}
 
+	if (hpsa_update_nvram_hba_mode(h)) {
+		h->drv_req_rescan = 1;
+		goto out;
+	}
+
 	/* We might see up to the maximum number of logical and physical disks
 	 * plus external target devices, and a device for the local RAID
 	 * controller.
@@ -4437,11 +4522,16 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
 		 * Expose all devices except for physical devices that
 		 * are masked.
 		 */
-		if (MASKED_DEVICE(lunaddrbytes) && this_device->physical_device)
-			this_device->expose_device = 0;
-		else
+		if (MASKED_DEVICE(lunaddrbytes) &&
+				this_device->physical_device) {
+			if (is_disk_or_zbc(this_device) &&
+					h->nvram_hba_mode_enabled)
+				this_device->expose_device = 1;
+			else
+				this_device->expose_device = 0;
+		} else {
 			this_device->expose_device = 1;
-
+		}
 
 		/*
 		 * Get the SAS address for physical devices that are exposed.
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
index 59e023696fff..5b508f270520 100644
--- a/drivers/scsi/hpsa.h
+++ b/drivers/scsi/hpsa.h
@@ -158,6 +158,8 @@ struct bmic_controller_parameters {
 };
 #pragma pack()
 
+#define HPSA_NVRAM_FLAG_HBA (1 << 3)
+
 struct ctlr_info {
 	unsigned int *reply_map;
 	int	ctlr;
@@ -182,6 +184,7 @@ struct ctlr_info {
 	unsigned int msix_vectors;
 	int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
 	struct access_method access;
+	bool nvram_hba_mode_enabled;
 
 	/* queue and queue Info */
 	unsigned int Qdepth;
-- 
2.19.2


  parent reply	other threads:[~2018-12-14 13:22 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-14 13:21 [PATCH 0/6] Add support of the HBA mode on HP Smart Array P410i controllers Ivan Mironov
2018-12-14 13:21 ` [PATCH 1/6] scsi: hpsa: Add function to check if device is a disk or a zoned device Ivan Mironov
2018-12-14 13:26   ` Johannes Thumshirn
2018-12-14 13:21 ` Ivan Mironov [this message]
2018-12-14 13:21 ` [PATCH 3/6] scsi: hpsa: Add/mask existing devices on rescan if visibility changes Ivan Mironov
2018-12-14 13:21 ` [PATCH 4/6] scsi: hpsa: Ignore HBA flag from NVRAM if logical devices exist Ivan Mironov
2018-12-14 13:21 ` [PATCH 5/6] scsi: hpsa: Name more fields in "struct bmic_identify_controller" Ivan Mironov
2018-12-14 13:21 ` [PATCH 6/6] scsi: hpsa: Do not use HBA flag from NVRAM if HBA is not supported Ivan Mironov
2018-12-14 19:38 ` [PATCH 0/6] Add support of the HBA mode on HP Smart Array P410i controllers Don.Brace
2018-12-14 19:38   ` Don.Brace
2018-12-14 20:30   ` Ivan Mironov
2018-12-17 16:32     ` Don.Brace
2018-12-17 16:32       ` Don.Brace

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181214132115.21440-3-mironov.ivan@gmail.com \
    --to=mironov.ivan@gmail.com \
    --cc=don.brace@microsemi.com \
    --cc=esc.storagedev@microsemi.com \
    --cc=jejb@linux.vnet.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.