ioctl32.c

来自「优龙2410linux2.6.8内核源代码」· 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 + -
显示快捷键?