^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright 2003 José Fonseca.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright 2003 Leif Delgass.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Permission is hereby granted, free of charge, to any person obtaining a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * copy of this software and associated documentation files (the "Software"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * to deal in the Software without restriction, including without limitation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * the rights to use, copy, modify, merge, publish, distribute, sublicense,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * and/or sell copies of the Software, and to permit persons to whom the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Software is furnished to do so, subject to the following conditions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * The above copyright notice and this permission notice (including the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * paragraph) shall be included in all copies or substantial portions of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <drm/drm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <drm/drm_agpsupport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <drm/drm_drv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "drm_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "drm_legacy.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #ifdef CONFIG_DRM_LEGACY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * drm_pci_alloc - Allocate a PCI consistent memory block, for DMA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * @size: size of block to allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * @align: alignment of block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * FIXME: This is a needless abstraction of the Linux dma-api and should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Return: A handle to the allocated memory block on success or NULL on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) drm_dma_handle_t *dmah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* pci_alloc_consistent only guarantees alignment to the smallest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * PAGE_SIZE order which is greater than or equal to the requested size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Return NULL here for now to make sure nobody tries for larger alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (align > size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if (!dmah)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) dmah->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) &dmah->busaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (dmah->vaddr == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) kfree(dmah);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return dmah;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) EXPORT_SYMBOL(drm_pci_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * drm_pci_free - Free a PCI consistent memory block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * @dmah: handle to memory block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * FIXME: This is a needless abstraction of the Linux dma-api and should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dmah->busaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) kfree(dmah);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) EXPORT_SYMBOL(drm_pci_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) static int drm_get_pci_domain(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #ifndef __alpha__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* For historical reasons, drm_get_pci_domain() is busticated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * on most archs and has to remain so for userspace interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * < 1.4, except on alpha which was right from the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (dev->if_version < 0x10004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #endif /* __alpha__ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return pci_domain_nr(dev->pdev->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) master->unique = kasprintf(GFP_KERNEL, "pci:%04x:%02x:%02x.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) drm_get_pci_domain(dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dev->pdev->bus->number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) PCI_SLOT(dev->pdev->devfn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) PCI_FUNC(dev->pdev->devfn));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!master->unique)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) master->unique_len = strlen(master->unique);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) (p->busnum & 0xff) != dev->pdev->bus->number ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) p->irq = dev->pdev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) p->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * drm_irq_by_busid - Get interrupt from bus ID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @dev: DRM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @data: IOCTL parameter pointing to a drm_irq_busid structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @file_priv: DRM file private.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * Finds the PCI device with the specified bus id and gets its IRQ number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * to that of the device that this DRM instance attached to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * Return: 0 on success or a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) int drm_irq_by_busid(struct drm_device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct drm_file *file_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct drm_irq_busid *p = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (!drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* UMS was only ever support on PCI devices. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (WARN_ON(!dev->pdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return drm_pci_irq_by_busid(dev, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) void drm_pci_agp_destroy(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (dev->agp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) arch_phys_wc_del(dev->agp->agp_mtrr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) drm_legacy_agp_clear(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) kfree(dev->agp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev->agp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #ifdef CONFIG_DRM_LEGACY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void drm_pci_agp_init(struct drm_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (pci_find_capability(dev->pdev, PCI_CAP_ID_AGP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) dev->agp = drm_agp_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (dev->agp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev->agp->agp_mtrr = arch_phys_wc_add(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev->agp->agp_info.aper_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev->agp->agp_info.aper_size *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 1024 * 1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static int drm_get_pci_dev(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) const struct pci_device_id *ent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct drm_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct drm_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) DRM_DEBUG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) dev = drm_dev_alloc(driver, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (IS_ERR(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return PTR_ERR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) ret = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) dev->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #ifdef __alpha__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) dev->hose = pdev->sysdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (drm_core_check_feature(dev, DRIVER_MODESET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pci_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) drm_pci_agp_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = drm_dev_register(dev, ent->driver_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto err_agp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /* No locking needed since shadow-attach is single-threaded since it may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * only be called from the per-driver module init hook. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (drm_core_check_feature(dev, DRIVER_LEGACY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) err_agp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) drm_pci_agp_destroy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) drm_dev_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * drm_legacy_pci_init - shadow-attach a legacy DRM PCI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * @driver: DRM device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * @pdriver: PCI device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * This is only used by legacy dri1 drivers and deprecated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * Return: 0 on success or a negative error code on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) int drm_legacy_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct pci_dev *pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const struct pci_device_id *pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) DRM_DEBUG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (WARN_ON(!(driver->driver_features & DRIVER_LEGACY)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* If not using KMS, fall back to stealth mode manual scanning. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) INIT_LIST_HEAD(&driver->legacy_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) pid = &pdriver->id_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* Loop around setting up a DRM device for each PCI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * matching our ID and device class. If we had the internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * function that pci_get_subsys and pci_get_class used, we'd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * be able to just pass pid in instead of doing a two-stage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) while ((pdev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) pid->subdevice, pdev)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if ((pdev->class & pid->class_mask) != pid->class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* stealth mode requires a manual probe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) pci_dev_get(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) drm_get_pci_dev(pdev, pid, driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) EXPORT_SYMBOL(drm_legacy_pci_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * drm_legacy_pci_exit - unregister shadow-attach legacy DRM driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @driver: DRM device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @pdriver: PCI device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Unregister a DRM driver shadow-attached through drm_legacy_pci_init(). This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * is deprecated and only used by dri1 drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) void drm_legacy_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct drm_device *dev, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) DRM_DEBUG("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (!(driver->driver_features & DRIVER_LEGACY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) legacy_dev_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) list_del(&dev->legacy_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) drm_put_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) DRM_INFO("Module unloaded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) EXPORT_SYMBOL(drm_legacy_pci_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #endif