dev->priv is for private use of the device driver, so do not use it in the pci core. Instead, introduce a id field in struct pci_device. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
303 lines
9.4 KiB
C
303 lines
9.4 KiB
C
/*
|
|
* pci.h
|
|
*
|
|
* PCI defines and function prototypes
|
|
* Copyright 1994, Drew Eckhardt
|
|
* Copyright 1997--1999 Martin Mares <mj@ucw.cz>
|
|
*
|
|
* For more information, please consult the following manuals (look at
|
|
* http://www.pcisig.com/ for how to get them):
|
|
*
|
|
* PCI BIOS Specification
|
|
* PCI Local Bus Specification
|
|
* PCI to PCI Bridge Specification
|
|
* PCI System Design Guide
|
|
*/
|
|
#ifndef LINUX_PCI_H
|
|
#define LINUX_PCI_H
|
|
|
|
#include <linux/mod_devicetable.h>
|
|
|
|
#include <linux/pci_regs.h>
|
|
#include <linux/types.h>
|
|
#include <linux/ioport.h>
|
|
#include <linux/list.h>
|
|
#include <linux/compiler.h>
|
|
#include <driver.h>
|
|
#include <errno.h>
|
|
#include <io.h>
|
|
|
|
#include <linux/pci_ids.h>
|
|
|
|
|
|
/*
|
|
* The PCI interface treats multi-function devices as independent
|
|
* devices. The slot/function address of each device is encoded
|
|
* in a single byte as follows:
|
|
*
|
|
* 7:3 = slot
|
|
* 2:0 = function
|
|
*/
|
|
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
|
|
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
|
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
|
|
|
/*
|
|
* For PCI devices, the region numbers are assigned this way:
|
|
*/
|
|
enum {
|
|
/* #0-5: standard PCI resources */
|
|
PCI_STD_RESOURCES,
|
|
PCI_STD_RESOURCE_END = 5,
|
|
|
|
/* #6: expansion ROM resource */
|
|
PCI_ROM_RESOURCE,
|
|
|
|
/* device specific resources */
|
|
#ifdef CONFIG_PCI_IOV
|
|
PCI_IOV_RESOURCES,
|
|
PCI_IOV_RESOURCE_END = PCI_IOV_RESOURCES + PCI_SRIOV_NUM_BARS - 1,
|
|
#endif
|
|
|
|
/* resources assigned to buses behind the bridge */
|
|
#define PCI_BRIDGE_RESOURCE_NUM 4
|
|
|
|
PCI_BRIDGE_RESOURCES,
|
|
PCI_BRIDGE_RESOURCE_END = PCI_BRIDGE_RESOURCES +
|
|
PCI_BRIDGE_RESOURCE_NUM - 1,
|
|
|
|
/* total resources associated with a PCI device */
|
|
PCI_NUM_RESOURCES,
|
|
|
|
/* preserve this for compatibility */
|
|
DEVICE_COUNT_RESOURCE = PCI_NUM_RESOURCES,
|
|
};
|
|
|
|
/*
|
|
* Error values that may be returned by PCI functions.
|
|
*/
|
|
#define PCIBIOS_SUCCESSFUL 0x00
|
|
#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81
|
|
#define PCIBIOS_BAD_VENDOR_ID 0x83
|
|
#define PCIBIOS_DEVICE_NOT_FOUND 0x86
|
|
#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
|
|
#define PCIBIOS_SET_FAILED 0x88
|
|
#define PCIBIOS_BUFFER_TOO_SMALL 0x89
|
|
|
|
/*
|
|
* The pci_dev structure is used to describe PCI devices.
|
|
*/
|
|
struct pci_dev {
|
|
struct list_head bus_list; /* node in per-bus list */
|
|
struct pci_bus *bus; /* bus this device is on */
|
|
struct pci_bus *subordinate; /* bus this device bridges to */
|
|
struct pci_slot *slot; /* Physical slot this device is in */
|
|
const struct pci_device_id *id; /* the id this device matches */
|
|
|
|
struct device_d dev;
|
|
|
|
unsigned int devfn; /* encoded device & function index */
|
|
unsigned short vendor;
|
|
unsigned short device;
|
|
unsigned short subsystem_vendor;
|
|
unsigned short subsystem_device;
|
|
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
|
|
u8 revision; /* PCI revision, low byte of class word */
|
|
u8 hdr_type; /* PCI header type (`multi' flag masked out) */
|
|
|
|
struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
|
|
|
|
/* Base registers for this device, can be adjusted by
|
|
* pcibios_fixup() as necessary.
|
|
*/
|
|
unsigned long base_address[6];
|
|
unsigned long rom_address;
|
|
};
|
|
#define to_pci_dev(dev) container_of(dev, struct pci_dev, dev)
|
|
|
|
enum {
|
|
PCI_BUS_RESOURCE_IO = 0,
|
|
PCI_BUS_RESOURCE_MEM = 1,
|
|
PCI_BUS_RESOURCE_MEM_PREF = 2,
|
|
PCI_BUS_RESOURCE_BUSN = 3,
|
|
};
|
|
struct pci_bus {
|
|
struct pci_controller *host; /* associated host controller */
|
|
struct device_d *parent;
|
|
struct pci_bus *parent_bus; /* parent bus */
|
|
struct list_head node; /* node in list of buses */
|
|
struct list_head children; /* list of child buses */
|
|
struct list_head devices; /* list of devices on this bus */
|
|
struct list_head slots; /* list of slots on this bus */
|
|
struct resource *resource[PCI_BRIDGE_RESOURCE_NUM];
|
|
struct list_head resources; /* address space routed to this bus */
|
|
|
|
struct pci_ops *ops; /* configuration access functions */
|
|
|
|
unsigned char number; /* bus number */
|
|
unsigned char primary; /* number of primary bridge */
|
|
unsigned char secondary; /* number of secondary bridge */
|
|
unsigned char subordinate; /* max number of subordinate buses */
|
|
|
|
char name[48];
|
|
};
|
|
|
|
/* Low-level architecture-dependent routines */
|
|
|
|
struct pci_ops {
|
|
int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val);
|
|
int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val);
|
|
|
|
/* return memory address for pci resource */
|
|
int (*res_start)(struct pci_bus *bus, resource_size_t res_addr);
|
|
};
|
|
|
|
extern struct pci_ops *pci_ops;
|
|
|
|
/*
|
|
* Each pci channel is a top-level PCI bus seem by CPU. A machine with
|
|
* multiple PCI channels may have multiple PCI host controllers or a
|
|
* single controller supporting multiple channels.
|
|
*/
|
|
struct pci_controller {
|
|
struct pci_controller *next;
|
|
struct device_d *parent;
|
|
struct pci_bus *bus;
|
|
|
|
struct pci_ops *pci_ops;
|
|
struct resource *mem_resource;
|
|
struct resource *mem_pref_resource;
|
|
unsigned long mem_offset;
|
|
struct resource *io_resource;
|
|
unsigned long io_offset;
|
|
unsigned long io_map_base;
|
|
|
|
unsigned int index;
|
|
|
|
/* Optional access method for writing the bus number */
|
|
void (*set_busno)(struct pci_controller *host, int busno);
|
|
};
|
|
|
|
struct pci_driver {
|
|
struct list_head node;
|
|
const char *name;
|
|
const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
|
|
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
|
|
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
|
|
struct driver_d driver;
|
|
};
|
|
|
|
#define to_pci_driver(drv) container_of(drv, struct pci_driver, driver)
|
|
|
|
/* these helpers provide future and backwards compatibility
|
|
* for accessing popular PCI BAR info */
|
|
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
|
|
|
|
/**
|
|
* DEFINE_PCI_DEVICE_TABLE - macro used to describe a pci device table
|
|
* @_table: device table name
|
|
*
|
|
* This macro is used to create a struct pci_device_id array (a device table)
|
|
* in a generic manner.
|
|
*/
|
|
#define DEFINE_PCI_DEVICE_TABLE(_table) \
|
|
const struct pci_device_id _table[]
|
|
|
|
/**
|
|
* PCI_DEVICE - macro used to describe a specific pci device
|
|
* @vend: the 16 bit PCI Vendor ID
|
|
* @dev: the 16 bit PCI Device ID
|
|
*
|
|
* This macro is used to create a struct pci_device_id that matches a
|
|
* specific device. The subvendor and subdevice fields will be set to
|
|
* PCI_ANY_ID.
|
|
*/
|
|
#define PCI_DEVICE(vend, dev) \
|
|
.vendor = (vend), .device = (dev), \
|
|
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
|
|
|
|
/**
|
|
* PCI_DEVICE_CLASS - macro used to describe a specific pci device class
|
|
* @dev_class: the class, subclass, prog-if triple for this device
|
|
* @dev_class_mask: the class mask for this device
|
|
*
|
|
* This macro is used to create a struct pci_device_id that matches a
|
|
* specific PCI class. The vendor, device, subvendor, and subdevice
|
|
* fields will be set to PCI_ANY_ID.
|
|
*/
|
|
#define PCI_DEVICE_CLASS(dev_class, dev_class_mask) \
|
|
.class = (dev_class), .class_mask = (dev_class_mask), \
|
|
.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
|
|
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
|
|
|
|
/**
|
|
* PCI_VDEVICE - macro used to describe a specific pci device in short form
|
|
* @vend: the vendor name
|
|
* @dev: the 16 bit PCI Device ID
|
|
*
|
|
* This macro is used to create a struct pci_device_id that matches a
|
|
* specific PCI device. The subvendor, and subdevice fields will be set
|
|
* to PCI_ANY_ID. The macro allows the next field to follow as the device
|
|
* private data.
|
|
*/
|
|
|
|
#define PCI_VDEVICE(vend, dev) \
|
|
.vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
|
|
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0
|
|
|
|
int pci_register_driver(struct pci_driver *pdrv);
|
|
int pci_register_device(struct pci_dev *pdev);
|
|
|
|
extern struct list_head pci_root_buses; /* list of all known PCI buses */
|
|
|
|
extern unsigned int pci_scan_bus(struct pci_bus *bus);
|
|
extern void register_pci_controller(struct pci_controller *hose);
|
|
|
|
int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn,
|
|
int where, u8 *val);
|
|
int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn,
|
|
int where, u16 *val);
|
|
int pci_bus_read_config_dword(struct pci_bus *bus, unsigned int devfn,
|
|
int where, u32 *val);
|
|
int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn,
|
|
int where, u8 val);
|
|
int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn,
|
|
int where, u16 val);
|
|
int pci_bus_write_config_dword(struct pci_bus *bus, unsigned int devfn,
|
|
int where, u32 val);
|
|
|
|
static inline int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)
|
|
{
|
|
return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
|
|
}
|
|
static inline int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val)
|
|
{
|
|
return pci_bus_read_config_word(dev->bus, dev->devfn, where, val);
|
|
}
|
|
static inline int pci_read_config_dword(const struct pci_dev *dev, int where,
|
|
u32 *val)
|
|
{
|
|
return pci_bus_read_config_dword(dev->bus, dev->devfn, where, val);
|
|
}
|
|
static inline int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val)
|
|
{
|
|
return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val);
|
|
}
|
|
static inline int pci_write_config_word(const struct pci_dev *dev, int where, u16 val)
|
|
{
|
|
return pci_bus_write_config_word(dev->bus, dev->devfn, where, val);
|
|
}
|
|
static inline int pci_write_config_dword(const struct pci_dev *dev, int where,
|
|
u32 val)
|
|
{
|
|
return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val);
|
|
}
|
|
|
|
void pci_set_master(struct pci_dev *dev);
|
|
void pci_clear_master(struct pci_dev *dev);
|
|
int pci_enable_device(struct pci_dev *dev);
|
|
|
|
extern void __iomem *pci_iomap(struct pci_dev *dev, int bar);
|
|
|
|
#endif /* LINUX_PCI_H */
|