Rev 2359 | Rev 2637 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2359 | Rev 2471 | ||
|---|---|---|---|
| Line 130... | Line 130... | ||
| 130 | #include <arch.h> |
130 | #include <arch.h> |
| 131 | #include <proc/task.h> |
131 | #include <proc/task.h> |
| 132 | #include <ipc/ipcrsc.h> |
132 | #include <ipc/ipcrsc.h> |
| 133 | #include <debug.h> |
133 | #include <debug.h> |
| 134 | 134 | ||
| 135 | /** Find call_t * in call table according to callid |
135 | /** Find call_t * in call table according to callid. |
| 136 | * |
136 | * |
| 137 | * TODO: Some speedup (hash table?) |
137 | * @todo Some speedup (hash table?) |
| - | 138 | * |
|
| - | 139 | * @param callid Userspace hash of the call. Currently it is the call |
|
| - | 140 | * structure kernel address. |
|
| - | 141 | * |
|
| 138 | * @return NULL on not found, otherwise pointer to call structure |
142 | * @return NULL on not found, otherwise pointer to the call |
| - | 143 | * structure. |
|
| 139 | */ |
144 | */ |
| 140 | call_t * get_call(unative_t callid) |
145 | call_t *get_call(unative_t callid) |
| 141 | { |
146 | { |
| 142 | link_t *lst; |
147 | link_t *lst; |
| 143 | call_t *call, *result = NULL; |
148 | call_t *call, *result = NULL; |
| 144 | 149 | ||
| 145 | spinlock_lock(&TASK->answerbox.lock); |
150 | spinlock_lock(&TASK->answerbox.lock); |
| 146 | for (lst = TASK->answerbox.dispatched_calls.next; |
151 | for (lst = TASK->answerbox.dispatched_calls.next; |
| 147 | lst != &TASK->answerbox.dispatched_calls; lst = lst->next) { |
152 | lst != &TASK->answerbox.dispatched_calls; lst = lst->next) { |
| 148 | call = list_get_instance(lst, call_t, link); |
153 | call = list_get_instance(lst, call_t, link); |
| 149 | if ((unative_t)call == callid) { |
154 | if ((unative_t) call == callid) { |
| 150 | result = call; |
155 | result = call; |
| 151 | break; |
156 | break; |
| 152 | } |
157 | } |
| 153 | } |
158 | } |
| 154 | spinlock_unlock(&TASK->answerbox.lock); |
159 | spinlock_unlock(&TASK->answerbox.lock); |
| 155 | return result; |
160 | return result; |
| 156 | } |
161 | } |
| 157 | 162 | ||
| 158 | /** Allocate new phone slot in current TASK structure */ |
163 | /** Allocate new phone slot in the current TASK structure. |
| - | 164 | * |
|
| - | 165 | * @return New phone handle or -1 if the phone handle limit is |
|
| - | 166 | * exceeded. |
|
| - | 167 | */ |
|
| 159 | int phone_alloc(void) |
168 | int phone_alloc(void) |
| 160 | { |
169 | { |
| 161 | int i; |
170 | int i; |
| 162 | 171 | ||
| 163 | spinlock_lock(&TASK->lock); |
172 | spinlock_lock(&TASK->lock); |
| 164 | 173 | ||
| 165 | for (i=0; i < IPC_MAX_PHONES; i++) { |
174 | for (i = 0; i < IPC_MAX_PHONES; i++) { |
| 166 | if (TASK->phones[i].state == IPC_PHONE_HUNGUP && \ |
175 | if (TASK->phones[i].state == IPC_PHONE_HUNGUP && |
| 167 | atomic_get(&TASK->phones[i].active_calls) == 0) |
176 | atomic_get(&TASK->phones[i].active_calls) == 0) |
| 168 | TASK->phones[i].state = IPC_PHONE_FREE; |
177 | TASK->phones[i].state = IPC_PHONE_FREE; |
| 169 | 178 | ||
| 170 | if (TASK->phones[i].state == IPC_PHONE_FREE) { |
179 | if (TASK->phones[i].state == IPC_PHONE_FREE) { |
| 171 | TASK->phones[i].state = IPC_PHONE_CONNECTING; |
180 | TASK->phones[i].state = IPC_PHONE_CONNECTING; |
| Line 177... | Line 186... | ||
| 177 | if (i >= IPC_MAX_PHONES) |
186 | if (i >= IPC_MAX_PHONES) |
| 178 | return -1; |
187 | return -1; |
| 179 | return i; |
188 | return i; |
| 180 | } |
189 | } |
| 181 | 190 | ||
| - | 191 | /** Mark a phone structure free. |
|
| - | 192 | * |
|
| - | 193 | * @param phone Phone structure to be marked free. |
|
| - | 194 | */ |
|
| 182 | static void phone_deallocp(phone_t *phone) |
195 | static void phone_deallocp(phone_t *phone) |
| 183 | { |
196 | { |
| 184 | ASSERT(phone->state == IPC_PHONE_CONNECTING); |
197 | ASSERT(phone->state == IPC_PHONE_CONNECTING); |
| 185 | 198 | ||
| 186 | /* atomic operation */ |
199 | /* atomic operation */ |
| 187 | phone->state = IPC_PHONE_FREE; |
200 | phone->state = IPC_PHONE_FREE; |
| 188 | } |
201 | } |
| 189 | 202 | ||
| 190 | /** Free slot from a disconnected phone |
203 | /** Free slot from a disconnected phone. |
| - | 204 | * |
|
| - | 205 | * All already sent messages will be correctly processed. |
|
| 191 | * |
206 | * |
| 192 | * All already sent messages will be correctly processed |
207 | * @param phoneid Phone handle of the phone to be freed. |
| 193 | */ |
208 | */ |
| 194 | void phone_dealloc(int phoneid) |
209 | void phone_dealloc(int phoneid) |
| 195 | { |
210 | { |
| 196 | phone_deallocp(&TASK->phones[phoneid]); |
211 | phone_deallocp(&TASK->phones[phoneid]); |
| 197 | } |
212 | } |
| 198 | 213 | ||
| 199 | /** Connect phone to a given answerbox |
214 | /** Connect phone to a given answerbox. |
| 200 | * |
215 | * |
| 201 | * @param phoneid The slot that will be connected |
216 | * @param phoneid Phone handle to be connected. |
| - | 217 | * @param box Answerbox to which to connect the phone handle. |
|
| 202 | * |
218 | * |
| 203 | * The procedure _enforces_ that the user first marks the phone |
219 | * The procedure _enforces_ that the user first marks the phone |
| 204 | * busy (e.g. via phone_alloc) and then connects the phone, otherwise |
220 | * busy (e.g. via phone_alloc) and then connects the phone, otherwise |
| 205 | * race condition may appear. |
221 | * race condition may appear. |
| 206 | */ |
222 | */ |