Changeset View
Changeset View
Standalone View
Standalone View
sys/contrib/vchiq/interface/vchiq_arm/vchiq_arm.c
| Show First 20 Lines • Show All 380 Lines • ▼ Show 20 Lines | |||||
| * | * | ||||
| * user_service_free | * user_service_free | ||||
| * | * | ||||
| ***************************************************************************/ | ***************************************************************************/ | ||||
| static void | static void | ||||
| user_service_free(void *userdata) | user_service_free(void *userdata) | ||||
| { | { | ||||
| USER_SERVICE_T *user_service = userdata; | USER_SERVICE_T *user_service = userdata; | ||||
| _sema_destroy(&user_service->insert_event); | _sema_destroy(&user_service->insert_event); | ||||
| _sema_destroy(&user_service->remove_event); | _sema_destroy(&user_service->remove_event); | ||||
| kfree(user_service); | kfree(user_service); | ||||
| } | } | ||||
| /**************************************************************************** | /**************************************************************************** | ||||
| * | * | ||||
| * close_delivered | * close_delivered | ||||
| * | * | ||||
| ***************************************************************************/ | ***************************************************************************/ | ||||
| static void close_delivered(USER_SERVICE_T *user_service) | static void close_delivered(USER_SERVICE_T *user_service) | ||||
| { | { | ||||
| vchiq_log_info(vchiq_arm_log_level, | vchiq_log_info(vchiq_arm_log_level, | ||||
| "close_delivered(handle=%x)", | "close_delivered(handle=%x)", | ||||
| user_service->service->handle); | user_service->service->handle); | ||||
| if (user_service->close_pending) { | if (user_service->close_pending) { | ||||
| /* Allow the underlying service to be culled */ | /* Allow the underlying service to be culled */ | ||||
| unlock_service(user_service->service); | unlock_service(user_service->service); | ||||
| /* Wake the user-thread blocked in close_ or remove_service */ | /* Wake the user-thread blocked in close_ or remove_service */ | ||||
| up(&user_service->close_event); | up(&user_service->close_event); | ||||
| user_service->close_pending = 0; | user_service->close_pending = 0; | ||||
| } | } | ||||
| } | } | ||||
| /**************************************************************************** | /**************************************************************************** | ||||
| * | * | ||||
| * vchiq_ioctl | * vchiq_ioctl | ||||
| * | * | ||||
| Show All 15 Lines | if ((ret = devfs_get_cdevpriv((void**)&instance))) { | ||||
| return (ret); | return (ret); | ||||
| } | } | ||||
| /* XXXBSD: HACK! */ | /* XXXBSD: HACK! */ | ||||
| #define _IOC_NR(x) ((x) & 0xff) | #define _IOC_NR(x) ((x) & 0xff) | ||||
| #define _IOC_TYPE(x) IOCGROUP(x) | #define _IOC_TYPE(x) IOCGROUP(x) | ||||
| vchiq_log_trace(vchiq_arm_log_level, | vchiq_log_trace(vchiq_arm_log_level, | ||||
| "vchiq_ioctl - instance %x, cmd %s, arg %p", | "vchiq_ioctl - instance %zx, cmd %s, arg %p", | ||||
| (unsigned int)instance, | (size_t)instance, | ||||
| ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && | ((_IOC_TYPE(cmd) == VCHIQ_IOC_MAGIC) && | ||||
| (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ? | (_IOC_NR(cmd) <= VCHIQ_IOC_MAX)) ? | ||||
| ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg); | ioctl_names[_IOC_NR(cmd)] : "<invalid>", arg); | ||||
| switch (cmd) { | switch (cmd) { | ||||
| case VCHIQ_IOC_SHUTDOWN: | case VCHIQ_IOC_SHUTDOWN: | ||||
| if (!instance->connected) | if (!instance->connected) | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | if (args.mode == VCHIQ_BULK_MODE_BLOCKING) { | ||||
| if (!waiter) { | if (!waiter) { | ||||
| vchiq_log_error(vchiq_arm_log_level, | vchiq_log_error(vchiq_arm_log_level, | ||||
| "no bulk_waiter found for pid %d", | "no bulk_waiter found for pid %d", | ||||
| current->p_pid); | current->p_pid); | ||||
| ret = -ESRCH; | ret = -ESRCH; | ||||
| break; | break; | ||||
| } | } | ||||
| vchiq_log_info(vchiq_arm_log_level, | vchiq_log_info(vchiq_arm_log_level, | ||||
| "found bulk_waiter %x for pid %d", | "found bulk_waiter %zx for pid %d", | ||||
| (unsigned int)waiter, current->p_pid); | (size_t)waiter, current->p_pid); | ||||
| args.userdata = &waiter->bulk_waiter; | args.userdata = &waiter->bulk_waiter; | ||||
| } | } | ||||
| status = vchiq_bulk_transfer | status = vchiq_bulk_transfer | ||||
| (args.handle, | (args.handle, | ||||
| VCHI_MEM_HANDLE_INVALID, | VCHI_MEM_HANDLE_INVALID, | ||||
| args.data, args.size, | args.data, args.size, | ||||
| args.userdata, args.mode, | args.userdata, args.mode, | ||||
| dir); | dir); | ||||
| if (!waiter) | if (!waiter) | ||||
| break; | break; | ||||
| Show All 11 Lines | case VCHIQ_IOC_QUEUE_BULK_RECEIVE: { | ||||
| } else { | } else { | ||||
| const VCHIQ_BULK_MODE_T mode_waiting = | const VCHIQ_BULK_MODE_T mode_waiting = | ||||
| VCHIQ_BULK_MODE_WAITING; | VCHIQ_BULK_MODE_WAITING; | ||||
| waiter->pid = current->p_pid; | waiter->pid = current->p_pid; | ||||
| lmutex_lock(&instance->bulk_waiter_list_mutex); | lmutex_lock(&instance->bulk_waiter_list_mutex); | ||||
| list_add(&waiter->list, &instance->bulk_waiter_list); | list_add(&waiter->list, &instance->bulk_waiter_list); | ||||
| lmutex_unlock(&instance->bulk_waiter_list_mutex); | lmutex_unlock(&instance->bulk_waiter_list_mutex); | ||||
| vchiq_log_info(vchiq_arm_log_level, | vchiq_log_info(vchiq_arm_log_level, | ||||
| "saved bulk_waiter %x for pid %d", | "saved bulk_waiter %zx for pid %d", | ||||
| (unsigned int)waiter, current->p_pid); | (size_t)waiter, current->p_pid); | ||||
| memcpy((void *) | memcpy((void *) | ||||
| &(((VCHIQ_QUEUE_BULK_TRANSFER_T *) | &(((VCHIQ_QUEUE_BULK_TRANSFER_T *) | ||||
| arg)->mode), | arg)->mode), | ||||
| (const void *)&mode_waiting, | (const void *)&mode_waiting, | ||||
| sizeof(mode_waiting)); | sizeof(mode_waiting)); | ||||
| } | } | ||||
| } break; | } break; | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | if (ret == 0) { | ||||
| int msglen; | int msglen; | ||||
| msglen = header->size + | msglen = header->size + | ||||
| sizeof(VCHIQ_HEADER_T); | sizeof(VCHIQ_HEADER_T); | ||||
| /* This must be a VCHIQ-style service */ | /* This must be a VCHIQ-style service */ | ||||
| if (args.msgbufsize < msglen) { | if (args.msgbufsize < msglen) { | ||||
| vchiq_log_error( | vchiq_log_error( | ||||
| vchiq_arm_log_level, | vchiq_arm_log_level, | ||||
| "header %x: msgbufsize" | "header %zx: msgbufsize" | ||||
| " %x < msglen %x", | " %x < msglen %x", | ||||
| (unsigned int)header, | (size_t)header, | ||||
| args.msgbufsize, | args.msgbufsize, | ||||
| msglen); | msglen); | ||||
| WARN(1, "invalid message " | WARN(1, "invalid message " | ||||
| "size\n"); | "size\n"); | ||||
| if (count == 0) | if (count == 0) | ||||
| ret = -EMSGSIZE; | ret = -EMSGSIZE; | ||||
| break; | break; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | else if (header->size <= args.bufsize) { | ||||
| sizeof(args)); | sizeof(args)); | ||||
| vchiq_release_message( | vchiq_release_message( | ||||
| service->handle, | service->handle, | ||||
| header); | header); | ||||
| } else | } else | ||||
| ret = -EFAULT; | ret = -EFAULT; | ||||
| } else { | } else { | ||||
| vchiq_log_error(vchiq_arm_log_level, | vchiq_log_error(vchiq_arm_log_level, | ||||
| "header %x: bufsize %x < size %x", | "header %zx: bufsize %x < size %x", | ||||
| (unsigned int)header, args.bufsize, | (size_t)header, args.bufsize, | ||||
| header->size); | header->size); | ||||
| WARN(1, "invalid size\n"); | WARN(1, "invalid size\n"); | ||||
| ret = -EMSGSIZE; | ret = -EMSGSIZE; | ||||
| } | } | ||||
| DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); | DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); | ||||
| } break; | } break; | ||||
| case VCHIQ_IOC_GET_CLIENT_ID: { | case VCHIQ_IOC_GET_CLIENT_ID: { | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | case VCHIQ_IOC_DUMP_PHYS_MEM: { | ||||
| memcpy(&args, (const void*)arg, sizeof(args)); | memcpy(&args, (const void*)arg, sizeof(args)); | ||||
| printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__); | printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__); | ||||
| #if 0 | #if 0 | ||||
| dump_phys_mem(args.virt_addr, args.num_bytes); | dump_phys_mem(args.virt_addr, args.num_bytes); | ||||
| #endif | #endif | ||||
| } break; | } break; | ||||
| case VCHIQ_IOC_LIB_VERSION: { | case VCHIQ_IOC_LIB_VERSION: { | ||||
| unsigned int lib_version = (unsigned int)arg; | size_t lib_version = (size_t)arg; | ||||
| if (lib_version < VCHIQ_VERSION_MIN) | if (lib_version < VCHIQ_VERSION_MIN) | ||||
| ret = -EINVAL; | ret = -EINVAL; | ||||
| else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED) | else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED) | ||||
| instance->use_close_delivered = 1; | instance->use_close_delivered = 1; | ||||
| } break; | } break; | ||||
| case VCHIQ_IOC_CLOSE_DELIVERED: { | case VCHIQ_IOC_CLOSE_DELIVERED: { | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | #endif | ||||
| /* XXXBSD: report BSD-style error to userland */ | /* XXXBSD: report BSD-style error to userland */ | ||||
| if (ret < 0) | if (ret < 0) | ||||
| ret = -ret; | ret = -ret; | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| static void | |||||
| instance_dtr(void *data) | |||||
| { | |||||
| kfree(data); | |||||
| } | |||||
| /**************************************************************************** | /**************************************************************************** | ||||
| * | * | ||||
| * vchiq_open | * vchiq_open | ||||
| * | * | ||||
| ***************************************************************************/ | ***************************************************************************/ | ||||
| static void instance_dtr(void *data); | |||||
| static int | static int | ||||
| vchiq_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) | vchiq_open(struct cdev *dev, int flags, int fmt __unused, struct thread *td) | ||||
| { | { | ||||
| vchiq_log_info(vchiq_arm_log_level, "vchiq_open"); | vchiq_log_info(vchiq_arm_log_level, "vchiq_open"); | ||||
| /* XXXBSD: do we really need this check? */ | /* XXXBSD: do we really need this check? */ | ||||
| if (1) { | if (1) { | ||||
| VCHIQ_STATE_T *state = vchiq_get_state(); | VCHIQ_STATE_T *state = vchiq_get_state(); | ||||
| Show All 23 Lines | #endif | ||||
| _sema_init(&instance->insert_event, 0); | _sema_init(&instance->insert_event, 0); | ||||
| _sema_init(&instance->remove_event, 0); | _sema_init(&instance->remove_event, 0); | ||||
| lmutex_init(&instance->completion_mutex); | lmutex_init(&instance->completion_mutex); | ||||
| lmutex_init(&instance->bulk_waiter_list_mutex); | lmutex_init(&instance->bulk_waiter_list_mutex); | ||||
| INIT_LIST_HEAD(&instance->bulk_waiter_list); | INIT_LIST_HEAD(&instance->bulk_waiter_list); | ||||
| devfs_set_cdevpriv(instance, instance_dtr); | devfs_set_cdevpriv(instance, instance_dtr); | ||||
| } | } | ||||
| else { | else { | ||||
| vchiq_log_error(vchiq_arm_log_level, | vchiq_log_error(vchiq_arm_log_level, | ||||
| "Unknown minor device"); | "Unknown minor device"); | ||||
| return -ENXIO; | return -ENXIO; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /**************************************************************************** | /**************************************************************************** | ||||
| * | * | ||||
| * vchiq_release | * vchiq_release | ||||
| * | * | ||||
| ***************************************************************************/ | ***************************************************************************/ | ||||
| static int | static int | ||||
| vchiq_close(struct cdev *dev, int flags __unused, int fmt __unused, | _vchiq_close_instance(VCHIQ_INSTANCE_T instance) | ||||
| struct thread *td) | |||||
| { | { | ||||
| int ret = 0; | int ret = 0; | ||||
| if (1) { | |||||
| VCHIQ_INSTANCE_T instance; | |||||
| VCHIQ_STATE_T *state = vchiq_get_state(); | VCHIQ_STATE_T *state = vchiq_get_state(); | ||||
| VCHIQ_SERVICE_T *service; | VCHIQ_SERVICE_T *service; | ||||
| int i; | int i; | ||||
| if ((ret = devfs_get_cdevpriv((void**)&instance))) { | |||||
| printf("devfs_get_cdevpriv failed: error %d\n", ret); | |||||
| return (ret); | |||||
| } | |||||
| vchiq_log_info(vchiq_arm_log_level, | vchiq_log_info(vchiq_arm_log_level, | ||||
| "vchiq_release: instance=%lx", | "vchiq_release: instance=%lx", | ||||
| (unsigned long)instance); | (unsigned long)instance); | ||||
| if (!state) { | if (!state) { | ||||
| ret = -EPERM; | ret = -EPERM; | ||||
| goto out; | goto out; | ||||
| } | } | ||||
| /* Ensure videocore is awake to allow termination. */ | /* Ensure videocore is awake to allow termination. */ | ||||
| vchiq_use_internal(instance->state, NULL, | vchiq_use_internal(instance->state, NULL, | ||||
| USE_TYPE_VCHIQ); | USE_TYPE_VCHIQ); | ||||
| lmutex_lock(&instance->completion_mutex); | lmutex_lock(&instance->completion_mutex); | ||||
| /* Wake the completion thread and ask it to exit */ | /* Wake the completion thread and ask it to exit */ | ||||
| instance->closing = 1; | instance->closing = 1; | ||||
| up(&instance->insert_event); | up(&instance->insert_event); | ||||
| lmutex_unlock(&instance->completion_mutex); | lmutex_unlock(&instance->completion_mutex); | ||||
| /* Wake the slot handler if the completion queue is full. */ | /* Wake the slot handler if the completion queue is full. */ | ||||
| up(&instance->remove_event); | up(&instance->remove_event); | ||||
| /* Mark all services for termination... */ | /* Mark all services for termination... */ | ||||
| i = 0; | i = 0; | ||||
| while ((service = next_service_by_instance(state, instance, | while ((service = next_service_by_instance(state, instance, | ||||
| &i)) != NULL) { | &i)) != NULL) { | ||||
| USER_SERVICE_T *user_service = service->base.userdata; | USER_SERVICE_T *user_service = service->base.userdata; | ||||
| /* Wake the slot handler if the msg queue is full. */ | /* Wake the slot handler if the msg queue is full. */ | ||||
| up(&user_service->remove_event); | up(&user_service->remove_event); | ||||
| vchiq_terminate_service_internal(service); | vchiq_terminate_service_internal(service); | ||||
| unlock_service(service); | unlock_service(service); | ||||
| } | } | ||||
| /* ...and wait for them to die */ | /* ...and wait for them to die */ | ||||
| i = 0; | i = 0; | ||||
| while ((service = next_service_by_instance(state, instance, &i)) | while ((service = next_service_by_instance(state, instance, &i)) | ||||
| != NULL) { | != NULL) { | ||||
| USER_SERVICE_T *user_service = service->base.userdata; | USER_SERVICE_T *user_service = service->base.userdata; | ||||
| down(&service->remove_event); | down(&service->remove_event); | ||||
| BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); | BUG_ON(service->srvstate != VCHIQ_SRVSTATE_FREE); | ||||
| spin_lock(&msg_queue_spinlock); | spin_lock(&msg_queue_spinlock); | ||||
| while (user_service->msg_remove != | while (user_service->msg_remove != | ||||
| user_service->msg_insert) { | user_service->msg_insert) { | ||||
| VCHIQ_HEADER_T *header = user_service-> | VCHIQ_HEADER_T *header = user_service-> | ||||
| msg_queue[user_service->msg_remove & | msg_queue[user_service->msg_remove & | ||||
| (MSG_QUEUE_SIZE - 1)]; | (MSG_QUEUE_SIZE - 1)]; | ||||
| user_service->msg_remove++; | user_service->msg_remove++; | ||||
| spin_unlock(&msg_queue_spinlock); | spin_unlock(&msg_queue_spinlock); | ||||
| if (header) | if (header) | ||||
| vchiq_release_message( | vchiq_release_message( | ||||
| service->handle, | service->handle, | ||||
| header); | header); | ||||
| spin_lock(&msg_queue_spinlock); | spin_lock(&msg_queue_spinlock); | ||||
| } | } | ||||
| spin_unlock(&msg_queue_spinlock); | spin_unlock(&msg_queue_spinlock); | ||||
| unlock_service(service); | unlock_service(service); | ||||
| } | } | ||||
| /* Release any closed services */ | /* Release any closed services */ | ||||
| while (instance->completion_remove != | while (instance->completion_remove != | ||||
| instance->completion_insert) { | instance->completion_insert) { | ||||
| VCHIQ_COMPLETION_DATA_T *completion; | VCHIQ_COMPLETION_DATA_T *completion; | ||||
| VCHIQ_SERVICE_T *service1; | VCHIQ_SERVICE_T *service; | ||||
| completion = &instance->completions[ | completion = &instance->completions[ | ||||
| instance->completion_remove & | instance->completion_remove & | ||||
| (MAX_COMPLETIONS - 1)]; | (MAX_COMPLETIONS - 1)]; | ||||
| service1 = completion->service_userdata; | service = completion->service_userdata; | ||||
| if (completion->reason == VCHIQ_SERVICE_CLOSED) | if (completion->reason == VCHIQ_SERVICE_CLOSED) | ||||
| { | { | ||||
| USER_SERVICE_T *user_service = | USER_SERVICE_T *user_service = | ||||
| service->base.userdata; | service->base.userdata; | ||||
| /* Wake any blocked user-thread */ | /* Wake any blocked user-thread */ | ||||
| if (instance->use_close_delivered) | if (instance->use_close_delivered) | ||||
| up(&user_service->close_event); | up(&user_service->close_event); | ||||
| unlock_service(service1); | |||||
| unlock_service(service); | |||||
| } | } | ||||
| instance->completion_remove++; | instance->completion_remove++; | ||||
| } | } | ||||
| /* Release the PEER service count. */ | /* Release the PEER service count. */ | ||||
| vchiq_release_internal(instance->state, NULL); | vchiq_release_internal(instance->state, NULL); | ||||
| { | { | ||||
| struct list_head *pos, *next; | struct list_head *pos, *next; | ||||
| list_for_each_safe(pos, next, | list_for_each_safe(pos, next, | ||||
| &instance->bulk_waiter_list) { | &instance->bulk_waiter_list) { | ||||
| struct bulk_waiter_node *waiter; | struct bulk_waiter_node *waiter; | ||||
| waiter = list_entry(pos, | waiter = list_entry(pos, | ||||
| struct bulk_waiter_node, | struct bulk_waiter_node, | ||||
| list); | list); | ||||
| list_del(pos); | list_del(pos); | ||||
| vchiq_log_info(vchiq_arm_log_level, | vchiq_log_info(vchiq_arm_log_level, | ||||
| "bulk_waiter - cleaned up %x " | "bulk_waiter - cleaned up %zx " | ||||
| "for pid %d", | "for pid %d", | ||||
| (unsigned int)waiter, waiter->pid); | (size_t)waiter, waiter->pid); | ||||
| _sema_destroy(&waiter->bulk_waiter.event); | _sema_destroy(&waiter->bulk_waiter.event); | ||||
| kfree(waiter); | kfree(waiter); | ||||
| } | } | ||||
| } | } | ||||
| out: | |||||
| return ret; | |||||
| } | } | ||||
| else { | |||||
| vchiq_log_error(vchiq_arm_log_level, | static void | ||||
| "Unknown minor device"); | instance_dtr(void *data) | ||||
| ret = -ENXIO; | { | ||||
| VCHIQ_INSTANCE_T instance = data; | |||||
| _vchiq_close_instance(instance); | |||||
| kfree(data); | |||||
| } | } | ||||
| out: | static int | ||||
| return ret; | vchiq_close(struct cdev *dev, int flags __unused, int fmt __unused, | ||||
| struct thread *td) | |||||
| { | |||||
| /* XXXMDC it's privdata that tracks opens */ | |||||
| /* XXXMDC only get closes when there are no more open fds on a vnode */ | |||||
| return(0); | |||||
| } | } | ||||
| /**************************************************************************** | /**************************************************************************** | ||||
| * | * | ||||
| * vchiq_dump | * vchiq_dump | ||||
| * | * | ||||
| ***************************************************************************/ | ***************************************************************************/ | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | vchiq_dump_platform_instances(void *dump_context) | ||||
| for (i = 0; i < state->unused_service; i++) { | for (i = 0; i < state->unused_service; i++) { | ||||
| VCHIQ_SERVICE_T *service = state->services[i]; | VCHIQ_SERVICE_T *service = state->services[i]; | ||||
| VCHIQ_INSTANCE_T instance; | VCHIQ_INSTANCE_T instance; | ||||
| if (service && (service->base.callback == service_callback)) { | if (service && (service->base.callback == service_callback)) { | ||||
| instance = service->instance; | instance = service->instance; | ||||
| if (instance && !instance->mark) { | if (instance && !instance->mark) { | ||||
| len = snprintf(buf, sizeof(buf), | len = snprintf(buf, sizeof(buf), | ||||
| "Instance %x: pid %d,%s completions " | "Instance %zx: pid %d,%s completions " | ||||
| "%d/%d", | "%d/%d", | ||||
| (unsigned int)instance, instance->pid, | (size_t)instance, instance->pid, | ||||
| instance->connected ? " connected, " : | instance->connected ? " connected, " : | ||||
| "", | "", | ||||
| instance->completion_insert - | instance->completion_insert - | ||||
| instance->completion_remove, | instance->completion_remove, | ||||
| MAX_COMPLETIONS); | MAX_COMPLETIONS); | ||||
| vchiq_dump(dump_context, buf, len + 1); | vchiq_dump(dump_context, buf, len + 1); | ||||
| Show All 11 Lines | |||||
| void | void | ||||
| vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service) | vchiq_dump_platform_service_state(void *dump_context, VCHIQ_SERVICE_T *service) | ||||
| { | { | ||||
| USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata; | USER_SERVICE_T *user_service = (USER_SERVICE_T *)service->base.userdata; | ||||
| char buf[80]; | char buf[80]; | ||||
| int len; | int len; | ||||
| len = snprintf(buf, sizeof(buf), " instance %x", | len = snprintf(buf, sizeof(buf), " instance %zx", | ||||
| (unsigned int)service->instance); | (size_t)service->instance); | ||||
| if ((service->base.callback == service_callback) && | if ((service->base.callback == service_callback) && | ||||
| user_service->is_vchi) { | user_service->is_vchi) { | ||||
| len += snprintf(buf + len, sizeof(buf) - len, | len += snprintf(buf + len, sizeof(buf) - len, | ||||
| ", %d/%d messages", | ", %d/%d messages", | ||||
| user_service->msg_insert - user_service->msg_remove, | user_service->msg_insert - user_service->msg_remove, | ||||
| MSG_QUEUE_SIZE); | MSG_QUEUE_SIZE); | ||||
| ▲ Show 20 Lines • Show All 1,449 Lines • Show Last 20 Lines | |||||