Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: vchiq_arm: fix open/release cdev functions

Both functions checked the minor number of the cdev prior running the
code. This was useless since the number of devices is already limited by
alloc_chrdev_region.

This removes the check and reindents the code where relevant.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Nicolas Saenz Julienne and committed by
Greg Kroah-Hartman
4ab0f5ce 187ac53e

+112 -159
+112 -159
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
··· 63 63 #undef MODULE_PARAM_PREFIX 64 64 #define MODULE_PARAM_PREFIX DEVICE_NAME "." 65 65 66 - #define VCHIQ_MINOR 0 67 - 68 66 /* Some per-instance constants */ 69 67 #define MAX_COMPLETIONS 128 70 68 #define MAX_SERVICES 64 ··· 1948 1950 1949 1951 #endif 1950 1952 1951 - /**************************************************************************** 1952 - * 1953 - * vchiq_open 1954 - * 1955 - ***************************************************************************/ 1956 - 1957 - static int 1958 - vchiq_open(struct inode *inode, struct file *file) 1953 + static int vchiq_open(struct inode *inode, struct file *file) 1959 1954 { 1960 - int dev = iminor(inode) & 0x0f; 1955 + VCHIQ_STATE_T *state = vchiq_get_state(); 1956 + VCHIQ_INSTANCE_T instance; 1961 1957 1962 1958 vchiq_log_info(vchiq_arm_log_level, "vchiq_open"); 1963 - switch (dev) { 1964 - case VCHIQ_MINOR: { 1965 - VCHIQ_STATE_T *state = vchiq_get_state(); 1966 - VCHIQ_INSTANCE_T instance; 1967 1959 1968 - if (!state) { 1969 - vchiq_log_error(vchiq_arm_log_level, 1970 - "vchiq has no connection to VideoCore"); 1971 - return -ENOTCONN; 1972 - } 1973 - 1974 - instance = kzalloc(sizeof(*instance), GFP_KERNEL); 1975 - if (!instance) 1976 - return -ENOMEM; 1977 - 1978 - instance->state = state; 1979 - instance->pid = current->tgid; 1980 - 1981 - vchiq_debugfs_add_instance(instance); 1982 - 1983 - init_completion(&instance->insert_event); 1984 - init_completion(&instance->remove_event); 1985 - mutex_init(&instance->completion_mutex); 1986 - mutex_init(&instance->bulk_waiter_list_mutex); 1987 - INIT_LIST_HEAD(&instance->bulk_waiter_list); 1988 - 1989 - file->private_data = instance; 1990 - } break; 1991 - 1992 - default: 1960 + if (!state) { 1993 1961 vchiq_log_error(vchiq_arm_log_level, 1994 - "Unknown minor device: %d", dev); 1995 - return -ENXIO; 1962 + "vchiq has no connection to VideoCore"); 1963 + return -ENOTCONN; 1996 1964 } 1965 + 1966 + instance = kzalloc(sizeof(*instance), GFP_KERNEL); 1967 + if (!instance) 1968 + return -ENOMEM; 1969 + 1970 + instance->state = state; 1971 + instance->pid = current->tgid; 1972 + 1973 + vchiq_debugfs_add_instance(instance); 1974 + 1975 + init_completion(&instance->insert_event); 1976 + init_completion(&instance->remove_event); 1977 + mutex_init(&instance->completion_mutex); 1978 + mutex_init(&instance->bulk_waiter_list_mutex); 1979 + INIT_LIST_HEAD(&instance->bulk_waiter_list); 1980 + 1981 + file->private_data = instance; 1997 1982 1998 1983 return 0; 1999 1984 } 2000 1985 2001 - /**************************************************************************** 2002 - * 2003 - * vchiq_release 2004 - * 2005 - ***************************************************************************/ 2006 - 2007 - static int 2008 - vchiq_release(struct inode *inode, struct file *file) 1986 + static int vchiq_release(struct inode *inode, struct file *file) 2009 1987 { 2010 - int dev = iminor(inode) & 0x0f; 1988 + VCHIQ_INSTANCE_T instance = file->private_data; 1989 + VCHIQ_STATE_T *state = vchiq_get_state(); 1990 + VCHIQ_SERVICE_T *service; 2011 1991 int ret = 0; 1992 + int i; 2012 1993 2013 - switch (dev) { 2014 - case VCHIQ_MINOR: { 2015 - VCHIQ_INSTANCE_T instance = file->private_data; 2016 - VCHIQ_STATE_T *state = vchiq_get_state(); 2017 - VCHIQ_SERVICE_T *service; 2018 - int i; 1994 + vchiq_log_info(vchiq_arm_log_level, "%s: instance=%lx", __func__, 1995 + (unsigned long)instance); 2019 1996 2020 - vchiq_log_info(vchiq_arm_log_level, 2021 - "%s: instance=%lx", 2022 - __func__, (unsigned long)instance); 1997 + if (!state) { 1998 + ret = -EPERM; 1999 + goto out; 2000 + } 2023 2001 2024 - if (!state) { 2025 - ret = -EPERM; 2026 - goto out; 2027 - } 2002 + /* Ensure videocore is awake to allow termination. */ 2003 + vchiq_use_internal(instance->state, NULL, USE_TYPE_VCHIQ); 2028 2004 2029 - /* Ensure videocore is awake to allow termination. */ 2030 - vchiq_use_internal(instance->state, NULL, 2031 - USE_TYPE_VCHIQ); 2005 + mutex_lock(&instance->completion_mutex); 2032 2006 2033 - mutex_lock(&instance->completion_mutex); 2007 + /* Wake the completion thread and ask it to exit */ 2008 + instance->closing = 1; 2009 + complete(&instance->insert_event); 2034 2010 2035 - /* Wake the completion thread and ask it to exit */ 2036 - instance->closing = 1; 2037 - complete(&instance->insert_event); 2011 + mutex_unlock(&instance->completion_mutex); 2038 2012 2039 - mutex_unlock(&instance->completion_mutex); 2013 + /* Wake the slot handler if the completion queue is full. */ 2014 + complete(&instance->remove_event); 2040 2015 2041 - /* Wake the slot handler if the completion queue is full. */ 2042 - complete(&instance->remove_event); 2016 + /* Mark all services for termination... */ 2017 + i = 0; 2018 + while ((service = next_service_by_instance(state, instance, &i))) { 2019 + USER_SERVICE_T *user_service = service->base.userdata; 2043 2020 2044 - /* Mark all services for termination... */ 2045 - i = 0; 2046 - while ((service = next_service_by_instance(state, instance, 2047 - &i)) != NULL) { 2048 - USER_SERVICE_T *user_service = service->base.userdata; 2021 + /* Wake the slot handler if the msg queue is full. */ 2022 + complete(&user_service->remove_event); 2049 2023 2050 - /* Wake the slot handler if the msg queue is full. */ 2051 - complete(&user_service->remove_event); 2024 + vchiq_terminate_service_internal(service); 2025 + unlock_service(service); 2026 + } 2052 2027 2053 - vchiq_terminate_service_internal(service); 2054 - unlock_service(service); 2055 - } 2028 + /* ...and wait for them to die */ 2029 + i = 0; 2030 + while ((service = next_service_by_instance(state, instance, &i))) { 2031 + USER_SERVICE_T *user_service = service->base.userdata; 2056 2032 2057 - /* ...and wait for them to die */ 2058 - i = 0; 2059 - while ((service = next_service_by_instance(state, instance, &i)) 2060 - != NULL) { 2061 - USER_SERVICE_T *user_service = service->base.userdata; 2033 + wait_for_completion(&service->remove_event); 2062 2034 2063 - wait_for_completion(&service->remove_event); 2035 + BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); 2064 2036 2065 - BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); 2037 + spin_lock(&msg_queue_spinlock); 2066 2038 2067 - spin_lock(&msg_queue_spinlock); 2039 + while (user_service->msg_remove != user_service->msg_insert) { 2040 + VCHIQ_HEADER_T *header; 2041 + int m = user_service->msg_remove & (MSG_QUEUE_SIZE - 1); 2068 2042 2069 - while (user_service->msg_remove != 2070 - user_service->msg_insert) { 2071 - VCHIQ_HEADER_T *header; 2072 - int m = user_service->msg_remove & 2073 - (MSG_QUEUE_SIZE - 1); 2074 - 2075 - header = user_service->msg_queue[m]; 2076 - user_service->msg_remove++; 2077 - spin_unlock(&msg_queue_spinlock); 2078 - 2079 - if (header) 2080 - vchiq_release_message( 2081 - service->handle, 2082 - header); 2083 - spin_lock(&msg_queue_spinlock); 2084 - } 2085 - 2043 + header = user_service->msg_queue[m]; 2044 + user_service->msg_remove++; 2086 2045 spin_unlock(&msg_queue_spinlock); 2087 2046 2047 + if (header) 2048 + vchiq_release_message(service->handle, header); 2049 + spin_lock(&msg_queue_spinlock); 2050 + } 2051 + 2052 + spin_unlock(&msg_queue_spinlock); 2053 + 2054 + unlock_service(service); 2055 + } 2056 + 2057 + /* Release any closed services */ 2058 + while (instance->completion_remove != 2059 + instance->completion_insert) { 2060 + VCHIQ_COMPLETION_DATA_T *completion; 2061 + VCHIQ_SERVICE_T *service; 2062 + 2063 + completion = &instance->completions[ 2064 + instance->completion_remove & (MAX_COMPLETIONS - 1)]; 2065 + service = completion->service_userdata; 2066 + if (completion->reason == VCHIQ_SERVICE_CLOSED) { 2067 + USER_SERVICE_T *user_service = service->base.userdata; 2068 + 2069 + /* Wake any blocked user-thread */ 2070 + if (instance->use_close_delivered) 2071 + complete(&user_service->close_event); 2088 2072 unlock_service(service); 2089 2073 } 2090 - 2091 - /* Release any closed services */ 2092 - while (instance->completion_remove != 2093 - instance->completion_insert) { 2094 - VCHIQ_COMPLETION_DATA_T *completion; 2095 - VCHIQ_SERVICE_T *service; 2096 - 2097 - completion = &instance->completions[ 2098 - instance->completion_remove & 2099 - (MAX_COMPLETIONS - 1)]; 2100 - service = completion->service_userdata; 2101 - if (completion->reason == VCHIQ_SERVICE_CLOSED) { 2102 - USER_SERVICE_T *user_service = 2103 - service->base.userdata; 2104 - 2105 - /* Wake any blocked user-thread */ 2106 - if (instance->use_close_delivered) 2107 - complete(&user_service->close_event); 2108 - unlock_service(service); 2109 - } 2110 - instance->completion_remove++; 2111 - } 2112 - 2113 - /* Release the PEER service count. */ 2114 - vchiq_release_internal(instance->state, NULL); 2115 - 2116 - { 2117 - struct bulk_waiter_node *waiter, *next; 2118 - 2119 - list_for_each_entry_safe(waiter, next, 2120 - &instance->bulk_waiter_list, list) { 2121 - list_del(&waiter->list); 2122 - vchiq_log_info(vchiq_arm_log_level, 2123 - "bulk_waiter - cleaned up %pK for pid %d", 2124 - waiter, waiter->pid); 2125 - kfree(waiter); 2126 - } 2127 - } 2128 - 2129 - vchiq_debugfs_remove_instance(instance); 2130 - 2131 - kfree(instance); 2132 - file->private_data = NULL; 2133 - } break; 2134 - 2135 - default: 2136 - vchiq_log_error(vchiq_arm_log_level, 2137 - "Unknown minor device: %d", dev); 2138 - ret = -ENXIO; 2074 + instance->completion_remove++; 2139 2075 } 2076 + 2077 + /* Release the PEER service count. */ 2078 + vchiq_release_internal(instance->state, NULL); 2079 + 2080 + { 2081 + struct bulk_waiter_node *waiter, *next; 2082 + 2083 + list_for_each_entry_safe(waiter, next, 2084 + &instance->bulk_waiter_list, list) { 2085 + list_del(&waiter->list); 2086 + vchiq_log_info(vchiq_arm_log_level, 2087 + "bulk_waiter - cleaned up %pK for pid %d", 2088 + waiter, waiter->pid); 2089 + kfree(waiter); 2090 + } 2091 + } 2092 + 2093 + vchiq_debugfs_remove_instance(instance); 2094 + 2095 + kfree(instance); 2096 + file->private_data = NULL; 2140 2097 2141 2098 out: 2142 2099 return ret; ··· 3566 3613 return PTR_ERR(vchiq_class); 3567 3614 } 3568 3615 3569 - ret = alloc_chrdev_region(&vchiq_devid, VCHIQ_MINOR, 1, DEVICE_NAME); 3616 + ret = alloc_chrdev_region(&vchiq_devid, 0, 1, DEVICE_NAME); 3570 3617 if (ret) { 3571 3618 pr_err("Failed to allocate vchiq's chrdev region\n"); 3572 3619 goto class_destroy;