📄 drm_ioc32.c
字号:
/** * \file drm_ioc32.c * * 32-bit ioctl compatibility routines for the DRM. * * \author Paul Mackerras <paulus@samba.org> * * Copyright (C) Paul Mackerras 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 <linux/compat.h>#include <linux/ioctl32.h>#include "drmP.h"#include "drm_core.h"#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t)#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t)#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t)#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t)#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t)#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t)#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t)#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t)#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t)#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t)#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t)#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t)#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t)#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t)#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t)#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t)#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t)#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t)#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t)#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t)#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t)#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t)#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t)#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)typedef struct drm_version_32 { int version_major; /**< Major version */ int version_minor; /**< Minor version */ int version_patchlevel; /**< Patch level */ u32 name_len; /**< Length of name buffer */ u32 name; /**< Name of driver */ u32 date_len; /**< Length of date buffer */ u32 date; /**< User-space buffer to hold date */ u32 desc_len; /**< Length of desc buffer */ u32 desc; /**< User-space buffer to hold desc */} drm_version32_t;static int compat_drm_version(struct file *file, unsigned int cmd, unsigned long arg){ drm_version32_t v32; drm_version_t __user *version; int err; if (copy_from_user(&v32, (void __user *)arg, sizeof(v32))) return -EFAULT; version = compat_alloc_user_space(sizeof(*version)); if (!access_ok(VERIFY_WRITE, version, sizeof(*version))) return -EFAULT; if (__put_user(v32.name_len, &version->name_len) || __put_user((void __user *)(unsigned long)v32.name, &version->name) || __put_user(v32.date_len, &version->date_len) || __put_user((void __user *)(unsigned long)v32.date, &version->date) || __put_user(v32.desc_len, &version->desc_len) || __put_user((void __user *)(unsigned long)v32.desc, &version->desc)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_VERSION, (unsigned long)version); if (err) return err; if (__get_user(v32.version_major, &version->version_major) || __get_user(v32.version_minor, &version->version_minor) || __get_user(v32.version_patchlevel, &version->version_patchlevel) || __get_user(v32.name_len, &version->name_len) || __get_user(v32.date_len, &version->date_len) || __get_user(v32.desc_len, &version->desc_len)) return -EFAULT; if (copy_to_user((void __user *)arg, &v32, sizeof(v32))) return -EFAULT; return 0;}typedef struct drm_unique32 { u32 unique_len; /**< Length of unique */ u32 unique; /**< Unique name for driver instantiation */} drm_unique32_t;static int compat_drm_getunique(struct file *file, unsigned int cmd, unsigned long arg){ drm_unique32_t uq32; drm_unique_t __user *u; int err; if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; u = compat_alloc_user_space(sizeof(*u)); if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) return -EFAULT; if (__put_user(uq32.unique_len, &u->unique_len) || __put_user((void __user *)(unsigned long)uq32.unique, &u->unique)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_GET_UNIQUE, (unsigned long)u); if (err) return err; if (__get_user(uq32.unique_len, &u->unique_len)) return -EFAULT; if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32))) return -EFAULT; return 0;}static int compat_drm_setunique(struct file *file, unsigned int cmd, unsigned long arg){ drm_unique32_t uq32; drm_unique_t __user *u; if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32))) return -EFAULT; u = compat_alloc_user_space(sizeof(*u)); if (!access_ok(VERIFY_WRITE, u, sizeof(*u))) return -EFAULT; if (__put_user(uq32.unique_len, &u->unique_len) || __put_user((void __user *)(unsigned long)uq32.unique, &u->unique)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_SET_UNIQUE, (unsigned long)u);}typedef struct drm_map32 { u32 offset; /**< Requested physical address (0 for SAREA)*/ u32 size; /**< Requested physical size (bytes) */ drm_map_type_t type; /**< Type of memory to map */ drm_map_flags_t flags; /**< Flags */ u32 handle; /**< User-space: "Handle" to pass to mmap() */ int mtrr; /**< MTRR slot used */} drm_map32_t;static int compat_drm_getmap(struct file *file, unsigned int cmd, unsigned long arg){ drm_map32_t __user *argp = (void __user *)arg; drm_map32_t m32; drm_map_t __user *map; int idx, err; void *handle; if (get_user(idx, &argp->offset)) return -EFAULT; map = compat_alloc_user_space(sizeof(*map)); if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) return -EFAULT; if (__put_user(idx, &map->offset)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_GET_MAP, (unsigned long)map); if (err) return err; if (__get_user(m32.offset, &map->offset) || __get_user(m32.size, &map->size) || __get_user(m32.type, &map->type) || __get_user(m32.flags, &map->flags) || __get_user(handle, &map->handle) || __get_user(m32.mtrr, &map->mtrr)) return -EFAULT; m32.handle = (unsigned long)handle; if (copy_to_user(argp, &m32, sizeof(m32))) return -EFAULT; return 0;}static int compat_drm_addmap(struct file *file, unsigned int cmd, unsigned long arg){ drm_map32_t __user *argp = (void __user *)arg; drm_map32_t m32; drm_map_t __user *map; int err; void *handle; if (copy_from_user(&m32, argp, sizeof(m32))) return -EFAULT; map = compat_alloc_user_space(sizeof(*map)); if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) return -EFAULT; if (__put_user(m32.offset, &map->offset) || __put_user(m32.size, &map->size) || __put_user(m32.type, &map->type) || __put_user(m32.flags, &map->flags)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_ADD_MAP, (unsigned long)map); if (err) return err; if (__get_user(m32.offset, &map->offset) || __get_user(m32.mtrr, &map->mtrr) || __get_user(handle, &map->handle)) return -EFAULT; m32.handle = (unsigned long)handle; if (m32.handle != (unsigned long)handle && printk_ratelimit()) printk(KERN_ERR "compat_drm_addmap truncated handle" " %p for type %d offset %x\n", handle, m32.type, m32.offset); if (copy_to_user(argp, &m32, sizeof(m32))) return -EFAULT; return 0;}static int compat_drm_rmmap(struct file *file, unsigned int cmd, unsigned long arg){ drm_map32_t __user *argp = (void __user *)arg; drm_map_t __user *map; u32 handle; if (get_user(handle, &argp->handle)) return -EFAULT; map = compat_alloc_user_space(sizeof(*map)); if (!access_ok(VERIFY_WRITE, map, sizeof(*map))) return -EFAULT; if (__put_user((void *)(unsigned long)handle, &map->handle)) return -EFAULT; return drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_RM_MAP, (unsigned long)map);}typedef struct drm_client32 { int idx; /**< Which client desired? */ int auth; /**< Is client authenticated? */ u32 pid; /**< Process ID */ u32 uid; /**< User ID */ u32 magic; /**< Magic */ u32 iocs; /**< Ioctl count */} drm_client32_t;static int compat_drm_getclient(struct file *file, unsigned int cmd, unsigned long arg){ drm_client32_t c32; drm_client32_t __user *argp = (void __user *)arg; drm_client_t __user *client; int idx, err; if (get_user(idx, &argp->idx)) return -EFAULT; client = compat_alloc_user_space(sizeof(*client)); if (!access_ok(VERIFY_WRITE, client, sizeof(*client))) return -EFAULT; if (__put_user(idx, &client->idx)) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_GET_CLIENT, (unsigned long)client); if (err) return err; if (__get_user(c32.auth, &client->auth) || __get_user(c32.pid, &client->pid) || __get_user(c32.uid, &client->uid) || __get_user(c32.magic, &client->magic) || __get_user(c32.iocs, &client->iocs)) return -EFAULT; if (copy_to_user(argp, &c32, sizeof(c32))) return -EFAULT; return 0;}typedef struct drm_stats32 { u32 count; struct { u32 value; drm_stat_type_t type; } data[15];} drm_stats32_t;static int compat_drm_getstats(struct file *file, unsigned int cmd, unsigned long arg){ drm_stats32_t s32; drm_stats32_t __user *argp = (void __user *)arg; drm_stats_t __user *stats; int i, err; stats = compat_alloc_user_space(sizeof(*stats)); if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) return -EFAULT; err = drm_ioctl(file->f_dentry->d_inode, file, DRM_IOCTL_GET_STATS, (unsigned long)stats); if (err) return err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -