#define PCI_ANY_ID (~0)
struct pci_device_id {
- unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
+ unsigned long driver_data; /* Data private to the driver */
};
struct pci_controller;
int indirect_type;
+ /*
+ * TODO(sjg@chromium.org): With driver model we use struct
+ * pci_controller for both the controller and any bridge devices
+ * attached to it. But there is only one region list and it is in the
+ * top-level controller.
+ *
+ * This could be changed so that struct pci_controller is only used
+ * for PCI controllers and a separate UCLASS (or perhaps
+ * UCLASS_PCI_GENERIC) is used for bridges.
+ */
struct pci_region regions[MAX_PCI_REGIONS];
int region_count;
* */
u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum);
-/**
- * pciauto_setup_rom() - Set up access to a device ROM
- *
- * @hose: PCI hose to use
- * @dev: PCI device to adjust
- * @return 0 if done, -ve on error
- */
-int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev);
-
/**
* pci_hose_find_devices() - Find devices by vendor/device ID
*
/* Get access to a PCI bus' operations */
#define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops)
+/**
+ * pci_get_bdf() - Get the BDF value for a device
+ *
+ * @dev: Device to check
+ * @return bus/device/function value (see PCI_BDF())
+ */
+pci_dev_t pci_get_bdf(struct udevice *dev);
+
/**
* pci_bind_bus_devices() - scan a PCI bus and bind devices
*
return pci_read_config8(pcidev, offset, valuep);
}
-#endif
+/**
+ * struct dm_pci_emul_ops - PCI device emulator operations
+ */
+struct dm_pci_emul_ops {
+ /**
+ * get_devfn(): Check which device and function this emulators
+ *
+ * @dev: device to check
+ * @return the device and function this emulates, or -ve on error
+ */
+ int (*get_devfn)(struct udevice *dev);
+ /**
+ * read_config() - Read a PCI configuration value
+ *
+ * @dev: Emulated device to read from
+ * @offset: Byte offset within the device's configuration space
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*read_config)(struct udevice *dev, uint offset, ulong *valuep,
+ enum pci_size_t size);
+ /**
+ * write_config() - Write a PCI configuration value
+ *
+ * @dev: Emulated device to write to
+ * @offset: Byte offset within the device's configuration space
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*write_config)(struct udevice *dev, uint offset, ulong value,
+ enum pci_size_t size);
+ /**
+ * read_io() - Read a PCI I/O value
+ *
+ * @dev: Emulated device to read from
+ * @addr: I/O address to read
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*read_io)(struct udevice *dev, unsigned int addr, ulong *valuep,
+ enum pci_size_t size);
+ /**
+ * write_io() - Write a PCI I/O value
+ *
+ * @dev: Emulated device to write from
+ * @addr: I/O address to write
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*write_io)(struct udevice *dev, unsigned int addr,
+ ulong value, enum pci_size_t size);
+ /**
+ * map_physmem() - Map a device into sandbox memory
+ *
+ * @dev: Emulated device to map
+ * @addr: Memory address, normally corresponding to a PCI BAR.
+ * The device should have been configured to have a BAR
+ * at this address.
+ * @lenp: On entry, the size of the area to map, On exit it is
+ * updated to the size actually mapped, which may be less
+ * if the device has less space
+ * @ptrp: Returns a pointer to the mapped address. The device's
+ * space can be accessed as @lenp bytes starting here
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*map_physmem)(struct udevice *dev, phys_addr_t addr,
+ unsigned long *lenp, void **ptrp);
+ /**
+ * unmap_physmem() - undo a memory mapping
+ *
+ * This must be called after map_physmem() to undo the mapping.
+ * Some devices can use this to check what has been written into
+ * their mapped memory and perform an operations they require on it.
+ * In this way, map/unmap can be used as a sort of handshake between
+ * the emulated device and its users.
+ *
+ * @dev: Emuated device to unmap
+ * @vaddr: Mapped memory address, as passed to map_physmem()
+ * @len: Size of area mapped, as returned by map_physmem()
+ * @return 0 if OK, -ve on error
+ */
+ int (*unmap_physmem)(struct udevice *dev, const void *vaddr,
+ unsigned long len);
+};
+
+/* Get access to a PCI device emulator's operations */
+#define pci_get_emul_ops(dev) ((struct dm_pci_emul_ops *)(dev)->driver->ops)
+
+/**
+ * sandbox_pci_get_emul() - Get the emulation device for a PCI device
+ *
+ * Searches for a suitable emulator for the given PCI bus device
+ *
+ * @bus: PCI bus to search
+ * @find_devfn: PCI device and function address (PCI_DEVFN())
+ * @emulp: Returns emulated device if found
+ * @return 0 if found, -ENODEV if not found
+ */
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **emulp);
+
+#endif /* CONFIG_DM_PCI */
+
+/**
+ * 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_SUB - macro used to describe a specific pci device with subsystem
+ * @vend: the 16 bit PCI Vendor ID
+ * @dev: the 16 bit PCI Device ID
+ * @subvend: the 16 bit PCI Subvendor ID
+ * @subdev: the 16 bit PCI Subdevice ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific device with subsystem information.
+ */
+#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \
+ .vendor = (vend), .device = (dev), \
+ .subvendor = (subvend), .subdevice = (subdev)
+
+/**
+ * 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
+
+/**
+ * struct pci_driver_entry - Matches a driver to its pci_device_id list
+ * @driver: Driver to use
+ * @match: List of match records for this driver, terminated by {}
+ */
+struct pci_driver_entry {
+ struct driver *driver;
+ const struct pci_device_id *match;
+};
+
+#define U_BOOT_PCI_DEVICE(__name, __match) \
+ ll_entry_declare(struct pci_driver_entry, __name, pci_driver_entry) = {\
+ .driver = llsym(struct driver, __name, driver), \
+ .match = __match, \
+ }
#endif /* __ASSEMBLY__ */
#endif /* _PCI_H */