scsi: mpi3mr: Enable STL on HBAs where multipath is disabled
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>
Thu, 4 Aug 2022 13:12:19 +0000 (18:42 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 23 Aug 2022 03:34:05 +0000 (23:34 -0400)
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 <himanshu.madhani@oracle.com>
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_fw.c
drivers/scsi/mpi3mr/mpi3mr_os.c

index 8ab843a..8c8703e 100644 (file)
@@ -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;
index c732586..8af43c5 100644 (file)
@@ -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);
index 1c38dba..533fdf9 100644 (file)
@@ -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) {