linuxkpi: Add more pci functions needed by DRM
-pci_get_class : This function search for a matching pci device based on the class/subclass and returns a newly created pci_dev. - pci_{save,restore}_state : This is analogous to ours with the same name - pci_is_root_bus : Return true if this is the root bus - pci_get_domain_bus_and_slot : This function search for a matching pci device based on domain, bus and slot/function concat into a single unsigned int (devfn) and returns a newly created pci_dev - pci_bus_{read,write}_config* : Read/Write to the config space. While here add some helper function to alloc and fill the pci_dev struct. Reviewed by: hselasky, bz (older version) Differential Revision: https://reviews.freebsd.org/D27550
This commit is contained in:
parent
8517a547a0
commit
105a37cac7
@ -460,6 +460,9 @@ linux_pci_disable_msi(struct pci_dev *pdev)
|
||||
pdev->msi_enabled = false;
|
||||
}
|
||||
|
||||
#define pci_free_irq_vectors(pdev) \
|
||||
linux_pci_disable_msi(pdev)
|
||||
|
||||
unsigned long pci_resource_start(struct pci_dev *pdev, int bar);
|
||||
unsigned long pci_resource_len(struct pci_dev *pdev, int bar);
|
||||
|
||||
@ -702,6 +705,23 @@ pci_iounmap(struct pci_dev *dev, void *res)
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
lkpi_pci_save_state(struct pci_dev *pdev)
|
||||
{
|
||||
|
||||
pci_save_state(pdev->dev.bsddev);
|
||||
}
|
||||
|
||||
static inline void
|
||||
lkpi_pci_restore_state(struct pci_dev *pdev)
|
||||
{
|
||||
|
||||
pci_restore_state(pdev->dev.bsddev);
|
||||
}
|
||||
|
||||
#define pci_save_state(dev) lkpi_pci_save_state(dev)
|
||||
#define pci_restore_state(dev) lkpi_pci_restore_state(dev)
|
||||
|
||||
#define DEFINE_PCI_DEVICE_TABLE(_table) \
|
||||
const struct pci_device_id _table[] __devinitdata
|
||||
|
||||
@ -1058,4 +1078,80 @@ pci_dev_present(const struct pci_device_id *cur)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
pci_is_root_bus(struct pci_bus *pbus)
|
||||
{
|
||||
|
||||
return (pbus->self == NULL);
|
||||
}
|
||||
|
||||
struct pci_dev *lkpi_pci_get_domain_bus_and_slot(int domain,
|
||||
unsigned int bus, unsigned int devfn);
|
||||
#define pci_get_domain_bus_and_slot(domain, bus, devfn) \
|
||||
lkpi_pci_get_domain_bus_and_slot(domain, bus, devfn)
|
||||
|
||||
static inline int
|
||||
pci_domain_nr(struct pci_bus *pbus)
|
||||
{
|
||||
|
||||
return (pci_get_domain(pbus->self->dev.bsddev));
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_bus_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||
int pos, uint32_t *val, int len)
|
||||
{
|
||||
|
||||
*val = pci_read_config(bus->self->dev.bsddev, pos, len);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int pos, u16 *val)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int ret;
|
||||
|
||||
ret = pci_bus_read_config(bus, devfn, pos, &tmp, 2);
|
||||
*val = (u16)tmp;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, u8 *val)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int ret;
|
||||
|
||||
ret = pci_bus_read_config(bus, devfn, pos, &tmp, 1);
|
||||
*val = (u8)tmp;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_bus_write_config(struct pci_bus *bus, unsigned int devfn, int pos,
|
||||
uint32_t val, int size)
|
||||
{
|
||||
|
||||
pci_write_config(bus->self->dev.bsddev, pos, val, size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int pos,
|
||||
uint8_t val)
|
||||
{
|
||||
return (pci_bus_write_config(bus, devfn, pos, val, 1));
|
||||
}
|
||||
|
||||
static inline int
|
||||
pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int pos,
|
||||
uint16_t val)
|
||||
{
|
||||
return (pci_bus_write_config(bus, devfn, pos, val, 2));
|
||||
}
|
||||
|
||||
struct pci_dev *lkpi_pci_get_class(unsigned int class, struct pci_dev *from);
|
||||
#define pci_get_class(class, from) lkpi_pci_get_class(class, from)
|
||||
|
||||
#endif /* _LINUX_PCI_H_ */
|
||||
|
@ -70,6 +70,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include "backlight_if.h"
|
||||
#include "pcib_if.h"
|
||||
|
||||
/* Undef the linux function macro defined in linux/pci.h */
|
||||
#undef pci_get_class
|
||||
|
||||
static device_probe_t linux_pci_probe;
|
||||
static device_attach_t linux_pci_attach;
|
||||
static device_detach_t linux_pci_detach;
|
||||
@ -210,6 +213,67 @@ linux_pci_find(device_t dev, const struct pci_device_id **idp)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
lkpifill_pci_dev(device_t dev, struct pci_dev *pdev)
|
||||
{
|
||||
|
||||
pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev));
|
||||
pdev->vendor = pci_get_vendor(dev);
|
||||
pdev->device = pci_get_device(dev);
|
||||
pdev->class = pci_get_class(dev);
|
||||
pdev->revision = pci_get_revid(dev);
|
||||
pdev->dev.bsddev = dev;
|
||||
pdev->bus->self = pdev;
|
||||
pdev->bus->number = pci_get_bus(dev);
|
||||
pdev->bus->domain = pci_get_domain(dev);
|
||||
}
|
||||
|
||||
static struct pci_dev *
|
||||
lkpinew_pci_dev(device_t dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
struct pci_bus *pbus;
|
||||
|
||||
pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO);
|
||||
pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO);
|
||||
pdev->bus = pbus;
|
||||
lkpifill_pci_dev(dev, pdev);
|
||||
return (pdev);
|
||||
}
|
||||
|
||||
struct pci_dev *
|
||||
lkpi_pci_get_class(unsigned int class, struct pci_dev *from)
|
||||
{
|
||||
device_t dev;
|
||||
device_t devfrom = NULL;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
if (from != NULL)
|
||||
devfrom = from->dev.bsddev;
|
||||
|
||||
dev = pci_find_class_from(class >> 16, (class >> 8) & 0xFF, devfrom);
|
||||
if (dev == NULL)
|
||||
return (NULL);
|
||||
|
||||
pdev = lkpinew_pci_dev(dev);
|
||||
return (pdev);
|
||||
}
|
||||
|
||||
struct pci_dev *
|
||||
lkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus,
|
||||
unsigned int devfn)
|
||||
{
|
||||
device_t dev;
|
||||
struct pci_dev *pdev;
|
||||
|
||||
dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||
if (dev == NULL)
|
||||
return (NULL);
|
||||
|
||||
pdev = lkpinew_pci_dev(dev);
|
||||
return (pdev);
|
||||
}
|
||||
|
||||
static int
|
||||
linux_pci_probe(device_t dev)
|
||||
{
|
||||
@ -245,7 +309,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
|
||||
const struct pci_device_id *id, struct pci_dev *pdev)
|
||||
{
|
||||
struct resource_list_entry *rle;
|
||||
struct pci_bus *pbus;
|
||||
struct pci_devinfo *dinfo;
|
||||
device_t parent;
|
||||
uintptr_t rid;
|
||||
@ -264,8 +327,9 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
|
||||
dinfo = device_get_ivars(dev);
|
||||
}
|
||||
|
||||
pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
lkpifill_pci_dev(dev, pdev);
|
||||
pdev->dev.parent = &linux_root_device;
|
||||
pdev->dev.bsddev = dev;
|
||||
INIT_LIST_HEAD(&pdev->dev.irqents);
|
||||
if (isdrm)
|
||||
PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid);
|
||||
@ -276,8 +340,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
|
||||
pdev->vendor = dinfo->cfg.vendor;
|
||||
pdev->subsystem_vendor = dinfo->cfg.subvendor;
|
||||
pdev->subsystem_device = dinfo->cfg.subdevice;
|
||||
pdev->class = pci_get_class(dev);
|
||||
pdev->revision = pci_get_revid(dev);
|
||||
pdev->pdrv = pdrv;
|
||||
kobject_init(&pdev->dev.kobj, &linux_dev_ktype);
|
||||
kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev));
|
||||
@ -294,11 +356,6 @@ linux_pci_attach_device(device_t dev, struct pci_driver *pdrv,
|
||||
goto out_dma_init;
|
||||
|
||||
TAILQ_INIT(&pdev->mmio);
|
||||
pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
pbus->self = pdev;
|
||||
pbus->number = pci_get_bus(dev);
|
||||
pbus->domain = pci_get_domain(dev);
|
||||
pdev->bus = pbus;
|
||||
|
||||
spin_lock(&pci_lock);
|
||||
list_add(&pdev->links, &pci_devices);
|
||||
|
@ -3781,7 +3781,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
return ret;
|
||||
} else {
|
||||
device_set_desc(pdev->dev.bsddev, mlx4_description);
|
||||
pci_save_state(pdev->dev.bsddev);
|
||||
pci_save_state(pdev);
|
||||
}
|
||||
|
||||
snprintf(dev->fw_str, sizeof(dev->fw_str), "%d.%d.%d",
|
||||
|
@ -1634,7 +1634,7 @@ static int init_one(struct pci_dev *pdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
pci_save_state(bsddev);
|
||||
pci_save_state(pdev);
|
||||
return 0;
|
||||
|
||||
clean_health:
|
||||
@ -1709,8 +1709,8 @@ static pci_ers_result_t mlx5_pci_slot_reset(struct pci_dev *pdev)
|
||||
}
|
||||
pci_set_master(pdev);
|
||||
pci_set_powerstate(pdev->dev.bsddev, PCI_POWERSTATE_D0);
|
||||
pci_restore_state(pdev->dev.bsddev);
|
||||
pci_save_state(pdev->dev.bsddev);
|
||||
pci_restore_state(pdev);
|
||||
pci_save_state(pdev);
|
||||
|
||||
return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user