Deleted Added
sdiff udiff text old ( 278430 ) new ( 290245 )
full compact
1/**
2 * Copyright (c) 2010-2012 Broadcom. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions, and the following disclaimer,
9 * without modification.

--- 87 unchanged lines hidden (view full) ---

97static void vchiq_proc_remove_instance(VCHIQ_INSTANCE_T instance);
98#endif
99
100
101typedef struct user_service_struct {
102 VCHIQ_SERVICE_T *service;
103 void *userdata;
104 VCHIQ_INSTANCE_T instance;
105 int is_vchi;
106 int dequeue_pending;
107 int message_available_pos;
108 int msg_insert;
109 int msg_remove;
110 struct semaphore insert_event;
111 struct semaphore remove_event;
112 VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE];
113} USER_SERVICE_T;
114
115struct bulk_waiter_node {
116 struct bulk_waiter bulk_waiter;
117 int pid;
118 struct list_head list;
119};

--- 6 unchanged lines hidden (view full) ---

126 struct semaphore insert_event;
127 struct semaphore remove_event;
128 struct mutex completion_mutex;
129
130 int connected;
131 int closing;
132 int pid;
133 int mark;
134
135 struct list_head bulk_waiter_list;
136 struct mutex bulk_waiter_list_mutex;
137
138 struct proc_dir_entry *proc_entry;
139};
140
141typedef struct dump_context_struct {
142 char __user *buf;
143 size_t actual;
144 size_t space;
145 loff_t offset;
146} DUMP_CONTEXT_T;

--- 13 unchanged lines hidden (view full) ---

160 "AWAIT_COMPLETION",
161 "DEQUEUE_MESSAGE",
162 "GET_CLIENT_ID",
163 "GET_CONFIG",
164 "CLOSE_SERVICE",
165 "USE_SERVICE",
166 "RELEASE_SERVICE",
167 "SET_SERVICE_OPTION",
168 "DUMP_PHYS_MEM"
169};
170
171vchiq_static_assert((sizeof(ioctl_names)/sizeof(ioctl_names[0])) ==
172 (VCHIQ_IOC_MAX + 1));
173
174static eventhandler_tag vchiq_ehtag = NULL;
175static d_open_t vchiq_open;
176static d_close_t vchiq_close;

--- 50 unchanged lines hidden (view full) ---

227 (MAX_COMPLETIONS - 1)];
228
229 completion->header = header;
230 completion->reason = reason;
231 /* N.B. service_userdata is updated while processing AWAIT_COMPLETION */
232 completion->service_userdata = user_service->service;
233 completion->bulk_userdata = bulk_userdata;
234
235 if (reason == VCHIQ_SERVICE_CLOSED)
236 /* Take an extra reference, to be held until
237 this CLOSED notification is delivered. */
238 lock_service(user_service->service);
239
240 /* A write barrier is needed here to ensure that the entire completion
241 record is written out before the insert point. */
242 wmb();
243
244 if (reason == VCHIQ_MESSAGE_AVAILABLE)
245 user_service->message_available_pos =
246 instance->completion_insert;

--- 30 unchanged lines hidden (view full) ---

277 BUG_ON(!service);
278 user_service = (USER_SERVICE_T *)service->base.userdata;
279 instance = user_service->instance;
280
281 if (!instance || instance->closing)
282 return VCHIQ_SUCCESS;
283
284 vchiq_log_trace(vchiq_arm_log_level,
285 "service_callback - service %lx(%d), handle %x, reason %d, header %lx, "
286 "instance %lx, bulk_userdata %lx",
287 (unsigned long)user_service,
288 service->localport, service->handle,
289 reason, (unsigned long)header,
290 (unsigned long)instance, (unsigned long)bulk_userdata);
291
292 if (header && user_service->is_vchi) {
293 spin_lock(&msg_queue_spinlock);
294 while (user_service->msg_insert ==
295 (user_service->msg_remove + MSG_QUEUE_SIZE)) {
296 spin_unlock(&msg_queue_spinlock);

--- 75 unchanged lines hidden (view full) ---

372 _sema_destroy(&user_service->insert_event);
373 _sema_destroy(&user_service->remove_event);
374
375 kfree(user_service);
376}
377
378/****************************************************************************
379*
380* vchiq_ioctl
381*
382***************************************************************************/
383
384static int
385vchiq_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int fflag,
386 struct thread *td)
387{

--- 103 unchanged lines hidden (view full) ---

491 instance->state,
492 &args.params, srvstate,
493 instance, user_service_free);
494
495 if (service != NULL) {
496 user_service->service = service;
497 user_service->userdata = userdata;
498 user_service->instance = instance;
499 user_service->is_vchi = args.is_vchi;
500 user_service->dequeue_pending = 0;
501 user_service->message_available_pos =
502 instance->completion_remove - 1;
503 user_service->msg_insert = 0;
504 user_service->msg_remove = 0;
505 _sema_init(&user_service->insert_event, 0);
506 _sema_init(&user_service->remove_event, 0);
507
508 if (args.is_open) {
509 status = vchiq_open_service_internal
510 (service, instance->pid);
511 if (status != VCHIQ_SUCCESS) {
512 vchiq_remove_service(service->handle);
513 service = NULL;
514 ret = (status == VCHIQ_RETRY) ?

--- 23 unchanged lines hidden (view full) ---

538
539 memcpy(&handle, (const void*)arg, sizeof(handle));
540
541#ifdef VCHIQ_IOCTL_DEBUG
542 printf("%s: [CLOSE SERVICE] handle = %08x\n", __func__, handle);
543#endif
544
545 service = find_service_for_instance(instance, handle);
546 if (service != NULL)
547 status = vchiq_close_service(service->handle);
548 else
549 ret = -EINVAL;
550 } break;
551
552 case VCHIQ_IOC_REMOVE_SERVICE: {
553 VCHIQ_SERVICE_HANDLE_T handle;
554
555 memcpy(&handle, (const void*)arg, sizeof(handle));
556
557#ifdef VCHIQ_IOCTL_DEBUG
558 printf("%s: [REMOVE SERVICE] handle = %08x\n", __func__, handle);
559#endif
560
561 service = find_service_for_instance(instance, handle);
562 if (service != NULL)
563 status = vchiq_remove_service(service->handle);
564 else
565 ret = -EINVAL;
566 } break;
567
568 case VCHIQ_IOC_USE_SERVICE:
569 case VCHIQ_IOC_RELEASE_SERVICE: {
570 VCHIQ_SERVICE_HANDLE_T handle;
571

--- 247 unchanged lines hidden (view full) ---

819 vchiq_release_message(service1->handle,
820 header);
821
822 /* The completion must point to the
823 ** msgbuf. */
824 completion->header = msgbuf;
825 }
826
827 if (completion->reason ==
828 VCHIQ_SERVICE_CLOSED)
829 unlock_service(service1);
830
831 if (copy_to_user((void __user *)(
832 (size_t)args.buf +
833 count * sizeof(VCHIQ_COMPLETION_DATA_T)),
834 completion,
835 sizeof(VCHIQ_COMPLETION_DATA_T)) != 0) {
836 if (ret == 0)

--- 165 unchanged lines hidden (view full) ---

1002
1003 memcpy(&args, (const void*)arg, sizeof(args));
1004 printf("IMPLEMENT ME: %s:%d\n", __FILE__, __LINE__);
1005#if 0
1006 dump_phys_mem(args.virt_addr, args.num_bytes);
1007#endif
1008 } break;
1009
1010 default:
1011 ret = -ENOTTY;
1012 break;
1013 }
1014
1015 if (service)
1016 unlock_service(service);
1017

--- 186 unchanged lines hidden (view full) ---

1204 instance->completion_insert) {
1205 VCHIQ_COMPLETION_DATA_T *completion;
1206 VCHIQ_SERVICE_T *service1;
1207 completion = &instance->completions[
1208 instance->completion_remove &
1209 (MAX_COMPLETIONS - 1)];
1210 service1 = completion->service_userdata;
1211 if (completion->reason == VCHIQ_SERVICE_CLOSED)
1212 unlock_service(service1);
1213 instance->completion_remove++;
1214 }
1215
1216 /* Release the PEER service count. */
1217 vchiq_release_internal(instance->state, NULL);
1218
1219 {
1220 struct list_head *pos, *next;

--- 478 unchanged lines hidden (view full) ---

1699** VC_RESUME_RESUMED - Resume has completed successfully. Videocore is running.
1700** Call complete_all on the resume completion to unblock
1701** any threads waiting for resume. Also reset the suspend
1702** state machine to it's idle state.
1703**
1704** VC_RESUME_FAILED - Currently unused - no mechanism to fail resume exists.
1705*/
1706
1707inline void
1708set_suspend_state(VCHIQ_ARM_STATE_T *arm_state,
1709 enum vc_suspend_status new_state)
1710{
1711 /* set the state in all cases */
1712 arm_state->vc_suspend_state = new_state;
1713
1714 /* state specific additional actions */
1715 switch (new_state) {

--- 4 unchanged lines hidden (view full) ---

1720 complete_all(&arm_state->vc_suspend_complete);
1721 break;
1722 case VC_SUSPEND_FAILED:
1723 complete_all(&arm_state->vc_suspend_complete);
1724 arm_state->vc_resume_state = VC_RESUME_RESUMED;
1725 complete_all(&arm_state->vc_resume_complete);
1726 break;
1727 case VC_SUSPEND_IDLE:
1728 INIT_COMPLETION(arm_state->vc_suspend_complete);
1729 break;
1730 case VC_SUSPEND_REQUESTED:
1731 break;
1732 case VC_SUSPEND_IN_PROGRESS:
1733 set_resume_state(arm_state, VC_RESUME_IDLE);
1734 break;
1735 case VC_SUSPEND_SUSPENDED:
1736 complete_all(&arm_state->vc_suspend_complete);
1737 break;
1738 default:
1739 BUG();
1740 break;
1741 }
1742}
1743
1744inline void
1745set_resume_state(VCHIQ_ARM_STATE_T *arm_state,
1746 enum vc_resume_status new_state)
1747{
1748 /* set the state in all cases */
1749 arm_state->vc_resume_state = new_state;
1750
1751 /* state specific additional actions */
1752 switch (new_state) {
1753 case VC_RESUME_FAILED:
1754 break;
1755 case VC_RESUME_IDLE:
1756 INIT_COMPLETION(arm_state->vc_resume_complete);
1757 break;
1758 case VC_RESUME_REQUESTED:
1759 break;
1760 case VC_RESUME_IN_PROGRESS:
1761 break;
1762 case VC_RESUME_RESUMED:
1763 complete_all(&arm_state->vc_resume_complete);

--- 46 unchanged lines hidden (view full) ---

1810 int resume_count = 0;
1811
1812 /* Allow any threads which were blocked by the last force suspend to
1813 * complete if they haven't already. Only give this one shot; if
1814 * blocked_count is incremented after blocked_blocker is completed
1815 * (which only happens when blocked_count hits 0) then those threads
1816 * will have to wait until next time around */
1817 if (arm_state->blocked_count) {
1818 INIT_COMPLETION(arm_state->blocked_blocker);
1819 write_unlock_bh(&arm_state->susp_res_lock);
1820 vchiq_log_info(vchiq_susp_log_level, "%s wait for previously "
1821 "blocked clients", __func__);
1822 if (wait_for_completion_interruptible_timeout(
1823 &arm_state->blocked_blocker, timeout_val)
1824 <= 0) {
1825 vchiq_log_error(vchiq_susp_log_level, "%s wait for "

--- 29 unchanged lines hidden (view full) ---

1855 status = VCHIQ_ERROR;
1856 write_lock_bh(&arm_state->susp_res_lock);
1857 goto out;
1858 }
1859 vchiq_log_info(vchiq_susp_log_level, "%s resumed", __func__);
1860 write_lock_bh(&arm_state->susp_res_lock);
1861 resume_count++;
1862 }
1863 INIT_COMPLETION(arm_state->resume_blocker);
1864 arm_state->resume_blocked = 1;
1865
1866out:
1867 return status;
1868}
1869
1870static inline void

--- 939 unchanged lines hidden ---