diff mbox series

[08/15] mpi3mr: Enable STL on HBAs where multipath is disabled

Message ID 20220729131627.15019-9-sreekanth.reddy@broadcom.com
State Superseded
Headers show
Series [01/15] mpi3mr: Add config and transport related debug flags | expand

Commit Message

Sreekanth Reddy July 29, 2022, 1:16 p.m. UTC
Register the SAS, SATA devices to SCSI Transport Layer (STL)
only if multipath capability is disabled on the controller's
firmware.

Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
---
 drivers/scsi/mpi3mr/mpi3mr.h    |  6 ++++++
 drivers/scsi/mpi3mr/mpi3mr_fw.c | 13 +++++++++++++
 drivers/scsi/mpi3mr/mpi3mr_os.c | 31 +++++++++++++++++++++++++++----
 3 files changed, 46 insertions(+), 4 deletions(-)

Comments

Himanshu Madhani Aug. 1, 2022, 7:12 p.m. UTC | #1
> On Jul 29, 2022, at 6:16 AM, Sreekanth Reddy <sreekanth.reddy@broadcom.com> wrote:
> 
> Register the SAS, SATA devices to SCSI Transport Layer (STL)
> only if multipath capability is disabled on the controller's
> firmware.
> 
> Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
> ---
> drivers/scsi/mpi3mr/mpi3mr.h    |  6 ++++++
> drivers/scsi/mpi3mr/mpi3mr_fw.c | 13 +++++++++++++
> drivers/scsi/mpi3mr/mpi3mr_os.c | 31 +++++++++++++++++++++++++++----
> 3 files changed, 46 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
> index 8ab843a..8c8703e 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr.h
> +++ b/drivers/scsi/mpi3mr/mpi3mr.h
> @@ -650,6 +650,8 @@ union _form_spec_inf {
>  * @dev_type: SAS/SATA/PCIE device type
>  * @is_hidden: Should be exposed to upper layers or not
>  * @host_exposed: Already exposed to host or not
> + * @io_unit_port: IO Unit port ID
> + * @non_stl: Is this device not to be attached with SAS TL
>  * @io_throttle_enabled: I/O throttling needed or not
>  * @q_depth: Device specific Queue Depth
>  * @wwid: World wide ID
> @@ -669,6 +671,8 @@ struct mpi3mr_tgt_dev {
> 	u8 dev_type;
> 	u8 is_hidden;
> 	u8 host_exposed;
> +	u8 io_unit_port;
> +	u8 non_stl;
> 	u8 io_throttle_enabled;
> 	u16 q_depth;
> 	u64 wwid;
> @@ -992,6 +996,7 @@ struct scmd_priv {
>  * @cfg_page: Default memory for configuration pages
>  * @cfg_page_dma: Configuration page DMA address
>  * @cfg_page_sz: Default configuration page memory size
> + * @sas_transport_enabled: SAS transport enabled or not
>  * @sas_hba: SAS node for the controller
>  * @sas_expander_list: SAS node list of expanders
>  * @sas_node_lock: Lock to protect SAS node list
> @@ -1174,6 +1179,7 @@ struct mpi3mr_ioc {
> 	dma_addr_t cfg_page_dma;
> 	u16 cfg_page_sz;
> 
> +	u8 sas_transport_enabled;
> 	struct mpi3mr_sas_node sas_hba;
> 	struct list_head sas_expander_list;
> 	spinlock_t sas_node_lock;
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> index 9c36f52..0659d3f 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
> @@ -1136,6 +1136,13 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
> 		return -EPERM;
> 	}
> 
> +	if ((mrioc->sas_transport_enabled) && (mrioc->facts.ioc_capabilities &
> +	    MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED))
> +		ioc_err(mrioc,
> +		    "critical error: multipath capability is enabled at the\n"
> +		    "\tcontroller while sas transport support is enabled at the\n"
> +		    "\tdriver, please reboot the system or reload the driver\n");
> +
> 	dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
> 	if (mrioc->facts.max_devhandle % 8)
> 		dev_handle_bitmap_sz++;
> @@ -3453,6 +3460,7 @@ static const struct {
> 	char *name;
> } mpi3mr_capabilities[] = {
> 	{ MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE, "RAID" },
> +	{ MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED, "MultiPath" },
> };
> 
> /**
> @@ -3734,6 +3742,11 @@ retry_init:
> 		mrioc->max_host_ios = min_t(int, mrioc->max_host_ios,
> 		    MPI3MR_HOST_IOS_KDUMP);
> 
> +	if (!(mrioc->facts.ioc_capabilities &
> +	    MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED)) {
> +		mrioc->sas_transport_enabled = 1;
> +	}
> +
> 	mrioc->reply_sz = mrioc->facts.reply_sz;
> 
> 	retval = mpi3mr_check_reset_dma_mask(mrioc);
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> index 905b434..ae77422 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> @@ -1032,6 +1032,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
> 	tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
> 	tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);
> 	tgtdev->dev_type = dev_pg0->device_form;
> +	tgtdev->io_unit_port = dev_pg0->io_unit_port;
> 	tgtdev->encl_handle = le16_to_cpu(dev_pg0->enclosure_handle);
> 	tgtdev->parent_handle = le16_to_cpu(dev_pg0->parent_dev_handle);
> 	tgtdev->slot = le16_to_cpu(dev_pg0->slot);
> @@ -1092,6 +1093,13 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
> 		else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET |
> 		    MPI3_SAS_DEVICE_INFO_SSP_TARGET)))
> 			tgtdev->is_hidden = 1;
> +
> +		if (((tgtdev->devpg0_flag &
> +		    MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)
> +		    && (tgtdev->devpg0_flag &
> +		    MPI3_DEVICE0_FLAGS_ATT_METHOD_VIRTUAL)) ||
> +		    (tgtdev->parent_handle == 0xFFFF))
> +			tgtdev->non_stl = 1;
> 		break;
> 	}
> 	case MPI3_DEVICE_DEVFORM_PCIE:
> @@ -1124,6 +1132,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
> 		    ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
> 		    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE))
> 			tgtdev->is_hidden = 1;
> +		tgtdev->non_stl = 1;
> 		if (!mrioc->shost)
> 			break;
> 		prot_mask = scsi_host_get_prot(mrioc->shost);
> @@ -1147,6 +1156,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
> 		tgtdev->dev_spec.vd_inf.state = vdinf->vd_state;
> 		if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE)
> 			tgtdev->is_hidden = 1;
> +		tgtdev->non_stl = 1;
> 		tgtdev->dev_spec.vd_inf.tg_id = vdinf_io_throttle_group;
> 		tgtdev->dev_spec.vd_inf.tg_high =
> 		    le16_to_cpu(vdinf->io_throttle_group_high) * 2048;
> @@ -1424,8 +1434,9 @@ mpi3mr_sastopochg_evt_debug(struct mpi3mr_ioc *mrioc,
> 	ioc_info(mrioc, "%s :sas topology change: (%s)\n",
> 	    __func__, status_str);
> 	ioc_info(mrioc,
> -	    "%s :\texpander_handle(0x%04x), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n",
> +	    "%s :\texpander_handle(0x%04x), port(%d), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n",
> 	    __func__, le16_to_cpu(event_data->expander_dev_handle),
> +	    event_data->io_unit_port,
> 	    le16_to_cpu(event_data->enclosure_handle),
> 	    event_data->start_phy_num, event_data->num_entries);
> 	for (i = 0; i < event_data->num_entries; i++) {
> @@ -1732,6 +1743,9 @@ static void mpi3mr_set_qd_for_all_vd_in_tg(struct mpi3mr_ioc *mrioc,
> static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
> 	struct mpi3mr_fwevt *fwevt)
> {
> +	struct mpi3_device_page0 *dev_pg0 = NULL;
> +	u16 perst_id;
> +
> 	mpi3mr_fwevt_del_from_list(mrioc, fwevt);
> 	mrioc->current_event = fwevt;
> 
> @@ -1752,8 +1766,10 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
> 	}
> 	case MPI3_EVENT_DEVICE_INFO_CHANGED:
> 	{
> -		mpi3mr_devinfochg_evt_bh(mrioc,
> -		    (struct mpi3_device_page0 *)fwevt->event_data);
> +		dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data;
> +		perst_id = le16_to_cpu(dev_pg0->persistent_id);
> +		if (perst_id != MPI3_DEVICE0_PERSISTENTID_INVALID)
> +			mpi3mr_devinfochg_evt_bh(mrioc, dev_pg0);
> 		break;
> 	}
> 	case MPI3_EVENT_DEVICE_STATUS_CHANGE:
> @@ -1851,6 +1867,9 @@ static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc,
> 	u16 perst_id = 0;
> 
> 	perst_id = le16_to_cpu(dev_pg0->persistent_id);
> +	if (perst_id == MPI3_DEVICE0_PERSISTENTID_INVALID)
> +		return retval;
> +
> 	tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id);
> 	if (tgtdev) {
> 		mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true);
> @@ -4850,7 +4869,11 @@ static void mpi3mr_remove(struct pci_dev *pdev)
> 	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);
> 	if (wq)
> 		destroy_workqueue(wq);
> -	scsi_remove_host(shost);
> +
> +	if (mrioc->sas_transport_enabled)
> +		sas_remove_host(shost);
> +	else
> +		scsi_remove_host(shost);
> 
> 	list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,
> 	    list) {
> -- 
> 2.27.0
> 

Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>

--
Himanshu Madhani	Oracle Linux Engineering
diff mbox series

Patch

diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h
index 8ab843a..8c8703e 100644
--- a/drivers/scsi/mpi3mr/mpi3mr.h
+++ b/drivers/scsi/mpi3mr/mpi3mr.h
@@ -650,6 +650,8 @@  union _form_spec_inf {
  * @dev_type: SAS/SATA/PCIE device type
  * @is_hidden: Should be exposed to upper layers or not
  * @host_exposed: Already exposed to host or not
+ * @io_unit_port: IO Unit port ID
+ * @non_stl: Is this device not to be attached with SAS TL
  * @io_throttle_enabled: I/O throttling needed or not
  * @q_depth: Device specific Queue Depth
  * @wwid: World wide ID
@@ -669,6 +671,8 @@  struct mpi3mr_tgt_dev {
 	u8 dev_type;
 	u8 is_hidden;
 	u8 host_exposed;
+	u8 io_unit_port;
+	u8 non_stl;
 	u8 io_throttle_enabled;
 	u16 q_depth;
 	u64 wwid;
@@ -992,6 +996,7 @@  struct scmd_priv {
  * @cfg_page: Default memory for configuration pages
  * @cfg_page_dma: Configuration page DMA address
  * @cfg_page_sz: Default configuration page memory size
+ * @sas_transport_enabled: SAS transport enabled or not
  * @sas_hba: SAS node for the controller
  * @sas_expander_list: SAS node list of expanders
  * @sas_node_lock: Lock to protect SAS node list
@@ -1174,6 +1179,7 @@  struct mpi3mr_ioc {
 	dma_addr_t cfg_page_dma;
 	u16 cfg_page_sz;
 
+	u8 sas_transport_enabled;
 	struct mpi3mr_sas_node sas_hba;
 	struct list_head sas_expander_list;
 	spinlock_t sas_node_lock;
diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c
index 9c36f52..0659d3f 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c
@@ -1136,6 +1136,13 @@  mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
 		return -EPERM;
 	}
 
+	if ((mrioc->sas_transport_enabled) && (mrioc->facts.ioc_capabilities &
+	    MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED))
+		ioc_err(mrioc,
+		    "critical error: multipath capability is enabled at the\n"
+		    "\tcontroller while sas transport support is enabled at the\n"
+		    "\tdriver, please reboot the system or reload the driver\n");
+
 	dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
 	if (mrioc->facts.max_devhandle % 8)
 		dev_handle_bitmap_sz++;
@@ -3453,6 +3460,7 @@  static const struct {
 	char *name;
 } mpi3mr_capabilities[] = {
 	{ MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE, "RAID" },
+	{ MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED, "MultiPath" },
 };
 
 /**
@@ -3734,6 +3742,11 @@  retry_init:
 		mrioc->max_host_ios = min_t(int, mrioc->max_host_ios,
 		    MPI3MR_HOST_IOS_KDUMP);
 
+	if (!(mrioc->facts.ioc_capabilities &
+	    MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED)) {
+		mrioc->sas_transport_enabled = 1;
+	}
+
 	mrioc->reply_sz = mrioc->facts.reply_sz;
 
 	retval = mpi3mr_check_reset_dma_mask(mrioc);
diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
index 905b434..ae77422 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
@@ -1032,6 +1032,7 @@  static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
 	tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
 	tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);
 	tgtdev->dev_type = dev_pg0->device_form;
+	tgtdev->io_unit_port = dev_pg0->io_unit_port;
 	tgtdev->encl_handle = le16_to_cpu(dev_pg0->enclosure_handle);
 	tgtdev->parent_handle = le16_to_cpu(dev_pg0->parent_dev_handle);
 	tgtdev->slot = le16_to_cpu(dev_pg0->slot);
@@ -1092,6 +1093,13 @@  static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
 		else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET |
 		    MPI3_SAS_DEVICE_INFO_SSP_TARGET)))
 			tgtdev->is_hidden = 1;
+
+		if (((tgtdev->devpg0_flag &
+		    MPI3_DEVICE0_FLAGS_ATT_METHOD_DIR_ATTACHED)
+		    && (tgtdev->devpg0_flag &
+		    MPI3_DEVICE0_FLAGS_ATT_METHOD_VIRTUAL)) ||
+		    (tgtdev->parent_handle == 0xFFFF))
+			tgtdev->non_stl = 1;
 		break;
 	}
 	case MPI3_DEVICE_DEVFORM_PCIE:
@@ -1124,6 +1132,7 @@  static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
 		    ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
 		    MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE))
 			tgtdev->is_hidden = 1;
+		tgtdev->non_stl = 1;
 		if (!mrioc->shost)
 			break;
 		prot_mask = scsi_host_get_prot(mrioc->shost);
@@ -1147,6 +1156,7 @@  static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
 		tgtdev->dev_spec.vd_inf.state = vdinf->vd_state;
 		if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE)
 			tgtdev->is_hidden = 1;
+		tgtdev->non_stl = 1;
 		tgtdev->dev_spec.vd_inf.tg_id = vdinf_io_throttle_group;
 		tgtdev->dev_spec.vd_inf.tg_high =
 		    le16_to_cpu(vdinf->io_throttle_group_high) * 2048;
@@ -1424,8 +1434,9 @@  mpi3mr_sastopochg_evt_debug(struct mpi3mr_ioc *mrioc,
 	ioc_info(mrioc, "%s :sas topology change: (%s)\n",
 	    __func__, status_str);
 	ioc_info(mrioc,
-	    "%s :\texpander_handle(0x%04x), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n",
+	    "%s :\texpander_handle(0x%04x), port(%d), enclosure_handle(0x%04x) start_phy(%02d), num_entries(%d)\n",
 	    __func__, le16_to_cpu(event_data->expander_dev_handle),
+	    event_data->io_unit_port,
 	    le16_to_cpu(event_data->enclosure_handle),
 	    event_data->start_phy_num, event_data->num_entries);
 	for (i = 0; i < event_data->num_entries; i++) {
@@ -1732,6 +1743,9 @@  static void mpi3mr_set_qd_for_all_vd_in_tg(struct mpi3mr_ioc *mrioc,
 static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
 	struct mpi3mr_fwevt *fwevt)
 {
+	struct mpi3_device_page0 *dev_pg0 = NULL;
+	u16 perst_id;
+
 	mpi3mr_fwevt_del_from_list(mrioc, fwevt);
 	mrioc->current_event = fwevt;
 
@@ -1752,8 +1766,10 @@  static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
 	}
 	case MPI3_EVENT_DEVICE_INFO_CHANGED:
 	{
-		mpi3mr_devinfochg_evt_bh(mrioc,
-		    (struct mpi3_device_page0 *)fwevt->event_data);
+		dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data;
+		perst_id = le16_to_cpu(dev_pg0->persistent_id);
+		if (perst_id != MPI3_DEVICE0_PERSISTENTID_INVALID)
+			mpi3mr_devinfochg_evt_bh(mrioc, dev_pg0);
 		break;
 	}
 	case MPI3_EVENT_DEVICE_STATUS_CHANGE:
@@ -1851,6 +1867,9 @@  static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc,
 	u16 perst_id = 0;
 
 	perst_id = le16_to_cpu(dev_pg0->persistent_id);
+	if (perst_id == MPI3_DEVICE0_PERSISTENTID_INVALID)
+		return retval;
+
 	tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id);
 	if (tgtdev) {
 		mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true);
@@ -4850,7 +4869,11 @@  static void mpi3mr_remove(struct pci_dev *pdev)
 	spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);
 	if (wq)
 		destroy_workqueue(wq);
-	scsi_remove_host(shost);
+
+	if (mrioc->sas_transport_enabled)
+		sas_remove_host(shost);
+	else
+		scsi_remove_host(shost);
 
 	list_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,
 	    list) {