底层驱动开发

源代码在线查看: r128_ioc32.c

软件大小: 49318 K
上传用户: pj117
关键词: 底层 驱动开发
下载地址: 免注册下载 普通下载 VIP

相关代码

				/**				 * \file r128_ioc32.c				 *				 * 32-bit ioctl compatibility routines for the R128 DRM.				 *				 * \author Dave Airlie  with code from patches by Egbert Eich				 *				 * Copyright (C) Paul Mackerras 2005				 * Copyright (C) Egbert Eich 2003,2004				 * Copyright (C) Dave Airlie 2005				 * All Rights Reserved.				 *				 * Permission is hereby granted, free of charge, to any person obtaining a				 * copy of this software and associated documentation files (the "Software"),				 * to deal in the Software without restriction, including without limitation				 * the rights to use, copy, modify, merge, publish, distribute, sublicense,				 * and/or sell copies of the Software, and to permit persons to whom the				 * Software is furnished to do so, subject to the following conditions:				 *				 * The above copyright notice and this permission notice (including the next				 * paragraph) shall be included in all copies or substantial portions of the				 * Software.				 *				 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR				 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,				 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL				 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,				 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,				 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS				 * IN THE SOFTWARE.				 */				#include 				#include 								#include "drmP.h"				#include "drm.h"				#include "r128_drm.h"								typedef struct drm_r128_init32 {					int func;					unsigned int sarea_priv_offset;					int is_pci;					int cce_mode;					int cce_secure;					int ring_size;					int usec_timeout;									unsigned int fb_bpp;					unsigned int front_offset, front_pitch;					unsigned int back_offset, back_pitch;					unsigned int depth_bpp;					unsigned int depth_offset, depth_pitch;					unsigned int span_offset;									unsigned int fb_offset;					unsigned int mmio_offset;					unsigned int ring_offset;					unsigned int ring_rptr_offset;					unsigned int buffers_offset;					unsigned int agp_textures_offset;				} drm_r128_init32_t;								static int compat_r128_init(struct file *file, unsigned int cmd,							    unsigned long arg)				{					drm_r128_init32_t init32;					drm_r128_init_t __user *init;										if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))						return -EFAULT;										init = compat_alloc_user_space(sizeof(*init));					if (!access_ok(VERIFY_WRITE, init, sizeof(*init))					    || __put_user(init32.func, &init->func)					    || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)					    || __put_user(init32.is_pci, &init->is_pci)					    || __put_user(init32.cce_mode, &init->cce_mode)					    || __put_user(init32.cce_secure, &init->cce_secure)					    || __put_user(init32.ring_size, &init->ring_size)					    || __put_user(init32.usec_timeout, &init->usec_timeout)					    || __put_user(init32.fb_bpp, &init->fb_bpp)					    || __put_user(init32.front_offset, &init->front_offset)					    || __put_user(init32.front_pitch, &init->front_pitch)					    || __put_user(init32.back_offset, &init->back_offset)					    || __put_user(init32.back_pitch, &init->back_pitch)					    || __put_user(init32.depth_bpp, &init->depth_bpp)					    || __put_user(init32.depth_offset, &init->depth_offset)					    || __put_user(init32.depth_pitch, &init->depth_pitch)					    || __put_user(init32.span_offset, &init->span_offset)					    || __put_user(init32.fb_offset, &init->fb_offset)					    || __put_user(init32.mmio_offset, &init->mmio_offset)					    || __put_user(init32.ring_offset, &init->ring_offset)					    || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)					    || __put_user(init32.buffers_offset, &init->buffers_offset)					    || __put_user(init32.agp_textures_offset, &init->agp_textures_offset))						return -EFAULT;										return drm_ioctl(file->f_dentry->d_inode, file,							 DRM_IOCTL_R128_INIT, (unsigned long)init);				}												typedef struct drm_r128_depth32 {					int func;					int n;					u32 x;					u32 y;					u32 buffer;					u32 mask;				} drm_r128_depth32_t;								static int compat_r128_depth(struct file *file, unsigned int cmd,							     unsigned long arg)				{					drm_r128_depth32_t depth32;					drm_r128_depth_t __user *depth;									if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))						return -EFAULT;									depth = compat_alloc_user_space(sizeof(*depth));					if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth))					    || __put_user(depth32.func, &depth->func)					    || __put_user(depth32.n, &depth->n)					    || __put_user((int __user *)(unsigned long)depth32.x, &depth->x)					    || __put_user((int __user *)(unsigned long)depth32.y, &depth->y)					    || __put_user((unsigned int __user *)(unsigned long)depth32.buffer, &depth->buffer)					    || __put_user((unsigned char __user *)(unsigned long)depth32.mask, &depth->mask))						return -EFAULT;										return drm_ioctl(file->f_dentry->d_inode, file,							 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);										}								typedef struct drm_r128_stipple32 {					u32 mask;				} drm_r128_stipple32_t;								static int compat_r128_stipple(struct file *file, unsigned int cmd,							       unsigned long arg)				{					drm_r128_stipple32_t stipple32;					drm_r128_stipple_t __user *stipple;									if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))						return -EFAULT;									stipple = compat_alloc_user_space(sizeof(*stipple));					if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))					    || __put_user((unsigned int __user *)(unsigned long)stipple32.mask, &stipple->mask))						return -EFAULT;									return drm_ioctl(file->f_dentry->d_inode, file,							 DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);				}								typedef struct drm_r128_getparam32 {					int param;					u32 value;				} drm_r128_getparam32_t;								static int compat_r128_getparam(struct file *file, unsigned int cmd,								unsigned long arg)				{					drm_r128_getparam32_t getparam32;					drm_r128_getparam_t __user *getparam;									if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))						return -EFAULT;									getparam = compat_alloc_user_space(sizeof(*getparam));					if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))					    || __put_user(getparam32.param, &getparam->param)					    || __put_user((void __user *)(unsigned long)getparam32.value, &getparam->value))						return -EFAULT;										return drm_ioctl(file->f_dentry->d_inode, file,							 DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);				}								drm_ioctl_compat_t *r128_compat_ioctls[] = {					[DRM_R128_INIT] = compat_r128_init,					[DRM_R128_DEPTH] = compat_r128_depth,					[DRM_R128_STIPPLE] = compat_r128_stipple,					[DRM_R128_GETPARAM] = compat_r128_getparam,				};								/**				 * Called whenever a 32-bit process running under a 64-bit kernel				 * performs an ioctl on /dev/dri/card.				 *				 * \param filp file pointer.				 * \param cmd command.				 * \param arg user argument.				 * \return zero on success or negative number on failure.				 */				long r128_compat_ioctl(struct file *filp, unsigned int cmd,							 unsigned long arg)				{					unsigned int nr = DRM_IOCTL_NR(cmd);					drm_ioctl_compat_t *fn = NULL;					int ret;									if (nr < DRM_COMMAND_BASE)						return drm_compat_ioctl(filp, cmd, arg);									if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls))						fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];									lock_kernel();		/* XXX for now */					if (fn != NULL)						ret = (*fn)(filp, cmd, arg);					else						ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);					unlock_kernel();									return ret;				}							

相关资源