Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_pci.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
#include <linux/pci.h> | #include <linux/pci.h> | ||||
#include <linux/compat.h> | #include <linux/compat.h> | ||||
#include <linux/backlight.h> | #include <linux/backlight.h> | ||||
#include "backlight_if.h" | #include "backlight_if.h" | ||||
#include "pcib_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_probe_t linux_pci_probe; | ||||
static device_attach_t linux_pci_attach; | static device_attach_t linux_pci_attach; | ||||
static device_detach_t linux_pci_detach; | static device_detach_t linux_pci_detach; | ||||
static device_suspend_t linux_pci_suspend; | static device_suspend_t linux_pci_suspend; | ||||
static device_resume_t linux_pci_resume; | static device_resume_t linux_pci_resume; | ||||
static device_shutdown_t linux_pci_shutdown; | static device_shutdown_t linux_pci_shutdown; | ||||
static pci_iov_init_t linux_pci_iov_init; | static pci_iov_init_t linux_pci_iov_init; | ||||
static pci_iov_uninit_t linux_pci_iov_uninit; | static pci_iov_uninit_t linux_pci_iov_uninit; | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | for (id = pdrv->id_table; id->vendor != 0; id++) { | ||||
return (pdrv); | return (pdrv); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
spin_unlock(&pci_lock); | spin_unlock(&pci_lock); | ||||
return (NULL); | 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 | static int | ||||
linux_pci_probe(device_t dev) | linux_pci_probe(device_t dev) | ||||
{ | { | ||||
const struct pci_device_id *id; | const struct pci_device_id *id; | ||||
struct pci_driver *pdrv; | struct pci_driver *pdrv; | ||||
if ((pdrv = linux_pci_find(dev, &id)) == NULL) | if ((pdrv = linux_pci_find(dev, &id)) == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
Show All 19 Lines | linux_pci_attach(device_t dev) | ||||
return (linux_pci_attach_device(dev, pdrv, id, pdev)); | return (linux_pci_attach_device(dev, pdrv, id, pdev)); | ||||
} | } | ||||
int | int | ||||
linux_pci_attach_device(device_t dev, struct pci_driver *pdrv, | linux_pci_attach_device(device_t dev, struct pci_driver *pdrv, | ||||
const struct pci_device_id *id, struct pci_dev *pdev) | const struct pci_device_id *id, struct pci_dev *pdev) | ||||
{ | { | ||||
struct resource_list_entry *rle; | struct resource_list_entry *rle; | ||||
struct pci_bus *pbus; | |||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
device_t parent; | device_t parent; | ||||
uintptr_t rid; | uintptr_t rid; | ||||
int error; | int error; | ||||
bool isdrm; | bool isdrm; | ||||
linux_set_current(curthread); | linux_set_current(curthread); | ||||
parent = device_get_parent(dev); | parent = device_get_parent(dev); | ||||
isdrm = pdrv != NULL && pdrv->isdrm; | isdrm = pdrv != NULL && pdrv->isdrm; | ||||
if (isdrm) { | if (isdrm) { | ||||
dinfo = device_get_ivars(parent); | dinfo = device_get_ivars(parent); | ||||
device_set_ivars(dev, dinfo); | device_set_ivars(dev, dinfo); | ||||
} else { | } else { | ||||
dinfo = device_get_ivars(dev); | 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.parent = &linux_root_device; | ||||
pdev->dev.bsddev = dev; | |||||
INIT_LIST_HEAD(&pdev->dev.irqents); | INIT_LIST_HEAD(&pdev->dev.irqents); | ||||
if (isdrm) | if (isdrm) | ||||
PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid); | PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid); | ||||
else | else | ||||
PCI_GET_ID(parent, dev, PCI_ID_RID, &rid); | PCI_GET_ID(parent, dev, PCI_ID_RID, &rid); | ||||
pdev->devfn = rid; | pdev->devfn = rid; | ||||
pdev->device = dinfo->cfg.device; | pdev->device = dinfo->cfg.device; | ||||
pdev->vendor = dinfo->cfg.vendor; | pdev->vendor = dinfo->cfg.vendor; | ||||
pdev->subsystem_vendor = dinfo->cfg.subvendor; | pdev->subsystem_vendor = dinfo->cfg.subvendor; | ||||
pdev->subsystem_device = dinfo->cfg.subdevice; | pdev->subsystem_device = dinfo->cfg.subdevice; | ||||
pdev->class = pci_get_class(dev); | |||||
pdev->revision = pci_get_revid(dev); | |||||
pdev->pdrv = pdrv; | pdev->pdrv = pdrv; | ||||
kobject_init(&pdev->dev.kobj, &linux_dev_ktype); | kobject_init(&pdev->dev.kobj, &linux_dev_ktype); | ||||
kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); | kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); | ||||
kobject_add(&pdev->dev.kobj, &linux_root_device.kobj, | kobject_add(&pdev->dev.kobj, &linux_root_device.kobj, | ||||
kobject_name(&pdev->dev.kobj)); | kobject_name(&pdev->dev.kobj)); | ||||
rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0); | rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 0); | ||||
if (rle != NULL) | if (rle != NULL) | ||||
pdev->dev.irq = rle->start; | pdev->dev.irq = rle->start; | ||||
else | else | ||||
pdev->dev.irq = LINUX_IRQ_INVALID; | pdev->dev.irq = LINUX_IRQ_INVALID; | ||||
pdev->irq = pdev->dev.irq; | pdev->irq = pdev->dev.irq; | ||||
error = linux_pdev_dma_init(pdev); | error = linux_pdev_dma_init(pdev); | ||||
if (error) | if (error) | ||||
goto out_dma_init; | goto out_dma_init; | ||||
TAILQ_INIT(&pdev->mmio); | 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); | spin_lock(&pci_lock); | ||||
list_add(&pdev->links, &pci_devices); | list_add(&pdev->links, &pci_devices); | ||||
spin_unlock(&pci_lock); | spin_unlock(&pci_lock); | ||||
if (pdrv != NULL) { | if (pdrv != NULL) { | ||||
error = pdrv->probe(pdev, id); | error = pdrv->probe(pdev, id); | ||||
if (error) | if (error) | ||||
▲ Show 20 Lines • Show All 735 Lines • Show Last 20 Lines |