11.2Sriastrad/*	$NetBSD: i915_ioc32.c,v 1.3 2021/12/18 23:45:28 riastradh Exp $	*/
21.2Sriastrad
31.3Sriastrad/*
41.1Sriastrad * 32-bit ioctl compatibility routines for the i915 DRM.
51.1Sriastrad *
61.1Sriastrad * Copyright (C) Paul Mackerras 2005
71.1Sriastrad * Copyright (C) Alan Hourihane 2005
81.1Sriastrad * All Rights Reserved.
91.1Sriastrad *
101.1Sriastrad * Permission is hereby granted, free of charge, to any person obtaining a
111.1Sriastrad * copy of this software and associated documentation files (the "Software"),
121.1Sriastrad * to deal in the Software without restriction, including without limitation
131.1Sriastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense,
141.1Sriastrad * and/or sell copies of the Software, and to permit persons to whom the
151.1Sriastrad * Software is furnished to do so, subject to the following conditions:
161.1Sriastrad *
171.1Sriastrad * The above copyright notice and this permission notice (including the next
181.1Sriastrad * paragraph) shall be included in all copies or substantial portions of the
191.1Sriastrad * Software.
201.1Sriastrad *
211.1Sriastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
221.1Sriastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
231.1Sriastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
241.1Sriastrad * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
251.1Sriastrad * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
261.1Sriastrad * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
271.1Sriastrad * IN THE SOFTWARE.
281.3Sriastrad *
291.3Sriastrad * Author: Alan Hourihane <alanh@fairlite.demon.co.uk>
301.1Sriastrad */
311.2Sriastrad#include <sys/cdefs.h>
321.2Sriastrad__KERNEL_RCSID(0, "$NetBSD: i915_ioc32.c,v 1.3 2021/12/18 23:45:28 riastradh Exp $");
331.2Sriastrad
341.1Sriastrad#include <linux/compat.h>
351.1Sriastrad
361.1Sriastrad#include <drm/i915_drm.h>
371.3Sriastrad#include <drm/drm_ioctl.h>
381.1Sriastrad#include "i915_drv.h"
391.1Sriastrad
401.2Sriastradstruct drm_i915_getparam32 {
411.2Sriastrad	s32 param;
421.2Sriastrad	/*
431.2Sriastrad	 * We screwed up the generic ioctl struct here and used a variable-sized
441.2Sriastrad	 * pointer. Use u32 in the compat struct to match the 32bit pointer
451.2Sriastrad	 * userspace expects.
461.2Sriastrad	 */
471.1Sriastrad	u32 value;
481.2Sriastrad};
491.1Sriastrad
501.1Sriastradstatic int compat_i915_getparam(struct file *file, unsigned int cmd,
511.1Sriastrad				unsigned long arg)
521.1Sriastrad{
531.2Sriastrad	struct drm_i915_getparam32 req32;
541.1Sriastrad	drm_i915_getparam_t __user *request;
551.1Sriastrad
561.1Sriastrad	if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
571.1Sriastrad		return -EFAULT;
581.1Sriastrad
591.1Sriastrad	request = compat_alloc_user_space(sizeof(*request));
601.3Sriastrad	if (!access_ok(request, sizeof(*request)) ||
611.3Sriastrad	    __put_user(req32.param, &request->param) ||
621.3Sriastrad	    __put_user((void __user *)(unsigned long)req32.value,
631.3Sriastrad		       &request->value))
641.1Sriastrad		return -EFAULT;
651.1Sriastrad
661.1Sriastrad	return drm_ioctl(file, DRM_IOCTL_I915_GETPARAM,
671.1Sriastrad			 (unsigned long)request);
681.1Sriastrad}
691.1Sriastrad
701.1Sriastradstatic drm_ioctl_compat_t *i915_compat_ioctls[] = {
711.1Sriastrad	[DRM_I915_GETPARAM] = compat_i915_getparam,
721.1Sriastrad};
731.1Sriastrad
741.1Sriastrad/**
751.3Sriastrad * i915_compat_ioctl - handle the mistakes of the past
761.3Sriastrad * @filp: the file pointer
771.3Sriastrad * @cmd: the ioctl command (and encoded flags)
781.3Sriastrad * @arg: the ioctl argument (from userspace)
791.3Sriastrad *
801.1Sriastrad * Called whenever a 32-bit process running under a 64-bit kernel
811.1Sriastrad * performs an ioctl on /dev/dri/card<n>.
821.1Sriastrad */
831.1Sriastradlong i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
841.1Sriastrad{
851.1Sriastrad	unsigned int nr = DRM_IOCTL_NR(cmd);
861.1Sriastrad	drm_ioctl_compat_t *fn = NULL;
871.1Sriastrad	int ret;
881.1Sriastrad
891.2Sriastrad	if (nr < DRM_COMMAND_BASE || nr >= DRM_COMMAND_END)
901.1Sriastrad		return drm_compat_ioctl(filp, cmd, arg);
911.1Sriastrad
921.2Sriastrad	if (nr < DRM_COMMAND_BASE + ARRAY_SIZE(i915_compat_ioctls))
931.1Sriastrad		fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
941.1Sriastrad
951.1Sriastrad	if (fn != NULL)
961.1Sriastrad		ret = (*fn) (filp, cmd, arg);
971.1Sriastrad	else
981.1Sriastrad		ret = drm_ioctl(filp, cmd, arg);
991.1Sriastrad
1001.1Sriastrad	return ret;
1011.1Sriastrad}
102