/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code was written by Surya Shankar for GSoC 2019.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
typedef struct {
int version_major; /**< Major version */
int version_minor; /**< Minor version */
int version_patchlevel; /**< Patch level */
uint32_t name_len; /**< Length of name buffer */
netbsd32_pointer_t name; /**< Name of driver */
uint32_t date_len; /**< Length of date buffer */
netbsd32_pointer_t date; /**< User-space buffer to hold date */
uint32_t desc_len; /**< Length of desc buffer */
netbsd32_pointer_t desc; /**< User-space buffer to hold desc */
} drm_version32_t;
static int
compat_drm_version(struct file *file, void *arg)
{
drm_version32_t v32;
struct drm_version v64;
int error;
if ((error = copyin(&v32, arg, sizeof(v32))) != 0)
return error;
static int
compat_drm_getstats(struct file *file, void *arg)
{
drm_stats32_t st32;
struct drm_stats st64;
int error;
if ((error = copyin(&st32, arg, sizeof(st32))) != 0)
return error;
st64.count = st32.count;
if (st64.count > __arraycount(st64.data))
return EINVAL;
error = drm_ioctl(file, DRM_IOCTL_GET_STATS, &st64);
if (error)
return error;
for (size_t i = 0; i < st64.count; ++i) {
st32.data[i].value = st64.data[i].value;
st32.data[i].type = st64.data[i].type;
}
st32.count = st64.count;
return copyout(arg, &st32, sizeof(s32));
}
typedef struct drm_buf_desc32 {
int count; /**< Number of buffers of this size */
int size; /**< Size in bytes */
int low_mark; /**< Low water mark */
int high_mark; /**< High water mark */
int flags;
netbsd32_pointer_t agp_start;
/**< Start address in the AGP aperture */
} drm_buf_desc32_t;
static int
compat_drm_addbufs(struct file *file, void *arg)
{
drm_buf_desc32_t buf32;
struct drm_buf_desc buf64;
int error;
if ((error = copyin(&buf32, arg, sizeof(buf32))) != 0)
return error;
typedef struct drm_buf_info32 {
int count; /**< Entries in list */
netbsd32_pointer_t list;
} drm_buf_info32_t;
typedef struct drm_buf_pub32 {
int idx; /**< Index into the master buffer list */
int total; /**< Buffer size */
int used; /**< Amount of buffer in use (for DMA) */
uint32_t address; /**< Address of buffer */
} drm_buf_pub32_t;
typedef struct drm_buf_map32 {
int count; /**< Length of the buffer list */
uint32_t virtual; /**< Mmap'd area in user-virtual */
netbsd32_pointer_t list; /**< Buffer information */
} drm_buf_map32_t;
typedef struct drm_buf_free32 {
int count;
netbsd32_pointer_t list;
} drm_buf_free32_t;
static int
compat_drm_freebufs(struct file *file, void *arg)
{
drm_buf_free32_t req32;
struct drm_buf_free req64;
int error;
if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
return error;
typedef struct drm_dma32 {
int context; /**< Context handle */
int send_count; /**< Number of buffers to send */
netbsd32_pointer_t send_indices; /**< List of handles to buffers */
netbsd32_pointer_t send_sizes; /**< Lengths of data to send */
enum drm_dma_flags flags; /**< Flags */
netbsd32_pointer_t request_count; /**< Number of buffers requested */
int request_size; /**< Desired size for buffers */
netbsd32_pointer_t request_indices; /**< Buffer information */
netbsd32_pointer_t request_sizes;
int granted_count; /**< Number of buffers granted */
} drm_dma32_t;
static int
compat_drm_dma(struct file *file, void *arg)
{
drm_dma32_t d32;
struct drm_dma d64;
int error;
if ((error = copyin(&d32, arg, sizeof(d32))) != 0)
return error;
dma32to64(&d64, &d32);
error = drm_ioctl(file, DRM_IOCTL_DMA, &d64);
if (error)
return error;
dma64to32(&d32, &d64);
return copyout(arg, &d32, sizeof(d32));
}
//XXX:i commented the below line for later use
#if IS_ENABLED(CONFIG_AGP)
typedef struct drm_agp_mode32 {
uint32_t mode; /**< AGP mode */
} drm_agp_mode32_t;
static int
compat_drm_agp_enable(struct file *file, void *arg)
{
drm_agp_mode32_t m32;
struct drm_agp_mode m64;
int error;
if ((error = copyin(&m32, arg, sizeof(m32))) != 0)
return error;
static int
compat_drm_agp_info(struct file *file, void *arg)
{
drm_agp_info32_t i32;
struct drm_agp_info i64;
int error;
error = drm_ioctl(file, DRM_IOCTL_AGP_INFO, &i64);
if (error)
return error;
info64to32(&i32, &i64);
return copyout(arg, &i32, sizeof(i32));
}
typedef struct drm_agp_buffer32 {
uint32_t size; /**< In bytes -- will round to page boundary */
uint32_t handle; /**< Used for binding / unbinding */
uint32_t type; /**< Type of memory to allocate */
uint32_t physical; /**< Physical used by i810 */
} drm_agp_buffer32_t;
static int
compat_drm_agp_alloc(struct file *file, void *arg)
{
drm_agp_buffer32_t req32;
struct drm_agp_buffer req64;
int error;
if ((error = copyin(&req32, arg, sizeof(req32))) != 0)
return error;
req64.size = req32.size;
req64.type = req32.type;
error = drm_ioctl(file, DRM_IOCTL_AGP_ALLOC, &req64);
if (error)
return error;
#if defined(CONFIG_X86) || defined(CONFIG_IA64)
typedef struct drm_update_draw32 {
drm_drawable_t handle;
unsigned int type;
unsigned int num;
/* 64-bit version has a 32-bit pad here */
uint64_t data; /**< Pointer */
} __attribute__((__packed__)) drm_update_draw32_t;