> On Jul 29, 2022, at 6:16 AM, Sreekanth Reddy <sreekanth.reddy@xxxxxxxxxxxx> wrote: > > - 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 > the same. If some phys are enabled/disabled during reset then > driver updates the same 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. > > Signed-off-by: Sreekanth Reddy <sreekanth.reddy@xxxxxxxxxxxx> > --- > drivers/scsi/mpi3mr/mpi3mr.h | 11 + > drivers/scsi/mpi3mr/mpi3mr_fw.c | 10 +- > drivers/scsi/mpi3mr/mpi3mr_os.c | 50 ++++ > drivers/scsi/mpi3mr/mpi3mr_transport.c | 351 +++++++++++++++++++++++++ > 4 files changed, 421 insertions(+), 1 deletion(-) > > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h > index d203167..0f47b45 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr.h > +++ b/drivers/scsi/mpi3mr/mpi3mr.h > @@ -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*/ > diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c > index 59ef373..dfb7570 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c > +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c > @@ -3977,6 +3977,11 @@ retry_init: > 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) { > @@ -4733,6 +4738,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; > @@ -4814,7 +4820,8 @@ out: > 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) > @@ -4828,6 +4835,7 @@ out: > } 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; > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c > index 139c164..d4f37b1 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c > @@ -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 > @@ -1114,6 +1116,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: > @@ -1886,6 +1891,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; > } > @@ -2655,6 +2676,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 > diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c > index e8a9a76..c1ca97c 100644 > --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c > +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c > @@ -9,6 +9,9 @@ > > #include "mpi3mr.h" > > +static void mpi3mr_expander_node_remove(struct mpi3mr_ioc *mrioc, > + struct mpi3mr_sas_node *sas_expander); > + > /** > * mpi3mr_post_transport_req - Issue transport requests and wait > * @mrioc: Adapter instance reference > @@ -597,6 +600,9 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, > > list_del(&mr_sas_phy->port_siblings); > mr_sas_port->num_phys--; > + mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); > + if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) > + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; > sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); > mr_sas_phy->phy_belongs_to_port = 0; > } > @@ -621,6 +627,9 @@ static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, > > list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); > mr_sas_port->num_phys++; > + mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); > + if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) > + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; > sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); > mr_sas_phy->phy_belongs_to_port = 1; > } > @@ -1356,6 +1365,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, > list_add_tail(&mr_sas_node->phy[i].port_siblings, > &mr_sas_port->phy_list); > mr_sas_port->num_phys++; > + mr_sas_port->phy_mask |= (1 << i); > } > > if (!mr_sas_port->num_phys) { > @@ -1364,6 +1374,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, > goto out_fail; > } > > + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; > + > if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { > tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc, > mr_sas_port->remote_identify.sas_address, > @@ -1565,6 +1577,345 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, > kfree(mr_sas_port); > } > > +/** > + * struct host_port - host port details > + * @sas_address: SAS Address of the attached device > + * @phy_mask: phy mask of host port > + * @handle: Device Handle of attached device > + * @iounit_port_id: port ID > + * @used: host port is already matched with sas port from sas_port_list > + * @lowest_phy: lowest phy ID of host port > + */ > +struct host_port { > + u64 sas_address; > + u32 phy_mask; > + u16 handle; > + u8 iounit_port_id; > + u8 used; > + u8 lowest_phy; > +}; > + > +/** > + * mpi3mr_update_mr_sas_port - update sas port objects during reset > + * @mrioc: Adapter instance reference > + * @h_port: host_port object > + * @mr_sas_port: sas_port objects which needs to be updated > + * > + * Update the port ID of sas port object. Also add the phys if new phys got > + * added to current sas port and remove the phys if some phys are moved > + * out of the current sas port. > + * > + * Return: Nothing. > + */ > +static void > +mpi3mr_update_mr_sas_port(struct mpi3mr_ioc *mrioc, struct host_port *h_port, > + struct mpi3mr_sas_port *mr_sas_port) > +{ > + struct mpi3mr_sas_phy *mr_sas_phy; > + u32 phy_mask_xor, phys_to_be_added, phys_to_be_removed; > + int i; > + > + h_port->used = 1; > + mr_sas_port->marked_responding = 1; > + > + dev_info(&mr_sas_port->port->dev, > + "sas_address(0x%016llx), old: port_id %d phy_mask 0x%x, new: port_id %d phy_mask:0x%x\n", > + mr_sas_port->remote_identify.sas_address, > + mr_sas_port->hba_port->port_id, mr_sas_port->phy_mask, > + h_port->iounit_port_id, h_port->phy_mask); > + > + mr_sas_port->hba_port->port_id = h_port->iounit_port_id; > + mr_sas_port->hba_port->flags &= ~MPI3MR_HBA_PORT_FLAG_DIRTY; > + > + /* Get the newly added phys bit map & removed phys bit map */ > + phy_mask_xor = mr_sas_port->phy_mask ^ h_port->phy_mask; > + phys_to_be_added = h_port->phy_mask & phy_mask_xor; > + phys_to_be_removed = mr_sas_port->phy_mask & phy_mask_xor; > + > + /* > + * Register these new phys to current mr_sas_port's port. > + * if these phys are previously registered with another port > + * then delete these phys from that port first. > + */ > + for_each_set_bit(i, (ulong *) &phys_to_be_added, BITS_PER_TYPE(u32)) { > + mr_sas_phy = &mrioc->sas_hba.phy[i]; > + if (mr_sas_phy->phy_belongs_to_port) > + mpi3mr_del_phy_from_an_existing_port(mrioc, > + &mrioc->sas_hba, mr_sas_phy); > + mpi3mr_add_phy_to_an_existing_port(mrioc, > + &mrioc->sas_hba, mr_sas_phy, > + mr_sas_port->remote_identify.sas_address, > + mr_sas_port->hba_port); > + } > + > + /* Delete the phys which are not part of current mr_sas_port's port. */ > + for_each_set_bit(i, (ulong *) &phys_to_be_removed, BITS_PER_TYPE(u32)) { > + mr_sas_phy = &mrioc->sas_hba.phy[i]; > + if (mr_sas_phy->phy_belongs_to_port) > + mpi3mr_del_phy_from_an_existing_port(mrioc, > + &mrioc->sas_hba, mr_sas_phy); > + } > +} > + > +/** > + * mpi3mr_refresh_sas_ports - update host's sas ports during reset > + * @mrioc: Adapter instance reference > + * > + * Update the host's sas ports during reset by checking whether > + * sas ports are still intact or not. Add/remove phys if any hba > + * phys are (moved in)/(moved out) of sas port. Also update > + * io_unit_port if it got changed during reset. > + * > + * Return: Nothing. > + */ > +void > +mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) > +{ > + struct host_port h_port[32]; > + int i, j, found, host_port_count = 0, port_idx; > + u16 sz, attached_handle, ioc_status; > + struct mpi3_sas_io_unit_page0 *sas_io_unit_pg0 = NULL; > + struct mpi3_device_page0 dev_pg0; > + struct mpi3_device0_sas_sata_format *sasinf; > + struct mpi3mr_sas_port *mr_sas_port; > + > + sz = offsetof(struct mpi3_sas_io_unit_page0, phy_data) + > + (mrioc->sas_hba.num_phys * > + sizeof(struct mpi3_sas_io_unit0_phy_data)); > + sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); > + if (!sas_io_unit_pg0) > + return; > + if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { > + ioc_err(mrioc, "failure at %s:%d/%s()!\n", > + __FILE__, __LINE__, __func__); > + goto out; > + } > + > + /* Create a new expander port table */ > + for (i = 0; i < mrioc->sas_hba.num_phys; i++) { > + attached_handle = le16_to_cpu( > + sas_io_unit_pg0->phy_data[i].attached_dev_handle); > + if (!attached_handle) > + continue; > + found = 0; > + for (j = 0; j < host_port_count; j++) { > + if (h_port[j].handle == attached_handle) { > + h_port[j].phy_mask |= (1 << i); > + found = 1; > + break; > + } > + } > + if (found) > + continue; > + if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0, > + sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, > + attached_handle))) { > + dprint_reset(mrioc, > + "failed to read dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n", > + attached_handle, __FILE__, __LINE__, __func__); > + continue; > + } > + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { > + dprint_reset(mrioc, > + "ioc_status(0x%x) while reading dev_pg0 for handle(0x%04x) at %s:%d/%s()!\n", > + ioc_status, attached_handle, > + __FILE__, __LINE__, __func__); > + continue; > + } > + sasinf = &dev_pg0.device_specific.sas_sata_format; > + > + port_idx = host_port_count; > + h_port[port_idx].sas_address = le64_to_cpu(sasinf->sas_address); > + h_port[port_idx].handle = attached_handle; > + h_port[port_idx].phy_mask = (1 << i); > + h_port[port_idx].iounit_port_id = sas_io_unit_pg0->phy_data[i].io_unit_port; > + h_port[port_idx].lowest_phy = sasinf->phy_num; > + h_port[port_idx].used = 0; > + host_port_count++; > + } > + > + if (!host_port_count) > + goto out; > + > + if (mrioc->logging_level & MPI3_DEBUG_RESET) { > + ioc_info(mrioc, "Host port details before reset\n"); > + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, > + port_list) { > + ioc_info(mrioc, > + "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", > + mr_sas_port->hba_port->port_id, > + mr_sas_port->remote_identify.sas_address, > + mr_sas_port->phy_mask, mr_sas_port->lowest_phy); > + } > + mr_sas_port = NULL; > + ioc_info(mrioc, "Host port details after reset\n"); > + for (i = 0; i < host_port_count; i++) { > + ioc_info(mrioc, > + "port_id:%d, sas_address:(0x%016llx), phy_mask:(0x%x), lowest phy id:%d\n", > + h_port[i].iounit_port_id, h_port[i].sas_address, > + h_port[i].phy_mask, h_port[i].lowest_phy); > + } > + } > + > + /* mark all host sas port entries as dirty */ > + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, > + port_list) { > + mr_sas_port->marked_responding = 0; > + mr_sas_port->hba_port->flags |= MPI3MR_HBA_PORT_FLAG_DIRTY; > + } > + > + /* First check for matching lowest phy */ > + for (i = 0; i < host_port_count; i++) { > + mr_sas_port = NULL; > + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, > + port_list) { > + if (mr_sas_port->marked_responding) > + continue; > + if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) > + continue; > + if (h_port[i].lowest_phy == mr_sas_port->lowest_phy) { > + mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port); > + break; > + } > + } > + } > + > + /* In case if lowest phy is got enabled or disabled during reset */ > + for (i = 0; i < host_port_count; i++) { > + if (h_port[i].used) > + continue; > + mr_sas_port = NULL; > + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, > + port_list) { > + if (mr_sas_port->marked_responding) > + continue; > + if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) > + continue; > + if (h_port[i].phy_mask & mr_sas_port->phy_mask) { > + mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port); > + break; > + } > + } > + } > + > + /* In case if expander cable is removed & connected to another HBA port during reset */ > + for (i = 0; i < host_port_count; i++) { > + if (h_port[i].used) > + continue; > + mr_sas_port = NULL; > + list_for_each_entry(mr_sas_port, &mrioc->sas_hba.sas_port_list, > + port_list) { > + if (mr_sas_port->marked_responding) > + continue; > + if (h_port[i].sas_address != mr_sas_port->remote_identify.sas_address) > + continue; > + mpi3mr_update_mr_sas_port(mrioc, &h_port[i], mr_sas_port); > + break; > + } > + } > +out: > + kfree(sas_io_unit_pg0); > +} > + > +/** > + * mpi3mr_refresh_expanders - Refresh expander device exposure > + * @mrioc: Adapter instance reference > + * > + * This is executed post controller reset to identify any > + * missing expander devices during reset and remove from the upper layers > + * or expose any newly detected expander device to the upper layers. > + * > + * Return: Nothing. > + */ > +void > +mpi3mr_refresh_expanders(struct mpi3mr_ioc *mrioc) > +{ > + struct mpi3mr_sas_node *sas_expander, *sas_expander_next; > + struct mpi3_sas_expander_page0 expander_pg0; > + u16 ioc_status, handle; > + u64 sas_address; > + int i; > + unsigned long flags; > + struct mpi3mr_hba_port *hba_port; > + > + spin_lock_irqsave(&mrioc->sas_node_lock, flags); > + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { > + sas_expander->non_responding = 1; > + } > + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); > + > + sas_expander = NULL; > + > + handle = 0xffff; > + > + /* Search for responding expander devices and add them if they are newly got added */ > + while (true) { > + if ((mpi3mr_cfg_get_sas_exp_pg0(mrioc, &ioc_status, &expander_pg0, > + sizeof(struct mpi3_sas_expander_page0), > + MPI3_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE, handle))) { > + dprint_reset(mrioc, > + "failed to read exp pg0 for handle(0x%04x) at %s:%d/%s()!\n", > + handle, __FILE__, __LINE__, __func__); > + break; > + } > + > + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { > + dprint_reset(mrioc, > + "ioc_status(0x%x) while reading exp pg0 for handle:(0x%04x), %s:%d/%s()!\n", > + ioc_status, handle, __FILE__, __LINE__, __func__); > + break; > + } > + > + handle = le16_to_cpu(expander_pg0.dev_handle); > + sas_address = le64_to_cpu(expander_pg0.sas_address); > + hba_port = mpi3mr_get_hba_port_by_id(mrioc, expander_pg0.io_unit_port); > + > + if (!hba_port) { > + mpi3mr_sas_host_refresh(mrioc); > + mpi3mr_expander_add(mrioc, handle); > + continue; > + } > + > + spin_lock_irqsave(&mrioc->sas_node_lock, flags); > + sas_expander = > + mpi3mr_expander_find_by_sas_address(mrioc, > + sas_address, hba_port); > + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); > + > + if (!sas_expander) { > + mpi3mr_sas_host_refresh(mrioc); > + mpi3mr_expander_add(mrioc, handle); > + continue; > + } > + > + sas_expander->non_responding = 0; > + if (sas_expander->handle == handle) > + continue; > + > + sas_expander->handle = handle; > + for (i = 0 ; i < sas_expander->num_phys ; i++) > + sas_expander->phy[i].handle = handle; > + } > + > + /* > + * Delete non responding expander devices and the corresponding > + * hba_port if the non responding expander device's parent device > + * is a host node. > + */ > + Remove newline here > + sas_expander = NULL; > + spin_lock_irqsave(&mrioc->sas_node_lock, flags); > + list_for_each_entry_safe_reverse(sas_expander, sas_expander_next, > + &mrioc->sas_expander_list, list) { > + if (sas_expander->non_responding) { > + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); > + mpi3mr_expander_node_remove(mrioc, sas_expander); > + spin_lock_irqsave(&mrioc->sas_node_lock, flags); > + } > + } > + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); > +} > + > /** > * mpi3mr_expander_node_add - insert an expander to the list. > * @mrioc: Adapter instance reference > -- > 2.27.0 > With the small nits fixed, you can add Reviewed-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> -- Himanshu Madhani Oracle Linux Engineering