@@ -812,6 +812,24 @@ void eeh_pe_restore_bars(struct eeh_pe *pe)
812812const char * eeh_pe_loc_get (struct eeh_pe * pe )
813813{
814814 struct pci_bus * bus = eeh_pe_bus_get (pe );
815+ return eeh_pe_loc_get_bus (bus );
816+ }
817+
818+ /**
819+ * eeh_pe_loc_get_bus - Retrieve location code binding to the given PCI bus
820+ * @bus: PCI bus
821+ *
822+ * Retrieve the location code associated with the given PCI bus. If the bus
823+ * is a root bus, the location code is fetched from the PHB device tree node
824+ * or root port. Otherwise, the location code is obtained from the device
825+ * tree node of the upstream bridge of the bus. The function walks up the
826+ * bus hierarchy if necessary, checking each node for the appropriate
827+ * location code property ("ibm,io-base-loc-code" for root buses,
828+ * "ibm,slot-location-code" for others). If no location code is found,
829+ * returns "N/A".
830+ */
831+ const char * eeh_pe_loc_get_bus (struct pci_bus * bus )
832+ {
815833 struct device_node * dn ;
816834 const char * loc = NULL ;
817835
@@ -838,16 +856,17 @@ const char *eeh_pe_loc_get(struct eeh_pe *pe)
838856}
839857
840858/**
841- * eeh_pe_bus_get - Retrieve PCI bus according to the given PE
859+ * _eeh_pe_bus_get - Retrieve PCI bus according to the given PE
842860 * @pe: EEH PE
861+ * @do_lock: Is the caller already held the pci_lock_rescan_remove?
843862 *
844863 * Retrieve the PCI bus according to the given PE. Basically,
845864 * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the
846865 * primary PCI bus will be retrieved. The parent bus will be
847866 * returned for BUS PE. However, we don't have associated PCI
848867 * bus for DEVICE PE.
849868 */
850- struct pci_bus * eeh_pe_bus_get (struct eeh_pe * pe )
869+ static struct pci_bus * _eeh_pe_bus_get (struct eeh_pe * pe , bool do_lock )
851870{
852871 struct eeh_dev * edev ;
853872 struct pci_dev * pdev ;
@@ -862,11 +881,58 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
862881
863882 /* Retrieve the parent PCI bus of first (top) PCI device */
864883 edev = list_first_entry_or_null (& pe -> edevs , struct eeh_dev , entry );
865- pci_lock_rescan_remove ();
884+ if (do_lock )
885+ pci_lock_rescan_remove ();
866886 pdev = eeh_dev_to_pci_dev (edev );
867887 if (pdev )
868888 bus = pdev -> bus ;
869- pci_unlock_rescan_remove ();
889+ if (do_lock )
890+ pci_unlock_rescan_remove ();
870891
871892 return bus ;
872893}
894+
895+ /**
896+ * eeh_pe_bus_get - Retrieve PCI bus associated with the given EEH PE, locking
897+ * if needed
898+ * @pe: Pointer to the EEH PE
899+ *
900+ * This function is a wrapper around _eeh_pe_bus_get(), which retrieves the PCI
901+ * bus associated with the provided EEH PE structure. It acquires the PCI
902+ * rescans lock to ensure safe access to shared data during the retrieval
903+ * process. This function should be used when the caller requires the PCI bus
904+ * while holding the rescan/remove lock, typically during operations that modify
905+ * or inspect PCIe device state in a safe manner.
906+ *
907+ * RETURNS:
908+ * A pointer to the PCI bus associated with the EEH PE, or NULL if none found.
909+ */
910+
911+ struct pci_bus * eeh_pe_bus_get (struct eeh_pe * pe )
912+ {
913+ return _eeh_pe_bus_get (pe , true);
914+ }
915+
916+ /**
917+ * eeh_pe_bus_get_nolock - Retrieve PCI bus associated with the given EEH PE
918+ * without locking
919+ * @pe: Pointer to the EEH PE
920+ *
921+ * This function is a variant of _eeh_pe_bus_get() that retrieves the PCI bus
922+ * associated with the specified EEH PE without acquiring the
923+ * pci_lock_rescan_remove lock. It should only be used when the caller can
924+ * guarantee safe access to PE structures without the need for that lock,
925+ * typically in contexts where the lock is already held locking is otherwise
926+ * managed.
927+ *
928+ * RETURNS:
929+ * pointer to the PCI bus associated with the EEH PE, or NULL if none is found.
930+ *
931+ * NOTE:
932+ * Use this function carefully to avoid race conditions and data corruption.
933+ */
934+
935+ struct pci_bus * eeh_pe_bus_get_nolock (struct eeh_pe * pe )
936+ {
937+ return _eeh_pe_bus_get (pe , false);
938+ }
0 commit comments