diff options
Diffstat (limited to 'linux-core/drm_ioctl.c')
-rw-r--r-- | linux-core/drm_ioctl.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/linux-core/drm_ioctl.c b/linux-core/drm_ioctl.c index 01604e75..d753cce0 100644 --- a/linux-core/drm_ioctl.c +++ b/linux-core/drm_ioctl.c @@ -41,6 +41,28 @@ int DRM(irq_busid)(struct inode *inode, struct file *filp, if (copy_from_user(&p, (drm_irq_busid_t *)arg, sizeof(p))) return -EFAULT; +#ifdef __alpha__ + { + int domain = p.busnum >> 8; + p.busnum &= 0xff; + + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + dev; + dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,dev)) { + struct pci_controller *hose = dev->sysdata; + + if (hose->index == domain) { + p.busnum += hose->bus->number; + break; + } + } + } +#endif dev = pci_find_slot(p.busnum, PCI_DEVFN(p.devnum, p.funcnum)); if (!dev) { DRM_ERROR("pci_find_slot failed for %d:%d:%d\n", @@ -113,7 +135,7 @@ int DRM(setunique)(struct inode *inode, struct file *filp, do { struct pci_dev *pci_dev; - int b, d, f; + int domain, b, d, f; char *p; for(p = dev->unique; p && *p && *p != ':'; p++); @@ -125,6 +147,27 @@ int DRM(setunique)(struct inode *inode, struct file *filp, f = (int)simple_strtoul(p+1, &p, 10); if (*p) break; + domain = b >> 8; + b &= 0xff; + +#ifdef __alpha__ + /* + * Find the hose the device is on (the domain number is the + * hose index) and offset the bus by the root bus of that + * hose. + */ + for(pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,NULL); + pci_dev; + pci_dev = pci_find_device(PCI_ANY_ID,PCI_ANY_ID,pci_dev)) { + struct pci_controller *hose = pci_dev->sysdata; + + if (hose->index == domain) { + b += hose->bus->number; + break; + } + } +#endif + pci_dev = pci_find_slot(b, PCI_DEVFN(d,f)); if (pci_dev) { dev->pdev = pci_dev; |