Rev 2661 | Rev 2676 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2661 | Rev 2662 | ||
---|---|---|---|
Line 233... | Line 233... | ||
233 | rc = as_area_share(AS, IPC_GET_ARG1(answer->data), |
233 | rc = as_area_share(AS, IPC_GET_ARG1(answer->data), |
234 | IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata), |
234 | IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata), |
235 | IPC_GET_ARG2(answer->data)); |
235 | IPC_GET_ARG2(answer->data)); |
236 | IPC_SET_RETVAL(answer->data, rc); |
236 | IPC_SET_RETVAL(answer->data, rc); |
237 | } |
237 | } |
- | 238 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_READ) { |
|
- | 239 | ASSERT(!answer->buffer); |
|
- | 240 | if (!IPC_GET_RETVAL(answer->data)) { |
|
- | 241 | /* The recipient agreed to send data. */ |
|
- | 242 | uintptr_t src = IPC_GET_ARG1(answer->data); |
|
- | 243 | uintptr_t dst = IPC_GET_ARG1(*olddata); |
|
- | 244 | size_t max_size = IPC_GET_ARG2(*olddata); |
|
- | 245 | size_t size = IPC_GET_ARG2(answer->data); |
|
- | 246 | if (size <= max_size) { |
|
- | 247 | /* |
|
- | 248 | * Copy the destination VA so that this piece of |
|
- | 249 | * information is not lost. |
|
- | 250 | */ |
|
- | 251 | IPC_SET_ARG1(answer->data, dst); |
|
- | 252 | ||
- | 253 | answer->buffer = malloc(size, 0); |
|
- | 254 | int rc = copy_from_uspace(answer->buffer, |
|
- | 255 | (void *) src, size); |
|
- | 256 | if (rc) { |
|
- | 257 | IPC_SET_RETVAL(answer->data, rc); |
|
- | 258 | free(answer->buffer); |
|
- | 259 | answer->buffer = NULL; |
|
- | 260 | } |
|
- | 261 | } else { |
|
- | 262 | IPC_SET_RETVAL(answer->data, ELIMIT); |
|
- | 263 | } |
|
- | 264 | } |
|
238 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_WRITE) { |
265 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_WRITE) { |
239 | ASSERT(answer->buffer); |
266 | ASSERT(answer->buffer); |
240 | if (!IPC_GET_RETVAL(answer->data)) { |
267 | if (!IPC_GET_RETVAL(answer->data)) { |
- | 268 | /* The recipient agreed to receive data. */ |
|
241 | int rc; |
269 | int rc; |
242 | uintptr_t dst; |
270 | uintptr_t dst; |
243 | uintptr_t size; |
271 | uintptr_t size; |
- | 272 | uintptr_t max_size; |
|
244 | 273 | ||
245 | dst = IPC_GET_ARG1(answer->data); |
274 | dst = IPC_GET_ARG1(answer->data); |
246 | size = IPC_GET_ARG3(answer->data); |
275 | size = IPC_GET_ARG3(answer->data); |
- | 276 | max_size = IPC_GET_ARG3(*olddata); |
|
247 | 277 | ||
- | 278 | if (size <= max_size) { |
|
248 | rc = copy_to_uspace((void *) dst, answer->buffer, size); |
279 | rc = copy_to_uspace((void *) dst, |
- | 280 | answer->buffer, size); |
|
249 | if (rc != 0) |
281 | if (rc) |
250 | IPC_SET_RETVAL(answer->data, rc); |
282 | IPC_SET_RETVAL(answer->data, rc); |
- | 283 | } else { |
|
- | 284 | IPC_SET_RETVAL(answer->data, ELIMIT); |
|
- | 285 | } |
|
251 | } |
286 | } |
252 | free(answer->buffer); |
287 | free(answer->buffer); |
253 | answer->buffer = NULL; |
288 | answer->buffer = NULL; |
254 | } |
289 | } |
255 | return 0; |
290 | return 0; |
Line 282... | Line 317... | ||
282 | size = as_area_get_size(IPC_GET_ARG1(call->data)); |
317 | size = as_area_get_size(IPC_GET_ARG1(call->data)); |
283 | if (!size) |
318 | if (!size) |
284 | return EPERM; |
319 | return EPERM; |
285 | IPC_SET_ARG2(call->data, size); |
320 | IPC_SET_ARG2(call->data, size); |
286 | break; |
321 | break; |
- | 322 | case IPC_M_DATA_READ: |
|
- | 323 | size = IPC_GET_ARG2(call->data); |
|
- | 324 | if ((size <= 0 || (size > DATA_XFER_LIMIT))) |
|
- | 325 | return ELIMIT; |
|
- | 326 | break; |
|
287 | case IPC_M_DATA_WRITE: |
327 | case IPC_M_DATA_WRITE: |
288 | src = IPC_GET_ARG2(call->data); |
328 | src = IPC_GET_ARG2(call->data); |
289 | size = IPC_GET_ARG3(call->data); |
329 | size = IPC_GET_ARG3(call->data); |
290 | 330 | ||
291 | if ((size <= 0) || (size > DATA_XFER_LIMIT)) |
331 | if ((size <= 0) || (size > DATA_XFER_LIMIT)) |
Line 322... | Line 362... | ||
322 | if (IPC_GET_RETVAL(call->data)) |
362 | if (IPC_GET_RETVAL(call->data)) |
323 | phone_dealloc(call->priv); |
363 | phone_dealloc(call->priv); |
324 | else |
364 | else |
325 | IPC_SET_ARG5(call->data, call->priv); |
365 | IPC_SET_ARG5(call->data, call->priv); |
326 | } |
366 | } |
- | 367 | ||
- | 368 | if (call->buffer) { |
|
- | 369 | /* This must be an affirmative answer to IPC_M_DATA_READ. */ |
|
- | 370 | uintptr_t dst = IPC_GET_ARG1(call->data); |
|
- | 371 | size_t size = IPC_GET_ARG2(call->data); |
|
- | 372 | int rc = copy_to_uspace((void *) dst, call->buffer, size); |
|
- | 373 | if (rc) |
|
- | 374 | IPC_SET_RETVAL(call->data, rc); |
|
- | 375 | free(call->buffer); |
|
- | 376 | call->buffer = NULL; |
|
- | 377 | } |
|
327 | } |
378 | } |
328 | 379 | ||
329 | /** Do basic kernel processing of received call request. |
380 | /** Do basic kernel processing of received call request. |
330 | * |
381 | * |
331 | * @param box Destination answerbox structure. |
382 | * @param box Destination answerbox structure. |