2 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
3 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 * Rickard E. (Rik) Faith <faith@valinux.com>
27 * Gareth Hughes <gareth@valinux.com>
32 * Varios minor DRM ioctls not applicable to other files, such as versioning
33 * information and reporting DRM information to userland.
36 #include "dev/drm/drmP.h"
39 * Beginning in revision 1.1 of the DRM interface, getunique will return
40 * a unique in the form pci:oooo:bb:dd.f (o=domain, b=bus, d=device, f=function)
41 * before setunique has been called. The format for the bus-specific part of
42 * the unique is not defined for any other bus.
44 int drm_getunique(struct drm_device
*dev
, void *data
,
45 struct drm_file
*file_priv
)
47 struct drm_unique
*u
= data
;
49 if (u
->unique_len
>= dev
->unique_len
) {
50 if (DRM_COPY_TO_USER(u
->unique
, dev
->unique
, dev
->unique_len
))
53 u
->unique_len
= dev
->unique_len
;
58 /* Deprecated in DRM version 1.1, and will return EBUSY when setversion has
59 * requested version 1.1 or greater.
61 int drm_setunique(struct drm_device
*dev
, void *data
,
62 struct drm_file
*file_priv
)
64 struct drm_unique
*u
= data
;
65 int domain
, bus
, slot
, func
, ret
;
68 /* Check and copy in the submitted Bus ID */
69 if (!u
->unique_len
|| u
->unique_len
> 1024)
72 busid
= malloc(u
->unique_len
+ 1, DRM_MEM_DRIVER
, M_WAITOK
);
76 if (DRM_COPY_FROM_USER(busid
, u
->unique
, u
->unique_len
)) {
77 free(busid
, DRM_MEM_DRIVER
);
80 busid
[u
->unique_len
] = '\0';
82 /* Return error if the busid submitted doesn't match the device's actual
85 ret
= sscanf(busid
, "PCI:%d:%d:%d", &bus
, &slot
, &func
);
87 free(busid
, DRM_MEM_DRIVER
);
93 if ((domain
!= dev
->pci_domain
) ||
94 (bus
!= dev
->pci_bus
) ||
95 (slot
!= dev
->pci_slot
) ||
96 (func
!= dev
->pci_func
)) {
97 free(busid
, DRM_MEM_DRIVER
);
101 /* Actually set the device's busid now. */
103 if (dev
->unique_len
|| dev
->unique
) {
108 dev
->unique_len
= u
->unique_len
;
117 drm_set_busid(struct drm_device
*dev
)
122 if (dev
->unique
!= NULL
) {
127 dev
->unique_len
= 20;
128 dev
->unique
= malloc(dev
->unique_len
+ 1, DRM_MEM_DRIVER
, M_NOWAIT
);
129 if (dev
->unique
== NULL
) {
134 snprintf(dev
->unique
, dev
->unique_len
, "pci:%04x:%02x:%02x.%1x",
135 dev
->pci_domain
, dev
->pci_bus
, dev
->pci_slot
, dev
->pci_func
);
142 int drm_getmap(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
144 struct drm_map
*map
= data
;
145 drm_local_map_t
*mapinlist
;
157 TAILQ_FOREACH(mapinlist
, &dev
->maplist
, link
) {
159 map
->offset
= mapinlist
->offset
;
160 map
->size
= mapinlist
->size
;
161 map
->type
= mapinlist
->type
;
162 map
->flags
= mapinlist
->flags
;
163 map
->handle
= mapinlist
->handle
;
164 map
->mtrr
= mapinlist
->mtrr
;
172 if (mapinlist
== NULL
)
178 int drm_getclient(struct drm_device
*dev
, void *data
,
179 struct drm_file
*file_priv
)
181 struct drm_client
*client
= data
;
188 TAILQ_FOREACH(pt
, &dev
->files
, link
) {
190 client
->auth
= pt
->authenticated
;
191 client
->pid
= pt
->pid
;
192 client
->uid
= pt
->uid
;
193 client
->magic
= pt
->magic
;
194 client
->iocs
= pt
->ioctl_count
;
205 int drm_getstats(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
207 struct drm_stats
*stats
= data
;
210 memset(stats
, 0, sizeof(struct drm_stats
));
214 for (i
= 0; i
< dev
->counters
; i
++) {
215 if (dev
->types
[i
] == _DRM_STAT_LOCK
)
216 stats
->data
[i
].value
=
217 (dev
->lock
.hw_lock
? dev
->lock
.hw_lock
->lock
: 0);
219 stats
->data
[i
].value
= atomic_read(&dev
->counts
[i
]);
220 stats
->data
[i
].type
= dev
->types
[i
];
223 stats
->count
= dev
->counters
;
230 #define DRM_IF_MAJOR 1
231 #define DRM_IF_MINOR 2
233 int drm_setversion(struct drm_device
*dev
, void *data
,
234 struct drm_file
*file_priv
)
236 struct drm_set_version
*sv
= data
;
237 struct drm_set_version ver
;
240 /* Save the incoming data, and set the response before continuing
244 sv
->drm_di_major
= DRM_IF_MAJOR
;
245 sv
->drm_di_minor
= DRM_IF_MINOR
;
246 sv
->drm_dd_major
= dev
->driver
->major
;
247 sv
->drm_dd_minor
= dev
->driver
->minor
;
249 if (ver
.drm_di_major
!= -1) {
250 if (ver
.drm_di_major
!= DRM_IF_MAJOR
||
251 ver
.drm_di_minor
< 0 || ver
.drm_di_minor
> DRM_IF_MINOR
) {
254 if_version
= DRM_IF_VERSION(ver
.drm_di_major
,
256 dev
->if_version
= DRM_MAX(if_version
, dev
->if_version
);
257 if (ver
.drm_di_minor
>= 1) {
259 * Version 1.1 includes tying of DRM to specific device
265 if (ver
.drm_dd_major
!= -1) {
266 if (ver
.drm_dd_major
!= dev
->driver
->major
||
267 ver
.drm_dd_minor
< 0 ||
268 ver
.drm_dd_minor
> dev
->driver
->minor
)
278 int drm_noop(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)