xref: /titanic_50/usr/src/uts/common/io/drm/drm_drv.c (revision 4045d94132614e1de2073685a6cdd4fbd86bec33)
1 /*
2  * drm_drv.h -- Generic driver template -*- linux-c -*-
3  * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
4  */
5 /*
6  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
7  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
8  * All Rights Reserved.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice (including the next
18  * paragraph) shall be included in all copies or substantial portions of the
19  * Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
25  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27  * OTHER DEALINGS IN THE SOFTWARE.
28  *
29  * Authors:
30  *    Rickard E. (Rik) Faith <faith@valinux.com>
31  *    Gareth Hughes <gareth@valinux.com>
32  *
33  */
34 
35 /*
36  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
37  * Use is subject to license terms.
38  */
39 
40 #pragma ident	"%Z%%M%	%I%	%E% SMI"
41 
42 #include "drmP.h"
43 #include "drm.h"
44 #include "drm_sarea.h"
45 
46 int drm_debug_flag = 1;
47 
48 #define	DRIVER_IOCTL_COUNT	256
49 drm_ioctl_desc_t drm_ioctls[DRIVER_IOCTL_COUNT];
50 
51 void
52 drm_set_ioctl_desc(int n, drm_ioctl_t *func, int auth_needed,
53     int root_only, char *desc)
54 {
55 	drm_ioctls[n].func = func;
56 	drm_ioctls[n].auth_needed = auth_needed;
57 	drm_ioctls[n].root_only = root_only;
58 	drm_ioctls[n].desc = desc;
59 }
60 
61 void
62 drm_init_ioctl_arrays(void)
63 {
64 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_VERSION),
65 	    drm_version, 0, 0, "drm_version");
66 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE),
67 	    drm_getunique, 0, 0, "drm_getunique");
68 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC),
69 	    drm_getmagic, 0, 0, "drm_getmagic");
70 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID),
71 	    drm_irq_by_busid, 0, 1, "drm_irq_by_busid");
72 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_MAP),
73 	    drm_getmap, 0, 0, "drm_getmap");
74 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT),
75 	    drm_getclient, 0, 0, "drm_getclient");
76 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_STATS),
77 	    drm_getstats, 0, 0, "drm_getstats");
78 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_SET_VERSION),
79 	    drm_setversion, 0, 1, "drm_setversion");
80 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE),
81 	    drm_setunique, 1, 1, "drm_setunique");
82 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_BLOCK),
83 	    drm_noop, 1, 1, "drm_ioctl_block");
84 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK),
85 	    drm_noop, 1, 1, "DRM_IOCTL_UNBLOCK");
86 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC),
87 	    drm_authmagic, 1, 1, "drm_authmagic");
88 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP),
89 	    drm_addmap_ioctl, 1, 1, "drm_addmap_ioctl");
90 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_RM_MAP),
91 	    drm_rmmap_ioctl, 1, 1, "drm_rmmap_ioctl");
92 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX),
93 	    drm_setsareactx, 1, 1, "drm_setsareactx");
94 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX),
95 	    drm_getsareactx, 1, 0, "drm_getsareactx");
96 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX),
97 	    drm_addctx, 1, 1, "drm_addctx");
98 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_RM_CTX),
99 	    drm_rmctx, 1, 1, "drm_rmctx");
100 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX),
101 	    drm_modctx, 1, 1, "drm_modctx");
102 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_GET_CTX),
103 	    drm_getctx,  1, 0, "drm_getctx");
104 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX),
105 	    drm_switchctx, 1, 1, "drm_switchctx");
106 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX),
107 	    drm_newctx, 1, 1, "drm_newctx");
108 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_RES_CTX),
109 	    drm_resctx, 1, 0, "drm_resctx");
110 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW),
111 	    drm_adddraw, 1, 1, "drm_adddraw");
112 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW),
113 	    drm_rmdraw, 1, 1, "drm_rmdraw");
114 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_LOCK),
115 	    drm_lock, 1, 0, "drm_lock");
116 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_UNLOCK),
117 	    drm_unlock, 1, 0, "drm_unlock");
118 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_FINISH),
119 	    drm_noop, 1, 0, "drm_noop");
120 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS),
121 	    drm_addbufs_ioctl, 1, 1, "drm_addbufs_ioctl");
122 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS),
123 	    drm_markbufs, 1, 1, "drm_markbufs");
124 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS),
125 	    drm_infobufs, 1, 0, "drm_infobufs");
126 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS),
127 	    drm_mapbufs, 1, 0, "drm_mapbufs");
128 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS),
129 	    drm_freebufs, 1, 0, "drm_freebufs");
130 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_DMA),
131 	    drm_dma, 1, 0, "drm_dma");
132 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_CONTROL),
133 	    drm_control, 1, 1, "drm_control");
134 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE),
135 	    drm_agp_acquire, 1, 1, "drm_agp_acquire");
136 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE),
137 	    drm_agp_release, 1, 1, "drm_agp_release");
138 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE),
139 	    drm_agp_enable, 1, 1, "drm_agp_enable");
140 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO),
141 	    drm_agp_info, 1, 0, "drm_agp_info");
142 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC),
143 	    drm_agp_alloc, 1, 1, "drm_agp_alloc");
144 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE),
145 	    drm_agp_free, 1, 1, "drm_agp_free");
146 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND),
147 	    drm_agp_bind, 1, 1, "drm_agp_bind");
148 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND),
149 	    drm_agp_unbind, 1, 1, "drm_agp_unbind");
150 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC),
151 	    drm_sg_alloc, 1, 1, "drm_sg_alloc");
152 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_SG_FREE),
153 	    drm_sg_free, 1, 1, "drm_sg_free");
154 	drm_set_ioctl_desc(DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK),
155 	    drm_wait_vblank, 0, 0, "drm_wait_vblank");
156 }
157 
158 
159 const char *
160 drm_find_description(int vendor, int device, drm_pci_id_list_t *idlist)
161 {
162 	int i = 0;
163 	for (i = 0; idlist[i].vendor != 0; i++) {
164 	if ((idlist[i].vendor == vendor) &&
165 	    (idlist[i].device == device)) {
166 			return (idlist[i].name);
167 		}
168 	}
169 	return ((char *)NULL);
170 }
171 
172 static int
173 drm_firstopen(drm_device_t *dev)
174 {
175 	int i;
176 	int retval;
177 	drm_local_map_t *map;
178 
179 	/* prebuild the SAREA */
180 	retval = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
181 	    _DRM_CONTAINS_LOCK, &map);
182 	if (retval != 0) {
183 		DRM_ERROR("firstopen: failed to prebuild SAREA");
184 		return (retval);
185 	}
186 
187 	if (dev->driver->use_agp) {
188 		DRM_DEBUG("drm_firstopen: use_agp=%d", dev->driver->use_agp);
189 		if (drm_device_is_agp(dev))
190 			dev->agp = drm_agp_init(dev);
191 		if (dev->driver->require_agp && dev->agp == NULL) {
192 			DRM_ERROR("couldn't initialize AGP");
193 			return (EIO);
194 		}
195 	}
196 
197 	if (dev->driver->firstopen)
198 		retval = dev->driver->firstopen(dev);
199 
200 	if (retval != 0) {
201 		DRM_ERROR("drm_firstopen: driver-specific firstopen failed");
202 		return (retval);
203 	}
204 
205 	dev->buf_use = 0;
206 
207 	if (dev->driver->use_dma) {
208 		i = drm_dma_setup(dev);
209 		if (i != 0)
210 			return (i);
211 	}
212 	dev->counters  = 6;
213 	dev->types[0]  = _DRM_STAT_LOCK;
214 	dev->types[1]  = _DRM_STAT_OPENS;
215 	dev->types[2]  = _DRM_STAT_CLOSES;
216 	dev->types[3]  = _DRM_STAT_IOCTLS;
217 	dev->types[4]  = _DRM_STAT_LOCKS;
218 	dev->types[5]  = _DRM_STAT_UNLOCKS;
219 
220 	for (i = 0; i < DRM_ARRAY_SIZE(dev->counts); i++)
221 		*(&dev->counts[i]) = 0;
222 
223 	for (i = 0; i < DRM_HASH_SIZE; i++) {
224 		dev->magiclist[i].head = NULL;
225 		dev->magiclist[i].tail = NULL;
226 	}
227 
228 	dev->irq_enabled	= 0;
229 	dev->context_flag	= 0;
230 	dev->last_context	= 0;
231 	dev->if_version		= 0;
232 
233 	return (0);
234 }
235 
236 /* Free resources associated with the DRM on the last close. */
237 static int
238 drm_lastclose(drm_device_t *dev)
239 {
240 	drm_magic_entry_t *pt, *next;
241 	drm_local_map_t *map, *mapsave;
242 	int i;
243 
244 	DRM_SPINLOCK_ASSERT(&dev->dev_lock);
245 
246 	if (dev->driver->lastclose != NULL)
247 		dev->driver->lastclose(dev);
248 
249 	if (dev->irq_enabled)
250 		(void) drm_irq_uninstall(dev);
251 
252 	if (dev->unique) {
253 		drm_free(dev->unique, dev->unique_len + 1, DRM_MEM_DRIVER);
254 		dev->unique = NULL;
255 		dev->unique_len = 0;
256 	}
257 
258 	/* Clear pid list */
259 	for (i = 0; i < DRM_HASH_SIZE; i++) {
260 		for (pt = dev->magiclist[i].head; pt; pt = next) {
261 			next = pt->next;
262 			drm_free(pt, sizeof (*pt), DRM_MEM_MAGIC);
263 		}
264 		dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
265 	}
266 
267 	/* Clear AGP information */
268 	if (dev->agp) {
269 		drm_agp_mem_t *entry;
270 		drm_agp_mem_t *nexte;
271 
272 		/*
273 		 * Remove AGP resources, but leave dev->agp
274 		 * intact until drm_cleanup is called.
275 		 */
276 		for (entry = dev->agp->memory; entry; entry = nexte) {
277 			nexte = entry->next;
278 			if (entry->bound)
279 				(void) drm_agp_unbind_memory(
280 				    (unsigned long)entry->handle, dev);
281 			(void) drm_agp_free_memory(entry->handle);
282 			drm_free(entry, sizeof (*entry), DRM_MEM_AGPLISTS);
283 		}
284 		dev->agp->memory = NULL;
285 
286 		if (dev->agp->acquired)
287 			(void) drm_agp_do_release(dev);
288 
289 		dev->agp->acquired = 0;
290 		dev->agp->enabled  = 0;
291 		drm_agp_fini(dev);
292 	}
293 
294 	if (dev->sg != NULL) {
295 		drm_sg_mem_t *entry;
296 		entry = dev->sg;
297 		dev->sg = NULL;
298 		drm_sg_cleanup(dev, entry);
299 	}
300 
301 
302 	/* Clean up maps that weren't set up by the driver. */
303 	TAILQ_FOREACH_SAFE(map, &dev->maplist, link, mapsave) {
304 		if (!map->kernel_owned)
305 			drm_rmmap(dev, map);
306 	}
307 
308 	drm_dma_takedown(dev);
309 	if (dev->lock.hw_lock) {
310 		dev->lock.hw_lock = NULL; /* SHM removed */
311 		dev->lock.filp = NULL;
312 
313 		mutex_enter(&(dev->lock.lock_mutex));
314 		cv_broadcast(&(dev->lock.lock_cv));
315 		mutex_exit(&(dev->lock.lock_mutex));
316 	}
317 
318 	return (0);
319 }
320 
321 static int
322 drm_load(drm_device_t *dev)
323 {
324 	int retcode;
325 
326 	cv_init(&(dev->lock.lock_cv), NULL, CV_DRIVER, NULL);
327 	mutex_init(&(dev->lock.lock_mutex), NULL, MUTEX_DRIVER, NULL);
328 	mutex_init(&(dev->dev_lock), NULL, MUTEX_DRIVER, NULL);
329 	mutex_init(&dev->drw_lock, NULL, MUTEX_DRIVER, NULL);
330 
331 	dev->pci_vendor = pci_get_vendor(dev);
332 	dev->pci_device = pci_get_device(dev);
333 
334 	TAILQ_INIT(&dev->maplist);
335 	TAILQ_INIT(&dev->minordevs);
336 	TAILQ_INIT(&dev->files);
337 	if (dev->driver->load != NULL) {
338 		retcode = dev->driver->load(dev, 0);
339 		if (retcode != 0) {
340 			DRM_ERROR("drm_load: failed\n");
341 			goto error;
342 		}
343 	}
344 
345 	retcode = drm_ctxbitmap_init(dev);
346 	if (retcode != 0) {
347 		DRM_ERROR("drm_load: Cannot allocate memory for ctx bitmap");
348 		goto error;
349 	}
350 
351 	if (drm_init_kstats(dev)) {
352 		DRM_ERROR("drm_attach => drm_load: init kstats error");
353 		retcode = EFAULT;
354 		goto error;
355 	}
356 
357 	DRM_INFO("!drm: Initialized %s %d.%d.%d %s ",
358 	    dev->driver->driver_name,
359 	    dev->driver->driver_major,
360 	    dev->driver->driver_minor,
361 	    dev->driver->driver_patchlevel,
362 	    dev->driver->driver_date);
363 	return (0);
364 
365 error:
366 	DRM_LOCK();
367 	(void) drm_lastclose(dev);
368 	DRM_UNLOCK();
369 	cv_destroy(&(dev->lock.lock_cv));
370 	mutex_destroy(&(dev->lock.lock_mutex));
371 	mutex_destroy(&(dev->dev_lock));
372 	mutex_destroy(&dev->drw_lock);
373 
374 	return (retcode);
375 }
376 
377 /* called when cleanup this module */
378 static void
379 drm_unload(drm_device_t *dev)
380 {
381 	drm_local_map_t *map;
382 
383 	drm_ctxbitmap_cleanup(dev);
384 
385 	DRM_LOCK();
386 	(void) drm_lastclose(dev);
387 	DRM_UNLOCK();
388 
389 	while ((map = TAILQ_FIRST(&dev->maplist)) != NULL) {
390 		drm_rmmap(dev, map);
391 	}
392 
393 	if (dev->driver->unload != NULL)
394 		dev->driver->unload(dev);
395 
396 	drm_mem_uninit();
397 	cv_destroy(&dev->lock.lock_cv);
398 	mutex_destroy(&dev->lock.lock_mutex);
399 	mutex_destroy(&dev->dev_lock);
400 	mutex_destroy(&dev->drw_lock);
401 }
402 
403 
404 /*ARGSUSED*/
405 int
406 drm_open(drm_device_t *dev, drm_cminor_t *mp, int openflags,
407     int otyp, cred_t *credp)
408 {
409 	int retcode;
410 
411 	retcode = drm_open_helper(dev, mp, openflags, otyp, credp);
412 
413 	if (!retcode) {
414 		atomic_inc_32(&dev->counts[_DRM_STAT_OPENS]);
415 		DRM_LOCK();
416 		if (!dev->open_count ++)
417 			retcode = drm_firstopen(dev);
418 		DRM_UNLOCK();
419 	}
420 
421 	return (retcode);
422 }
423 
424 /*ARGSUSED*/
425 int
426 drm_close(drm_device_t *dev, int minor, int flag, int otyp,
427     cred_t *credp)
428 {
429 	drm_cminor_t	*mp;
430 	drm_file_t		*fpriv;
431 	int		retcode = 0;
432 
433 	DRM_LOCK();
434 	mp = drm_find_file_by_minor(dev, minor);
435 	if (!mp) {
436 		DRM_UNLOCK();
437 		DRM_ERROR("drm_close: can't find authenticator");
438 		return (EACCES);
439 	}
440 
441 	fpriv = mp->fpriv;
442 	ASSERT(fpriv);
443 
444 	if (--fpriv->refs != 0)
445 		goto done;
446 
447 	if (dev->driver->preclose != NULL)
448 		dev->driver->preclose(dev, fpriv);
449 
450 	/*
451 	 * Begin inline drm_release
452 	 */
453 	DRM_DEBUG("drm_close :pid = %d , open_count = %d",
454 	    DRM_CURRENTPID, dev->open_count);
455 
456 	if (dev->lock.hw_lock &&
457 	    _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
458 	    dev->lock.filp == fpriv) {
459 		DRM_DEBUG("Process %d dead, freeing lock for context %d",
460 		    DRM_CURRENTPID,
461 		    _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
462 		if (dev->driver->reclaim_buffers_locked != NULL)
463 			dev->driver->reclaim_buffers_locked(dev, fpriv);
464 		(void) drm_lock_free(dev, &dev->lock.hw_lock->lock,
465 		    _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
466 	} else if (dev->driver->reclaim_buffers_locked != NULL &&
467 	    dev->lock.hw_lock != NULL) {
468 		DRM_ERROR("drm_close: "
469 		    "retake lock not implemented yet");
470 	}
471 
472 	if (dev->driver->use_dma)
473 		drm_reclaim_buffers(dev, fpriv);
474 
475 
476 	if (dev->driver->postclose != NULL)
477 		dev->driver->postclose(dev, fpriv);
478 	TAILQ_REMOVE(&dev->files, fpriv, link);
479 	drm_free(fpriv, sizeof (*fpriv), DRM_MEM_FILES);
480 
481 done:
482 	atomic_inc_32(&dev->counts[_DRM_STAT_CLOSES]);
483 
484 	TAILQ_REMOVE(&dev->minordevs, mp, link);
485 	drm_free(mp, sizeof (*mp), DRM_MEM_FILES);
486 
487 	if (--dev->open_count == 0) {
488 		retcode = drm_lastclose(dev);
489 	}
490 	DRM_UNLOCK();
491 
492 	return (retcode);
493 }
494 
495 int
496 drm_attach(drm_device_t *dev)
497 {
498 	drm_init_ioctl_arrays();
499 	return (drm_load(dev));
500 }
501 
502 int
503 drm_detach(drm_device_t *dev)
504 {
505 	drm_unload(dev);
506 	drm_fini_kstats(dev);
507 	return (DDI_SUCCESS);
508 }
509 
510 static int
511 drm_get_businfo(drm_device_t *dev)
512 {
513 	dev->irq = pci_get_irq(dev);
514 	if (dev->irq == -1) {
515 		DRM_ERROR("drm_get_businfo: get irq error");
516 		return (DDI_FAILURE);
517 	}
518 	/* XXX Fix domain number (alpha hoses) */
519 	dev->pci_domain = 0;
520 	if (pci_get_info(dev, &dev->pci_bus,
521 	    &dev->pci_slot, &dev->pci_func) != DDI_SUCCESS) {
522 		DRM_ERROR("drm_get_businfo: get bus slot func error ");
523 		return (DDI_FAILURE);
524 	}
525 	DRM_DEBUG("drm_get_businfo: pci bus: %d, pci slot :%d pci func %d",
526 	    dev->pci_bus, dev->pci_slot, dev->pci_func);
527 	return (DDI_SUCCESS);
528 }
529 
530 int
531 drm_probe(drm_device_t *dev, drm_pci_id_list_t *idlist)
532 {
533 	const char *s = NULL;
534 	int vendor, device;
535 
536 	vendor = pci_get_vendor(dev);
537 	device = pci_get_device(dev);
538 
539 	s = drm_find_description(vendor, device, idlist);
540 	if (s != NULL) {
541 		dev->desc = s;
542 		if (drm_get_businfo(dev) != DDI_SUCCESS) {
543 			DRM_ERROR("drm_probe: drm get bus info error");
544 			return (DDI_FAILURE);
545 		}
546 		return (DDI_SUCCESS);
547 	}
548 	return (DDI_FAILURE);
549 }
550