zephyr/include/drivers/pci/pci.h

70 lines
2.3 KiB
C
Raw Normal View History

/* pci.h - PCI probe and information routines */
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3) Neither the name of Wind River Systems nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
DESCRIPTION
Module declares routines of PCI bus initialization and query
*/
#ifndef _PCI_H_
#define _PCI_H_
#define BAR_SPACE_MEM 0
#define BAR_SPACE_IO 1
#define PCI_MAX_BARS 6
#define PCI_BAR_ANY PCI_MAX_BARS
/* PCI device information */
struct pci_dev_info {
uint32_t addr; /* I/O or memory region address */
uint32_t size; /* memory region size */
int irq;
pci: Provide a simpler yet powerful PCI enumeration API This fixes many issues around PCI enumeration from old API: - a static internal table was fed with scanning results, thus eating memory, and worse: due to the limit of its size, scanning for new classes was impossible unless growing statically the size of this table --> more memory eaten! Not to mention PCI enumeration is done once at boot time for driver initialization and that's all, so this table is hanging around for nothing afterwards. - one needs first to scan a class, then maybe he will be able to find his device via pci_dev_find. Where all could be done at once. - pci_dev_find was not trustworthy due again to the internal table. Now if the device is not found, one will know it really went through all the possbilities. - still let the possibility for hard-coded BARs value on driver side (thus no PCI scan required). However this is greatly advised not to do so as BARs might change over a firmware/BIOS update. Comparison: old pci_dev_scan: could only filter out via class mask. new pci_dev_scan: can filter out via a class, a vendor and device ID (it could easily do the same for Function and BAR index as these are usually fixed and informed through datasheet) old pci_dev_scan: was limited in its findings by the size of the internal result table. new pci_dev_scan: can proceed through all the buses and devices every time (there are optimizations to avoid useless work of course) old results did not tell about the function or BAR index. new one tells, and the structure has not bloated. old internal code: was storing a big table of results new internal code: is only storing a small lookup structure and an array of Bus:Dev pairs for each PCI class for optimizations purpose. (though, if needed, we could disable this through some #ifdef) Usage: - Have a local struct dev_info - Fill it with what you want to look for, currently: only class and vendor_id/device_id. Function and BAR index could be added if needed. - Call pci_bus_scan_init(): this will reset the internal lookup structure. - Call pci_dev_scan(<a pointer to your dev_info>): at first call, the internal lookup structure will pick up the informations from dev_info and will try to find out what has been requested. It will return 1 on success, or 0. On 1, your dev_info structure will be updated with the found informations. If more devices can be found against the same lookup informations, just call again pci_dev_scan(<a pointer to your dev_info>) as long as it returns 1. When 0 is hit, it will mean you found all. Change-Id: Ibc2a16c4485ee3fed7ef4946af0ece032ae406e4 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2015-05-20 19:30:35 +08:00
uint16_t mem_type:1; /* memory type: BAR_SPACE_MEM/BAR_SPACE_IO */
uint16_t class:8;
uint16_t function:3;
uint16_t bar:3;
uint16_t unused:1;
uint16_t vendor_id;
uint16_t device_id;
};
pci: Provide a simpler yet powerful PCI enumeration API This fixes many issues around PCI enumeration from old API: - a static internal table was fed with scanning results, thus eating memory, and worse: due to the limit of its size, scanning for new classes was impossible unless growing statically the size of this table --> more memory eaten! Not to mention PCI enumeration is done once at boot time for driver initialization and that's all, so this table is hanging around for nothing afterwards. - one needs first to scan a class, then maybe he will be able to find his device via pci_dev_find. Where all could be done at once. - pci_dev_find was not trustworthy due again to the internal table. Now if the device is not found, one will know it really went through all the possbilities. - still let the possibility for hard-coded BARs value on driver side (thus no PCI scan required). However this is greatly advised not to do so as BARs might change over a firmware/BIOS update. Comparison: old pci_dev_scan: could only filter out via class mask. new pci_dev_scan: can filter out via a class, a vendor and device ID (it could easily do the same for Function and BAR index as these are usually fixed and informed through datasheet) old pci_dev_scan: was limited in its findings by the size of the internal result table. new pci_dev_scan: can proceed through all the buses and devices every time (there are optimizations to avoid useless work of course) old results did not tell about the function or BAR index. new one tells, and the structure has not bloated. old internal code: was storing a big table of results new internal code: is only storing a small lookup structure and an array of Bus:Dev pairs for each PCI class for optimizations purpose. (though, if needed, we could disable this through some #ifdef) Usage: - Have a local struct dev_info - Fill it with what you want to look for, currently: only class and vendor_id/device_id. Function and BAR index could be added if needed. - Call pci_bus_scan_init(): this will reset the internal lookup structure. - Call pci_dev_scan(<a pointer to your dev_info>): at first call, the internal lookup structure will pick up the informations from dev_info and will try to find out what has been requested. It will return 1 on success, or 0. On 1, your dev_info structure will be updated with the found informations. If more devices can be found against the same lookup informations, just call again pci_dev_scan(<a pointer to your dev_info>) as long as it returns 1. When 0 is hit, it will mean you found all. Change-Id: Ibc2a16c4485ee3fed7ef4946af0ece032ae406e4 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2015-05-20 19:30:35 +08:00
extern void pci_bus_scan_init(void);
extern int pci_bus_scan(struct pci_dev_info *dev_info);
#ifdef CONFIG_PCI_DEBUG
pci: Provide a simpler yet powerful PCI enumeration API This fixes many issues around PCI enumeration from old API: - a static internal table was fed with scanning results, thus eating memory, and worse: due to the limit of its size, scanning for new classes was impossible unless growing statically the size of this table --> more memory eaten! Not to mention PCI enumeration is done once at boot time for driver initialization and that's all, so this table is hanging around for nothing afterwards. - one needs first to scan a class, then maybe he will be able to find his device via pci_dev_find. Where all could be done at once. - pci_dev_find was not trustworthy due again to the internal table. Now if the device is not found, one will know it really went through all the possbilities. - still let the possibility for hard-coded BARs value on driver side (thus no PCI scan required). However this is greatly advised not to do so as BARs might change over a firmware/BIOS update. Comparison: old pci_dev_scan: could only filter out via class mask. new pci_dev_scan: can filter out via a class, a vendor and device ID (it could easily do the same for Function and BAR index as these are usually fixed and informed through datasheet) old pci_dev_scan: was limited in its findings by the size of the internal result table. new pci_dev_scan: can proceed through all the buses and devices every time (there are optimizations to avoid useless work of course) old results did not tell about the function or BAR index. new one tells, and the structure has not bloated. old internal code: was storing a big table of results new internal code: is only storing a small lookup structure and an array of Bus:Dev pairs for each PCI class for optimizations purpose. (though, if needed, we could disable this through some #ifdef) Usage: - Have a local struct dev_info - Fill it with what you want to look for, currently: only class and vendor_id/device_id. Function and BAR index could be added if needed. - Call pci_bus_scan_init(): this will reset the internal lookup structure. - Call pci_dev_scan(<a pointer to your dev_info>): at first call, the internal lookup structure will pick up the informations from dev_info and will try to find out what has been requested. It will return 1 on success, or 0. On 1, your dev_info structure will be updated with the found informations. If more devices can be found against the same lookup informations, just call again pci_dev_scan(<a pointer to your dev_info>) as long as it returns 1. When 0 is hit, it will mean you found all. Change-Id: Ibc2a16c4485ee3fed7ef4946af0ece032ae406e4 Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2015-05-20 19:30:35 +08:00
extern void pci_show(struct pci_dev_info *dev_info);
#endif
#endif /* _PCI_H_ */