Commit c4723e68 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Martin K. Petersen

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.comReviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 42fc9fee
...@@ -650,6 +650,8 @@ union _form_spec_inf { ...@@ -650,6 +650,8 @@ union _form_spec_inf {
* @dev_type: SAS/SATA/PCIE device type * @dev_type: SAS/SATA/PCIE device type
* @is_hidden: Should be exposed to upper layers or not * @is_hidden: Should be exposed to upper layers or not
* @host_exposed: Already exposed to host 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 * @io_throttle_enabled: I/O throttling needed or not
* @q_depth: Device specific Queue Depth * @q_depth: Device specific Queue Depth
* @wwid: World wide ID * @wwid: World wide ID
...@@ -669,6 +671,8 @@ struct mpi3mr_tgt_dev { ...@@ -669,6 +671,8 @@ struct mpi3mr_tgt_dev {
u8 dev_type; u8 dev_type;
u8 is_hidden; u8 is_hidden;
u8 host_exposed; u8 host_exposed;
u8 io_unit_port;
u8 non_stl;
u8 io_throttle_enabled; u8 io_throttle_enabled;
u16 q_depth; u16 q_depth;
u64 wwid; u64 wwid;
...@@ -992,6 +996,7 @@ struct scmd_priv { ...@@ -992,6 +996,7 @@ struct scmd_priv {
* @cfg_page: Default memory for configuration pages * @cfg_page: Default memory for configuration pages
* @cfg_page_dma: Configuration page DMA address * @cfg_page_dma: Configuration page DMA address
* @cfg_page_sz: Default configuration page memory size * @cfg_page_sz: Default configuration page memory size
* @sas_transport_enabled: SAS transport enabled or not
* @sas_hba: SAS node for the controller * @sas_hba: SAS node for the controller
* @sas_expander_list: SAS node list of expanders * @sas_expander_list: SAS node list of expanders
* @sas_node_lock: Lock to protect SAS node list * @sas_node_lock: Lock to protect SAS node list
...@@ -1174,6 +1179,7 @@ struct mpi3mr_ioc { ...@@ -1174,6 +1179,7 @@ struct mpi3mr_ioc {
dma_addr_t cfg_page_dma; dma_addr_t cfg_page_dma;
u16 cfg_page_sz; u16 cfg_page_sz;
u8 sas_transport_enabled;
struct mpi3mr_sas_node sas_hba; struct mpi3mr_sas_node sas_hba;
struct list_head sas_expander_list; struct list_head sas_expander_list;
spinlock_t sas_node_lock; spinlock_t sas_node_lock;
......
...@@ -1136,6 +1136,13 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc) ...@@ -1136,6 +1136,13 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
return -EPERM; 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; dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
if (mrioc->facts.max_devhandle % 8) if (mrioc->facts.max_devhandle % 8)
dev_handle_bitmap_sz++; dev_handle_bitmap_sz++;
...@@ -3453,6 +3460,7 @@ static const struct { ...@@ -3453,6 +3460,7 @@ static const struct {
char *name; char *name;
} mpi3mr_capabilities[] = { } mpi3mr_capabilities[] = {
{ MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE, "RAID" }, { MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE, "RAID" },
{ MPI3_IOCFACTS_CAPABILITY_MULTIPATH_ENABLED, "MultiPath" },
}; };
/** /**
...@@ -3734,6 +3742,11 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc) ...@@ -3734,6 +3742,11 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc)
mrioc->max_host_ios = min_t(int, mrioc->max_host_ios, mrioc->max_host_ios = min_t(int, mrioc->max_host_ios,
MPI3MR_HOST_IOS_KDUMP); 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; mrioc->reply_sz = mrioc->facts.reply_sz;
retval = mpi3mr_check_reset_dma_mask(mrioc); retval = mpi3mr_check_reset_dma_mask(mrioc);
......
...@@ -1024,6 +1024,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1024,6 +1024,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id); tgtdev->perst_id = le16_to_cpu(dev_pg0->persistent_id);
tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle); tgtdev->dev_handle = le16_to_cpu(dev_pg0->dev_handle);
tgtdev->dev_type = dev_pg0->device_form; 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->encl_handle = le16_to_cpu(dev_pg0->enclosure_handle);
tgtdev->parent_handle = le16_to_cpu(dev_pg0->parent_dev_handle); tgtdev->parent_handle = le16_to_cpu(dev_pg0->parent_dev_handle);
tgtdev->slot = le16_to_cpu(dev_pg0->slot); tgtdev->slot = le16_to_cpu(dev_pg0->slot);
...@@ -1084,6 +1085,13 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1084,6 +1085,13 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET | else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET |
MPI3_SAS_DEVICE_INFO_SSP_TARGET))) MPI3_SAS_DEVICE_INFO_SSP_TARGET)))
tgtdev->is_hidden = 1; 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; break;
} }
case MPI3_DEVICE_DEVFORM_PCIE: case MPI3_DEVICE_DEVFORM_PCIE:
...@@ -1116,6 +1124,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1116,6 +1124,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) != ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE)) MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE))
tgtdev->is_hidden = 1; tgtdev->is_hidden = 1;
tgtdev->non_stl = 1;
if (!mrioc->shost) if (!mrioc->shost)
break; break;
prot_mask = scsi_host_get_prot(mrioc->shost); prot_mask = scsi_host_get_prot(mrioc->shost);
...@@ -1139,6 +1148,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1139,6 +1148,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
tgtdev->dev_spec.vd_inf.state = vdinf->vd_state; tgtdev->dev_spec.vd_inf.state = vdinf->vd_state;
if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE) if (vdinf->vd_state == MPI3_DEVICE0_VD_STATE_OFFLINE)
tgtdev->is_hidden = 1; 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_id = vdinf_io_throttle_group;
tgtdev->dev_spec.vd_inf.tg_high = tgtdev->dev_spec.vd_inf.tg_high =
le16_to_cpu(vdinf->io_throttle_group_high) * 2048; le16_to_cpu(vdinf->io_throttle_group_high) * 2048;
...@@ -1416,8 +1426,9 @@ mpi3mr_sastopochg_evt_debug(struct mpi3mr_ioc *mrioc, ...@@ -1416,8 +1426,9 @@ mpi3mr_sastopochg_evt_debug(struct mpi3mr_ioc *mrioc,
ioc_info(mrioc, "%s :sas topology change: (%s)\n", ioc_info(mrioc, "%s :sas topology change: (%s)\n",
__func__, status_str); __func__, status_str);
ioc_info(mrioc, 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), __func__, le16_to_cpu(event_data->expander_dev_handle),
event_data->io_unit_port,
le16_to_cpu(event_data->enclosure_handle), le16_to_cpu(event_data->enclosure_handle),
event_data->start_phy_num, event_data->num_entries); event_data->start_phy_num, event_data->num_entries);
for (i = 0; i < event_data->num_entries; i++) { 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, ...@@ -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, static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
struct mpi3mr_fwevt *fwevt) struct mpi3mr_fwevt *fwevt)
{ {
struct mpi3_device_page0 *dev_pg0 = NULL;
u16 perst_id;
mpi3mr_fwevt_del_from_list(mrioc, fwevt); mpi3mr_fwevt_del_from_list(mrioc, fwevt);
mrioc->current_event = fwevt; mrioc->current_event = fwevt;
...@@ -1744,8 +1758,10 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc, ...@@ -1744,8 +1758,10 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
} }
case MPI3_EVENT_DEVICE_INFO_CHANGED: case MPI3_EVENT_DEVICE_INFO_CHANGED:
{ {
mpi3mr_devinfochg_evt_bh(mrioc, dev_pg0 = (struct mpi3_device_page0 *)fwevt->event_data;
(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; break;
} }
case MPI3_EVENT_DEVICE_STATUS_CHANGE: case MPI3_EVENT_DEVICE_STATUS_CHANGE:
...@@ -1843,6 +1859,9 @@ static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc, ...@@ -1843,6 +1859,9 @@ static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc,
u16 perst_id = 0; u16 perst_id = 0;
perst_id = le16_to_cpu(dev_pg0->persistent_id); 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); tgtdev = mpi3mr_get_tgtdev_by_perst_id(mrioc, perst_id);
if (tgtdev) { if (tgtdev) {
mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true); mpi3mr_update_tgtdev(mrioc, tgtdev, dev_pg0, true);
...@@ -4842,7 +4861,11 @@ static void mpi3mr_remove(struct pci_dev *pdev) ...@@ -4842,7 +4861,11 @@ static void mpi3mr_remove(struct pci_dev *pdev)
spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); spin_unlock_irqrestore(&mrioc->fwevt_lock, flags);
if (wq) if (wq)
destroy_workqueue(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_for_each_entry_safe(tgtdev, tgtdev_next, &mrioc->tgtdev_list,
list) { list) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment