summaryrefslogtreecommitdiff
path: root/sys/dev/pci/drm/drm_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci/drm/drm_drv.c')
-rw-r--r--sys/dev/pci/drm/drm_drv.c88
1 files changed, 41 insertions, 47 deletions
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c
index 0dd934858cc..c5969e94e05 100644
--- a/sys/dev/pci/drm/drm_drv.c
+++ b/sys/dev/pci/drm/drm_drv.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: drm_drv.c,v 1.171 2020/02/20 16:56:52 visa Exp $ */
+/* $OpenBSD: drm_drv.c,v 1.172 2020/03/03 09:23:54 kettenis Exp $ */
/*-
* Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org>
* Copyright © 2008 Intel Corporation
@@ -110,7 +110,6 @@ drm_attach_pci(struct drm_driver *driver, struct pci_attach_args *pa,
{
struct drm_attach_args arg;
struct drm_softc *sc;
- pcireg_t subsys;
arg.drm = drm;
arg.driver = driver;
@@ -118,20 +117,7 @@ drm_attach_pci(struct drm_driver *driver, struct pci_attach_args *pa,
arg.bst = pa->pa_memt;
arg.is_agp = is_agp;
arg.primary = primary;
-
- arg.pci_vendor = PCI_VENDOR(pa->pa_id);
- arg.pci_device = PCI_PRODUCT(pa->pa_id);
-
- subsys = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
- arg.pci_subvendor = PCI_VENDOR(subsys);
- arg.pci_subdevice = PCI_PRODUCT(subsys);
-
- arg.pci_revision = PCI_REVISION(pa->pa_class);
-
arg.pa = pa;
- arg.pc = pa->pa_pc;
- arg.tag = pa->pa_tag;
- arg.bridgetag = pa->pa_bridgetag;
arg.busid_len = 20;
arg.busid = malloc(arg.busid_len + 1, M_DRM, M_NOWAIT);
@@ -209,7 +195,6 @@ drm_attach(struct device *parent, struct device *self, void *aux)
struct drm_softc *sc = (struct drm_softc *)self;
struct drm_attach_args *da = aux;
struct drm_device *dev = da->drm;
- int bus, slot, func;
int ret;
drm_linux_init();
@@ -230,39 +215,44 @@ drm_attach(struct device *parent, struct device *self, void *aux)
dev->bst = da->bst;
dev->unique = da->busid;
dev->unique_len = da->busid_len;
- dev->pdev = &dev->_pdev;
- dev->pci_vendor = dev->pdev->vendor = da->pci_vendor;
- dev->pci_device = dev->pdev->device = da->pci_device;
- dev->pdev->subsystem_vendor = da->pci_subvendor;
- dev->pdev->subsystem_device = da->pci_subdevice;
- dev->pdev->revision = da->pci_revision;
-
- pci_decompose_tag(da->pc, da->tag, &bus, &slot, &func);
- dev->pdev->bus = &dev->pdev->_bus;
- dev->pdev->bus->pc = da->pc;
- dev->pdev->bus->number = bus;
- dev->pdev->bus->bridgetag = da->bridgetag;
- dev->pdev->devfn = PCI_DEVFN(slot, func);
-
- dev->pdev->bus->self = malloc(sizeof(struct pci_dev), M_DRM,
- M_NOWAIT | M_ZERO);
- if (dev->pdev->bus->self == NULL)
- goto error;
- dev->pdev->bus->self->pc = da->pc;
- if (da->bridgetag != NULL)
- dev->pdev->bus->self->tag = *da->bridgetag;
-
- dev->pc = da->pc;
- dev->pdev->pc = da->pc;
- dev->bridgetag = da->bridgetag;
- dev->pdev->tag = da->tag;
- dev->pdev->pci = (struct pci_softc *)parent->dv_parent;
+
+ if (da->pa) {
+ struct pci_attach_args *pa = da->pa;
+ pcireg_t subsys;
+
+ subsys = pci_conf_read(pa->pa_pc, pa->pa_tag,
+ PCI_SUBSYS_ID_REG);
+
+ dev->pdev = &dev->_pdev;
+ dev->pdev->vendor = PCI_VENDOR(pa->pa_id);
+ dev->pdev->device = PCI_PRODUCT(pa->pa_id);
+ dev->pdev->subsystem_vendor = PCI_VENDOR(subsys);
+ dev->pdev->subsystem_device = PCI_PRODUCT(subsys);
+ dev->pdev->revision = PCI_REVISION(pa->pa_class);
+
+ dev->pdev->devfn = PCI_DEVFN(pa->pa_device, pa->pa_function);
+ dev->pdev->bus = &dev->pdev->_bus;
+ dev->pdev->bus->pc = pa->pa_pc;
+ dev->pdev->bus->number = pa->pa_bus;
+ dev->pdev->bus->bridgetag = pa->pa_bridgetag;
+
+ if (pa->pa_bridgetag != NULL) {
+ dev->pdev->bus->self = malloc(sizeof(struct pci_dev),
+ M_DRM, M_WAITOK | M_ZERO);
+ dev->pdev->bus->self->pc = pa->pa_pc;
+ dev->pdev->bus->self->tag = *pa->pa_bridgetag;
+ }
+
+ dev->pdev->pc = pa->pa_pc;
+ dev->pdev->tag = pa->pa_tag;
+ dev->pdev->pci = (struct pci_softc *)parent->dv_parent;
#ifdef CONFIG_ACPI
- dev->pdev->dev.node = acpi_find_pci(da->pc, da->tag);
- aml_register_notify(dev->pdev->dev.node, NULL,
- drm_linux_acpi_notify, NULL, ACPIDEV_NOPOLL);
+ dev->pdev->dev.node = acpi_find_pci(pa->pa_pc, pa->pa_tag);
+ aml_register_notify(dev->pdev->dev.node, NULL,
+ drm_linux_acpi_notify, NULL, ACPIDEV_NOPOLL);
#endif
+ }
rw_init(&dev->struct_mutex, "drmdevlk");
mtx_init(&dev->event_lock, IPL_TTY);
@@ -331,7 +321,8 @@ drm_detach(struct device *self, int flags)
}
free(dev->agp, M_DRM, 0);
- free(dev->pdev->bus->self, M_DRM, sizeof(struct pci_dev));
+ if (dev->pdev && dev->pdev->bus)
+ free(dev->pdev->bus->self, M_DRM, sizeof(struct pci_dev));
if (sc->sc_allocated)
free(dev, M_DRM, sizeof(struct drm_device));
@@ -988,6 +979,9 @@ drm_getpciinfo(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
struct drm_pciinfo *info = data;
+ if (dev->pdev == NULL)
+ return -ENOTTY;
+
info->domain = 0;
info->bus = dev->pdev->bus->number;
info->dev = PCI_SLOT(dev->pdev->devfn);