From c4723e68a0d816f23e0807908cdb66e67528594f Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Thu, 4 Aug 2022 18:42:19 +0530 Subject: [PATCH] scsi: mpi3mr: Enable STL on HBAs where multipath is disabled Register the SAS, SATA devices to SCSI Transport Layer (STL) only if multipath capability is disabled in the controller's firmware. Link: https://lore.kernel.org/r/20220804131226.16653-9-sreekanth.reddy@broadcom.com Reviewed-by: Himanshu Madhani Signed-off-by: Sreekanth Reddy Signed-off-by: Martin K. Petersen --- 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 8ab843a8ab71..8c8703efbe15 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 c73258648d07..8af43c553dd1 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 1c38dba3a2b5..533fdf9385df 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -1024,6 +1024,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); @@ -1084,6 +1085,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: @@ -1116,6 +1124,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); @@ -1139,6 +1148,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; @@ -1416,8 +1426,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++) { @@ -1724,6 +1735,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; @@ -1744,8 +1758,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: @@ -1843,6 +1859,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); @@ -4842,7 +4861,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.25.1