We want to implement a COMPAT version of this function so let's abstract
away all the copy_to/from_user bits.

diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
index 5caf53942604..0ffe4bf8d826 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
@@ -506,25 +506,23 @@ vchiq_ioc_queue_message(VCHIQ_SERVICE_HANDLE_T handle,
                                   &context, total_size);
 }
 
-static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
-                                     VCHIQ_CREATE_SERVICE_T __user *uargs)
+static int
+do_ioctl_create_service(struct file *file,
+                       VCHIQ_CREATE_SERVICE_T *args,
+                       int __user *handle)
 {
        VCHIQ_INSTANCE_T instance = file->private_data;
        VCHIQ_STATUS_T status = VCHIQ_SUCCESS;
        VCHIQ_SERVICE_T *service = NULL;
-       VCHIQ_CREATE_SERVICE_T args;
        USER_SERVICE_T *user_service = NULL;
        void *userdata;
        int srvstate;
 
-       if (copy_from_user(&args, uargs, sizeof(args)))
-               return -EFAULT;
-
        user_service = kmalloc(sizeof(*user_service), GFP_KERNEL);
        if (!user_service)
                return -ENOMEM;
 
-       if (args.is_open) {
+       if (args->is_open) {
                if (!instance->connected) {
                        kfree(user_service);
                        return -ENOTCONN;
@@ -536,11 +534,11 @@ static int vchiq_ioctl_create_service(struct file *file, 
unsigned int cmd,
                                VCHIQ_SRVSTATE_HIDDEN;
        }
 
-       userdata = args.params.userdata;
-       args.params.callback = service_callback;
-       args.params.userdata = user_service;
+       userdata = args->params.userdata;
+       args->params.callback = service_callback;
+       args->params.userdata = user_service;
        service = vchiq_add_service_internal(instance->state,
-                                            &args.params, srvstate,
+                                            &args->params, srvstate,
                                             instance, user_service_free);
        if (!service) {
                kfree(user_service);
@@ -550,7 +548,7 @@ static int vchiq_ioctl_create_service(struct file *file, 
unsigned int cmd,
        user_service->service = service;
        user_service->userdata = userdata;
        user_service->instance = instance;
-       user_service->is_vchi = (args.is_vchi != 0);
+       user_service->is_vchi = (args->is_vchi != 0);
        user_service->dequeue_pending = 0;
        user_service->close_pending = 0;
        user_service->message_available_pos = instance->completion_remove - 1;
@@ -559,7 +557,7 @@ static int vchiq_ioctl_create_service(struct file *file, 
unsigned int cmd,
        sema_init(&user_service->insert_event, 0);
        sema_init(&user_service->remove_event, 0);
        sema_init(&user_service->close_event, 0);
-       if (args.is_open) {
+       if (args->is_open) {
                status = vchiq_open_service_internal(service, instance->pid);
                if (status != VCHIQ_SUCCESS) {
                        vchiq_remove_service(service->handle);
@@ -569,8 +567,7 @@ static int vchiq_ioctl_create_service(struct file *file, 
unsigned int cmd,
                }
        }
 
-       if (copy_to_user(&uargs->handle, &service->handle,
-                        sizeof(service->handle))) {
+       if (copy_to_user(handle, &service->handle, sizeof(service->handle))) {
                vchiq_remove_service(service->handle);
                return -EFAULT;
        }
@@ -578,6 +575,18 @@ static int vchiq_ioctl_create_service(struct file *file, 
unsigned int cmd,
        return 0;
 }
 
+static int
+vchiq_ioctl_create_service(struct file *file, unsigned int cmd,
+                          VCHIQ_CREATE_SERVICE_T __user *uargs)
+{
+       VCHIQ_CREATE_SERVICE_T args;
+
+       if (copy_from_user(&args, uargs, sizeof(args)))
+               return -EFAULT;
+
+       return do_ioctl_create_service(file, &args, &uargs->handle);
+}
+
 /****************************************************************************
 *
 *   vchiq_ioctl
_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to