aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
diff options
context:
space:
mode:
authorJakob Bornecrantz <jakob@vmware.com>2009-12-09 19:19:58 -0500
committerDave Airlie <airlied@redhat.com>2009-12-14 17:38:43 -0500
commitfb1d9738ca053ea8afa5e86af6463155f983b01c (patch)
tree53aa407922c989f48aead5fcf61f9945ca6051d5 /drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
parent632f61178d0473861ba77e774bb654b37bc7eccc (diff)
drm/vmwgfx: Add DRM driver for VMware Virtual GPU
This commit adds the vmwgfx driver for the VWware Virtual GPU aka SVGA. The driver is under staging the same as Nouveau and Radeon KMS. Hopefully the 2D ioctls are bug free and don't need changing, so that part of the API should be stable. But there there is a pretty big chance that the 3D API will change in the future. Signed-off-by: Thomas Hellström <thellstrom@vmware.com> Signed-off-by: Jakob Bornecrantz <jakob@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/vmwgfx/vmwgfx_drv.c')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c735
1 files changed, 735 insertions, 0 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
new file mode 100644
index 000000000000..7b48bb3b63b2
--- /dev/null
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -0,0 +1,735 @@
1/**************************************************************************
2 *
3 * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include "drmP.h"
29#include "vmwgfx_drv.h"
30#include "ttm/ttm_placement.h"
31#include "ttm/ttm_bo_driver.h"
32#include "ttm/ttm_object.h"
33#include "ttm/ttm_module.h"
34
35#define VMWGFX_DRIVER_NAME "vmwgfx"
36#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices"
37#define VMWGFX_CHIP_SVGAII 0
38#define VMW_FB_RESERVATION 0
39
40/**
41 * Fully encoded drm commands. Might move to vmw_drm.h
42 */
43
44#define DRM_IOCTL_VMW_GET_PARAM \
45 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GET_PARAM, \
46 struct drm_vmw_getparam_arg)
47#define DRM_IOCTL_VMW_ALLOC_DMABUF \
48 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_ALLOC_DMABUF, \
49 union drm_vmw_alloc_dmabuf_arg)
50#define DRM_IOCTL_VMW_UNREF_DMABUF \
51 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_DMABUF, \
52 struct drm_vmw_unref_dmabuf_arg)
53#define DRM_IOCTL_VMW_CURSOR_BYPASS \
54 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CURSOR_BYPASS, \
55 struct drm_vmw_cursor_bypass_arg)
56
57#define DRM_IOCTL_VMW_CONTROL_STREAM \
58 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CONTROL_STREAM, \
59 struct drm_vmw_control_stream_arg)
60#define DRM_IOCTL_VMW_CLAIM_STREAM \
61 DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CLAIM_STREAM, \
62 struct drm_vmw_stream_arg)
63#define DRM_IOCTL_VMW_UNREF_STREAM \
64 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_STREAM, \
65 struct drm_vmw_stream_arg)
66
67#define DRM_IOCTL_VMW_CREATE_CONTEXT \
68 DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CREATE_CONTEXT, \
69 struct drm_vmw_context_arg)
70#define DRM_IOCTL_VMW_UNREF_CONTEXT \
71 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_CONTEXT, \
72 struct drm_vmw_context_arg)
73#define DRM_IOCTL_VMW_CREATE_SURFACE \
74 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_CREATE_SURFACE, \
75 union drm_vmw_surface_create_arg)
76#define DRM_IOCTL_VMW_UNREF_SURFACE \
77 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_SURFACE, \
78 struct drm_vmw_surface_arg)
79#define DRM_IOCTL_VMW_REF_SURFACE \
80 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_REF_SURFACE, \
81 union drm_vmw_surface_reference_arg)
82#define DRM_IOCTL_VMW_EXECBUF \
83 DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_EXECBUF, \
84 struct drm_vmw_execbuf_arg)
85#define DRM_IOCTL_VMW_FIFO_DEBUG \
86 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FIFO_DEBUG, \
87 struct drm_vmw_fifo_debug_arg)
88#define DRM_IOCTL_VMW_FENCE_WAIT \
89 DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \
90 struct drm_vmw_fence_wait_arg)
91
92
93/**
94 * The core DRM version of this macro doesn't account for
95 * DRM_COMMAND_BASE.
96 */
97
98#define VMW_IOCTL_DEF(ioctl, func, flags) \
99 [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
100
101/**
102 * Ioctl definitions.
103 */
104
105static struct drm_ioctl_desc vmw_ioctls[] = {
106 VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, 0),
107 VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl,
108 0),
109 VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl,
110 0),
111 VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS,
112 vmw_kms_cursor_bypass_ioctl, 0),
113
114 VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl,
115 0),
116 VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl,
117 0),
118 VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl,
119 0),
120
121 VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl,
122 0),
123 VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl,
124 0),
125 VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl,
126 0),
127 VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl,
128 0),
129 VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl,
130 0),
131 VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl,
132 0),
133 VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl,
134 0),
135 VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl,
136 0)
137};
138
139static struct pci_device_id vmw_pci_id_list[] = {
140 {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII},
141 {0, 0, 0}
142};
143
144static char *vmw_devname = "vmwgfx";
145
146static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
147static void vmw_master_init(struct vmw_master *);
148
149static void vmw_print_capabilities(uint32_t capabilities)
150{
151 DRM_INFO("Capabilities:\n");
152 if (capabilities & SVGA_CAP_RECT_COPY)
153 DRM_INFO(" Rect copy.\n");
154 if (capabilities & SVGA_CAP_CURSOR)
155 DRM_INFO(" Cursor.\n");
156 if (capabilities & SVGA_CAP_CURSOR_BYPASS)
157 DRM_INFO(" Cursor bypass.\n");
158 if (capabilities & SVGA_CAP_CURSOR_BYPASS_2)
159 DRM_INFO(" Cursor bypass 2.\n");
160 if (capabilities & SVGA_CAP_8BIT_EMULATION)
161 DRM_INFO(" 8bit emulation.\n");
162 if (capabilities & SVGA_CAP_ALPHA_CURSOR)
163 DRM_INFO(" Alpha cursor.\n");
164 if (capabilities & SVGA_CAP_3D)
165 DRM_INFO(" 3D.\n");
166 if (capabilities & SVGA_CAP_EXTENDED_FIFO)
167 DRM_INFO(" Extended Fifo.\n");
168 if (capabilities & SVGA_CAP_MULTIMON)
169 DRM_INFO(" Multimon.\n");
170 if (capabilities & SVGA_CAP_PITCHLOCK)
171 DRM_INFO(" Pitchlock.\n");
172 if (capabilities & SVGA_CAP_IRQMASK)
173 DRM_INFO(" Irq mask.\n");
174 if (capabilities & SVGA_CAP_DISPLAY_TOPOLOGY)
175 DRM_INFO(" Display Topology.\n");
176 if (capabilities & SVGA_CAP_GMR)
177 DRM_INFO(" GMR.\n");
178 if (capabilities & SVGA_CAP_TRACES)
179 DRM_INFO(" Traces.\n");
180}
181
182static int vmw_request_device(struct vmw_private *dev_priv)
183{
184 int ret;
185
186 vmw_kms_save_vga(dev_priv);
187
188 ret = vmw_fifo_init(dev_priv, &dev_priv->fifo);
189 if (unlikely(ret != 0)) {
190 DRM_ERROR("Unable to initialize FIFO.\n");
191 return ret;
192 }
193
194 return 0;
195}
196
197static void vmw_release_device(struct vmw_private *dev_priv)
198{
199 vmw_fifo_release(dev_priv, &dev_priv->fifo);
200 vmw_kms_restore_vga(dev_priv);
201}
202
203
204static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
205{
206 struct vmw_private *dev_priv;
207 int ret;
208
209 dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
210 if (unlikely(dev_priv == NULL)) {
211 DRM_ERROR("Failed allocating a device private struct.\n");
212 return -ENOMEM;
213 }
214 memset(dev_priv, 0, sizeof(*dev_priv));
215
216 dev_priv->dev = dev;
217 dev_priv->vmw_chipset = chipset;
218 mutex_init(&dev_priv->hw_mutex);
219 mutex_init(&dev_priv->cmdbuf_mutex);
220 rwlock_init(&dev_priv->resource_lock);
221 idr_init(&dev_priv->context_idr);
222 idr_init(&dev_priv->surface_idr);
223 idr_init(&dev_priv->stream_idr);
224 ida_init(&dev_priv->gmr_ida);
225 mutex_init(&dev_priv->init_mutex);
226 init_waitqueue_head(&dev_priv->fence_queue);
227 init_waitqueue_head(&dev_priv->fifo_queue);
228 atomic_set(&dev_priv->fence_queue_waiters, 0);
229 atomic_set(&dev_priv->fifo_queue_waiters, 0);
230 INIT_LIST_HEAD(&dev_priv->gmr_lru);
231
232 dev_priv->io_start = pci_resource_start(dev->pdev, 0);
233 dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
234 dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
235
236 mutex_lock(&dev_priv->hw_mutex);
237 dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES);
238
239 if (dev_priv->capabilities & SVGA_CAP_GMR) {
240 dev_priv->max_gmr_descriptors =
241 vmw_read(dev_priv,
242 SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH);
243 dev_priv->max_gmr_ids =
244 vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS);
245 }
246
247 dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE);
248 dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE);
249 dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH);
250 dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT);
251
252 mutex_unlock(&dev_priv->hw_mutex);
253
254 vmw_print_capabilities(dev_priv->capabilities);
255
256 if (dev_priv->capabilities & SVGA_CAP_GMR) {
257 DRM_INFO("Max GMR ids is %u\n",
258 (unsigned)dev_priv->max_gmr_ids);
259 DRM_INFO("Max GMR descriptors is %u\n",
260 (unsigned)dev_priv->max_gmr_descriptors);
261 }
262 DRM_INFO("VRAM at 0x%08x size is %u kiB\n",
263 dev_priv->vram_start, dev_priv->vram_size / 1024);
264 DRM_INFO("MMIO at 0x%08x size is %u kiB\n",
265 dev_priv->mmio_start, dev_priv->mmio_size / 1024);
266
267 ret = vmw_ttm_global_init(dev_priv);
268 if (unlikely(ret != 0))
269 goto out_err0;
270
271
272 vmw_master_init(&dev_priv->fbdev_master);
273 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
274 dev_priv->active_master = &dev_priv->fbdev_master;
275
276
277 ret = ttm_bo_device_init(&dev_priv->bdev,
278 dev_priv->bo_global_ref.ref.object,
279 &vmw_bo_driver, VMWGFX_FILE_PAGE_OFFSET,
280 false);
281 if (unlikely(ret != 0)) {
282 DRM_ERROR("Failed initializing TTM buffer object driver.\n");
283 goto out_err1;
284 }
285
286 ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,
287 (dev_priv->vram_size >> PAGE_SHIFT));
288 if (unlikely(ret != 0)) {
289 DRM_ERROR("Failed initializing memory manager for VRAM.\n");
290 goto out_err2;
291 }
292
293 dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start,
294 dev_priv->mmio_size, DRM_MTRR_WC);
295
296 dev_priv->mmio_virt = ioremap_wc(dev_priv->mmio_start,
297 dev_priv->mmio_size);
298
299 if (unlikely(dev_priv->mmio_virt == NULL)) {
300 ret = -ENOMEM;
301 DRM_ERROR("Failed mapping MMIO.\n");
302 goto out_err3;
303 }
304
305 dev_priv->tdev = ttm_object_device_init
306 (dev_priv->mem_global_ref.object, 12);
307
308 if (unlikely(dev_priv->tdev == NULL)) {
309 DRM_ERROR("Unable to initialize TTM object management.\n");
310 ret = -ENOMEM;
311 goto out_err4;
312 }
313
314 dev->dev_private = dev_priv;
315
316 if (!dev->devname)
317 dev->devname = vmw_devname;
318
319 if (dev_priv->capabilities & SVGA_CAP_IRQMASK) {
320 ret = drm_irq_install(dev);
321 if (unlikely(ret != 0)) {
322 DRM_ERROR("Failed installing irq: %d\n", ret);
323 goto out_no_irq;
324 }
325 }
326
327 ret = pci_request_regions(dev->pdev, "vmwgfx probe");
328 dev_priv->stealth = (ret != 0);
329 if (dev_priv->stealth) {
330 /**
331 * Request at least the mmio PCI resource.
332 */
333
334 DRM_INFO("It appears like vesafb is loaded. "
335 "Ignore above error if any. Entering stealth mode.\n");
336 ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe");
337 if (unlikely(ret != 0)) {
338 DRM_ERROR("Failed reserving the SVGA MMIO resource.\n");
339 goto out_no_device;
340 }
341 vmw_kms_init(dev_priv);
342 vmw_overlay_init(dev_priv);
343 } else {
344 ret = vmw_request_device(dev_priv);
345 if (unlikely(ret != 0))
346 goto out_no_device;
347 vmw_kms_init(dev_priv);
348 vmw_overlay_init(dev_priv);
349 vmw_fb_init(dev_priv);
350 }
351
352 return 0;
353
354out_no_device:
355 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
356 drm_irq_uninstall(dev_priv->dev);
357 if (dev->devname == vmw_devname)
358 dev->devname = NULL;
359out_no_irq:
360 ttm_object_device_release(&dev_priv->tdev);
361out_err4:
362 iounmap(dev_priv->mmio_virt);
363out_err3:
364 drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
365 dev_priv->mmio_size, DRM_MTRR_WC);
366 (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
367out_err2:
368 (void)ttm_bo_device_release(&dev_priv->bdev);
369out_err1:
370 vmw_ttm_global_release(dev_priv);
371out_err0:
372 ida_destroy(&dev_priv->gmr_ida);
373 idr_destroy(&dev_priv->surface_idr);
374 idr_destroy(&dev_priv->context_idr);
375 idr_destroy(&dev_priv->stream_idr);
376 kfree(dev_priv);
377 return ret;
378}
379
380static int vmw_driver_unload(struct drm_device *dev)
381{
382 struct vmw_private *dev_priv = vmw_priv(dev);
383
384 DRM_INFO(VMWGFX_DRIVER_NAME " unload.\n");
385
386 if (!dev_priv->stealth) {
387 vmw_fb_close(dev_priv);
388 vmw_kms_close(dev_priv);
389 vmw_overlay_close(dev_priv);
390 vmw_release_device(dev_priv);
391 pci_release_regions(dev->pdev);
392 } else {
393 vmw_kms_close(dev_priv);
394 vmw_overlay_close(dev_priv);
395 pci_release_region(dev->pdev, 2);
396 }
397 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
398 drm_irq_uninstall(dev_priv->dev);
399 if (dev->devname == vmw_devname)
400 dev->devname = NULL;
401 ttm_object_device_release(&dev_priv->tdev);
402 iounmap(dev_priv->mmio_virt);
403 drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start,
404 dev_priv->mmio_size, DRM_MTRR_WC);
405 (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
406 (void)ttm_bo_device_release(&dev_priv->bdev);
407 vmw_ttm_global_release(dev_priv);
408 ida_destroy(&dev_priv->gmr_ida);
409 idr_destroy(&dev_priv->surface_idr);
410 idr_destroy(&dev_priv->context_idr);
411 idr_destroy(&dev_priv->stream_idr);
412
413 kfree(dev_priv);
414
415 return 0;
416}
417
418static void vmw_postclose(struct drm_device *dev,
419 struct drm_file *file_priv)
420{
421 struct vmw_fpriv *vmw_fp;
422
423 vmw_fp = vmw_fpriv(file_priv);
424 ttm_object_file_release(&vmw_fp->tfile);
425 if (vmw_fp->locked_master)
426 drm_master_put(&vmw_fp->locked_master);
427 kfree(vmw_fp);
428}
429
430static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
431{
432 struct vmw_private *dev_priv = vmw_priv(dev);
433 struct vmw_fpriv *vmw_fp;
434 int ret = -ENOMEM;
435
436 vmw_fp = kzalloc(sizeof(*vmw_fp), GFP_KERNEL);
437 if (unlikely(vmw_fp == NULL))
438 return ret;
439
440 vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
441 if (unlikely(vmw_fp->tfile == NULL))
442 goto out_no_tfile;
443
444 file_priv->driver_priv = vmw_fp;
445
446 if (unlikely(dev_priv->bdev.dev_mapping == NULL))
447 dev_priv->bdev.dev_mapping =
448 file_priv->filp->f_path.dentry->d_inode->i_mapping;
449
450 return 0;
451
452out_no_tfile:
453 kfree(vmw_fp);
454 return ret;
455}
456
457static long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd,
458 unsigned long arg)
459{
460 struct drm_file *file_priv = filp->private_data;
461 struct drm_device *dev = file_priv->minor->dev;
462 unsigned int nr = DRM_IOCTL_NR(cmd);
463 long ret;
464
465 /*
466 * The driver private ioctls and TTM ioctls should be
467 * thread-safe.
468 */
469
470 if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
471 && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
472 struct drm_ioctl_desc *ioctl =
473 &vmw_ioctls[nr - DRM_COMMAND_BASE];
474
475 if (unlikely(ioctl->cmd != cmd)) {
476 DRM_ERROR("Invalid command format, ioctl %d\n",
477 nr - DRM_COMMAND_BASE);
478 return -EINVAL;
479 }
480 return drm_ioctl(filp->f_path.dentry->d_inode,
481 filp, cmd, arg);
482 }
483
484 /*
485 * Not all old drm ioctls are thread-safe.
486 */
487
488 lock_kernel();
489 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
490 unlock_kernel();
491 return ret;
492}
493
494static int vmw_firstopen(struct drm_device *dev)
495{
496 struct vmw_private *dev_priv = vmw_priv(dev);
497 dev_priv->is_opened = true;
498
499 return 0;
500}
501
502static void vmw_lastclose(struct drm_device *dev)
503{
504 struct vmw_private *dev_priv = vmw_priv(dev);
505 struct drm_crtc *crtc;
506 struct drm_mode_set set;
507 int ret;
508
509 /**
510 * Do nothing on the lastclose call from drm_unload.
511 */
512
513 if (!dev_priv->is_opened)
514 return;
515
516 dev_priv->is_opened = false;
517 set.x = 0;
518 set.y = 0;
519 set.fb = NULL;
520 set.mode = NULL;
521 set.connectors = NULL;
522 set.num_connectors = 0;
523
524 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
525 set.crtc = crtc;
526 ret = crtc->funcs->set_config(&set);
527 WARN_ON(ret != 0);
528 }
529
530}
531
532static void vmw_master_init(struct vmw_master *vmaster)
533{
534 ttm_lock_init(&vmaster->lock);
535}
536
537static int vmw_master_create(struct drm_device *dev,
538 struct drm_master *master)
539{
540 struct vmw_master *vmaster;
541
542 DRM_INFO("Master create.\n");
543 vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL);
544 if (unlikely(vmaster == NULL))
545 return -ENOMEM;
546
547 ttm_lock_init(&vmaster->lock);
548 ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
549 master->driver_priv = vmaster;
550
551 return 0;
552}
553
554static void vmw_master_destroy(struct drm_device *dev,
555 struct drm_master *master)
556{
557 struct vmw_master *vmaster = vmw_master(master);
558
559 DRM_INFO("Master destroy.\n");
560 master->driver_priv = NULL;
561 kfree(vmaster);
562}
563
564
565static int vmw_master_set(struct drm_device *dev,
566 struct drm_file *file_priv,
567 bool from_open)
568{
569 struct vmw_private *dev_priv = vmw_priv(dev);
570 struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
571 struct vmw_master *active = dev_priv->active_master;
572 struct vmw_master *vmaster = vmw_master(file_priv->master);
573 int ret = 0;
574
575 DRM_INFO("Master set.\n");
576 if (dev_priv->stealth) {
577 ret = vmw_request_device(dev_priv);
578 if (unlikely(ret != 0))
579 return ret;
580 }
581
582 if (active) {
583 BUG_ON(active != &dev_priv->fbdev_master);
584 ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile);
585 if (unlikely(ret != 0))
586 goto out_no_active_lock;
587
588 ttm_lock_set_kill(&active->lock, true, SIGTERM);
589 ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
590 if (unlikely(ret != 0)) {
591 DRM_ERROR("Unable to clean VRAM on "
592 "master drop.\n");
593 }
594
595 dev_priv->active_master = NULL;
596 }
597
598 ttm_lock_set_kill(&vmaster->lock, false, SIGTERM);
599 if (!from_open) {
600 ttm_vt_unlock(&vmaster->lock);
601 BUG_ON(vmw_fp->locked_master != file_priv->master);
602 drm_master_put(&vmw_fp->locked_master);
603 }
604
605 dev_priv->active_master = vmaster;
606
607 return 0;
608
609out_no_active_lock:
610 vmw_release_device(dev_priv);
611 return ret;
612}
613
614static void vmw_master_drop(struct drm_device *dev,
615 struct drm_file *file_priv,
616 bool from_release)
617{
618 struct vmw_private *dev_priv = vmw_priv(dev);
619 struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
620 struct vmw_master *vmaster = vmw_master(file_priv->master);
621 int ret;
622
623 DRM_INFO("Master drop.\n");
624
625 /**
626 * Make sure the master doesn't disappear while we have
627 * it locked.
628 */
629
630 vmw_fp->locked_master = drm_master_get(file_priv->master);
631 ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile);
632
633 if (unlikely((ret != 0))) {
634 DRM_ERROR("Unable to lock TTM at VT switch.\n");
635 drm_master_put(&vmw_fp->locked_master);
636 }
637
638 ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
639
640 if (dev_priv->stealth) {
641 ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
642 if (unlikely(ret != 0))
643 DRM_ERROR("Unable to clean VRAM on master drop.\n");
644 vmw_release_device(dev_priv);
645 }
646 dev_priv->active_master = &dev_priv->fbdev_master;
647 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
648 ttm_vt_unlock(&dev_priv->fbdev_master.lock);
649
650 if (!dev_priv->stealth)
651 vmw_fb_on(dev_priv);
652}
653
654
655static void vmw_remove(struct pci_dev *pdev)
656{
657 struct drm_device *dev = pci_get_drvdata(pdev);
658
659 drm_put_dev(dev);
660}
661
662static struct drm_driver driver = {
663 .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
664 DRIVER_MODESET,
665 .load = vmw_driver_load,
666 .unload = vmw_driver_unload,
667 .firstopen = vmw_firstopen,
668 .lastclose = vmw_lastclose,
669 .irq_preinstall = vmw_irq_preinstall,
670 .irq_postinstall = vmw_irq_postinstall,
671 .irq_uninstall = vmw_irq_uninstall,
672 .irq_handler = vmw_irq_handler,
673 .reclaim_buffers_locked = NULL,
674 .get_map_ofs = drm_core_get_map_ofs,
675 .get_reg_ofs = drm_core_get_reg_ofs,
676 .ioctls = vmw_ioctls,
677 .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls),
678 .dma_quiescent = NULL, /*vmw_dma_quiescent, */
679 .master_create = vmw_master_create,
680 .master_destroy = vmw_master_destroy,
681 .master_set = vmw_master_set,
682 .master_drop = vmw_master_drop,
683 .open = vmw_driver_open,
684 .postclose = vmw_postclose,
685 .fops = {
686 .owner = THIS_MODULE,
687 .open = drm_open,
688 .release = drm_release,
689 .unlocked_ioctl = vmw_unlocked_ioctl,
690 .mmap = vmw_mmap,
691 .poll = drm_poll,
692 .fasync = drm_fasync,
693#if defined(CONFIG_COMPAT)
694 .compat_ioctl = drm_compat_ioctl,
695#endif
696 },
697 .pci_driver = {
698 .name = VMWGFX_DRIVER_NAME,
699 .id_table = vmw_pci_id_list,
700 .probe = vmw_probe,
701 .remove = vmw_remove
702 },
703 .name = VMWGFX_DRIVER_NAME,
704 .desc = VMWGFX_DRIVER_DESC,
705 .date = VMWGFX_DRIVER_DATE,
706 .major = VMWGFX_DRIVER_MAJOR,
707 .minor = VMWGFX_DRIVER_MINOR,
708 .patchlevel = VMWGFX_DRIVER_PATCHLEVEL
709};
710
711static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
712{
713 return drm_get_dev(pdev, ent, &driver);
714}
715
716static int __init vmwgfx_init(void)
717{
718 int ret;
719 ret = drm_init(&driver);
720 if (ret)
721 DRM_ERROR("Failed initializing DRM.\n");
722 return ret;
723}
724
725static void __exit vmwgfx_exit(void)
726{
727 drm_exit(&driver);
728}
729
730module_init(vmwgfx_init);
731module_exit(vmwgfx_exit);
732
733MODULE_AUTHOR("VMware Inc. and others");
734MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device");
735MODULE_LICENSE("GPL and additional rights");