PCI : Add selected_regions funcs
This patch adds the following changes into generic PCI code especially for PCI legacy I/O port free drivers. - Added new pci_request_selected_regions() and pci_release_selected_regions() for PCI legacy I/O port free drivers in order to request/release only the selected regions. - Added helper routine pci_select_bars() which makes proper mask of BARs from the specified resource type. This would be very helpful for users of pci_enable_device_bars(). Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Cc: Inaky Perez-Gonzalez <inaky@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
38cc13022e
Коммит
c87deff776
|
@ -921,6 +921,47 @@ err_out:
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pci_release_selected_regions - Release selected PCI I/O and memory resources
|
||||||
|
* @pdev: PCI device whose resources were previously reserved
|
||||||
|
* @bars: Bitmask of BARs to be released
|
||||||
|
*
|
||||||
|
* Release selected PCI I/O and memory resources previously reserved.
|
||||||
|
* Call this function only after all use of the PCI regions has ceased.
|
||||||
|
*/
|
||||||
|
void pci_release_selected_regions(struct pci_dev *pdev, int bars)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
if (bars & (1 << i))
|
||||||
|
pci_release_region(pdev, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pci_request_selected_regions - Reserve selected PCI I/O and memory resources
|
||||||
|
* @pdev: PCI device whose resources are to be reserved
|
||||||
|
* @bars: Bitmask of BARs to be requested
|
||||||
|
* @res_name: Name to be associated with resource
|
||||||
|
*/
|
||||||
|
int pci_request_selected_regions(struct pci_dev *pdev, int bars,
|
||||||
|
const char *res_name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
if (bars & (1 << i))
|
||||||
|
if(pci_request_region(pdev, i, res_name))
|
||||||
|
goto err_out;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
while(--i >= 0)
|
||||||
|
if (bars & (1 << i))
|
||||||
|
pci_release_region(pdev, i);
|
||||||
|
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* pci_release_regions - Release reserved PCI I/O and memory resources
|
* pci_release_regions - Release reserved PCI I/O and memory resources
|
||||||
|
@ -933,10 +974,7 @@ err_out:
|
||||||
|
|
||||||
void pci_release_regions(struct pci_dev *pdev)
|
void pci_release_regions(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
int i;
|
pci_release_selected_regions(pdev, (1 << 6) - 1);
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
pci_release_region(pdev, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -954,18 +992,7 @@ void pci_release_regions(struct pci_dev *pdev)
|
||||||
*/
|
*/
|
||||||
int pci_request_regions(struct pci_dev *pdev, const char *res_name)
|
int pci_request_regions(struct pci_dev *pdev, const char *res_name)
|
||||||
{
|
{
|
||||||
int i;
|
return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name);
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
if(pci_request_region(pdev, i, res_name))
|
|
||||||
goto err_out;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
while(--i >= 0)
|
|
||||||
pci_release_region(pdev, i);
|
|
||||||
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1149,6 +1176,22 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pci_select_bars - Make BAR mask from the type of resource
|
||||||
|
* @pdev: the PCI device for which BAR mask is made
|
||||||
|
* @flags: resource type mask to be selected
|
||||||
|
*
|
||||||
|
* This helper routine makes bar mask from the type of resource.
|
||||||
|
*/
|
||||||
|
int pci_select_bars(struct pci_dev *dev, unsigned long flags)
|
||||||
|
{
|
||||||
|
int i, bars = 0;
|
||||||
|
for (i = 0; i < PCI_NUM_RESOURCES; i++)
|
||||||
|
if (pci_resource_flags(dev, i) & flags)
|
||||||
|
bars |= (1 << i);
|
||||||
|
return bars;
|
||||||
|
}
|
||||||
|
|
||||||
static int __devinit pci_init(void)
|
static int __devinit pci_init(void)
|
||||||
{
|
{
|
||||||
struct pci_dev *dev = NULL;
|
struct pci_dev *dev = NULL;
|
||||||
|
@ -1197,6 +1240,8 @@ EXPORT_SYMBOL(pci_release_regions);
|
||||||
EXPORT_SYMBOL(pci_request_regions);
|
EXPORT_SYMBOL(pci_request_regions);
|
||||||
EXPORT_SYMBOL(pci_release_region);
|
EXPORT_SYMBOL(pci_release_region);
|
||||||
EXPORT_SYMBOL(pci_request_region);
|
EXPORT_SYMBOL(pci_request_region);
|
||||||
|
EXPORT_SYMBOL(pci_release_selected_regions);
|
||||||
|
EXPORT_SYMBOL(pci_request_selected_regions);
|
||||||
EXPORT_SYMBOL(pci_set_master);
|
EXPORT_SYMBOL(pci_set_master);
|
||||||
EXPORT_SYMBOL(pci_set_mwi);
|
EXPORT_SYMBOL(pci_set_mwi);
|
||||||
EXPORT_SYMBOL(pci_clear_mwi);
|
EXPORT_SYMBOL(pci_clear_mwi);
|
||||||
|
@ -1205,6 +1250,7 @@ EXPORT_SYMBOL(pci_set_dma_mask);
|
||||||
EXPORT_SYMBOL(pci_set_consistent_dma_mask);
|
EXPORT_SYMBOL(pci_set_consistent_dma_mask);
|
||||||
EXPORT_SYMBOL(pci_assign_resource);
|
EXPORT_SYMBOL(pci_assign_resource);
|
||||||
EXPORT_SYMBOL(pci_find_parent_resource);
|
EXPORT_SYMBOL(pci_find_parent_resource);
|
||||||
|
EXPORT_SYMBOL(pci_select_bars);
|
||||||
|
|
||||||
EXPORT_SYMBOL(pci_set_power_state);
|
EXPORT_SYMBOL(pci_set_power_state);
|
||||||
EXPORT_SYMBOL(pci_save_state);
|
EXPORT_SYMBOL(pci_save_state);
|
||||||
|
|
|
@ -533,6 +533,7 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
|
||||||
int __must_check pci_assign_resource(struct pci_dev *dev, int i);
|
int __must_check pci_assign_resource(struct pci_dev *dev, int i);
|
||||||
int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
|
int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
|
||||||
void pci_restore_bars(struct pci_dev *dev);
|
void pci_restore_bars(struct pci_dev *dev);
|
||||||
|
int pci_select_bars(struct pci_dev *dev, unsigned long flags);
|
||||||
|
|
||||||
/* ROM control related routines */
|
/* ROM control related routines */
|
||||||
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
|
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
|
||||||
|
@ -561,6 +562,8 @@ int __must_check pci_request_regions(struct pci_dev *, const char *);
|
||||||
void pci_release_regions(struct pci_dev *);
|
void pci_release_regions(struct pci_dev *);
|
||||||
int __must_check pci_request_region(struct pci_dev *, int, const char *);
|
int __must_check pci_request_region(struct pci_dev *, int, const char *);
|
||||||
void pci_release_region(struct pci_dev *, int);
|
void pci_release_region(struct pci_dev *, int);
|
||||||
|
int pci_request_selected_regions(struct pci_dev *, int, const char *);
|
||||||
|
void pci_release_selected_regions(struct pci_dev *, int);
|
||||||
|
|
||||||
/* drivers/pci/bus.c */
|
/* drivers/pci/bus.c */
|
||||||
int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
|
int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче