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.
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 #if defined(__NetBSD__)
67 struct drm_unique
*u
= data
;
68 int domain
, bus
, slot
, func
, ret
;
71 /* Check and copy in the submitted Bus ID */
72 if (!u
->unique_len
|| u
->unique_len
> 1024)
75 busid
= malloc(u
->unique_len
+ 1, DRM_MEM_DRIVER
, M_WAITOK
);
79 if (DRM_COPY_FROM_USER(busid
, u
->unique
, u
->unique_len
)) {
80 free(busid
, DRM_MEM_DRIVER
);
83 busid
[u
->unique_len
] = '\0';
85 /* Return error if the busid submitted doesn't match the device's actual
88 ret
= sscanf(busid
, "PCI:%d:%d:%d", &bus
, &slot
, &func
);
90 free(busid
, DRM_MEM_DRIVER
);
96 if ((domain
!= dev
->pci_domain
) ||
97 (bus
!= dev
->pci_bus
) ||
98 (slot
!= dev
->pci_slot
) ||
99 (func
!= dev
->pci_func
)) {
100 free(busid
, DRM_MEM_DRIVER
);
104 /* Actually set the device's busid now. */
106 if (dev
->unique_len
|| dev
->unique
) {
111 dev
->unique_len
= u
->unique_len
;
121 drm_set_busid(struct drm_device
*dev
)
126 if (dev
->unique
!= NULL
) {
131 dev
->unique_len
= 20;
132 dev
->unique
= malloc(dev
->unique_len
+ 1, DRM_MEM_DRIVER
, M_NOWAIT
);
133 if (dev
->unique
== NULL
) {
138 snprintf(dev
->unique
, dev
->unique_len
, "pci:%04x:%02x:%02x.%1x",
139 dev
->pci_domain
, dev
->pci_bus
, dev
->pci_slot
, dev
->pci_func
);
146 int drm_getmap(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
148 struct drm_map
*map
= data
;
149 drm_local_map_t
*mapinlist
;
161 TAILQ_FOREACH(mapinlist
, &dev
->maplist
, link
) {
163 map
->offset
= mapinlist
->offset
;
164 map
->size
= mapinlist
->size
;
165 map
->type
= mapinlist
->type
;
166 map
->flags
= mapinlist
->flags
;
167 map
->handle
= mapinlist
->handle
;
168 map
->mtrr
= mapinlist
->mtrr
;
176 if (mapinlist
== NULL
)
182 int drm_getclient(struct drm_device
*dev
, void *data
,
183 struct drm_file
*file_priv
)
185 struct drm_client
*client
= data
;
192 TAILQ_FOREACH(pt
, &dev
->files
, link
) {
194 client
->auth
= pt
->authenticated
;
195 client
->pid
= pt
->pid
;
196 client
->uid
= pt
->uid
;
197 client
->magic
= pt
->magic
;
198 client
->iocs
= pt
->ioctl_count
;
209 int drm_getstats(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)
211 struct drm_stats
*stats
= data
;
214 memset(stats
, 0, sizeof(struct drm_stats
));
218 for (i
= 0; i
< dev
->counters
; i
++) {
219 if (dev
->types
[i
] == _DRM_STAT_LOCK
)
220 stats
->data
[i
].value
=
221 (dev
->lock
.hw_lock
? dev
->lock
.hw_lock
->lock
: 0);
223 stats
->data
[i
].value
= atomic_read(&dev
->counts
[i
]);
224 stats
->data
[i
].type
= dev
->types
[i
];
227 stats
->count
= dev
->counters
;
234 #define DRM_IF_MAJOR 1
235 #define DRM_IF_MINOR 2
237 int drm_setversion(struct drm_device
*dev
, void *data
,
238 struct drm_file
*file_priv
)
240 struct drm_set_version
*sv
= data
;
241 struct drm_set_version ver
;
244 /* Save the incoming data, and set the response before continuing
248 sv
->drm_di_major
= DRM_IF_MAJOR
;
249 sv
->drm_di_minor
= DRM_IF_MINOR
;
250 sv
->drm_dd_major
= dev
->driver
->major
;
251 sv
->drm_dd_minor
= dev
->driver
->minor
;
253 if (ver
.drm_di_major
!= -1) {
254 if (ver
.drm_di_major
!= DRM_IF_MAJOR
||
255 ver
.drm_di_minor
< 0 || ver
.drm_di_minor
> DRM_IF_MINOR
) {
258 if_version
= DRM_IF_VERSION(ver
.drm_di_major
,
260 dev
->if_version
= DRM_MAX(if_version
, dev
->if_version
);
261 if (ver
.drm_di_minor
>= 1) {
263 * Version 1.1 includes tying of DRM to specific device
269 if (ver
.drm_dd_major
!= -1) {
270 if (ver
.drm_dd_major
!= dev
->driver
->major
||
271 ver
.drm_dd_minor
< 0 ||
272 ver
.drm_dd_minor
> dev
->driver
->minor
)
282 int drm_noop(struct drm_device
*dev
, void *data
, struct drm_file
*file_priv
)