Subversion Repositories HelenOS

Rev

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.