Rev 3495 | Rev 3620 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3495 | Rev 3496 | ||
|---|---|---|---|
| Line 89... | Line 89... | ||
| 89 | ipc_cleanup_call_list(&TASK->kernel_box.dispatched_calls); |
89 | ipc_cleanup_call_list(&TASK->kernel_box.dispatched_calls); |
| 90 | ipc_cleanup_call_list(&TASK->kernel_box.calls); |
90 | ipc_cleanup_call_list(&TASK->kernel_box.calls); |
| 91 | spinlock_unlock(&TASK->kernel_box.lock); |
91 | spinlock_unlock(&TASK->kernel_box.lock); |
| 92 | } |
92 | } |
| 93 | 93 | ||
| - | 94 | /** Handle hangup message in kbox. |
|
| - | 95 | * |
|
| - | 96 | * @param call The IPC_M_PHONE_HUNGUP call structure. |
|
| - | 97 | * @param last Output, the function stores @c true here if |
|
| - | 98 | * this was the last phone, @c false otherwise. |
|
| - | 99 | **/ |
|
| - | 100 | static void kbox_proc_phone_hungup(call_t *call, bool *last) |
|
| - | 101 | { |
|
| - | 102 | ipl_t ipl; |
|
| - | 103 | ||
| - | 104 | LOG("kbox_proc_phone_hungup()\n"); |
|
| - | 105 | ||
| - | 106 | /* Was it our debugger, who hung up? */ |
|
| - | 107 | if (call->sender == TASK->udebug.debugger) { |
|
| - | 108 | /* Terminate debugging session (if any) */ |
|
| - | 109 | LOG("kbox: terminate debug session\n"); |
|
| - | 110 | ipl = interrupts_disable(); |
|
| - | 111 | spinlock_lock(&TASK->lock); |
|
| - | 112 | udebug_task_cleanup(TASK); |
|
| - | 113 | spinlock_unlock(&TASK->lock); |
|
| - | 114 | interrupts_restore(ipl); |
|
| - | 115 | } else { |
|
| - | 116 | LOG("kbox: was not debugger\n"); |
|
| - | 117 | } |
|
| - | 118 | ||
| - | 119 | LOG("kbox: continue with hangup message\n"); |
|
| - | 120 | IPC_SET_RETVAL(call->data, 0); |
|
| - | 121 | ipc_answer(&TASK->kernel_box, call); |
|
| - | 122 | ||
| - | 123 | ipl = interrupts_disable(); |
|
| - | 124 | spinlock_lock(&TASK->lock); |
|
| - | 125 | spinlock_lock(&TASK->answerbox.lock); |
|
| - | 126 | if (list_empty(&TASK->answerbox.connected_phones)) { |
|
| - | 127 | /* |
|
| - | 128 | * Last phone has been disconnected. Detach this thread so it |
|
| - | 129 | * gets freed and signal to the caller. |
|
| - | 130 | */ |
|
| - | 131 | ||
| - | 132 | /* Only detach kbox thread unless already terminating. */ |
|
| - | 133 | mutex_lock(&TASK->kb_cleanup_lock); |
|
| - | 134 | if (&TASK->kb_finished == false) { |
|
| - | 135 | /* Detach kbox thread so it gets freed from memory. */ |
|
| - | 136 | thread_detach(TASK->kb_thread); |
|
| - | 137 | TASK->kb_thread = NULL; |
|
| - | 138 | } |
|
| - | 139 | mutex_unlock(&TASK->kb_cleanup_lock); |
|
| 94 | 140 | ||
| - | 141 | LOG("phone list is empty\n"); |
|
| - | 142 | *last = true; |
|
| - | 143 | } else { |
|
| - | 144 | *last = false; |
|
| - | 145 | } |
|
| - | 146 | ||
| - | 147 | spinlock_unlock(&TASK->answerbox.lock); |
|
| - | 148 | spinlock_unlock(&TASK->lock); |
|
| - | 149 | interrupts_restore(ipl); |
|
| - | 150 | } |
|
| - | 151 | ||
| - | 152 | /** Implementing function for the kbox thread. |
|
| - | 153 | * |
|
| - | 154 | * This function listens for debug requests. It terminates |
|
| - | 155 | * when all phones are disconnected from the kbox. |
|
| - | 156 | * |
|
| - | 157 | * @param arg Ignored. |
|
| - | 158 | */ |
|
| 95 | static void kbox_thread_proc(void *arg) |
159 | static void kbox_thread_proc(void *arg) |
| 96 | { |
160 | { |
| 97 | call_t *call; |
161 | call_t *call; |
| 98 | int method; |
- | |
| 99 | bool done; |
162 | bool done; |
| 100 | ipl_t ipl; |
- | |
| 101 | 163 | ||
| 102 | (void)arg; |
164 | (void)arg; |
| 103 | LOG("kbox_thread_proc()\n"); |
165 | LOG("kbox_thread_proc()\n"); |
| 104 | done = false; |
166 | done = false; |
| 105 | 167 | ||
| 106 | while (!done) { |
168 | while (!done) { |
| 107 | call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT, |
169 | call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT, |
| 108 | SYNCH_FLAGS_NONE); |
170 | SYNCH_FLAGS_NONE); |
| 109 | 171 | ||
| 110 | if (call != NULL) { |
172 | if (call == NULL) |
| - | 173 | continue; /* Try again. */ |
|
| - | 174 | ||
| 111 | method = IPC_GET_METHOD(call->data); |
175 | switch (IPC_GET_METHOD(call->data)) { |
| 112 | 176 | ||
| 113 | if (method == IPC_M_DEBUG_ALL) { |
177 | case IPC_M_DEBUG_ALL: |
| - | 178 | /* Handle debug call. */ |
|
| 114 | udebug_call_receive(call); |
179 | udebug_call_receive(call); |
| 115 | } |
180 | break; |
| 116 | 181 | ||
| 117 | if (method == IPC_M_PHONE_HUNGUP) { |
182 | case IPC_M_PHONE_HUNGUP: |
| 118 | LOG("kbox: handle hangup message\n"); |
- | |
| 119 | - | ||
| 120 | /* Was it our debugger, who hung up? */ |
- | |
| 121 | if (call->sender == TASK->udebug.debugger) { |
- | |
| 122 | /* Terminate debugging session (if any) */ |
- | |
| 123 | LOG("kbox: terminate debug session\n"); |
- | |
| 124 | ipl = interrupts_disable(); |
- | |
| 125 | spinlock_lock(&TASK->lock); |
- | |
| 126 | udebug_task_cleanup(TASK); |
- | |
| 127 | spinlock_unlock(&TASK->lock); |
- | |
| 128 | interrupts_restore(ipl); |
- | |
| 129 | } else { |
- | |
| 130 | LOG("kbox: was not debugger\n"); |
- | |
| 131 | } |
183 | /* |
| 132 | - | ||
| 133 | LOG("kbox: continue with hangup message\n"); |
184 | * Process the hangup call. If this was the last |
| 134 | IPC_SET_RETVAL(call->data, 0); |
- | |
| 135 | ipc_answer(&TASK->kernel_box, call); |
185 | * phone, done will be set to true and the |
| 136 | - | ||
| 137 | ipl = interrupts_disable(); |
186 | * while loop will terminate. |
| 138 | spinlock_lock(&TASK->lock); |
- | |
| 139 | spinlock_lock(&TASK->answerbox.lock); |
- | |
| 140 | if (list_empty(&TASK->answerbox.connected_phones)) { |
- | |
| 141 | /* |
187 | */ |
| 142 | * Last phone has been disconnected. |
188 | kbox_proc_phone_hungup(call, &done); |
| 143 | * Detach this thread so it gets |
- | |
| 144 | * freed and terminate. |
- | |
| 145 | */ |
189 | break; |
| 146 | 190 | ||
| 147 | /* Only need to detach thread unless already terminating. */ |
- | |
| 148 | mutex_lock(&TASK->kb_cleanup_lock); |
- | |
| 149 | if (&TASK->kb_finished == false) { |
- | |
| 150 | /* Detach thread so it gets freed. */ |
- | |
| 151 | thread_detach(TASK->kb_thread); |
- | |
| 152 | TASK->kb_thread = NULL; |
- | |
| 153 | } |
191 | default: |
| 154 | mutex_unlock(&TASK->kb_cleanup_lock); |
- | |
| 155 | done = true; |
192 | /* Ignore */ |
| 156 | LOG("phone list is empty\n"); |
- | |
| 157 | } |
193 | break; |
| 158 | spinlock_unlock(&TASK->answerbox.lock); |
- | |
| 159 | spinlock_unlock(&TASK->lock); |
- | |
| 160 | interrupts_restore(ipl); |
- | |
| 161 | } |
- | |
| 162 | } |
194 | } |
| 163 | } |
195 | } |
| 164 | 196 | ||
| 165 | LOG("kbox: finished\n"); |
197 | LOG("kbox: finished\n"); |
| 166 | } |
198 | } |