static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
			     struct v4l2_buffer32 __user *up,
			     void __user *aux_buf, u32 aux_space)
{
	u32 type;
	u32 length;
	enum v4l2_memory memory;
	struct v4l2_plane32 __user *uplane32;
	struct v4l2_plane __user *uplane;
	compat_caddr_t p;
	int ret;

	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
	    assign_in_user(&kp->index, &up->index) ||
	    get_user(type, &up->type) ||
	    put_user(type, &kp->type) ||
	    assign_in_user(&kp->flags, &up->flags) ||
	    get_user(memory, &up->memory) ||
	    put_user(memory, &kp->memory) ||
	    get_user(length, &up->length) ||
	    put_user(length, &kp->length))
		return -EFAULT;

	if (V4L2_TYPE_IS_OUTPUT(type))
		if (assign_in_user(&kp->bytesused, &up->bytesused) ||
		    assign_in_user(&kp->field, &up->field) ||
		    assign_in_user(&kp->timestamp.tv_sec,
				   &up->timestamp.tv_sec) ||
		    assign_in_user(&kp->timestamp.tv_usec,
				   &up->timestamp.tv_usec))
			return -EFAULT;

	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
		u32 num_planes = length;

		if (num_planes == 0) {
			/*
			 * num_planes == 0 is legal, e.g. when userspace doesn't
			 * need planes array on DQBUF
			 */
			return put_user(NULL, &kp->m.planes);
		}
		if (num_planes > VIDEO_MAX_PLANES)
			return -EINVAL;

		if (get_user(p, &up->m.planes))
			return -EFAULT;

		uplane32 = compat_ptr(p);
		if (!access_ok(VERIFY_READ, uplane32,
			       num_planes * sizeof(*uplane32)))
			return -EFAULT;

		/*
		 * We don't really care if userspace decides to kill itself
		 * by passing a very big num_planes value
		 */
		if (aux_space < num_planes * sizeof(*uplane))
			return -EFAULT;

		uplane = aux_buf;
		if (put_user((__force struct v4l2_plane *)uplane,
			     &kp->m.planes))
			return -EFAULT;

		while (num_planes--) {
			ret = get_v4l2_plane32(uplane, uplane32, memory);
			if (ret)
				return ret;
			uplane++;
			uplane32++;
		}
	} else {
		switch (memory) {
		case V4L2_MEMORY_MMAP:
		case V4L2_MEMORY_OVERLAY:
			if (assign_in_user(&kp->m.offset, &up->m.offset))
				return -EFAULT;
			break;
		case V4L2_MEMORY_USERPTR: {
			compat_ulong_t userptr;

			if (get_user(userptr, &up->m.userptr) ||
			    put_user((unsigned long)compat_ptr(userptr),
				     &kp->m.userptr))
				return -EFAULT;
			break;
		}
		case V4L2_MEMORY_DMABUF:
			if (assign_in_user(&kp->m.fd, &up->m.fd))
				return -EFAULT;
			break;
		}
	}

	return 0;
}
static int get_v4l2_buffer32(struct v4l2_buffer __user *kp,
			     struct v4l2_buffer32 __user *up,
			     void __user *aux_buf, u32 aux_space)
{
	u32 type;
	u32 length;
	enum v4l2_memory memory;
	struct v4l2_plane32 __user *uplane32;
	struct v4l2_plane __user *uplane;
	compat_caddr_t p;
	int ret;

	if (!access_ok(VERIFY_READ, up, sizeof(*up)) ||
	    assign_in_user(&kp->index, &up->index) ||
	    get_user(type, &up->type) ||
	    put_user(type, &kp->type) ||
	    assign_in_user(&kp->flags, &up->flags) ||
	    get_user(memory, &up->memory) ||
	    put_user(memory, &kp->memory) ||
	    get_user(length, &up->length) ||
	    put_user(length, &kp->length))
		return -EFAULT;

	if (V4L2_TYPE_IS_OUTPUT(type))
		if (assign_in_user(&kp->bytesused, &up->bytesused) ||
		    assign_in_user(&kp->field, &up->field) ||
		    assign_in_user(&kp->timestamp.tv_sec,
				   &up->timestamp.tv_sec) ||
		    assign_in_user(&kp->timestamp.tv_usec,
				   &up->timestamp.tv_usec))
			return -EFAULT;

	if (V4L2_TYPE_IS_MULTIPLANAR(type)) {
		u32 num_planes = length;

		if (num_planes == 0) {
			 
			return put_user(NULL, &kp->m.planes);
		}
		if (num_planes > VIDEO_MAX_PLANES)
			return -EINVAL;

		if (get_user(p, &up->m.planes))
			return -EFAULT;

		uplane32 = compat_ptr(p);
		if (!access_ok(VERIFY_READ, uplane32,
			       num_planes * sizeof(*uplane32)))
			return -EFAULT;

		 
		if (aux_space < num_planes * sizeof(*uplane))
			return -EFAULT;

		uplane = aux_buf;
		if (put_user((__force struct v4l2_plane *)uplane,
			     &kp->m.planes))
			return -EFAULT;

		while (num_planes--) {
			ret = get_v4l2_plane32(uplane, uplane32, memory);
			if (ret)
				return ret;
			uplane++;
			uplane32++;
		}
	} else {
		switch (memory) {
		case V4L2_MEMORY_MMAP:
		case V4L2_MEMORY_OVERLAY:
			if (assign_in_user(&kp->m.offset, &up->m.offset))
				return -EFAULT;
			break;
		case V4L2_MEMORY_USERPTR: {
			compat_ulong_t userptr;

			if (get_user(userptr, &up->m.userptr) ||
			    put_user((unsigned long)compat_ptr(userptr),
				     &kp->m.userptr))
				return -EFAULT;
			break;
		}
		case V4L2_MEMORY_DMABUF:
			if (assign_in_user(&kp->m.fd, &up->m.fd))
				return -EFAULT;
			break;
		}
	}

	return 0;
}