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

scsi: mpi3mr: Refresh SAS ports during soft reset

Update the host's SAS ports if there is change in port id or phys. If the
port id is changed, then the driver updates it. If some phys are
enabled/disabled during reset, then driver updates them in STL.

Check for the responding expander devices and update the device handle if
it got changed. Register the expander with STL if it got added during reset
and unregister the expander device if it got removed during reset.

[mkp: include fix for zeroday warning]

Link: https://lore.kernel.org/r/20220804131226.16653-15-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 176d4aa6
......@@ -482,6 +482,9 @@ struct mpi3mr_hba_port {
* struct mpi3mr_sas_port - Internal SAS port information
* @port_list: List of ports belonging to a SAS node
* @num_phys: Number of phys associated with port
* @marked_responding: used while refresing the sas ports
* @lowest_phy: lowest phy ID of current sas port
* @phy_mask: phy_mask of current sas port
* @hba_port: HBA port entry
* @remote_identify: Attached device identification
* @rphy: SAS transport layer rphy object
......@@ -491,6 +494,9 @@ struct mpi3mr_hba_port {
struct mpi3mr_sas_port {
struct list_head port_list;
u8 num_phys;
u8 marked_responding;
int lowest_phy;
u32 phy_mask;
struct mpi3mr_hba_port *hba_port;
struct sas_identify remote_identify;
struct sas_rphy *rphy;
......@@ -939,6 +945,7 @@ struct scmd_priv {
* @scan_started: Async scan started
* @scan_failed: Asycn scan failed
* @stop_drv_processing: Stop all command processing
* @device_refresh_on: Don't process the events until devices are refreshed
* @max_host_ios: Maximum host I/O count
* @chain_buf_count: Chain buffer count
* @chain_buf_pool: Chain buffer pool
......@@ -1107,6 +1114,7 @@ struct mpi3mr_ioc {
u8 scan_started;
u16 scan_failed;
u8 stop_drv_processing;
u8 device_refresh_on;
u16 max_host_ios;
spinlock_t tgtdev_lock;
......@@ -1378,4 +1386,7 @@ struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr_and_rphy(
struct mpi3mr_ioc *mrioc, u64 sas_address, struct sas_rphy *rphy);
void mpi3mr_print_device_event_notice(struct mpi3mr_ioc *mrioc,
bool device_add);
void mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc);
void mpi3mr_refresh_expanders(struct mpi3mr_ioc *mrioc);
void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc);
#endif /*MPI3MR_H_INCLUDED*/
......@@ -3974,6 +3974,11 @@ int mpi3mr_reinit_ioc(struct mpi3mr_ioc *mrioc, u8 is_resume)
goto out_failed;
}
if (!is_resume) {
mrioc->device_refresh_on = 1;
mpi3mr_add_event_wait_for_device_refresh(mrioc);
}
ioc_info(mrioc, "sending port enable\n");
retval = mpi3mr_issue_port_enable(mrioc, 0);
if (retval) {
......@@ -4730,6 +4735,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
ioc_info(mrioc, "controller reset is triggered by %s\n",
mpi3mr_reset_rc_name(reset_reason));
mrioc->device_refresh_on = 0;
mrioc->reset_in_progress = 1;
mrioc->stop_bsgs = 1;
mrioc->prev_reset_result = -1;
......@@ -4811,7 +4817,8 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
mpi3mr_pel_wait_post(mrioc, &mrioc->pel_cmds);
}
mpi3mr_rfresh_tgtdevs(mrioc);
mrioc->device_refresh_on = 0;
mrioc->ts_update_counter = 0;
spin_lock_irqsave(&mrioc->watchdog_lock, flags);
if (mrioc->watchdog_work_q)
......@@ -4825,6 +4832,7 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
} else {
mpi3mr_issue_reset(mrioc,
MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason);
mrioc->device_refresh_on = 0;
mrioc->unrecoverable = 1;
mrioc->reset_in_progress = 0;
retval = -1;
......
......@@ -40,6 +40,8 @@ static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
#define MPI3MR_DRIVER_EVENT_TG_QD_REDUCTION (0xFFFF)
#define MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH (0xFFFE)
/**
* mpi3mr_host_tag_for_scmd - Get host tag for a scmd
* @mrioc: Adapter instance reference
......@@ -1106,6 +1108,9 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
MPI3_DEVICE0_FLAGS_ATT_METHOD_VIRTUAL)) ||
(tgtdev->parent_handle == 0xFFFF))
tgtdev->non_stl = 1;
if (tgtdev->dev_spec.sas_sata_inf.hba_port)
tgtdev->dev_spec.sas_sata_inf.hba_port->port_id =
dev_pg0->io_unit_port;
break;
}
case MPI3_DEVICE_DEVFORM_PCIE:
......@@ -1879,6 +1884,22 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
}
break;
}
case MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH:
{
while (mrioc->device_refresh_on)
msleep(500);
dprint_event_bh(mrioc,
"scan for non responding and newly added devices after soft reset started\n");
if (mrioc->sas_transport_enabled) {
mpi3mr_refresh_sas_ports(mrioc);
mpi3mr_refresh_expanders(mrioc);
}
mpi3mr_rfresh_tgtdevs(mrioc);
ioc_info(mrioc,
"scan for non responding and newly added devices after soft reset completed\n");
break;
}
default:
break;
}
......@@ -2648,6 +2669,35 @@ static void mpi3mr_cablemgmt_evt_th(struct mpi3mr_ioc *mrioc,
}
}
/**
* mpi3mr_add_event_wait_for_device_refresh - Add Wait for Device Refresh Event
* @mrioc: Adapter instance reference
*
* Add driver specific event to make sure that the driver won't process the
* events until all the devices are refreshed during soft reset.
*
* Return: Nothing
*/
void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc)
{
struct mpi3mr_fwevt *fwevt = NULL;
fwevt = mpi3mr_alloc_fwevt(0);
if (!fwevt) {
dprint_event_th(mrioc,
"failed to schedule bottom half handler for event(0x%02x)\n",
MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH);
return;
}
fwevt->mrioc = mrioc;
fwevt->event_id = MPI3_EVENT_WAIT_FOR_DEVICES_TO_REFRESH;
fwevt->send_ack = 0;
fwevt->process_evt = 1;
fwevt->evt_ctx = 0;
fwevt->event_data_size = 0;
mpi3mr_fwevt_add_to_list(mrioc, fwevt);
}
/**
* mpi3mr_os_handle_events - Firmware event handler
* @mrioc: Adapter instance reference
......
This diff is collapsed.
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