Pull vchiq_ioctl_create_service() into its own function. I did this as simply as I could and left checkpatch.pl warnings in if they were in the original code. There is a slight functional change in that we skip some debugging but we should be using ftrace for that and get rid of the debug code anyway. 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 cb0b7ca36b1e..f9f69ca501b2 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -506,6 +506,91 @@ vchiq_ioc_queue_message(VCHIQ_SERVICE_HANDLE_T handle, &context, total_size); } +static int vchiq_ioctl_create_service(struct file *file, unsigned int cmd, unsigned long arg) +{ + 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; + int ret = 0; + + if (copy_from_user(&args, (const void __user *)arg, + sizeof(args)) != 0) { + return -EFAULT; + } + + user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL); + if (!user_service) + return -ENOMEM; + + if (args.is_open) { + if (!instance->connected) { + kfree(user_service); + return -ENOTCONN; + } + srvstate = VCHIQ_SRVSTATE_OPENING; + } else { + srvstate = + instance->connected ? + VCHIQ_SRVSTATE_LISTENING : + VCHIQ_SRVSTATE_HIDDEN; + } + + userdata = args.params.userdata; + args.params.callback = service_callback; + args.params.userdata = user_service; + service = vchiq_add_service_internal( + instance->state, + &args.params, srvstate, + instance, user_service_free); + + if (service != NULL) { + user_service->service = service; + user_service->userdata = userdata; + user_service->instance = instance; + 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; + user_service->msg_insert = 0; + user_service->msg_remove = 0; + 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) { + status = vchiq_open_service_internal + (service, instance->pid); + if (status != VCHIQ_SUCCESS) { + vchiq_remove_service(service->handle); + service = NULL; + ret = (status == VCHIQ_RETRY) ? + -EINTR : -EIO; + return ret; + } + } + + if (copy_to_user((void __user *) + &(((VCHIQ_CREATE_SERVICE_T __user *) + arg)->handle), + (const void *)&service->handle, + sizeof(service->handle)) != 0) { + ret = -EFAULT; + vchiq_remove_service(service->handle); + } + + } else { + ret = -EEXIST; + kfree(user_service); + } + + return ret; +} + /**************************************************************************** * * vchiq_ioctl @@ -576,90 +661,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) "vchiq: could not connect: %d", status); break; - case VCHIQ_IOC_CREATE_SERVICE: { - VCHIQ_CREATE_SERVICE_T args; - USER_SERVICE_T *user_service = NULL; - void *userdata; - int srvstate; - - if (copy_from_user - (&args, (const void __user *)arg, - sizeof(args)) != 0) { - ret = -EFAULT; - break; - } - - user_service = kmalloc(sizeof(USER_SERVICE_T), GFP_KERNEL); - if (!user_service) { - ret = -ENOMEM; - break; - } - - if (args.is_open) { - if (!instance->connected) { - ret = -ENOTCONN; - kfree(user_service); - break; - } - srvstate = VCHIQ_SRVSTATE_OPENING; - } else { - srvstate = - instance->connected ? - VCHIQ_SRVSTATE_LISTENING : - VCHIQ_SRVSTATE_HIDDEN; - } - - userdata = args.params.userdata; - args.params.callback = service_callback; - args.params.userdata = user_service; - service = vchiq_add_service_internal( - instance->state, - &args.params, srvstate, - instance, user_service_free); - - if (service != NULL) { - user_service->service = service; - user_service->userdata = userdata; - user_service->instance = instance; - 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; - user_service->msg_insert = 0; - user_service->msg_remove = 0; - 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) { - status = vchiq_open_service_internal - (service, instance->pid); - if (status != VCHIQ_SUCCESS) { - vchiq_remove_service(service->handle); - service = NULL; - ret = (status == VCHIQ_RETRY) ? - -EINTR : -EIO; - break; - } - } - - if (copy_to_user((void __user *) - &(((VCHIQ_CREATE_SERVICE_T __user *) - arg)->handle), - (const void *)&service->handle, - sizeof(service->handle)) != 0) { - ret = -EFAULT; - vchiq_remove_service(service->handle); - } - - service = NULL; - } else { - ret = -EEXIST; - kfree(user_service); - } - } break; - + case VCHIQ_IOC_CREATE_SERVICE: + return vchiq_ioctl_create_service(file, cmd, arg); case VCHIQ_IOC_CLOSE_SERVICE: { VCHIQ_SERVICE_HANDLE_T handle = (VCHIQ_SERVICE_HANDLE_T)arg; _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel