Rev 2359 | Rev 3362 | 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 | */ |