The PCI region-request functions become managed functions when pcim_enable_device() has been called previously instead of pci_enable_device(). This has already caused a bug (in 8558de401b5f) by confusing users, who came to believe that all PCI functions, such as pci_iomap_range(), suddenly are managed that way, which is not the case. Add comments to the relevant functions' docstrings that warn users about this behavior. Link: https://lore.kernel.org/r/20240605081605.18769-8-pstanner@xxxxxxxxxx Signed-off-by: Philipp Stanner <pstanner@xxxxxxxxxx> Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> --- drivers/pci/iomap.c | 16 ++++++++++++++++ drivers/pci/pci.c | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/drivers/pci/iomap.c b/drivers/pci/iomap.c index c9725428e387..a715a4803c95 100644 --- a/drivers/pci/iomap.c +++ b/drivers/pci/iomap.c @@ -23,6 +23,10 @@ * * @maxlen specifies the maximum length to map. If you want to get access to * the complete BAR from offset to the end, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). * */ void __iomem *pci_iomap_range(struct pci_dev *dev, int bar, @@ -63,6 +67,10 @@ EXPORT_SYMBOL(pci_iomap_range); * * @maxlen specifies the maximum length to map. If you want to get access to * the complete BAR from offset to the end, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). * */ void __iomem *pci_iomap_wc_range(struct pci_dev *dev, int bar, @@ -106,6 +114,10 @@ EXPORT_SYMBOL_GPL(pci_iomap_wc_range); * * @maxlen specifies the maximum length to map. If you want to get access to * the complete BAR without checking for its length first, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). If you need automatic cleanup, use pcim_iomap(). * */ void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) { @@ -127,6 +139,10 @@ EXPORT_SYMBOL(pci_iomap); * * @maxlen specifies the maximum length to map. If you want to get access to * the complete BAR without checking for its length first, pass %0 here. + * + * NOTE: + * This function is never managed, even if you initialized with + * pcim_enable_device(). * */ void __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen) { diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7013699db242..5e4f377411ec 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3900,6 +3900,8 @@ EXPORT_SYMBOL(pci_release_region); * @res_name: Name to be associated with resource. * @exclusive: whether the region access is exclusive or not * + * Returns: 0 on success, negative error code on failure. + * * Mark the PCI region associated with PCI device @pdev BAR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns @@ -3950,6 +3952,8 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, * @bar: BAR to be reserved * @res_name: Name to be associated with resource * + * Returns: 0 on success, negative error code on failure. + * * Mark the PCI region associated with PCI device @pdev BAR @bar as * being reserved by owner @res_name. Do not access any * address inside the PCI regions unless this call returns @@ -3957,6 +3961,11 @@ static int __pci_request_region(struct pci_dev *pdev, int bar, * * Returns 0 on success, or %EBUSY on error. A warning * message is also printed on failure. + * + * NOTE: + * This is a "hybrid" function: It's normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. This hybrid feature is + * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) { @@ -4007,6 +4016,13 @@ static int __pci_request_selected_regions(struct pci_dev *pdev, int bars, * @pdev: PCI device whose resources are to be reserved * @bars: Bitmask of BARs to be requested * @res_name: Name to be associated with resource + * + * Returns: 0 on success, negative error code on failure. + * + * NOTE: + * This is a "hybrid" function: It's normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. This hybrid feature is + * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ int pci_request_selected_regions(struct pci_dev *pdev, int bars, const char *res_name) @@ -4015,6 +4031,19 @@ int pci_request_selected_regions(struct pci_dev *pdev, int bars, } EXPORT_SYMBOL(pci_request_selected_regions); +/** + * pci_request_selected_regions_exclusive - Request regions exclusively + * @pdev: PCI device to request regions from + * @bars: bit mask of BARs to request + * @res_name: name to be associated with the requests + * + * Returns: 0 on success, negative error code on failure. + * + * NOTE: + * This is a "hybrid" function: It's normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. This hybrid feature is + * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. + */ int pci_request_selected_regions_exclusive(struct pci_dev *pdev, int bars, const char *res_name) { @@ -4032,7 +4061,6 @@ EXPORT_SYMBOL(pci_request_selected_regions_exclusive); * successful call to pci_request_regions(). Call this function only * after all use of the PCI regions has ceased. */ - void pci_release_regions(struct pci_dev *pdev) { pci_release_selected_regions(pdev, (1 << PCI_STD_NUM_BARS) - 1); @@ -4064,6 +4092,8 @@ EXPORT_SYMBOL(pci_request_regions); * @pdev: PCI device whose resources are to be reserved * @res_name: Name to be associated with resource. * + * Returns: 0 on success, negative error code on failure. + * * Mark all PCI regions associated with PCI device @pdev as being reserved * by owner @res_name. Do not access any address inside the PCI regions * unless this call returns successfully. @@ -4073,6 +4103,11 @@ EXPORT_SYMBOL(pci_request_regions); * * Returns 0 on success, or %EBUSY on error. A warning message is also * printed on failure. + * + * NOTE: + * This is a "hybrid" function: It's normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. This hybrid feature is + * DEPRECATED! If you want managed cleanup, use the pcim_* functions instead. */ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) { @@ -4404,6 +4439,11 @@ void pci_disable_parity(struct pci_dev *dev) * @enable: boolean: whether to enable or disable PCI INTx * * Enables/disables PCI INTx for device @pdev + * + * NOTE: + * This is a "hybrid" function: It's normally unmanaged, but becomes managed + * when pcim_enable_device() has been called in advance. This hybrid feature is + * DEPRECATED! */ void pci_intx(struct pci_dev *pdev, int enable) { -- 2.45.0