Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145574194
D37879.id165323.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
15 KB
Referenced Files
None
Subscribers
None
D37879.id165323.diff
View Options
diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c
--- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c
+++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c
@@ -448,6 +448,22 @@
(_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ?
ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg);
+#ifdef COMPAT_FREEBSD32
+/* A fork in the road to freebsd32 compatibilty */
+#define _CF32_FORK(compat_c, native_c) { \
+ int _____dont_call_your_vars_this = 0; \
+ switch (cmd) { \
+ _CF32_CASE {_____dont_call_your_vars_this = 1;} \
+ break; \
+ } \
+ if (_____dont_call_your_vars_this) \
+ { compat_c } \
+ else \
+ { native_c } \
+ }
+#else
+#define _CF32_FORK(compat_c, native_c) { native_c }
+#endif
switch (cmd) {
case VCHIQ_IOC_SHUTDOWN:
if (!instance->connected)
@@ -496,13 +512,33 @@
"vchiq: could not connect: %d", status);
break;
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_CREATE_SERVICE32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_CREATE_SERVICE: {
VCHIQ_CREATE_SERVICE_T args;
USER_SERVICE_T *user_service = NULL;
void *userdata;
int srvstate;
+_CF32_FORK(
+ VCHIQ_CREATE_SERVICE32_T args32;
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ args.params.fourcc = args32.params.fourcc;
+ /* XXXMDC not actually used? overwritten straight away */
+ args.params.callback =
+ (VCHIQ_CALLBACK_T)(uintptr_t) args32.params.callback;
+ args.params.userdata = (void*)(uintptr_t)args32.params.userdata;
+ args.params.version = args32.params.version;
+ args.params.version_min = args32.params.version_min;
+ args.is_open = args32.is_open;
+ args.is_vchi = args32.is_vchi;
+ args.handle = args32.handle;
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL);
if (!user_service) {
@@ -558,15 +594,22 @@
break;
}
}
-
#ifdef VCHIQ_IOCTL_DEBUG
printf("%s: [CREATE SERVICE] handle = %08x\n", __func__, service->handle);
#endif
+_CF32_FORK(
+ memcpy((void *)
+ &(((VCHIQ_CREATE_SERVICE32_T*)
+ arg)->handle),
+ (const void *)&service->handle,
+ sizeof(service->handle));
+,
memcpy((void *)
&(((VCHIQ_CREATE_SERVICE_T*)
arg)->handle),
(const void *)&service->handle,
sizeof(service->handle));
+);
service = NULL;
} else {
@@ -574,6 +617,7 @@
kfree(user_service);
}
} break;
+#undef _CF32_CASE
case VCHIQ_IOC_CLOSE_SERVICE: {
VCHIQ_SERVICE_HANDLE_T handle;
@@ -673,9 +717,22 @@
ret = -EINVAL;
} break;
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_QUEUE_MESSAGE32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_QUEUE_MESSAGE: {
VCHIQ_QUEUE_MESSAGE_T args;
+_CF32_FORK(
+ VCHIQ_QUEUE_MESSAGE32_T args32;
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ args.handle = args32.handle;
+ args.count = args32.count;
+ args.elements = (VCHIQ_ELEMENT_T *)(uintptr_t)args32.elements;
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
#ifdef VCHIQ_IOCTL_DEBUG
printf("%s: [QUEUE MESSAGE] handle = %08x\n", __func__, args.handle);
@@ -686,8 +743,22 @@
if ((service != NULL) && (args.count <= MAX_ELEMENTS)) {
/* Copy elements into kernel space */
VCHIQ_ELEMENT_T elements[MAX_ELEMENTS];
- if (copy_from_user(elements, args.elements,
- args.count * sizeof(VCHIQ_ELEMENT_T)) == 0)
+ long cp_ret;
+_CF32_FORK(
+ VCHIQ_ELEMENT32_T elements32[MAX_ELEMENTS];
+ cp_ret = copy_from_user(elements32, args.elements,
+ args.count * sizeof(VCHIQ_ELEMENT32_T));
+ for(int i=0;cp_ret == 0 && i < args.count;++i){
+ elements[i].data =
+ (void *)(uintptr_t)elements32[i].data;
+ elements[i].size = elements32[i].size;
+ }
+
+,
+ cp_ret = copy_from_user(elements, args.elements,
+ args.count * sizeof(VCHIQ_ELEMENT_T));
+)
+ if (cp_ret == 0)
status = vchiq_queue_message
(args.handle,
elements, args.count);
@@ -697,16 +768,38 @@
ret = -EINVAL;
}
} break;
+#undef _CF32_CASE
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_QUEUE_BULK_TRANSMIT32: \
+ case VCHIQ_IOC_QUEUE_BULK_RECEIVE32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_QUEUE_BULK_TRANSMIT:
case VCHIQ_IOC_QUEUE_BULK_RECEIVE: {
VCHIQ_QUEUE_BULK_TRANSFER_T args;
+
struct bulk_waiter_node *waiter = NULL;
VCHIQ_BULK_DIR_T dir =
- (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ?
- VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
-
+ (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT) ||
+ (cmd == VCHIQ_IOC_QUEUE_BULK_TRANSMIT32)?
+ VCHIQ_BULK_TRANSMIT : VCHIQ_BULK_RECEIVE;
+
+_CF32_FORK(
+ VCHIQ_QUEUE_BULK_TRANSFER32_T args32;
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ /* XXXMDC parens needed (macro parsing?) */
+ args = ((VCHIQ_QUEUE_BULK_TRANSFER_T) {
+ .handle = args32.handle,
+ .data = (void *)(uintptr_t) args32.data,
+ .size = args32.size,
+ .userdata = (void *)(uintptr_t) args32.userdata,
+ .mode = args32.mode,
+ });
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
service = find_service_for_instance(instance, args.handle);
if (!service) {
@@ -734,7 +827,6 @@
list_del(pos);
break;
}
-
}
lmutex_unlock(&instance->bulk_waiter_list_mutex);
if (!waiter) {
@@ -780,14 +872,28 @@
"saved bulk_waiter %zx for pid %d",
(size_t)waiter, current->p_pid);
+_CF32_FORK(
+ memcpy((void *)
+ &(((VCHIQ_QUEUE_BULK_TRANSFER32_T *)
+ arg)->mode),
+ (const void *)&mode_waiting,
+ sizeof(mode_waiting));
+,
memcpy((void *)
&(((VCHIQ_QUEUE_BULK_TRANSFER_T *)
arg)->mode),
(const void *)&mode_waiting,
sizeof(mode_waiting));
+)
}
} break;
+#undef _CF32_CASE
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_AWAIT_COMPLETION32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_AWAIT_COMPLETION: {
VCHIQ_AWAIT_COMPLETION_T args;
int count = 0;
@@ -798,7 +904,17 @@
break;
}
+_CF32_FORK(
+ VCHIQ_AWAIT_COMPLETION32_T args32;
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ args.count = args32.count;
+ args.buf = (VCHIQ_COMPLETION_DATA_T *)(uintptr_t)args32.buf;
+ args.msgbufsize = args32.msgbufsize;
+ args.msgbufcount = args32.msgbufcount;
+ args.msgbufs = (void **)(uintptr_t)args32.msgbufs;
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
lmutex_lock(&instance->completion_mutex);
@@ -878,6 +994,20 @@
break;
/* Get the pointer from user space */
msgbufcount--;
+_CF32_FORK(
+ uint32_t *msgbufs32 =
+ (uint32_t *) args.msgbufs;
+ uint32_t msgbuf32 = 0;
+ if (copy_from_user(&msgbuf32,
+ (const uint32_t __user *)
+ &msgbufs32[msgbufcount],
+ sizeof(msgbuf32)) != 0) {
+ if (count == 0)
+ ret = -EFAULT;
+ break;
+ }
+ msgbuf = (void __user *)(uintptr_t)msgbuf32;
+,
if (copy_from_user(&msgbuf,
(const void __user *)
&args.msgbufs[msgbufcount],
@@ -886,6 +1016,7 @@
ret = -EFAULT;
break;
}
+)
/* Copy the message to user space */
if (copy_to_user(msgbuf, header,
@@ -909,7 +1040,30 @@
VCHIQ_SERVICE_CLOSED) &&
!instance->use_close_delivered)
unlock_service(service1);
-
+_CF32_FORK(
+ VCHIQ_COMPLETION_DATA32_T comp32 = {0};
+ comp32.reason =
+ (uint32_t)(size_t) completion->reason;
+ comp32.service_userdata =
+ (uint32_t)(size_t)
+ completion->service_userdata;
+ comp32.bulk_userdata =
+ (uint32_t)(size_t)
+ completion->bulk_userdata;
+ comp32.header =
+ (uint32_t)(size_t)completion->header;
+
+ VCHIQ_COMPLETION_DATA32_T __user *buf_loc;
+ buf_loc = (VCHIQ_COMPLETION_DATA32_T __user *)
+ args.buf;
+ buf_loc += count;
+ if (copy_to_user(
+ buf_loc, &comp32, sizeof(comp32)
+ ) != 0) {
+ if (ret == 0)
+ ret = -EFAULT;
+ }
+,
if (copy_to_user((void __user *)(
(size_t)args.buf +
count * sizeof(VCHIQ_COMPLETION_DATA_T)),
@@ -919,6 +1073,7 @@
ret = -EFAULT;
break;
}
+)
/* Ensure that the above copy has completed
** before advancing the remove pointer. */
@@ -928,18 +1083,33 @@
}
if (msgbufcount != args.msgbufcount) {
+_CF32_FORK(
+ memcpy(
+ (void __user *)
+ &((VCHIQ_AWAIT_COMPLETION32_T *)arg)->
+ msgbufcount,
+ &msgbufcount,
+ sizeof(msgbufcount));
+,
memcpy((void __user *)
&((VCHIQ_AWAIT_COMPLETION_T *)arg)->
msgbufcount,
&msgbufcount,
sizeof(msgbufcount));
+)
}
if (count != args.count)
{
+_CF32_FORK(
+ memcpy((void __user *)
+ &((VCHIQ_AWAIT_COMPLETION32_T *)arg)->count,
+ &count, sizeof(count));
+,
memcpy((void __user *)
&((VCHIQ_AWAIT_COMPLETION_T *)arg)->count,
&count, sizeof(count));
+)
}
}
@@ -948,9 +1118,9 @@
if ((ret == 0) && instance->closing)
ret = -ENOTCONN;
- /*
+ /*
* XXXBSD: ioctl return codes are not negative as in linux, so
- * we can not indicate success with positive number of passed
+ * we can not indicate success with positive number of passed
* messages
*/
if (ret > 0)
@@ -959,14 +1129,29 @@
lmutex_unlock(&instance->completion_mutex);
DEBUG_TRACE(AWAIT_COMPLETION_LINE);
} break;
+#undef _CF32_CASE
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_DEQUEUE_MESSAGE32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_DEQUEUE_MESSAGE: {
VCHIQ_DEQUEUE_MESSAGE_T args;
USER_SERVICE_T *user_service;
VCHIQ_HEADER_T *header;
DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
+_CF32_FORK(
+ VCHIQ_DEQUEUE_MESSAGE32_T args32;
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ args.handle = args32.handle;
+ args.blocking = args32.blocking;
+ args.bufsize = args32.bufsize;
+ args.buf = (void *)(uintptr_t)args32.buf;
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
service = find_service_for_instance(instance, args.handle);
if (!service) {
ret = -EINVAL;
@@ -1023,8 +1208,19 @@
header->data,
header->size) == 0)) {
args.bufsize = header->size;
+_CF32_FORK(
+ VCHIQ_DEQUEUE_MESSAGE32_T args32;
+ args32.handle = args.handle;
+ args32.blocking = args.blocking;
+ args32.bufsize = args.bufsize;
+ args32.buf = (uintptr_t)(void *)args.buf;
+
+ memcpy((void *)arg, &args32,
+ sizeof(args32));
+,
memcpy((void *)arg, &args,
sizeof(args));
+)
vchiq_release_message(
service->handle,
header);
@@ -1040,6 +1236,7 @@
}
DEBUG_TRACE(DEQUEUE_MESSAGE_LINE);
} break;
+#undef _CF32_CASE
case VCHIQ_IOC_GET_CLIENT_ID: {
VCHIQ_SERVICE_HANDLE_T handle;
@@ -1049,11 +1246,24 @@
ret = vchiq_get_client_id(handle);
} break;
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_GET_CONFIG32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_GET_CONFIG: {
VCHIQ_GET_CONFIG_T args;
VCHIQ_CONFIG_T config;
-
+_CF32_FORK(
+ VCHIQ_GET_CONFIG32_T args32;
+
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ args.config_size = args32.config_size;
+ args.pconfig = (VCHIQ_CONFIG_T *)
+ (uintptr_t)args32.pconfig;
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
if (args.config_size > sizeof(config)) {
ret = -EINVAL;
break;
@@ -1067,6 +1277,7 @@
}
}
} break;
+#undef _CF32_CASE
case VCHIQ_IOC_SET_SERVICE_OPTION: {
VCHIQ_SET_SERVICE_OPTION_T args;
@@ -1083,15 +1294,28 @@
args.handle, args.option, args.value);
} break;
+#ifdef COMPAT_FREEBSD32
+#define _CF32_CASE \
+ case VCHIQ_IOC_DUMP_PHYS_MEM32:
+ _CF32_CASE
+#endif
case VCHIQ_IOC_DUMP_PHYS_MEM: {
VCHIQ_DUMP_MEM_T args;
+_CF32_FORK(
+ VCHIQ_DUMP_MEM32_T args32;
+ memcpy(&args32, (const void*)arg, sizeof(args32));
+ args.virt_addr = (void *)(uintptr_t)args32.virt_addr;
+ args.num_bytes = (size_t)args32.num_bytes;
+,
memcpy(&args, (const void*)arg, sizeof(args));
+)
printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__);
#if 0
dump_phys_mem(args.virt_addr, args.num_bytes);
#endif
} break;
+#undef _CF32_CASE
case VCHIQ_IOC_LIB_VERSION: {
size_t lib_version = (size_t)arg;
@@ -1120,6 +1344,7 @@
ret = -ENOTTY;
break;
}
+#undef _CF32_FORK
if (service)
unlock_service(service);
diff --git a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h
--- a/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h
+++ b/sys/contrib/vchiq/interface/vchiq_arm/vchiq_ioctl.h
@@ -127,4 +127,125 @@
#define VCHIQ_IOC_CLOSE_DELIVERED _IO(VCHIQ_IOC_MAGIC, 17)
#define VCHIQ_IOC_MAX 17
+
+/*
+ * COMPAT_FREEBSD32
+ */
+
+typedef struct {
+ unsigned int config_size;
+ /*VCHIQ_CONFIG_T * */ uint32_t pconfig;
+} VCHIQ_GET_CONFIG32_T;
+
+typedef struct {
+ unsigned int handle;
+ /*void * */ uint32_t data;
+ unsigned int size;
+ /*void * */ uint32_t userdata;
+ VCHIQ_BULK_MODE_T mode;
+} VCHIQ_QUEUE_BULK_TRANSFER32_T;
+
+typedef struct {
+ unsigned int handle;
+ unsigned int count;
+ const /*VCHIQ_ELEMENT_T * */ uint32_t elements;
+} VCHIQ_QUEUE_MESSAGE32_T;
+
+typedef struct {
+ unsigned int handle;
+ int blocking;
+ unsigned int bufsize;
+ /*void * */ uint32_t buf;
+} VCHIQ_DEQUEUE_MESSAGE32_T;
+
+typedef struct {
+ /*void * */ uint32_t virt_addr;
+ /*size_t*/ uint32_t num_bytes;
+} VCHIQ_DUMP_MEM32_T;
+
+typedef struct {
+ VCHIQ_REASON_T reason;
+ /* VCHIQ_HEADER_T * */ uint32_t header;
+ /* void * */ uint32_t service_userdata;
+ /* void * */ uint32_t bulk_userdata;
+} VCHIQ_COMPLETION_DATA32_T;
+
+typedef struct {
+ unsigned int count;
+ /* VCHIQ_COMPLETION_DATA32_T * */ uint32_t buf;
+ unsigned int msgbufsize;
+ unsigned int msgbufcount; /* IN/OUT */
+ /* void ** */ uint32_t msgbufs;
+} VCHIQ_AWAIT_COMPLETION32_T;
+
+typedef struct vchiq_service_params32_struct {
+ int fourcc;
+ /* VCHIQ_CALLBACK_T */ uint32_t callback;
+ /*void * */ uint32_t userdata;
+ short version; /* Increment for non-trivial changes */
+ short version_min; /* Update for incompatible changes */
+} VCHIQ_SERVICE_PARAMS32_T;
+
+typedef struct {
+ VCHIQ_SERVICE_PARAMS32_T params;
+ int is_open;
+ int is_vchi;
+ unsigned int handle; /* OUT */
+} VCHIQ_CREATE_SERVICE32_T;
+
+typedef struct {
+ const /*void */ uint32_t data;
+ unsigned int size;
+} VCHIQ_ELEMENT32_T;
+
+
+#define VCHIQ_IOC_GET_CONFIG32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_GET_CONFIG, \
+ VCHIQ_GET_CONFIG32_T \
+ )
+
+#define VCHIQ_IOC_QUEUE_BULK_TRANSMIT32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_QUEUE_BULK_TRANSMIT, \
+ VCHIQ_QUEUE_BULK_TRANSFER32_T \
+ )
+
+#define VCHIQ_IOC_QUEUE_BULK_RECEIVE32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_QUEUE_BULK_RECEIVE, \
+ VCHIQ_QUEUE_BULK_TRANSFER32_T \
+ )
+
+#define VCHIQ_IOC_QUEUE_MESSAGE32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_QUEUE_MESSAGE, \
+ VCHIQ_QUEUE_MESSAGE32_T \
+ )
+
+#define VCHIQ_IOC_DEQUEUE_MESSAGE32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_DEQUEUE_MESSAGE, \
+ VCHIQ_DEQUEUE_MESSAGE32_T \
+ )
+
+#define VCHIQ_IOC_DUMP_PHYS_MEM32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_DUMP_PHYS_MEM, \
+ VCHIQ_DUMP_MEM32_T \
+ )
+
+#define VCHIQ_IOC_AWAIT_COMPLETION32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_AWAIT_COMPLETION, \
+ VCHIQ_AWAIT_COMPLETION32_T \
+ )
+
+#define VCHIQ_IOC_CREATE_SERVICE32 \
+ _IOC_NEWTYPE( \
+ VCHIQ_IOC_CREATE_SERVICE, \
+ VCHIQ_CREATE_SERVICE32_T \
+ )
+
+
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 22, 4:48 PM (2 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28927261
Default Alt Text
D37879.id165323.diff (15 KB)
Attached To
Mode
D37879: vchiq: add compat_freebsd32 ioctls and respective datatypes
Attached
Detach File
Event Timeline
Log In to Comment