ioctl32.c
来自「h内核」· C语言 代码 · 共 599 行 · 第 1/2 页
C
599 行
return sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long)p);}typedef struct drm32_buf_pub { int idx; /* Index into master buflist */ int total; /* Buffer size */ int used; /* Amount of buffer in use (for DMA) */ u32 address; /* Address of buffer (void *) */} drm32_buf_pub_t;typedef struct drm32_buf_map { int count; /* Length of buflist */ u32 virtual; /* Mmaped area in user-virtual (void *) */ u32 list; /* Buffer information (drm_buf_pub_t *) */} drm32_buf_map_t;#define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t)static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg){ drm32_buf_map_t __user *uarg = (drm32_buf_map_t __user *)arg; drm32_buf_pub_t __user *ulist; drm_buf_map_t __user *arg64; drm_buf_pub_t __user *list; int orig_count, ret, i; int n; compat_uptr_t addr; if (get_user(orig_count, &uarg->count)) return -EFAULT; arg64 = compat_alloc_user_space(sizeof(drm_buf_map_t) + (size_t)orig_count * sizeof(drm_buf_pub_t)); list = (void __user *)(arg64 + 1); if (put_user(orig_count, &arg64->count) || put_user(list, &arg64->list) || get_user(addr, &uarg->virtual) || put_user(compat_ptr(addr), &arg64->virtual) || get_user(addr, &uarg->list)) return -EFAULT; ulist = compat_ptr(addr); for (i = 0; i < orig_count; i++) { if (get_user(n, &ulist[i].idx) || put_user(n, &list[i].idx) || get_user(n, &ulist[i].total) || put_user(n, &list[i].total) || get_user(n, &ulist[i].used) || put_user(n, &list[i].used) || get_user(addr, &ulist[i].address) || put_user(compat_ptr(addr), &list[i].address)) return -EFAULT; } ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) arg64); if (ret) return ret; for (i = 0; i < orig_count; i++) { void __user *p; if (get_user(n, &list[i].idx) || put_user(n, &ulist[i].idx) || get_user(n, &list[i].total) || put_user(n, &ulist[i].total) || get_user(n, &list[i].used) || put_user(n, &ulist[i].used) || get_user(p, &list[i].address) || put_user((unsigned long)p, &ulist[i].address)) return -EFAULT; } if (get_user(n, &arg64->count) || put_user(n, &uarg->count)) return -EFAULT; return 0;}typedef struct drm32_dma { /* Indices here refer to the offset into buflist in drm_buf_get_t. */ int context; /* Context handle */ int send_count; /* Number of buffers to send */ u32 send_indices; /* List of handles to buffers (int *) */ u32 send_sizes; /* Lengths of data to send (int *) */ drm_dma_flags_t flags; /* Flags */ int request_count; /* Number of buffers requested */ int request_size; /* Desired size for buffers */ u32 request_indices; /* Buffer information (int *) */ u32 request_sizes; /* (int *) */ int granted_count; /* Number of buffers granted */} drm32_dma_t;#define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t)/* RED PEN The DRM layer blindly dereferences the send/request * index/size arrays even though they are userland * pointers. -DaveM */static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg){ drm32_dma_t __user *uarg = (drm32_dma_t __user *) arg; drm_dma_t __user *p = compat_alloc_user_space(sizeof(*p)); compat_uptr_t addr; int ret; if (copy_in_user(p, uarg, 2 * sizeof(int)) || get_user(addr, &uarg->send_indices) || put_user(compat_ptr(addr), &p->send_indices) || get_user(addr, &uarg->send_sizes) || put_user(compat_ptr(addr), &p->send_sizes) || copy_in_user(&p->flags, &uarg->flags, sizeof(drm_dma_flags_t)) || copy_in_user(&p->request_count, &uarg->request_count, sizeof(int))|| copy_in_user(&p->request_size, &uarg->request_size, sizeof(int)) || get_user(addr, &uarg->request_indices) || put_user(compat_ptr(addr), &p->request_indices) || get_user(addr, &uarg->request_sizes) || put_user(compat_ptr(addr), &p->request_sizes) || copy_in_user(&p->granted_count, &uarg->granted_count, sizeof(int))) return -EFAULT; ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long)p); if (ret) return ret; if (copy_in_user(uarg, p, 2 * sizeof(int)) || copy_in_user(&uarg->flags, &p->flags, sizeof(drm_dma_flags_t)) || copy_in_user(&uarg->request_count, &p->request_count, sizeof(int))|| copy_in_user(&uarg->request_size, &p->request_size, sizeof(int)) || copy_in_user(&uarg->granted_count, &p->granted_count, sizeof(int))) return -EFAULT; return 0;}typedef struct drm32_ctx_res { int count; u32 contexts; /* (drm_ctx_t *) */} drm32_ctx_res_t;#define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t)static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg){ drm32_ctx_res_t __user *uarg = (drm32_ctx_res_t __user *) arg; drm_ctx_res_t __user *p = compat_alloc_user_space(sizeof(*p)); compat_uptr_t addr; int ret; if (copy_in_user(p, uarg, sizeof(int)) || get_user(addr, &uarg->contexts) || put_user(compat_ptr(addr), &p->contexts)) return -EFAULT; ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long)p); if (ret) return ret; if (copy_in_user(uarg, p, sizeof(int))) return -EFAULT; return 0;}#endiftypedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl)#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl32_handler_t)(handler), NULL },#define IOCTL_TABLE_START \ struct ioctl_trans ioctl_start[] = {#define IOCTL_TABLE_END \ };IOCTL_TABLE_START#include <linux/compat_ioctl.h>#define DECLARES#include "compat_ioctl.c"COMPATIBLE_IOCTL(TCSBRKP)COMPATIBLE_IOCTL(TIOCSTART)COMPATIBLE_IOCTL(TIOCSTOP)COMPATIBLE_IOCTL(TIOCSLTC)COMPATIBLE_IOCTL(FBIOGTYPE)COMPATIBLE_IOCTL(FBIOSATTR)COMPATIBLE_IOCTL(FBIOGATTR)COMPATIBLE_IOCTL(FBIOSVIDEO)COMPATIBLE_IOCTL(FBIOGVIDEO)COMPATIBLE_IOCTL(FBIOGCURSOR32) /* This is not implemented yet. Later it should be converted... */COMPATIBLE_IOCTL(FBIOSCURPOS)COMPATIBLE_IOCTL(FBIOGCURPOS)COMPATIBLE_IOCTL(FBIOGCURMAX)/* Little k */COMPATIBLE_IOCTL(KIOCTYPE)COMPATIBLE_IOCTL(KIOCLAYOUT)COMPATIBLE_IOCTL(KIOCGTRANS)COMPATIBLE_IOCTL(KIOCTRANS)COMPATIBLE_IOCTL(KIOCCMD)COMPATIBLE_IOCTL(KIOCSDIRECT)COMPATIBLE_IOCTL(KIOCSLED)COMPATIBLE_IOCTL(KIOCGLED)COMPATIBLE_IOCTL(KIOCSRATE)COMPATIBLE_IOCTL(KIOCGRATE)COMPATIBLE_IOCTL(VUIDSFORMAT)COMPATIBLE_IOCTL(VUIDGFORMAT)/* Little v, the video4linux ioctls */COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE)COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE)COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE)COMPATIBLE_IOCTL(ENVCTRL_RD_FAN_STATUS)COMPATIBLE_IOCTL(ENVCTRL_RD_VOLTAGE_STATUS)COMPATIBLE_IOCTL(ENVCTRL_RD_SCSI_TEMPERATURE)COMPATIBLE_IOCTL(ENVCTRL_RD_ETHERNET_TEMPERATURE)COMPATIBLE_IOCTL(ENVCTRL_RD_MTHRBD_TEMPERATURE)COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_VOLTAGE)COMPATIBLE_IOCTL(ENVCTRL_RD_GLOBALADDRESS)/* COMPATIBLE_IOCTL(D7SIOCRD) same value as ENVCTRL_RD_VOLTAGE_STATUS */COMPATIBLE_IOCTL(D7SIOCWR)COMPATIBLE_IOCTL(D7SIOCTM)/* OPENPROMIO, SunOS/Solaris only, the NetBSD one's have * embedded pointers in the arg which we'd need to clean up... */COMPATIBLE_IOCTL(OPROMGETOPT)COMPATIBLE_IOCTL(OPROMSETOPT)COMPATIBLE_IOCTL(OPROMNXTOPT)COMPATIBLE_IOCTL(OPROMSETOPT2)COMPATIBLE_IOCTL(OPROMNEXT)COMPATIBLE_IOCTL(OPROMCHILD)COMPATIBLE_IOCTL(OPROMGETPROP)COMPATIBLE_IOCTL(OPROMNXTPROP)COMPATIBLE_IOCTL(OPROMU2P)COMPATIBLE_IOCTL(OPROMGETCONS)COMPATIBLE_IOCTL(OPROMGETFBNAME)COMPATIBLE_IOCTL(OPROMGETBOOTARGS)COMPATIBLE_IOCTL(OPROMSETCUR)COMPATIBLE_IOCTL(OPROMPCI2NODE)COMPATIBLE_IOCTL(OPROMPATH2NODE)/* Big L */COMPATIBLE_IOCTL(LOOP_SET_STATUS64)COMPATIBLE_IOCTL(LOOP_GET_STATUS64)/* Big A */COMPATIBLE_IOCTL(AUDIO_GETINFO)COMPATIBLE_IOCTL(AUDIO_SETINFO)COMPATIBLE_IOCTL(AUDIO_DRAIN)COMPATIBLE_IOCTL(AUDIO_GETDEV)COMPATIBLE_IOCTL(AUDIO_GETDEV_SUNOS)COMPATIBLE_IOCTL(AUDIO_FLUSH)COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI)#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC)COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID)COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC)COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK)COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK)COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL)COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS)COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS)COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX)COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX)COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX)COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX)COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX)COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX)COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW)COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW)COMPATIBLE_IOCTL(DRM_IOCTL_LOCK)COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK)COMPATIBLE_IOCTL(DRM_IOCTL_FINISH)#endif /* DRM */COMPATIBLE_IOCTL(WIOCSTART)COMPATIBLE_IOCTL(WIOCSTOP)COMPATIBLE_IOCTL(WIOCGSTAT)/* And these ioctls need translation *//* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap)HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap)HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor)#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)#endif /* DRM */#if 0HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl)HANDLE_IOCTL(RTC32_EPOCH_READ, do_rtc_ioctl)HANDLE_IOCTL(RTC32_EPOCH_SET, do_rtc_ioctl)#endif/* take care of sizeof(sizeof()) breakage */IOCTL_TABLE_ENDint ioctl_table_size = ARRAY_SIZE(ioctl_start);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?