drm_pci.c revision 1.3 1 1.1 riastrad /* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */
2 1.1 riastrad /**
3 1.1 riastrad * \file drm_pci.c
4 1.1 riastrad * \brief Functions and ioctls to manage PCI memory
5 1.1 riastrad *
6 1.1 riastrad * \warning These interfaces aren't stable yet.
7 1.1 riastrad *
8 1.1 riastrad * \todo Implement the remaining ioctl's for the PCI pools.
9 1.1 riastrad * \todo The wrappers here are so thin that they would be better off inlined..
10 1.1 riastrad *
11 1.1 riastrad * \author Jos Fonseca <jrfonseca (at) tungstengraphics.com>
12 1.1 riastrad * \author Leif Delgass <ldelgass (at) retinalburn.net>
13 1.1 riastrad */
14 1.1 riastrad
15 1.1 riastrad /*
16 1.1 riastrad * Copyright 2003 Jos Fonseca.
17 1.1 riastrad * Copyright 2003 Leif Delgass.
18 1.1 riastrad * All Rights Reserved.
19 1.1 riastrad *
20 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a
21 1.1 riastrad * copy of this software and associated documentation files (the "Software"),
22 1.1 riastrad * to deal in the Software without restriction, including without limitation
23 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the
25 1.1 riastrad * Software is furnished to do so, subject to the following conditions:
26 1.1 riastrad *
27 1.1 riastrad * The above copyright notice and this permission notice (including the next
28 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the
29 1.1 riastrad * Software.
30 1.1 riastrad *
31 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 1.1 riastrad * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
35 1.1 riastrad * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 1.1 riastrad * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 1.1 riastrad */
38 1.1 riastrad
39 1.1 riastrad #include <linux/pci.h>
40 1.1 riastrad #include <linux/slab.h>
41 1.1 riastrad #include <linux/dma-mapping.h>
42 1.1 riastrad #include <linux/export.h>
43 1.1 riastrad #include <drm/drmP.h>
44 1.1 riastrad
45 1.1 riastrad /**********************************************************************/
46 1.1 riastrad /** \name PCI memory */
47 1.1 riastrad /*@{*/
48 1.1 riastrad
49 1.1 riastrad /**
50 1.1 riastrad * \brief Allocate a PCI consistent memory block, for DMA.
51 1.1 riastrad */
52 1.1 riastrad drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align)
53 1.1 riastrad {
54 1.1 riastrad drm_dma_handle_t *dmah;
55 1.1 riastrad unsigned long addr;
56 1.1 riastrad size_t sz;
57 1.1 riastrad
58 1.1 riastrad /* pci_alloc_consistent only guarantees alignment to the smallest
59 1.1 riastrad * PAGE_SIZE order which is greater than or equal to the requested size.
60 1.1 riastrad * Return NULL here for now to make sure nobody tries for larger alignment
61 1.1 riastrad */
62 1.1 riastrad if (align > size)
63 1.1 riastrad return NULL;
64 1.1 riastrad
65 1.1 riastrad dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
66 1.1 riastrad if (!dmah)
67 1.1 riastrad return NULL;
68 1.1 riastrad
69 1.1 riastrad dmah->size = size;
70 1.1 riastrad dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP);
71 1.1 riastrad
72 1.1 riastrad if (dmah->vaddr == NULL) {
73 1.1 riastrad kfree(dmah);
74 1.1 riastrad return NULL;
75 1.1 riastrad }
76 1.1 riastrad
77 1.1 riastrad memset(dmah->vaddr, 0, size);
78 1.1 riastrad
79 1.1 riastrad /* XXX - Is virt_to_page() legal for consistent mem? */
80 1.1 riastrad /* Reserve */
81 1.1 riastrad for (addr = (unsigned long)dmah->vaddr, sz = size;
82 1.1 riastrad sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
83 1.3 riastrad SetPageReserved(virt_to_page((void *)addr));
84 1.1 riastrad }
85 1.1 riastrad
86 1.1 riastrad return dmah;
87 1.1 riastrad }
88 1.1 riastrad
89 1.1 riastrad EXPORT_SYMBOL(drm_pci_alloc);
90 1.1 riastrad
91 1.1 riastrad /**
92 1.1 riastrad * \brief Free a PCI consistent memory block without freeing its descriptor.
93 1.1 riastrad *
94 1.1 riastrad * This function is for internal use in the Linux-specific DRM core code.
95 1.1 riastrad */
96 1.1 riastrad void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
97 1.1 riastrad {
98 1.1 riastrad unsigned long addr;
99 1.1 riastrad size_t sz;
100 1.1 riastrad
101 1.1 riastrad if (dmah->vaddr) {
102 1.1 riastrad /* XXX - Is virt_to_page() legal for consistent mem? */
103 1.1 riastrad /* Unreserve */
104 1.1 riastrad for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
105 1.1 riastrad sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
106 1.3 riastrad ClearPageReserved(virt_to_page((void *)addr));
107 1.1 riastrad }
108 1.1 riastrad dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
109 1.1 riastrad dmah->busaddr);
110 1.1 riastrad }
111 1.1 riastrad }
112 1.1 riastrad
113 1.1 riastrad /**
114 1.1 riastrad * \brief Free a PCI consistent memory block
115 1.1 riastrad */
116 1.1 riastrad void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
117 1.1 riastrad {
118 1.1 riastrad __drm_pci_free(dev, dmah);
119 1.1 riastrad kfree(dmah);
120 1.1 riastrad }
121 1.1 riastrad
122 1.1 riastrad EXPORT_SYMBOL(drm_pci_free);
123 1.1 riastrad
124 1.1 riastrad #ifdef CONFIG_PCI
125 1.1 riastrad
126 1.1 riastrad static int drm_get_pci_domain(struct drm_device *dev)
127 1.1 riastrad {
128 1.1 riastrad #ifndef __alpha__
129 1.1 riastrad /* For historical reasons, drm_get_pci_domain() is busticated
130 1.1 riastrad * on most archs and has to remain so for userspace interface
131 1.1 riastrad * < 1.4, except on alpha which was right from the beginning
132 1.1 riastrad */
133 1.1 riastrad if (dev->if_version < 0x10004)
134 1.1 riastrad return 0;
135 1.1 riastrad #endif /* __alpha__ */
136 1.1 riastrad
137 1.1 riastrad return pci_domain_nr(dev->pdev->bus);
138 1.1 riastrad }
139 1.1 riastrad
140 1.1 riastrad static int drm_pci_get_irq(struct drm_device *dev)
141 1.1 riastrad {
142 1.1 riastrad return dev->pdev->irq;
143 1.1 riastrad }
144 1.1 riastrad
145 1.1 riastrad static const char *drm_pci_get_name(struct drm_device *dev)
146 1.1 riastrad {
147 1.1 riastrad struct pci_driver *pdriver = dev->driver->kdriver.pci;
148 1.1 riastrad return pdriver->name;
149 1.1 riastrad }
150 1.1 riastrad
151 1.3 riastrad static int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
152 1.1 riastrad {
153 1.1 riastrad int len, ret;
154 1.1 riastrad struct pci_driver *pdriver = dev->driver->kdriver.pci;
155 1.1 riastrad master->unique_len = 40;
156 1.1 riastrad master->unique_size = master->unique_len;
157 1.1 riastrad master->unique = kmalloc(master->unique_size, GFP_KERNEL);
158 1.1 riastrad if (master->unique == NULL)
159 1.1 riastrad return -ENOMEM;
160 1.1 riastrad
161 1.1 riastrad
162 1.1 riastrad len = snprintf(master->unique, master->unique_len,
163 1.1 riastrad "pci:%04x:%02x:%02x.%d",
164 1.1 riastrad drm_get_pci_domain(dev),
165 1.1 riastrad dev->pdev->bus->number,
166 1.1 riastrad PCI_SLOT(dev->pdev->devfn),
167 1.1 riastrad PCI_FUNC(dev->pdev->devfn));
168 1.1 riastrad
169 1.1 riastrad if (len >= master->unique_len) {
170 1.1 riastrad DRM_ERROR("buffer overflow");
171 1.1 riastrad ret = -EINVAL;
172 1.1 riastrad goto err;
173 1.1 riastrad } else
174 1.1 riastrad master->unique_len = len;
175 1.1 riastrad
176 1.2 christos size_t devlen = strlen(pdriver->name) + master->unique_len + 2;
177 1.2 christos dev->devname = kmalloc(dev->devlen, GFP_KERNEL);
178 1.1 riastrad
179 1.1 riastrad if (dev->devname == NULL) {
180 1.1 riastrad ret = -ENOMEM;
181 1.1 riastrad goto err;
182 1.1 riastrad }
183 1.1 riastrad
184 1.2 christos snprintf(dev->devname, devlen, "%s@%s", pdriver->name,
185 1.1 riastrad master->unique);
186 1.1 riastrad
187 1.1 riastrad return 0;
188 1.1 riastrad err:
189 1.1 riastrad return ret;
190 1.1 riastrad }
191 1.1 riastrad
192 1.3 riastrad static int drm_pci_set_unique(struct drm_device *dev,
193 1.3 riastrad struct drm_master *master,
194 1.3 riastrad struct drm_unique *u)
195 1.1 riastrad {
196 1.1 riastrad int domain, bus, slot, func, ret;
197 1.1 riastrad const char *bus_name;
198 1.1 riastrad
199 1.1 riastrad master->unique_len = u->unique_len;
200 1.1 riastrad master->unique_size = u->unique_len + 1;
201 1.1 riastrad master->unique = kmalloc(master->unique_size, GFP_KERNEL);
202 1.1 riastrad if (!master->unique) {
203 1.1 riastrad ret = -ENOMEM;
204 1.1 riastrad goto err;
205 1.1 riastrad }
206 1.1 riastrad
207 1.1 riastrad if (copy_from_user(master->unique, u->unique, master->unique_len)) {
208 1.1 riastrad ret = -EFAULT;
209 1.1 riastrad goto err;
210 1.1 riastrad }
211 1.1 riastrad
212 1.1 riastrad master->unique[master->unique_len] = '\0';
213 1.1 riastrad
214 1.1 riastrad bus_name = dev->driver->bus->get_name(dev);
215 1.2 christos size_t devlen = strlen(bus_name) + strlen(master->unique) + 2;
216 1.2 christos dev->devname = kmalloc(devlen, GFP_KERNEL);
217 1.1 riastrad if (!dev->devname) {
218 1.1 riastrad ret = -ENOMEM;
219 1.1 riastrad goto err;
220 1.1 riastrad }
221 1.1 riastrad
222 1.2 christos snprintf(dev->devname, devlen, "%s@%s", bus_name,
223 1.1 riastrad master->unique);
224 1.1 riastrad
225 1.1 riastrad /* Return error if the busid submitted doesn't match the device's actual
226 1.1 riastrad * busid.
227 1.1 riastrad */
228 1.1 riastrad ret = sscanf(master->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
229 1.1 riastrad if (ret != 3) {
230 1.1 riastrad ret = -EINVAL;
231 1.1 riastrad goto err;
232 1.1 riastrad }
233 1.1 riastrad
234 1.1 riastrad domain = bus >> 8;
235 1.1 riastrad bus &= 0xff;
236 1.1 riastrad
237 1.1 riastrad if ((domain != drm_get_pci_domain(dev)) ||
238 1.1 riastrad (bus != dev->pdev->bus->number) ||
239 1.1 riastrad (slot != PCI_SLOT(dev->pdev->devfn)) ||
240 1.1 riastrad (func != PCI_FUNC(dev->pdev->devfn))) {
241 1.1 riastrad ret = -EINVAL;
242 1.1 riastrad goto err;
243 1.1 riastrad }
244 1.1 riastrad return 0;
245 1.1 riastrad err:
246 1.1 riastrad return ret;
247 1.1 riastrad }
248 1.1 riastrad
249 1.1 riastrad
250 1.1 riastrad static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
251 1.1 riastrad {
252 1.1 riastrad if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
253 1.1 riastrad (p->busnum & 0xff) != dev->pdev->bus->number ||
254 1.1 riastrad p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
255 1.1 riastrad return -EINVAL;
256 1.1 riastrad
257 1.1 riastrad p->irq = dev->pdev->irq;
258 1.1 riastrad
259 1.1 riastrad DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
260 1.1 riastrad p->irq);
261 1.1 riastrad return 0;
262 1.1 riastrad }
263 1.1 riastrad
264 1.3 riastrad static void drm_pci_agp_init(struct drm_device *dev)
265 1.1 riastrad {
266 1.3 riastrad if (drm_core_check_feature(dev, DRIVER_USE_AGP)) {
267 1.1 riastrad if (drm_pci_device_is_agp(dev))
268 1.1 riastrad dev->agp = drm_agp_init(dev);
269 1.3 riastrad if (dev->agp) {
270 1.3 riastrad dev->agp->agp_mtrr = arch_phys_wc_add(
271 1.3 riastrad dev->agp->agp_info.aper_base,
272 1.3 riastrad dev->agp->agp_info.aper_size *
273 1.3 riastrad 1024 * 1024);
274 1.1 riastrad }
275 1.1 riastrad }
276 1.3 riastrad }
277 1.3 riastrad
278 1.3 riastrad void drm_pci_agp_destroy(struct drm_device *dev)
279 1.3 riastrad {
280 1.3 riastrad if (dev->agp) {
281 1.3 riastrad arch_phys_wc_del(dev->agp->agp_mtrr);
282 1.3 riastrad drm_agp_clear(dev);
283 1.3 riastrad kfree(dev->agp);
284 1.3 riastrad dev->agp = NULL;
285 1.3 riastrad }
286 1.1 riastrad }
287 1.1 riastrad
288 1.1 riastrad static struct drm_bus drm_pci_bus = {
289 1.1 riastrad .bus_type = DRIVER_BUS_PCI,
290 1.1 riastrad .get_irq = drm_pci_get_irq,
291 1.1 riastrad .get_name = drm_pci_get_name,
292 1.1 riastrad .set_busid = drm_pci_set_busid,
293 1.1 riastrad .set_unique = drm_pci_set_unique,
294 1.1 riastrad .irq_by_busid = drm_pci_irq_by_busid,
295 1.1 riastrad };
296 1.1 riastrad
297 1.1 riastrad /**
298 1.1 riastrad * Register.
299 1.1 riastrad *
300 1.1 riastrad * \param pdev - PCI device structure
301 1.1 riastrad * \param ent entry from the PCI ID table with device type flags
302 1.1 riastrad * \return zero on success or a negative number on failure.
303 1.1 riastrad *
304 1.1 riastrad * Attempt to gets inter module "drm" information. If we are first
305 1.1 riastrad * then register the character device and inter module information.
306 1.1 riastrad * Try and register, if we fail to register, backout previous work.
307 1.1 riastrad */
308 1.1 riastrad int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
309 1.1 riastrad struct drm_driver *driver)
310 1.1 riastrad {
311 1.1 riastrad struct drm_device *dev;
312 1.1 riastrad int ret;
313 1.1 riastrad
314 1.1 riastrad DRM_DEBUG("\n");
315 1.1 riastrad
316 1.3 riastrad dev = drm_dev_alloc(driver, &pdev->dev);
317 1.1 riastrad if (!dev)
318 1.1 riastrad return -ENOMEM;
319 1.1 riastrad
320 1.1 riastrad ret = pci_enable_device(pdev);
321 1.1 riastrad if (ret)
322 1.3 riastrad goto err_free;
323 1.1 riastrad
324 1.1 riastrad dev->pdev = pdev;
325 1.1 riastrad #ifdef __alpha__
326 1.1 riastrad dev->hose = pdev->sysdata;
327 1.1 riastrad #endif
328 1.1 riastrad
329 1.3 riastrad if (drm_core_check_feature(dev, DRIVER_MODESET))
330 1.1 riastrad pci_set_drvdata(pdev, dev);
331 1.1 riastrad
332 1.3 riastrad drm_pci_agp_init(dev);
333 1.1 riastrad
334 1.3 riastrad ret = drm_dev_register(dev, ent->driver_data);
335 1.3 riastrad if (ret)
336 1.3 riastrad goto err_agp;
337 1.1 riastrad
338 1.1 riastrad DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
339 1.1 riastrad driver->name, driver->major, driver->minor, driver->patchlevel,
340 1.1 riastrad driver->date, pci_name(pdev), dev->primary->index);
341 1.1 riastrad
342 1.3 riastrad /* No locking needed since shadow-attach is single-threaded since it may
343 1.3 riastrad * only be called from the per-driver module init hook. */
344 1.3 riastrad if (!drm_core_check_feature(dev, DRIVER_MODESET))
345 1.3 riastrad list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list);
346 1.3 riastrad
347 1.1 riastrad return 0;
348 1.1 riastrad
349 1.3 riastrad err_agp:
350 1.3 riastrad drm_pci_agp_destroy(dev);
351 1.1 riastrad pci_disable_device(pdev);
352 1.3 riastrad err_free:
353 1.3 riastrad drm_dev_unref(dev);
354 1.1 riastrad return ret;
355 1.1 riastrad }
356 1.1 riastrad EXPORT_SYMBOL(drm_get_pci_dev);
357 1.1 riastrad
358 1.1 riastrad /**
359 1.1 riastrad * PCI device initialization. Called direct from modules at load time.
360 1.1 riastrad *
361 1.1 riastrad * \return zero on success or a negative number on failure.
362 1.1 riastrad *
363 1.1 riastrad * Initializes a drm_device structures,registering the
364 1.1 riastrad * stubs and initializing the AGP device.
365 1.1 riastrad *
366 1.1 riastrad * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
367 1.1 riastrad * after the initialization for driver customization.
368 1.1 riastrad */
369 1.1 riastrad int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
370 1.1 riastrad {
371 1.1 riastrad struct pci_dev *pdev = NULL;
372 1.1 riastrad const struct pci_device_id *pid;
373 1.1 riastrad int i;
374 1.1 riastrad
375 1.1 riastrad DRM_DEBUG("\n");
376 1.1 riastrad
377 1.1 riastrad driver->kdriver.pci = pdriver;
378 1.1 riastrad driver->bus = &drm_pci_bus;
379 1.1 riastrad
380 1.1 riastrad if (driver->driver_features & DRIVER_MODESET)
381 1.1 riastrad return pci_register_driver(pdriver);
382 1.1 riastrad
383 1.1 riastrad /* If not using KMS, fall back to stealth mode manual scanning. */
384 1.3 riastrad INIT_LIST_HEAD(&driver->legacy_dev_list);
385 1.1 riastrad for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
386 1.1 riastrad pid = &pdriver->id_table[i];
387 1.1 riastrad
388 1.1 riastrad /* Loop around setting up a DRM device for each PCI device
389 1.1 riastrad * matching our ID and device class. If we had the internal
390 1.1 riastrad * function that pci_get_subsys and pci_get_class used, we'd
391 1.1 riastrad * be able to just pass pid in instead of doing a two-stage
392 1.1 riastrad * thing.
393 1.1 riastrad */
394 1.1 riastrad pdev = NULL;
395 1.1 riastrad while ((pdev =
396 1.1 riastrad pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
397 1.1 riastrad pid->subdevice, pdev)) != NULL) {
398 1.1 riastrad if ((pdev->class & pid->class_mask) != pid->class)
399 1.1 riastrad continue;
400 1.1 riastrad
401 1.1 riastrad /* stealth mode requires a manual probe */
402 1.1 riastrad pci_dev_get(pdev);
403 1.1 riastrad drm_get_pci_dev(pdev, pid, driver);
404 1.1 riastrad }
405 1.1 riastrad }
406 1.1 riastrad return 0;
407 1.1 riastrad }
408 1.1 riastrad
409 1.1 riastrad int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
410 1.1 riastrad {
411 1.1 riastrad struct pci_dev *root;
412 1.3 riastrad u32 lnkcap, lnkcap2;
413 1.1 riastrad
414 1.1 riastrad *mask = 0;
415 1.1 riastrad if (!dev->pdev)
416 1.1 riastrad return -EINVAL;
417 1.1 riastrad
418 1.1 riastrad root = dev->pdev->bus->self;
419 1.1 riastrad
420 1.1 riastrad /* we've been informed via and serverworks don't make the cut */
421 1.1 riastrad if (root->vendor == PCI_VENDOR_ID_VIA ||
422 1.1 riastrad root->vendor == PCI_VENDOR_ID_SERVERWORKS)
423 1.1 riastrad return -EINVAL;
424 1.1 riastrad
425 1.3 riastrad pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
426 1.3 riastrad pcie_capability_read_dword(root, PCI_EXP_LNKCAP2, &lnkcap2);
427 1.1 riastrad
428 1.3 riastrad if (lnkcap2) { /* PCIe r3.0-compliant */
429 1.1 riastrad if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
430 1.1 riastrad *mask |= DRM_PCIE_SPEED_25;
431 1.1 riastrad if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
432 1.1 riastrad *mask |= DRM_PCIE_SPEED_50;
433 1.1 riastrad if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
434 1.1 riastrad *mask |= DRM_PCIE_SPEED_80;
435 1.3 riastrad } else { /* pre-r3.0 */
436 1.3 riastrad if (lnkcap & PCI_EXP_LNKCAP_SLS_2_5GB)
437 1.1 riastrad *mask |= DRM_PCIE_SPEED_25;
438 1.3 riastrad if (lnkcap & PCI_EXP_LNKCAP_SLS_5_0GB)
439 1.3 riastrad *mask |= (DRM_PCIE_SPEED_25 | DRM_PCIE_SPEED_50);
440 1.1 riastrad }
441 1.1 riastrad
442 1.1 riastrad DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", root->vendor, root->device, lnkcap, lnkcap2);
443 1.1 riastrad return 0;
444 1.1 riastrad }
445 1.1 riastrad EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask);
446 1.3 riastrad
447 1.3 riastrad #else
448 1.3 riastrad
449 1.3 riastrad int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
450 1.3 riastrad {
451 1.3 riastrad return -1;
452 1.3 riastrad }
453 1.3 riastrad
454 1.3 riastrad void drm_pci_agp_destroy(struct drm_device *dev) {}
455 1.3 riastrad #endif
456 1.3 riastrad
457 1.3 riastrad EXPORT_SYMBOL(drm_pci_init);
458 1.3 riastrad
459 1.3 riastrad /*@}*/
460 1.3 riastrad void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
461 1.3 riastrad {
462 1.3 riastrad struct drm_device *dev, *tmp;
463 1.3 riastrad DRM_DEBUG("\n");
464 1.3 riastrad
465 1.3 riastrad if (driver->driver_features & DRIVER_MODESET) {
466 1.3 riastrad pci_unregister_driver(pdriver);
467 1.3 riastrad } else {
468 1.3 riastrad list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
469 1.3 riastrad legacy_dev_list) {
470 1.3 riastrad list_del(&dev->legacy_dev_list);
471 1.3 riastrad drm_put_dev(dev);
472 1.3 riastrad }
473 1.3 riastrad }
474 1.3 riastrad DRM_INFO("Module unloaded\n");
475 1.3 riastrad }
476 1.3 riastrad EXPORT_SYMBOL(drm_pci_exit);
477