MODULE_PARM_DESC(enable_sdev_max_qd,
"Enable sdev max qd as can_queue, def=disabled(0)");
+static int multipath_on_hba = -1;
+module_param(multipath_on_hba, int, 0);
+MODULE_PARM_DESC(multipath_on_hba,
+ "Multipath support to add same target device\n\t\t"
+ "as many times as it is visible to HBA from various paths\n\t\t"
+ "(by default:\n\t\t"
+ "\t SAS 2.0 & SAS 3.0 HBA - This will be disabled,\n\t\t"
+ "\t SAS 3.5 HBA - This will be enabled)");
+
/* raid transport support */
static struct raid_template *mpt3sas_raid_template;
static struct raid_template *mpt2sas_raid_template;
{
struct hba_port *port, *port_next;
+ /*
+ * When multipath_on_hba is disabled then
+ * search the hba_port entry using default
+ * port id i.e. 255
+ */
+ if (!ioc->multipath_on_hba)
+ port_id = MULTIPATH_DISABLED_PORT_ID;
+
list_for_each_entry_safe(port, port_next,
&ioc->port_table_list, list) {
if (port->port_id != port_id)
return port;
}
+ /*
+ * Allocate hba_port object for default port id (i.e. 255)
+ * when multipath_on_hba is disabled for the HBA.
+ * And add this object to port_table_list.
+ */
+ if (!ioc->multipath_on_hba) {
+ port = kzalloc(sizeof(struct hba_port), GFP_KERNEL);
+ if (!port)
+ return NULL;
+
+ port->port_id = port_id;
+ ioc_info(ioc,
+ "hba_port entry: %p, port: %d is added to hba_port list\n",
+ port, port->port_id);
+ list_add_tail(&port->list,
+ &ioc->port_table_list);
+ return port;
+ }
return NULL;
}
u16 ioc_status;
u64 sas_address;
u16 handle;
+ u8 port;
ioc_info(ioc, "search for expanders: start\n");
handle = le16_to_cpu(expander_pg0.DevHandle);
sas_address = le64_to_cpu(expander_pg0.SASAddress);
+ port = expander_pg0.PhysicalPort;
pr_info(
"\texpander present: handle(0x%04x), sas_addr(0x%016llx), port:%d\n",
handle, (unsigned long long)sas_address,
- expander_pg0.PhysicalPort);
+ (ioc->multipath_on_hba ?
+ port : MULTIPATH_DISABLED_PORT_ID));
_scsih_mark_responding_expander(ioc, &expander_pg0);
}
dtmprintk(ioc, ioc_info(ioc, "%s: MPT3_IOC_DONE_RESET\n", __func__));
if ((!ioc->is_driver_loading) && !(disable_discovery > 0 &&
!ioc->sas_hba.num_phys)) {
- _scsih_sas_port_refresh(ioc);
- _scsih_update_vphys_after_reset(ioc);
+ if (ioc->multipath_on_hba) {
+ _scsih_sas_port_refresh(ioc);
+ _scsih_update_vphys_after_reset(ioc);
+ }
_scsih_prep_device_scan(ioc);
_scsih_create_enclosure_list_after_reset(ioc);
_scsih_search_responding_sas_devices(ioc);
ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
break;
}
+
+ if (multipath_on_hba == -1 || multipath_on_hba == 0)
+ ioc->multipath_on_hba = 0;
+ else
+ ioc->multipath_on_hba = 1;
+
break;
case MPI25_VERSION:
case MPI26_VERSION:
ioc->combined_reply_index_count =
MPT3_SUP_REPLY_POST_HOST_INDEX_REG_COUNT_G3;
}
+
+ switch (ioc->is_gen35_ioc) {
+ case 0:
+ if (multipath_on_hba == -1 || multipath_on_hba == 0)
+ ioc->multipath_on_hba = 0;
+ else
+ ioc->multipath_on_hba = 1;
+ break;
+ case 1:
+ if (multipath_on_hba == -1 || multipath_on_hba > 0)
+ ioc->multipath_on_hba = 1;
+ else
+ ioc->multipath_on_hba = 0;
+ default:
+ break;
+ }
+
break;
default:
return -ENODEV;
return;
}
- if (sas_node->handle <= ioc->sas_hba.num_phys) {
+ if (sas_node->handle <= ioc->sas_hba.num_phys &&
+ (ioc->multipath_on_hba)) {
if (port->vphys_mask) {
list_for_each_entry_safe(vphy, vphy_next,
&port->vphys_list, list) {
if (handle && (link_rate >= MPI2_SAS_NEG_LINK_RATE_1_5)) {
_transport_set_identify(ioc, handle,
&mpt3sas_phy->remote_identify);
- if (sas_node->handle <= ioc->sas_hba.num_phys) {
+ if ((sas_node->handle <= ioc->sas_hba.num_phys) &&
+ (ioc->multipath_on_hba)) {
list_for_each_entry(hba_port,
&ioc->port_table_list, list) {
if (hba_port->sas_address == sas_address &&