1 1.4 riastrad /* $NetBSD: vmwgfx_ioctl.c,v 1.4 2022/10/25 23:35:43 riastradh Exp $ */ 2 1.2 riastrad 3 1.3 riastrad // SPDX-License-Identifier: GPL-2.0 OR MIT 4 1.1 riastrad /************************************************************************** 5 1.1 riastrad * 6 1.3 riastrad * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA 7 1.1 riastrad * 8 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 9 1.1 riastrad * copy of this software and associated documentation files (the 10 1.1 riastrad * "Software"), to deal in the Software without restriction, including 11 1.1 riastrad * without limitation the rights to use, copy, modify, merge, publish, 12 1.1 riastrad * distribute, sub license, and/or sell copies of the Software, and to 13 1.1 riastrad * permit persons to whom the Software is furnished to do so, subject to 14 1.1 riastrad * the following conditions: 15 1.1 riastrad * 16 1.1 riastrad * The above copyright notice and this permission notice (including the 17 1.1 riastrad * next paragraph) shall be included in all copies or substantial portions 18 1.1 riastrad * of the Software. 19 1.1 riastrad * 20 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 23 1.1 riastrad * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 24 1.1 riastrad * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 25 1.1 riastrad * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 26 1.1 riastrad * USE OR OTHER DEALINGS IN THE SOFTWARE. 27 1.1 riastrad * 28 1.1 riastrad **************************************************************************/ 29 1.1 riastrad 30 1.2 riastrad #include <sys/cdefs.h> 31 1.4 riastrad __KERNEL_RCSID(0, "$NetBSD: vmwgfx_ioctl.c,v 1.4 2022/10/25 23:35:43 riastradh Exp $"); 32 1.2 riastrad 33 1.1 riastrad #include "vmwgfx_drv.h" 34 1.1 riastrad #include <drm/vmwgfx_drm.h> 35 1.1 riastrad #include "vmwgfx_kms.h" 36 1.2 riastrad #include "device_include/svga3d_caps.h" 37 1.2 riastrad 38 1.2 riastrad struct svga_3d_compat_cap { 39 1.2 riastrad SVGA3dCapsRecordHeader header; 40 1.2 riastrad SVGA3dCapPair pairs[SVGA3D_DEVCAP_MAX]; 41 1.2 riastrad }; 42 1.1 riastrad 43 1.1 riastrad int vmw_getparam_ioctl(struct drm_device *dev, void *data, 44 1.1 riastrad struct drm_file *file_priv) 45 1.1 riastrad { 46 1.1 riastrad struct vmw_private *dev_priv = vmw_priv(dev); 47 1.1 riastrad struct drm_vmw_getparam_arg *param = 48 1.1 riastrad (struct drm_vmw_getparam_arg *)data; 49 1.2 riastrad struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); 50 1.1 riastrad 51 1.1 riastrad switch (param->param) { 52 1.1 riastrad case DRM_VMW_PARAM_NUM_STREAMS: 53 1.1 riastrad param->value = vmw_overlay_num_overlays(dev_priv); 54 1.1 riastrad break; 55 1.1 riastrad case DRM_VMW_PARAM_NUM_FREE_STREAMS: 56 1.1 riastrad param->value = vmw_overlay_num_free_overlays(dev_priv); 57 1.1 riastrad break; 58 1.1 riastrad case DRM_VMW_PARAM_3D: 59 1.1 riastrad param->value = vmw_fifo_have_3d(dev_priv) ? 1 : 0; 60 1.1 riastrad break; 61 1.1 riastrad case DRM_VMW_PARAM_HW_CAPS: 62 1.1 riastrad param->value = dev_priv->capabilities; 63 1.1 riastrad break; 64 1.3 riastrad case DRM_VMW_PARAM_HW_CAPS2: 65 1.3 riastrad param->value = dev_priv->capabilities2; 66 1.3 riastrad break; 67 1.1 riastrad case DRM_VMW_PARAM_FIFO_CAPS: 68 1.1 riastrad param->value = dev_priv->fifo.capabilities; 69 1.1 riastrad break; 70 1.1 riastrad case DRM_VMW_PARAM_MAX_FB_SIZE: 71 1.2 riastrad param->value = dev_priv->prim_bb_mem; 72 1.1 riastrad break; 73 1.1 riastrad case DRM_VMW_PARAM_FIFO_HW_VERSION: 74 1.1 riastrad { 75 1.2 riastrad u32 *fifo_mem = dev_priv->mmio_virt; 76 1.1 riastrad const struct vmw_fifo_state *fifo = &dev_priv->fifo; 77 1.1 riastrad 78 1.2 riastrad if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS)) { 79 1.2 riastrad param->value = SVGA3D_HWVERSION_WS8_B1; 80 1.2 riastrad break; 81 1.2 riastrad } 82 1.2 riastrad 83 1.1 riastrad param->value = 84 1.2 riastrad vmw_mmio_read(fifo_mem + 85 1.2 riastrad ((fifo->capabilities & 86 1.2 riastrad SVGA_FIFO_CAP_3D_HWVERSION_REVISED) ? 87 1.2 riastrad SVGA_FIFO_3D_HWVERSION_REVISED : 88 1.2 riastrad SVGA_FIFO_3D_HWVERSION)); 89 1.1 riastrad break; 90 1.1 riastrad } 91 1.2 riastrad case DRM_VMW_PARAM_MAX_SURF_MEMORY: 92 1.2 riastrad if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS) && 93 1.2 riastrad !vmw_fp->gb_aware) 94 1.2 riastrad param->value = dev_priv->max_mob_pages * PAGE_SIZE / 2; 95 1.2 riastrad else 96 1.2 riastrad param->value = dev_priv->memory_size; 97 1.2 riastrad break; 98 1.2 riastrad case DRM_VMW_PARAM_3D_CAPS_SIZE: 99 1.2 riastrad if ((dev_priv->capabilities & SVGA_CAP_GBOBJECTS) && 100 1.2 riastrad vmw_fp->gb_aware) 101 1.2 riastrad param->value = SVGA3D_DEVCAP_MAX * sizeof(uint32_t); 102 1.2 riastrad else if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS) 103 1.2 riastrad param->value = sizeof(struct svga_3d_compat_cap) + 104 1.2 riastrad sizeof(uint32_t); 105 1.2 riastrad else 106 1.2 riastrad param->value = (SVGA_FIFO_3D_CAPS_LAST - 107 1.2 riastrad SVGA_FIFO_3D_CAPS + 1) * 108 1.2 riastrad sizeof(uint32_t); 109 1.2 riastrad break; 110 1.2 riastrad case DRM_VMW_PARAM_MAX_MOB_MEMORY: 111 1.2 riastrad vmw_fp->gb_aware = true; 112 1.2 riastrad param->value = dev_priv->max_mob_pages * PAGE_SIZE; 113 1.2 riastrad break; 114 1.2 riastrad case DRM_VMW_PARAM_MAX_MOB_SIZE: 115 1.2 riastrad param->value = dev_priv->max_mob_size; 116 1.2 riastrad break; 117 1.2 riastrad case DRM_VMW_PARAM_SCREEN_TARGET: 118 1.2 riastrad param->value = 119 1.2 riastrad (dev_priv->active_display_unit == vmw_du_screen_target); 120 1.2 riastrad break; 121 1.2 riastrad case DRM_VMW_PARAM_DX: 122 1.2 riastrad param->value = dev_priv->has_dx; 123 1.2 riastrad break; 124 1.3 riastrad case DRM_VMW_PARAM_SM4_1: 125 1.3 riastrad param->value = dev_priv->has_sm4_1; 126 1.3 riastrad break; 127 1.1 riastrad default: 128 1.1 riastrad return -EINVAL; 129 1.1 riastrad } 130 1.1 riastrad 131 1.1 riastrad return 0; 132 1.1 riastrad } 133 1.1 riastrad 134 1.2 riastrad static u32 vmw_mask_multisample(unsigned int cap, u32 fmt_value) 135 1.2 riastrad { 136 1.3 riastrad /* 137 1.3 riastrad * A version of user-space exists which use MULTISAMPLE_MASKABLESAMPLES 138 1.3 riastrad * to check the sample count supported by virtual device. Since there 139 1.3 riastrad * never was support for multisample count for backing MOB return 0. 140 1.3 riastrad */ 141 1.3 riastrad if (cap == SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES) 142 1.2 riastrad return 0; 143 1.2 riastrad 144 1.2 riastrad return fmt_value; 145 1.2 riastrad } 146 1.2 riastrad 147 1.2 riastrad static int vmw_fill_compat_cap(struct vmw_private *dev_priv, void *bounce, 148 1.2 riastrad size_t size) 149 1.2 riastrad { 150 1.2 riastrad struct svga_3d_compat_cap *compat_cap = 151 1.2 riastrad (struct svga_3d_compat_cap *) bounce; 152 1.2 riastrad unsigned int i; 153 1.2 riastrad size_t pair_offset = offsetof(struct svga_3d_compat_cap, pairs); 154 1.2 riastrad unsigned int max_size; 155 1.2 riastrad 156 1.2 riastrad if (size < pair_offset) 157 1.2 riastrad return -EINVAL; 158 1.2 riastrad 159 1.2 riastrad max_size = (size - pair_offset) / sizeof(SVGA3dCapPair); 160 1.2 riastrad 161 1.2 riastrad if (max_size > SVGA3D_DEVCAP_MAX) 162 1.2 riastrad max_size = SVGA3D_DEVCAP_MAX; 163 1.2 riastrad 164 1.2 riastrad compat_cap->header.length = 165 1.2 riastrad (pair_offset + max_size * sizeof(SVGA3dCapPair)) / sizeof(u32); 166 1.2 riastrad compat_cap->header.type = SVGA3DCAPS_RECORD_DEVCAPS; 167 1.2 riastrad 168 1.2 riastrad spin_lock(&dev_priv->cap_lock); 169 1.2 riastrad for (i = 0; i < max_size; ++i) { 170 1.2 riastrad vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); 171 1.2 riastrad compat_cap->pairs[i][0] = i; 172 1.2 riastrad compat_cap->pairs[i][1] = vmw_mask_multisample 173 1.2 riastrad (i, vmw_read(dev_priv, SVGA_REG_DEV_CAP)); 174 1.2 riastrad } 175 1.2 riastrad spin_unlock(&dev_priv->cap_lock); 176 1.2 riastrad 177 1.2 riastrad return 0; 178 1.2 riastrad } 179 1.2 riastrad 180 1.1 riastrad 181 1.1 riastrad int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data, 182 1.1 riastrad struct drm_file *file_priv) 183 1.1 riastrad { 184 1.1 riastrad struct drm_vmw_get_3d_cap_arg *arg = 185 1.1 riastrad (struct drm_vmw_get_3d_cap_arg *) data; 186 1.1 riastrad struct vmw_private *dev_priv = vmw_priv(dev); 187 1.1 riastrad uint32_t size; 188 1.2 riastrad u32 *fifo_mem; 189 1.1 riastrad void __user *buffer = (void __user *)((unsigned long)(arg->buffer)); 190 1.1 riastrad void *bounce; 191 1.1 riastrad int ret; 192 1.2 riastrad bool gb_objects = !!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS); 193 1.2 riastrad struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); 194 1.1 riastrad 195 1.2 riastrad if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) { 196 1.3 riastrad VMW_DEBUG_USER("Illegal GET_3D_CAP argument.\n"); 197 1.1 riastrad return -EINVAL; 198 1.1 riastrad } 199 1.1 riastrad 200 1.2 riastrad if (gb_objects && vmw_fp->gb_aware) 201 1.2 riastrad size = SVGA3D_DEVCAP_MAX * sizeof(uint32_t); 202 1.2 riastrad else if (gb_objects) 203 1.2 riastrad size = sizeof(struct svga_3d_compat_cap) + sizeof(uint32_t); 204 1.2 riastrad else 205 1.2 riastrad size = (SVGA_FIFO_3D_CAPS_LAST - SVGA_FIFO_3D_CAPS + 1) * 206 1.2 riastrad sizeof(uint32_t); 207 1.1 riastrad 208 1.1 riastrad if (arg->max_size < size) 209 1.1 riastrad size = arg->max_size; 210 1.1 riastrad 211 1.2 riastrad bounce = vzalloc(size); 212 1.1 riastrad if (unlikely(bounce == NULL)) { 213 1.1 riastrad DRM_ERROR("Failed to allocate bounce buffer for 3D caps.\n"); 214 1.1 riastrad return -ENOMEM; 215 1.1 riastrad } 216 1.1 riastrad 217 1.2 riastrad if (gb_objects && vmw_fp->gb_aware) { 218 1.2 riastrad int i, num; 219 1.2 riastrad uint32_t *bounce32 = (uint32_t *) bounce; 220 1.2 riastrad 221 1.2 riastrad num = size / sizeof(uint32_t); 222 1.2 riastrad if (num > SVGA3D_DEVCAP_MAX) 223 1.2 riastrad num = SVGA3D_DEVCAP_MAX; 224 1.2 riastrad 225 1.2 riastrad spin_lock(&dev_priv->cap_lock); 226 1.2 riastrad for (i = 0; i < num; ++i) { 227 1.2 riastrad vmw_write(dev_priv, SVGA_REG_DEV_CAP, i); 228 1.2 riastrad *bounce32++ = vmw_mask_multisample 229 1.2 riastrad (i, vmw_read(dev_priv, SVGA_REG_DEV_CAP)); 230 1.2 riastrad } 231 1.2 riastrad spin_unlock(&dev_priv->cap_lock); 232 1.2 riastrad } else if (gb_objects) { 233 1.2 riastrad ret = vmw_fill_compat_cap(dev_priv, bounce, size); 234 1.2 riastrad if (unlikely(ret != 0)) 235 1.2 riastrad goto out_err; 236 1.2 riastrad } else { 237 1.2 riastrad fifo_mem = dev_priv->mmio_virt; 238 1.2 riastrad memcpy(bounce, &fifo_mem[SVGA_FIFO_3D_CAPS], size); 239 1.2 riastrad } 240 1.1 riastrad 241 1.1 riastrad ret = copy_to_user(buffer, bounce, size); 242 1.1 riastrad if (ret) 243 1.1 riastrad ret = -EFAULT; 244 1.2 riastrad out_err: 245 1.1 riastrad vfree(bounce); 246 1.1 riastrad 247 1.1 riastrad if (unlikely(ret != 0)) 248 1.1 riastrad DRM_ERROR("Failed to report 3D caps info.\n"); 249 1.1 riastrad 250 1.1 riastrad return ret; 251 1.1 riastrad } 252 1.1 riastrad 253 1.1 riastrad int vmw_present_ioctl(struct drm_device *dev, void *data, 254 1.1 riastrad struct drm_file *file_priv) 255 1.1 riastrad { 256 1.1 riastrad struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; 257 1.1 riastrad struct vmw_private *dev_priv = vmw_priv(dev); 258 1.1 riastrad struct drm_vmw_present_arg *arg = 259 1.1 riastrad (struct drm_vmw_present_arg *)data; 260 1.1 riastrad struct vmw_surface *surface; 261 1.1 riastrad struct drm_vmw_rect __user *clips_ptr; 262 1.1 riastrad struct drm_vmw_rect *clips = NULL; 263 1.2 riastrad struct drm_framebuffer *fb; 264 1.1 riastrad struct vmw_framebuffer *vfb; 265 1.1 riastrad struct vmw_resource *res; 266 1.1 riastrad uint32_t num_clips; 267 1.1 riastrad int ret; 268 1.1 riastrad 269 1.1 riastrad num_clips = arg->num_clips; 270 1.2 riastrad clips_ptr = (struct drm_vmw_rect __user *)(unsigned long)arg->clips_ptr; 271 1.1 riastrad 272 1.1 riastrad if (unlikely(num_clips == 0)) 273 1.1 riastrad return 0; 274 1.1 riastrad 275 1.1 riastrad if (clips_ptr == NULL) { 276 1.3 riastrad VMW_DEBUG_USER("Variable clips_ptr must be specified.\n"); 277 1.1 riastrad ret = -EINVAL; 278 1.1 riastrad goto out_clips; 279 1.1 riastrad } 280 1.1 riastrad 281 1.1 riastrad clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); 282 1.1 riastrad if (clips == NULL) { 283 1.1 riastrad DRM_ERROR("Failed to allocate clip rect list.\n"); 284 1.1 riastrad ret = -ENOMEM; 285 1.1 riastrad goto out_clips; 286 1.1 riastrad } 287 1.1 riastrad 288 1.1 riastrad ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); 289 1.1 riastrad if (ret) { 290 1.1 riastrad DRM_ERROR("Failed to copy clip rects from userspace.\n"); 291 1.1 riastrad ret = -EFAULT; 292 1.1 riastrad goto out_no_copy; 293 1.1 riastrad } 294 1.1 riastrad 295 1.2 riastrad drm_modeset_lock_all(dev); 296 1.1 riastrad 297 1.3 riastrad fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); 298 1.2 riastrad if (!fb) { 299 1.3 riastrad VMW_DEBUG_USER("Invalid framebuffer id.\n"); 300 1.2 riastrad ret = -ENOENT; 301 1.1 riastrad goto out_no_fb; 302 1.1 riastrad } 303 1.2 riastrad vfb = vmw_framebuffer_to_vfb(fb); 304 1.1 riastrad 305 1.2 riastrad ret = ttm_read_lock(&dev_priv->reservation_sem, true); 306 1.1 riastrad if (unlikely(ret != 0)) 307 1.1 riastrad goto out_no_ttm_lock; 308 1.1 riastrad 309 1.1 riastrad ret = vmw_user_resource_lookup_handle(dev_priv, tfile, arg->sid, 310 1.1 riastrad user_surface_converter, 311 1.1 riastrad &res); 312 1.1 riastrad if (ret) 313 1.1 riastrad goto out_no_surface; 314 1.1 riastrad 315 1.1 riastrad surface = vmw_res_to_srf(res); 316 1.1 riastrad ret = vmw_kms_present(dev_priv, file_priv, 317 1.1 riastrad vfb, surface, arg->sid, 318 1.1 riastrad arg->dest_x, arg->dest_y, 319 1.1 riastrad clips, num_clips); 320 1.1 riastrad 321 1.1 riastrad /* vmw_user_surface_lookup takes one ref so does new_fb */ 322 1.1 riastrad vmw_surface_unreference(&surface); 323 1.1 riastrad 324 1.1 riastrad out_no_surface: 325 1.2 riastrad ttm_read_unlock(&dev_priv->reservation_sem); 326 1.1 riastrad out_no_ttm_lock: 327 1.3 riastrad drm_framebuffer_put(fb); 328 1.1 riastrad out_no_fb: 329 1.2 riastrad drm_modeset_unlock_all(dev); 330 1.1 riastrad out_no_copy: 331 1.1 riastrad kfree(clips); 332 1.1 riastrad out_clips: 333 1.1 riastrad return ret; 334 1.1 riastrad } 335 1.1 riastrad 336 1.1 riastrad int vmw_present_readback_ioctl(struct drm_device *dev, void *data, 337 1.1 riastrad struct drm_file *file_priv) 338 1.1 riastrad { 339 1.1 riastrad struct vmw_private *dev_priv = vmw_priv(dev); 340 1.1 riastrad struct drm_vmw_present_readback_arg *arg = 341 1.1 riastrad (struct drm_vmw_present_readback_arg *)data; 342 1.1 riastrad struct drm_vmw_fence_rep __user *user_fence_rep = 343 1.1 riastrad (struct drm_vmw_fence_rep __user *) 344 1.1 riastrad (unsigned long)arg->fence_rep; 345 1.1 riastrad struct drm_vmw_rect __user *clips_ptr; 346 1.1 riastrad struct drm_vmw_rect *clips = NULL; 347 1.2 riastrad struct drm_framebuffer *fb; 348 1.1 riastrad struct vmw_framebuffer *vfb; 349 1.1 riastrad uint32_t num_clips; 350 1.1 riastrad int ret; 351 1.1 riastrad 352 1.1 riastrad num_clips = arg->num_clips; 353 1.2 riastrad clips_ptr = (struct drm_vmw_rect __user *)(unsigned long)arg->clips_ptr; 354 1.1 riastrad 355 1.1 riastrad if (unlikely(num_clips == 0)) 356 1.1 riastrad return 0; 357 1.1 riastrad 358 1.1 riastrad if (clips_ptr == NULL) { 359 1.3 riastrad VMW_DEBUG_USER("Argument clips_ptr must be specified.\n"); 360 1.1 riastrad ret = -EINVAL; 361 1.1 riastrad goto out_clips; 362 1.1 riastrad } 363 1.1 riastrad 364 1.1 riastrad clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); 365 1.1 riastrad if (clips == NULL) { 366 1.1 riastrad DRM_ERROR("Failed to allocate clip rect list.\n"); 367 1.1 riastrad ret = -ENOMEM; 368 1.1 riastrad goto out_clips; 369 1.1 riastrad } 370 1.1 riastrad 371 1.1 riastrad ret = copy_from_user(clips, clips_ptr, num_clips * sizeof(*clips)); 372 1.1 riastrad if (ret) { 373 1.1 riastrad DRM_ERROR("Failed to copy clip rects from userspace.\n"); 374 1.1 riastrad ret = -EFAULT; 375 1.1 riastrad goto out_no_copy; 376 1.1 riastrad } 377 1.1 riastrad 378 1.2 riastrad drm_modeset_lock_all(dev); 379 1.1 riastrad 380 1.3 riastrad fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id); 381 1.2 riastrad if (!fb) { 382 1.3 riastrad VMW_DEBUG_USER("Invalid framebuffer id.\n"); 383 1.2 riastrad ret = -ENOENT; 384 1.1 riastrad goto out_no_fb; 385 1.1 riastrad } 386 1.1 riastrad 387 1.2 riastrad vfb = vmw_framebuffer_to_vfb(fb); 388 1.3 riastrad if (!vfb->bo) { 389 1.3 riastrad VMW_DEBUG_USER("Framebuffer not buffer backed.\n"); 390 1.1 riastrad ret = -EINVAL; 391 1.2 riastrad goto out_no_ttm_lock; 392 1.1 riastrad } 393 1.1 riastrad 394 1.2 riastrad ret = ttm_read_lock(&dev_priv->reservation_sem, true); 395 1.1 riastrad if (unlikely(ret != 0)) 396 1.1 riastrad goto out_no_ttm_lock; 397 1.1 riastrad 398 1.1 riastrad ret = vmw_kms_readback(dev_priv, file_priv, 399 1.1 riastrad vfb, user_fence_rep, 400 1.1 riastrad clips, num_clips); 401 1.1 riastrad 402 1.2 riastrad ttm_read_unlock(&dev_priv->reservation_sem); 403 1.1 riastrad out_no_ttm_lock: 404 1.3 riastrad drm_framebuffer_put(fb); 405 1.1 riastrad out_no_fb: 406 1.2 riastrad drm_modeset_unlock_all(dev); 407 1.1 riastrad out_no_copy: 408 1.1 riastrad kfree(clips); 409 1.1 riastrad out_clips: 410 1.1 riastrad return ret; 411 1.1 riastrad } 412 1.1 riastrad 413 1.1 riastrad 414 1.4 riastrad #ifndef __NetBSD__ /* XXX vmwgfx fops ping */ 415 1.4 riastrad 416 1.1 riastrad /** 417 1.1 riastrad * vmw_fops_poll - wrapper around the drm_poll function 418 1.1 riastrad * 419 1.1 riastrad * @filp: See the linux fops poll documentation. 420 1.1 riastrad * @wait: See the linux fops poll documentation. 421 1.1 riastrad * 422 1.1 riastrad * Wrapper around the drm_poll function that makes sure the device is 423 1.1 riastrad * processing the fifo if drm_poll decides to wait. 424 1.1 riastrad */ 425 1.3 riastrad __poll_t vmw_fops_poll(struct file *filp, struct poll_table_struct *wait) 426 1.1 riastrad { 427 1.1 riastrad struct drm_file *file_priv = filp->private_data; 428 1.1 riastrad struct vmw_private *dev_priv = 429 1.1 riastrad vmw_priv(file_priv->minor->dev); 430 1.1 riastrad 431 1.1 riastrad vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); 432 1.1 riastrad return drm_poll(filp, wait); 433 1.1 riastrad } 434 1.1 riastrad 435 1.1 riastrad 436 1.1 riastrad /** 437 1.1 riastrad * vmw_fops_read - wrapper around the drm_read function 438 1.1 riastrad * 439 1.1 riastrad * @filp: See the linux fops read documentation. 440 1.1 riastrad * @buffer: See the linux fops read documentation. 441 1.1 riastrad * @count: See the linux fops read documentation. 442 1.1 riastrad * offset: See the linux fops read documentation. 443 1.1 riastrad * 444 1.1 riastrad * Wrapper around the drm_read function that makes sure the device is 445 1.1 riastrad * processing the fifo if drm_read decides to wait. 446 1.1 riastrad */ 447 1.1 riastrad ssize_t vmw_fops_read(struct file *filp, char __user *buffer, 448 1.1 riastrad size_t count, loff_t *offset) 449 1.1 riastrad { 450 1.1 riastrad struct drm_file *file_priv = filp->private_data; 451 1.1 riastrad struct vmw_private *dev_priv = 452 1.1 riastrad vmw_priv(file_priv->minor->dev); 453 1.1 riastrad 454 1.1 riastrad vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); 455 1.1 riastrad return drm_read(filp, buffer, count, offset); 456 1.1 riastrad } 457 1.4 riastrad 458 1.4 riastrad #endif /* __NetBSD__ */ 459