On Sat, Jul 30, 2022 at 1:41 AM Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> wrote: > > > > > On Jul 29, 2022, at 6:16 AM, Sreekanth Reddy <sreekanth.reddy@xxxxxxxxxxxx> wrote: > > > > Added below helper functions, > > - Get the device's sas address by reading > > correspond device's Device page0, > > - Get the expander object from expander list based > > on expander's handle, > > - Get the target device object from target device list > > based on device's sas address, > > - Get the expander device object from expander list > > based on expanders's sas address, > > - Get hba port object from hba port table list > > based on port's port id > > > > Signed-off-by: Sreekanth Reddy <sreekanth.reddy@xxxxxxxxxxxx> > > --- > > drivers/scsi/mpi3mr/mpi3mr.h | 14 ++ > > drivers/scsi/mpi3mr/mpi3mr_os.c | 3 + > > drivers/scsi/mpi3mr/mpi3mr_transport.c | 280 +++++++++++++++++++++++++ > > 3 files changed, 297 insertions(+) > > > > diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h > > index 006bc5d..742caf5 100644 > > --- a/drivers/scsi/mpi3mr/mpi3mr.h > > +++ b/drivers/scsi/mpi3mr/mpi3mr.h > > @@ -570,10 +570,12 @@ struct mpi3mr_enclosure_node { > > * > > * @sas_address: World wide unique SAS address > > * @dev_info: Device information bits > > + * @hba_port: HBA port entry > > */ > > struct tgt_dev_sas_sata { > > u64 sas_address; > > u16 dev_info; > > + struct mpi3mr_hba_port *hba_port; > > }; > > > > /** > > @@ -984,6 +986,10 @@ 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_hba: SAS node for the controller > > + * @sas_expander_list: SAS node list of expanders > > + * @sas_node_lock: Lock to protect SAS node list > > + * @hba_port_table_list: List of HBA Ports > > * @enclosure_list: List of Enclosure objects > > */ > > struct mpi3mr_ioc { > > @@ -1162,6 +1168,10 @@ struct mpi3mr_ioc { > > dma_addr_t cfg_page_dma; > > u16 cfg_page_sz; > > > > + struct mpi3mr_sas_node sas_hba; > > + struct list_head sas_expander_list; > > + spinlock_t sas_node_lock; > > + struct list_head hba_port_table_list; > > struct list_head enclosure_list; > > }; > > > > @@ -1317,4 +1327,8 @@ int mpi3mr_cfg_set_sas_io_unit_pg1(struct mpi3mr_ioc *mrioc, > > struct mpi3_sas_io_unit_page1 *sas_io_unit_pg1, u16 pg_sz); > > int mpi3mr_cfg_get_driver_pg1(struct mpi3mr_ioc *mrioc, > > struct mpi3_driver_page1 *driver_pg1, u16 pg_sz); > > + > > +u8 mpi3mr_is_expander_device(u16 device_info); > > +struct mpi3mr_hba_port *mpi3mr_get_hba_port_by_id(struct mpi3mr_ioc *mrioc, > > + u8 port_id); > > #endif /*MPI3MR_H_INCLUDED*/ > > diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c > > index ca718cb..b75ce73 100644 > > --- a/drivers/scsi/mpi3mr/mpi3mr_os.c > > +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c > > @@ -4692,11 +4692,14 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id) > > spin_lock_init(&mrioc->tgtdev_lock); > > spin_lock_init(&mrioc->watchdog_lock); > > spin_lock_init(&mrioc->chain_buf_lock); > > + spin_lock_init(&mrioc->sas_node_lock); > > > > INIT_LIST_HEAD(&mrioc->fwevt_list); > > INIT_LIST_HEAD(&mrioc->tgtdev_list); > > INIT_LIST_HEAD(&mrioc->delayed_rmhs_list); > > INIT_LIST_HEAD(&mrioc->delayed_evtack_cmds_list); > > + INIT_LIST_HEAD(&mrioc->sas_expander_list); > > + INIT_LIST_HEAD(&mrioc->hba_port_table_list); > > INIT_LIST_HEAD(&mrioc->enclosure_list); > > > > mutex_init(&mrioc->reset_mutex); > > diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c > > index 989bf63..fea3aae 100644 > > --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c > > +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c > > @@ -9,6 +9,237 @@ > > > > #include "mpi3mr.h" > > > > +/** > > + * __mpi3mr_expander_find_by_handle - expander search by handle > > + * @mrioc: Adapter instance reference > > + * @handle: Firmware device handle of the expander > > + * > > + * Context: The caller should acquire sas_node_lock > > + * > > + * This searches for expander device based on handle, then > > + * returns the sas_node object. > > + * > > + * Return: Expander sas_node object reference or NULL > > + */ > > +static struct mpi3mr_sas_node *__mpi3mr_expander_find_by_handle(struct mpi3mr_ioc > > + *mrioc, u16 handle) > > +{ > > + struct mpi3mr_sas_node *sas_expander, *r; > > + > > + r = NULL; > > + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { > > + if (sas_expander->handle != handle) > > + continue; > > + r = sas_expander; > > + goto out; > > + } > > + out: > > + return r; > > +} > > + > > +/** > > + * mpi3mr_is_expander_device - if device is an expander > > + * @device_info: Bitfield providing information about the device > > + * > > + * Return: 1 if the device is expander device, else 0. > > + */ > > +u8 mpi3mr_is_expander_device(u16 device_info) > > +{ > > + if ((device_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) == > > + MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_EXPANDER) > > + return 1; > > + else > > + return 0; > > +} > > + > > +/** > > + * mpi3mr_get_sas_address - retrieve sas_address for handle > > + * @mrioc: Adapter instance reference > > + * @handle: Firmware device handle > > + * @sas_address: Address to hold sas address > > + * > > + * This function issues device page0 read for a given device > > + * handle and gets the SAS address and return it back > > + * > > + * Return: 0 for success, non-zero for failure > > + */ > > +static int mpi3mr_get_sas_address(struct mpi3mr_ioc *mrioc, u16 handle, > > + u64 *sas_address) > > +{ > > + struct mpi3_device_page0 dev_pg0; > > + u16 ioc_status; > > + struct mpi3_device0_sas_sata_format *sasinf; > > + > > + *sas_address = 0; > > + > > + if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0, > > + sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, > > + handle))) { > > + ioc_err(mrioc, "%s: device page0 read failed\n", __func__); > > + return -ENXIO; > > + } > > + > > + if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { > > + ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n", > > + handle, ioc_status, __FILE__, __LINE__, __func__); > > + return -ENXIO; > > + } > > + > > + if (le16_to_cpu(dev_pg0.flags) & > > + MPI3_DEVICE0_FLAGS_CONTROLLER_DEV_HANDLE) > > + *sas_address = mrioc->sas_hba.sas_address; > > + else if (dev_pg0.device_form == MPI3_DEVICE_DEVFORM_SAS_SATA) { > > + sasinf = &dev_pg0.device_specific.sas_sata_format; > > + *sas_address = le64_to_cpu(sasinf->sas_address); > > + } else { > > + ioc_err(mrioc, "%s: device_form(%d) is not SAS_SATA\n", > > + __func__, dev_pg0.device_form); > > + return -ENXIO; > > + } > > + return 0; > > +} > > + > > +/** > > + * __mpi3mr_get_tgtdev_by_addr - target device search > > + * @mrioc: Adapter instance reference > > + * @sas_address: SAS address of the device > > + * @hba_port: HBA port entry > > + * > > + * This searches for target device from sas address and hba port > > + * pointer then return mpi3mr_tgt_dev object. > > + * > > + * Return: Valid tget_dev or NULL > > + */ > > +static struct mpi3mr_tgt_dev *__mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc, > > + u64 sas_address, struct mpi3mr_hba_port *hba_port) > > +{ > > + struct mpi3mr_tgt_dev *tgtdev; > > + > > + assert_spin_locked(&mrioc->tgtdev_lock); > > + > > + list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) > > + if ((tgtdev->dev_type == MPI3_DEVICE_DEVFORM_SAS_SATA) && > > + (tgtdev->dev_spec.sas_sata_inf.sas_address == sas_address) > > + && (tgtdev->dev_spec.sas_sata_inf.hba_port == hba_port)) > > + goto found_device; > > + return NULL; > > +found_device: > > + mpi3mr_tgtdev_get(tgtdev); > > + return tgtdev; > > +} > > + > > +/** > > + * mpi3mr_get_tgtdev_by_addr - target device search > > + * @mrioc: Adapter instance reference > > + * @sas_address: SAS address of the device > > + * @hba_port: HBA port entry > > + * > > + * This searches for target device from sas address and hba port > > + * pointer then return mpi3mr_tgt_dev object. > > + * > > + * Context: This function will acquire tgtdev_lock and will > > + * release before returning the mpi3mr_tgt_dev object. > > + * > > + * Return: Valid tget_dev or NULL > > + */ > > +static struct mpi3mr_tgt_dev *mpi3mr_get_tgtdev_by_addr(struct mpi3mr_ioc *mrioc, > > + u64 sas_address, struct mpi3mr_hba_port *hba_port) > > +{ > > + struct mpi3mr_tgt_dev *tgtdev = NULL; > > + unsigned long flags; > > + > > + if (!hba_port) > > + goto out; > > + > > + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); > > + tgtdev = __mpi3mr_get_tgtdev_by_addr(mrioc, sas_address, hba_port); > > + spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); > > + > > +out: > > + return tgtdev; > > +} > > + > > +/** > > + * mpi3mr_expander_find_by_sas_address - sas expander search > > + * @mrioc: Adapter instance reference > > + * @sas_address: SAS address of expander > > + * @hba_port: HBA port entry > > + * > > + * Return: A valid SAS expander node or NULL. > > + * > > + */ > > +static struct mpi3mr_sas_node *mpi3mr_expander_find_by_sas_address( > > + struct mpi3mr_ioc *mrioc, u64 sas_address, > > + struct mpi3mr_hba_port *hba_port) > > +{ > > + struct mpi3mr_sas_node *sas_expander, *r = NULL; > > + > > + if (!hba_port) > > + goto out; > > + > > + list_for_each_entry(sas_expander, &mrioc->sas_expander_list, list) { > > + if ((sas_expander->sas_address != sas_address) || > > + (sas_expander->hba_port != hba_port)) > > + continue; > > + r = sas_expander; > > + goto out; > > + } > > +out: > > + return r; > > +} > > + > > +/** > > + * __mpi3mr_sas_node_find_by_sas_address - sas node search > > + * @mrioc: Adapter instance reference > > + * @sas_address: SAS address of expander or sas host > > + * @hba_port: HBA port entry > > + * Context: Caller should acquire mrioc->sas_node_lock. > > + * > > + * If the SAS address indicates the device is direct attached to > > + * the controller (controller's SAS address) then the SAS node > > + * associated with the controller is returned back else the SAS > > + * address and hba port are used to identify the exact expander > > + * and the associated sas_node object is returned. If there is > > + * no match NULL is returned. > > + * > > + * Return: A valid SAS node or NULL. > > + * > > + */ > > +static struct mpi3mr_sas_node *__mpi3mr_sas_node_find_by_sas_address( > > + struct mpi3mr_ioc *mrioc, u64 sas_address, > > + struct mpi3mr_hba_port *hba_port) > > +{ > > + > Remove new line here > > + if (mrioc->sas_hba.sas_address == sas_address) > > + return &mrioc->sas_hba; > > + return mpi3mr_expander_find_by_sas_address(mrioc, sas_address, > > + hba_port); > > +} > > + > > +/** > > + * mpi3mr_parent_present - Is parent present for a phy > > + * @mrioc: Adapter instance reference > > + * @phy: SAS transport layer phy object > > + * > > + * Return: 0 if parent is present else non-zero > > + */ > > +static int mpi3mr_parent_present(struct mpi3mr_ioc *mrioc, struct sas_phy *phy) > > +{ > > + > remove new line Agree. Will remove it next version patch set. > > + unsigned long flags; > > + struct mpi3mr_hba_port *hba_port = phy->hostdata; > > + > > + spin_lock_irqsave(&mrioc->sas_node_lock, flags); > > + if (__mpi3mr_sas_node_find_by_sas_address(mrioc, > > + phy->identify.sas_address, > > + hba_port) == NULL) { > > + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); > > + return -1; > > + } > > + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); > > + return 0; > > +} > > + > > /** > > * mpi3mr_convert_phy_link_rate - > > * @link_rate: link rate as defined in the MPI header > > @@ -428,3 +659,52 @@ static int mpi3mr_add_expander_phy(struct mpi3mr_ioc *mrioc, > > mr_sas_phy->phy = phy; > > return 0; > > } > > + > > +/** > > + * mpi3mr_alloc_hba_port - alloc hba port object > > + * @mrioc: Adapter instance reference > > + * @port_id: Port number > > + * > > + * Alloc memory for hba port object. > > + */ > > +static struct mpi3mr_hba_port * > > +mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id) > > +{ > > + struct mpi3mr_hba_port *hba_port; > > + > > + hba_port = kzalloc(sizeof(struct mpi3mr_hba_port), > > + GFP_KERNEL); > > + if (!hba_port) > > + return NULL; > > + hba_port->port_id = port_id; > > + ioc_info(mrioc, "hba_port entry: %p, port: %d is added to hba_port list\n", > > + hba_port, hba_port->port_id); > > + list_add_tail(&hba_port->list, &mrioc->hba_port_table_list); > > + return hba_port; > > +} > > + > > +/** > > + * mpi3mr_get_hba_port_by_id - find hba port by id > > + * @mrioc: Adapter instance reference > > + * @port_id - Port ID to search > > + * > > + * Return: mpi3mr_hba_port reference for the matched port > > + */ > > + > > +struct mpi3mr_hba_port *mpi3mr_get_hba_port_by_id(struct mpi3mr_ioc *mrioc, > > + u8 port_id) > > +{ > > + > Ditto remove newline Agree. Will remove it next version patch set. > > + struct mpi3mr_hba_port *port, *port_next; > > + > > + list_for_each_entry_safe(port, port_next, > > + &mrioc->hba_port_table_list, list) { > > + if (port->port_id != port_id) > > + continue; > > + if (port->flags & MPI3MR_HBA_PORT_FLAG_DIRTY) > > + continue; > > + return port; > > + } > > + > > + return NULL; > > +} > > -- > > 2.27.0 > > > > -- > Himanshu Madhani Oracle Linux Engineering >
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature