1a2
> * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
105,106c106,108
< int is_vchi;
< int dequeue_pending;
---
> char is_vchi;
> char dequeue_pending;
> char close_pending;
111a114
> struct semaphore close_event;
133a137,138
> int use_close_delivered;
> int trace;
138c143,145
< struct proc_dir_entry *proc_entry;
---
> #ifdef notyet
> VCHIQ_DEBUGFS_NODE_T proc_entry;
> #endif
168c175,177
< "DUMP_PHYS_MEM"
---
> "DUMP_PHYS_MEM",
> "LIB_VERSION",
> "CLOSE_DELIVERED"
235c244
< if (reason == VCHIQ_SERVICE_CLOSED)
---
> if (reason == VCHIQ_SERVICE_CLOSED) {
238a248,250
> if (instance->use_close_delivered)
> user_service->close_pending = 1;
> }
285c297
< "service_callback - service %lx(%d), handle %x, reason %d, header %lx, "
---
> "service_callback - service %lx(%d,%p), reason %d, header %lx, "
288c300
< service->localport, service->handle,
---
> service->localport, user_service->userdata,
379a392,413
> * close_delivered
> *
> ***************************************************************************/
> static void close_delivered(USER_SERVICE_T *user_service)
> {
> vchiq_log_info(vchiq_arm_log_level,
> "close_delivered(handle=%x)",
> user_service->service->handle);
>
> if (user_service->close_pending) {
> /* Allow the underlying service to be culled */
> unlock_service(user_service->service);
>
> /* Wake the user-thread blocked in close_ or remove_service */
> up(&user_service->close_event);
>
> user_service->close_pending = 0;
> }
> }
>
> /****************************************************************************
> *
499c533
< user_service->is_vchi = args.is_vchi;
---
> user_service->is_vchi = (args.is_vchi != 0);
500a535
> user_service->close_pending = 0;
506a542
> _sema_init(&user_service->close_event, 0);
546,547c582,599
< if (service != NULL)
< status = vchiq_close_service(service->handle);
---
> if (service != NULL) {
> USER_SERVICE_T *user_service =
> (USER_SERVICE_T *)service->base.userdata;
> /* close_pending is false on first entry, and when the
> wait in vchiq_close_service has been interrupted. */
> if (!user_service->close_pending) {
> status = vchiq_close_service(service->handle);
> if (status != VCHIQ_SUCCESS)
> break;
> }
>
> /* close_pending is true once the underlying service
> has been closed until the client library calls the
> CLOSE_DELIVERED ioctl, signalling close_event. */
> if (user_service->close_pending &&
> down_interruptible(&user_service->close_event))
> status = VCHIQ_RETRY;
> }
562,563c614,631
< if (service != NULL)
< status = vchiq_remove_service(service->handle);
---
> if (service != NULL) {
> USER_SERVICE_T *user_service =
> (USER_SERVICE_T *)service->base.userdata;
> /* close_pending is false on first entry, and when the
> wait in vchiq_close_service has been interrupted. */
> if (!user_service->close_pending) {
> status = vchiq_remove_service(service->handle);
> if (status != VCHIQ_SUCCESS)
> break;
> }
>
> /* close_pending is true once the underlying service
> has been closed until the client library calls the
> CLOSE_DELIVERED ioctl, signalling close_event. */
> if (user_service->close_pending &&
> down_interruptible(&user_service->close_event))
> status = VCHIQ_RETRY;
> }
827,828c895,897
< if (completion->reason ==
< VCHIQ_SERVICE_CLOSED)
---
> if ((completion->reason ==
> VCHIQ_SERVICE_CLOSED) &&
> !instance->use_close_delivered)
1009a1079,1101
> case VCHIQ_IOC_LIB_VERSION: {
> unsigned int lib_version = (unsigned int)arg;
>
> if (lib_version < VCHIQ_VERSION_MIN)
> ret = -EINVAL;
> else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED)
> instance->use_close_delivered = 1;
> } break;
>
> case VCHIQ_IOC_CLOSE_DELIVERED: {
> VCHIQ_SERVICE_HANDLE_T handle;
> memcpy(&handle, (const void*)arg, sizeof(handle));
>
> service = find_closed_service_for_instance(instance, handle);
> if (service != NULL) {
> USER_SERVICE_T *user_service =
> (USER_SERVICE_T *)service->base.userdata;
> close_delivered(user_service);
> }
> else
> ret = -EINVAL;
> } break;
>
1211a1304,1310
> {
> USER_SERVICE_T *user_service =
> service->base.userdata;
>
> /* Wake any blocked user-thread */
> if (instance->use_close_delivered)
> up(&user_service->close_event);
1212a1312
> }
1707c1807
< inline void
---
> void
1727a1828
> /* TODO: reinit_completion */
1744c1845
< inline void
---
> void
1755a1857
> /* TODO: reinit_completion */
1817a1920
> /* TODO: reinit_completion */
1862a1966
> /* TODO: reinit_completion */
> * Copyright (c) 2014 Raspberry Pi (Trading) Ltd. All rights reserved.
105,106c106,108
< int is_vchi;
< int dequeue_pending;
---
> char is_vchi;
> char dequeue_pending;
> char close_pending;
111a114
> struct semaphore close_event;
133a137,138
> int use_close_delivered;
> int trace;
138c143,145
< struct proc_dir_entry *proc_entry;
---
> #ifdef notyet
> VCHIQ_DEBUGFS_NODE_T proc_entry;
> #endif
168c175,177
< "DUMP_PHYS_MEM"
---
> "DUMP_PHYS_MEM",
> "LIB_VERSION",
> "CLOSE_DELIVERED"
235c244
< if (reason == VCHIQ_SERVICE_CLOSED)
---
> if (reason == VCHIQ_SERVICE_CLOSED) {
238a248,250
> if (instance->use_close_delivered)
> user_service->close_pending = 1;
> }
285c297
< "service_callback - service %lx(%d), handle %x, reason %d, header %lx, "
---
> "service_callback - service %lx(%d,%p), reason %d, header %lx, "
288c300
< service->localport, service->handle,
---
> service->localport, user_service->userdata,
379a392,413
> * close_delivered
> *
> ***************************************************************************/
> static void close_delivered(USER_SERVICE_T *user_service)
> {
> vchiq_log_info(vchiq_arm_log_level,
> "close_delivered(handle=%x)",
> user_service->service->handle);
>
> if (user_service->close_pending) {
> /* Allow the underlying service to be culled */
> unlock_service(user_service->service);
>
> /* Wake the user-thread blocked in close_ or remove_service */
> up(&user_service->close_event);
>
> user_service->close_pending = 0;
> }
> }
>
> /****************************************************************************
> *
499c533
< user_service->is_vchi = args.is_vchi;
---
> user_service->is_vchi = (args.is_vchi != 0);
500a535
> user_service->close_pending = 0;
506a542
> _sema_init(&user_service->close_event, 0);
546,547c582,599
< if (service != NULL)
< status = vchiq_close_service(service->handle);
---
> if (service != NULL) {
> USER_SERVICE_T *user_service =
> (USER_SERVICE_T *)service->base.userdata;
> /* close_pending is false on first entry, and when the
> wait in vchiq_close_service has been interrupted. */
> if (!user_service->close_pending) {
> status = vchiq_close_service(service->handle);
> if (status != VCHIQ_SUCCESS)
> break;
> }
>
> /* close_pending is true once the underlying service
> has been closed until the client library calls the
> CLOSE_DELIVERED ioctl, signalling close_event. */
> if (user_service->close_pending &&
> down_interruptible(&user_service->close_event))
> status = VCHIQ_RETRY;
> }
562,563c614,631
< if (service != NULL)
< status = vchiq_remove_service(service->handle);
---
> if (service != NULL) {
> USER_SERVICE_T *user_service =
> (USER_SERVICE_T *)service->base.userdata;
> /* close_pending is false on first entry, and when the
> wait in vchiq_close_service has been interrupted. */
> if (!user_service->close_pending) {
> status = vchiq_remove_service(service->handle);
> if (status != VCHIQ_SUCCESS)
> break;
> }
>
> /* close_pending is true once the underlying service
> has been closed until the client library calls the
> CLOSE_DELIVERED ioctl, signalling close_event. */
> if (user_service->close_pending &&
> down_interruptible(&user_service->close_event))
> status = VCHIQ_RETRY;
> }
827,828c895,897
< if (completion->reason ==
< VCHIQ_SERVICE_CLOSED)
---
> if ((completion->reason ==
> VCHIQ_SERVICE_CLOSED) &&
> !instance->use_close_delivered)
1009a1079,1101
> case VCHIQ_IOC_LIB_VERSION: {
> unsigned int lib_version = (unsigned int)arg;
>
> if (lib_version < VCHIQ_VERSION_MIN)
> ret = -EINVAL;
> else if (lib_version >= VCHIQ_VERSION_CLOSE_DELIVERED)
> instance->use_close_delivered = 1;
> } break;
>
> case VCHIQ_IOC_CLOSE_DELIVERED: {
> VCHIQ_SERVICE_HANDLE_T handle;
> memcpy(&handle, (const void*)arg, sizeof(handle));
>
> service = find_closed_service_for_instance(instance, handle);
> if (service != NULL) {
> USER_SERVICE_T *user_service =
> (USER_SERVICE_T *)service->base.userdata;
> close_delivered(user_service);
> }
> else
> ret = -EINVAL;
> } break;
>
1211a1304,1310
> {
> USER_SERVICE_T *user_service =
> service->base.userdata;
>
> /* Wake any blocked user-thread */
> if (instance->use_close_delivered)
> up(&user_service->close_event);
1212a1312
> }
1707c1807
< inline void
---
> void
1727a1828
> /* TODO: reinit_completion */
1744c1845
< inline void
---
> void
1755a1857
> /* TODO: reinit_completion */
1817a1920
> /* TODO: reinit_completion */
1862a1966
> /* TODO: reinit_completion */