/*
 *  ======== control ========
 *  This is the stub-implementation for the control method
 */
static XDAS_Int32 control(ISCALE_Handle h, ISCALE_Cmd id,
    ISCALE_DynamicParams *params)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _SCALE_Msg *msg;

    /* get a message appropriate for this algorithm */
    if ((msg = (_SCALE_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (SCALE_ERUNTIME);
    }

    /* marshall the command */
    msg->visa.cmd = _SCALE_CCONTROL;

    msg->cmd.control.id = id;

    /* no pointers, just copy the dynamic params struct into the msg */
    msg->cmd.control.params = *params;

    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* nothing to unmarshall, just free the msg. */
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
/*
 *  ======== process ========
 *  This is the stub-implementation for the process method
 */
static XDAS_Int32 process(ISCALE_Handle h, XDAS_Int8 *inBuf,
    XDAS_Int8 *outBuf, ISCALE_InArgs *inArgs, ISCALE_OutArgs *outArgs)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _SCALE_Msg *msg;

    /* get a message appropriate for this algorithm */
    if ((msg = (_SCALE_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (SCALE_ERUNTIME);
    }

    /* Specify the processing command that the skeleton should do */
    msg->visa.cmd = _SCALE_CPROCESS;

    /* inBuf is a pointer, so we have to convert it */
    msg->cmd.process.inBuf = (XDAS_Int8 *)
        Memory_getBufferPhysicalAddress(inBuf, inArgs->inBufSize, NULL);

    if (msg->cmd.process.inBuf == NULL) {
        retVal = SCALE_ERUNTIME;
        goto exit;
    }

    /* Similarly with outBuf. Note that inArgs and outArgs contain no
     * pointers, so we can simply copy the entire original structure.
     */
    msg->cmd.process.outBuf = (XDAS_Int8 *)
        Memory_getBufferPhysicalAddress(outBuf, inArgs->outBufSize, NULL);

    if (msg->cmd.process.outBuf == NULL) {
        retVal = SCALE_ERUNTIME;
        goto exit;
    }

    /* inArgs has no pointers, so simply copy the struct fields into the msg */
    msg->cmd.process.inArgs = *inArgs;

    /* Note that outArgs is *output* and need not be provided to the skel */

    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* copy out the outArgs */
    *outArgs = msg->cmd.process.outArgs;

    /* Note that we need not copy inArgs out of the msg. */

    /*
     * Note that we don't have to do any reverse address translation, as the
     * originally provided buffers haven't changed.
     */

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
Ejemplo n.º 3
0
/*
 *  ======== marshallMsg ========
 */
static XDAS_Int32 marshallMsg(IAUDDEC_Handle h, XDM_BufDesc *inBufs,
    XDM_BufDesc *outBufs, IAUDDEC_InArgs *inArgs, IAUDDEC_OutArgs *outArgs,
    _AUDDEC_Msg **pmsg)
{
    XDAS_Int32 retVal = IAUDDEC_EOK;
    VISA_Handle visa = (VISA_Handle)h;
    _AUDDEC_Msg *msg;
    Int i;
    IAUDDEC_OutArgs *pMsgOutArgs;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((inArgs == NULL) || (inArgs->size < sizeof(IAUDDEC_InArgs)) ||
            (outArgs == NULL) || (outArgs->size < sizeof(IAUDDEC_OutArgs))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (AUDDEC_EFAIL);
    }

    /*
     * Initialize extendedError to zero so we don't return something
     * uninitialized in extendedError.
     */
    outArgs->extendedError = 0;

    if (pmsg == NULL) {
        return (AUDDEC_EFAIL);
    }

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) +
            (sizeof(msg->cmd.process.inBufs) * XDM_MAX_IO_BUFFERS) +
            sizeof(msg->cmd.process.numInBufs) +
            (sizeof(msg->cmd.process.inBufSizes[0]) * XDM_MAX_IO_BUFFERS) +
            (sizeof(msg->cmd.process.outBufs) * XDM_MAX_IO_BUFFERS) +
            sizeof(msg->cmd.process.numOutBufs) +
            (sizeof(msg->cmd.process.outBufSizes[0]) * XDM_MAX_IO_BUFFERS) +
            inArgs->size + outArgs->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        Log_print2(Diags_USER6,
                "[+6] process> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (IAUDDEC_EFAIL);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_AUDDEC_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IAUDDEC_ERUNTIME);
    }

    /*
     * Marshall the command: copy the client-passed arguments into flattened
     * message data structures, converting every pointer address to alg.
     * data buffer into physical address.
     */

    /* First specify the processing command that the skeleton should do */
    msg->visa.cmd = _AUDDEC_CPROCESS;

    /* commentary follows for marshalling the inBufs argument: */

    /* 1) inBufs->numBufs is a plain integer, we just copy it */
    msg->cmd.process.numInBufs = inBufs->numBufs;

    /* 2) inBufs->bufSizes is an array of integers, we copy them all */
    for (i = 0; i < inBufs->numBufs; i++) {
        msg->cmd.process.inBufSizes[i] = inBufs->bufSizes[i];
    }

    /* 3) inBufs->bufs is a pointer to an array of pointers, so we take
     * individual pointers, convert them, and store in the the message
     * counterpart of inBufs->bufs
     */
    for (i = 0; i < inBufs->numBufs; i++) {
        msg->cmd.process.inBufs[i] = (XDAS_Int8 *)
            Memory_getBufferPhysicalAddress(inBufs->bufs[i],
                inBufs->bufSizes[i], NULL);

        if (msg->cmd.process.inBufs[i] == NULL) {
            retVal = AUDDEC_ERUNTIME;
            goto exit;
        }
    }

    /* we're done (with inBufs). Because msg->cmd.process is non-cacheable
     * and contiguous (it has been allocated by MSGQ), we don't have to do
     * anything else.
     */

    /* Now we repeat the procedure for outBufs. Note that
     * inArgs and outArgs contain no pointers, so we can simply copy the
     * entire original structure, accounting for the first "size" field.
     */
    msg->cmd.process.numOutBufs = outBufs->numBufs;
    for (i = 0; i < outBufs->numBufs; i++) {
        msg->cmd.process.outBufSizes[i] = outBufs->bufSizes[i];
    }

    for (i = 0; i < outBufs->numBufs; i++) {
        msg->cmd.process.outBufs[i] = (XDAS_Int8 *)
            Memory_getBufferPhysicalAddress(outBufs->bufs[i],
                outBufs->bufSizes[i], NULL);

        if (msg->cmd.process.outBufs[i] == NULL) {
            retVal = AUDDEC_ERUNTIME;
            goto exit;
        }
    }

    /* inArgs has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.process.inArgs), inArgs, inArgs->size);

    /* point at outArgs and set the "size" */
    pMsgOutArgs = (IAUDDEC_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) +
        inArgs->size);

    /* set the size field - the rest is filled in by the codec */
    /* TODO:H probably want to zero out the rest of the outArgs struct */
    pMsgOutArgs->size = outArgs->size;

    *pmsg = msg;

    return (retVal);

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
Ejemplo n.º 4
0
/*
 *  ======== control ========
 *  This is the stub-implementation for the control method
 */
static XDAS_Int32 control(IAUDDEC_Handle h, IAUDDEC_Cmd id,
    IAUDDEC_DynamicParams *params, IAUDDEC_Status *status)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _AUDDEC_Msg *msg;
    IAUDDEC_Status *pMsgStatus;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((params == NULL) || (params->size < sizeof(IAUDDEC_DynamicParams)) ||
            (status == NULL) || (status->size < sizeof(IAUDDEC_Status))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IAUDDEC_EFAIL);
    }

    /*
     * Initialize extendedError to zero so we don't return something
     * uninitialized in extendedError.
     */
    status->extendedError = 0;

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + params->size +
            status->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        Log_print2(Diags_USER6,
                "[+6] process> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (IAUDDEC_EFAIL);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_AUDDEC_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IAUDDEC_ERUNTIME);
    }

    /* marshall the command */
    msg->visa.cmd = _AUDDEC_CCONTROL;

    msg->cmd.control.id = id;

    /* params has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.control.params), params, params->size);

    /* unmarshall status based on the "size" of params */
    pMsgStatus = (IAUDDEC_Status *)((UInt)(&(msg->cmd.control.params)) +
            params->size);

    /*
     * Initialize the .size and .data fields - the rest are filled in by
     * the codec.
     */
    pMsgStatus->size = status->size;

    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */
    Assert_isTrue(msg->visa.cmd == _AUDDEC_CCONTROL, (Assert_Id)NULL);

    /* unmarshall status */
    pMsgStatus = (IAUDDEC_Status *)((UInt)(&(msg->cmd.control.params)) +
        params->size);

    if (VISA_isChecked()) {
        /* ensure codec didn't modify status->size */
        Assert_isTrue(pMsgStatus->size == status->size, (Assert_Id)NULL);
    }
    memcpy(status, pMsgStatus, status->size);

    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
Ejemplo n.º 5
0
/*
 *  ======== control ========
 *  This is the stub-implementation for the control method
 */
static XDAS_Int32 control(ISPHDEC_Handle h, ISPHDEC_Cmd id,
     ISPHDEC_DynamicParams *params, ISPHDEC_Status *status)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _SPHDEC_Msg *msg;
    ISPHDEC_Status *pMsgStatus;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((params == NULL) || (params->size < sizeof(ISPHDEC_DynamicParams)) ||
        (status == NULL) || (status->size < sizeof(ISPHDEC_Status))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (SPHDEC_EFAIL);
    }

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + params->size +
            status->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        GT_2trace(CURTRACE, GT_6CLASS,
                "process> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields\n", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (SPHDEC_EFAIL);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_SPHDEC_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (ISPHDEC_ERUNTIME);
    }

    /* marshall the command */
    msg->visa.cmd = _SPHDEC_CCONTROL;

    msg->cmd.control.id = id;

    /* params has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.control.params), params, params->size);

    /* unmarshall status based on the "size" of params */
    pMsgStatus = (ISPHDEC_Status *)((UInt)(&(msg->cmd.control.params)) +
        params->size);

    /* set the size field - the rest is filled in by the codec */
    /* TODO:H probably want to zero out the rest of the status struct */
    pMsgStatus->size = status->size;

    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */
    GT_assert(CURTRACE, msg->visa.cmd == _SPHDEC_CCONTROL);

    /* unmarshall status */
    pMsgStatus = (ISPHDEC_Status *)((UInt)(&(msg->cmd.control.params)) +
        params->size);

    if (VISA_isChecked()) {
        /* ensure codec didn't modify status->size */
        GT_assert(CURTRACE, pMsgStatus->size == status->size);
    }
    memcpy(status, pMsgStatus, status->size);

    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
Ejemplo n.º 6
0
/*
 *  ======== marshallMsg ========
 */
static XDAS_Int32 marshallMsg(IVIDDEC2_Handle h, XDM1_BufDesc *inBufs,
    XDM_BufDesc *outBufs, IVIDDEC2_InArgs *inArgs, IVIDDEC2_OutArgs *outArgs,
    _VIDDEC2_Msg **pmsg)
{
    XDAS_Int32 retVal = IVIDDEC2_EOK;
    VISA_Handle visa = (VISA_Handle)h;
    _VIDDEC2_Msg *msg;
    Int i;
    IVIDDEC2_OutArgs *pMsgOutArgs;
    Int numBufs;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((inArgs == NULL) || (inArgs->size < sizeof(IVIDDEC2_InArgs)) ||
            (outArgs == NULL) || (outArgs->size < sizeof(IVIDDEC2_OutArgs))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IVIDDEC2_EFAIL);
    }

    if (pmsg == NULL) {
        return (IVIDDEC2_EFAIL);
    }

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) + (sizeof(*inBufs)) +
            (sizeof(outBufs[0]) * XDM_MAX_IO_BUFFERS) +
            sizeof(msg->cmd.process.numOutBufs) +
            (sizeof(msg->cmd.process.outBufSizes[0]) * XDM_MAX_IO_BUFFERS) +
            inArgs->size + outArgs->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        Log_print2(Diags_USER6,
                "[+6] process> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (IVIDDEC2_EUNSUPPORTED);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_VIDDEC2_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IVIDDEC2_EFAIL);
    }

    /* zero out msg->cmd (not msg->visa!) */
    memset(&(msg->cmd), 0, sizeof(msg->cmd));

    /*
     * Marshall the command: copy the client-passed arguments into flattened
     * message data structures, converting every pointer address to alg.
     * data buffer into physical address.
     */

    /* First specify the processing command that the skeleton should do */
    msg->visa.cmd = _VIDDEC2_CPROCESS;

    /* commentary follows for marshalling the inBufs argument: */

    /* 1) inBufs->numBufs is a plain integer, we just copy it */
    msg->cmd.process.inBufs.numBufs = inBufs->numBufs;

    /*
     * 2) inBufs->bufSizes is a sparse array of integers, we copy them all.
     *
     * 3) inBufs->bufs is a pointer to a sparse array of pointers, so we take
     * individual pointers, convert them if non-NULL, and store them in the
     * message counterpart of inBufs->bufs.
     */
    for (i = 0, numBufs = 0;
         ((numBufs < inBufs->numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) {
        if (inBufs->descs[i].buf != NULL) {
            /* valid member of sparse array, convert it */
            msg->cmd.process.inBufs.descs[i].bufSize = inBufs->descs[i].bufSize;

            msg->cmd.process.inBufs.descs[i].buf = (XDAS_Int8 *)
                Memory_getBufferPhysicalAddress(inBufs->descs[i].buf,
                    inBufs->descs[i].bufSize, NULL);

            if (msg->cmd.process.inBufs.descs[i].buf == NULL) {
                retVal = IVIDDEC2_EFAIL;
                goto exit;
            }

            /* Clear .accessMask; the local processor won't access this buf */
            inBufs->descs[i].accessMask = 0;

            /* found, and handled, another buffer. */
            numBufs++;
        }
        else {
            /* empty member of sparse array, no conversion needed. */
            msg->cmd.process.inBufs.descs[i].bufSize = 0;
            msg->cmd.process.inBufs.descs[i].buf = NULL;
        }
    }

    if (VISA_isChecked()) {
        /* check that we found inBufs->numBufs pointers in inBufs->bufs[] */
        Assert_isTrue(inBufs->numBufs == numBufs, (Assert_Id)NULL);
    }

    /* we're done (with inBufs). Because msg->cmd.process is non-cacheable
     * and contiguous (it has been allocated by MSGQ), we don't have to do
     * anything else.
     */

    /* Now we repeat the procedure for outBufs. Note that
     * inArgs contains no pointers, so we can simply copy the
     * entire original structure, accounting for the first "size" field.
     */
    msg->cmd.process.numOutBufs = outBufs->numBufs;

    for (i = 0, numBufs = 0;
         ((numBufs < outBufs->numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) {

        if (outBufs->bufs[i] != NULL) {
            /* valid member of sparse array, convert it */
            msg->cmd.process.outBufSizes[i] = outBufs->bufSizes[i];

            msg->cmd.process.outBufs[i] = (XDAS_Int8 *)
                Memory_getBufferPhysicalAddress(outBufs->bufs[i],
                    outBufs->bufSizes[i], NULL);

            if (msg->cmd.process.outBufs[i] == NULL) {
                /* TODO:M - should add at least a trace statement when trace
                 * is supported.  Another good idea is to return something
                 * more clear than EFAIL.
                 */
                retVal = IVIDDEC2_EFAIL;
                goto exit;
            }

            /* found, and handled, another buffer. */
            numBufs++;
        }
        else {
            /* empty member of sparse array, no conversion needed */
            msg->cmd.process.outBufSizes[i] = 0;
            msg->cmd.process.outBufs[i] = NULL;
        }
    }

    if (VISA_isChecked()) {
        /* check that we found outBufs->numBufs pointers in outBufs->bufs[] */
        Assert_isTrue(outBufs->numBufs == numBufs, (Assert_Id)NULL);
    }

    /* inArgs has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.process.inArgs), inArgs, inArgs->size);

    /* point at outArgs and set the "size" */
    pMsgOutArgs = (IVIDDEC2_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) +
        inArgs->size);

    /* set the size field - the rest is filled in by the codec */
    pMsgOutArgs->size = outArgs->size;

    *pmsg = msg;

    return (retVal);

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
Ejemplo n.º 7
0
/*
 *  ======== control ========
 *  This is the stub-implementation for the control method
 */
static XDAS_Int32 control(IVIDDEC2_Handle h, IVIDDEC2_Cmd id,
     IVIDDEC2_DynamicParams *params, IVIDDEC2_Status *status)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _VIDDEC2_Msg *msg;
    IVIDDEC2_Status *pMsgStatus;
    XDAS_Int8 *virtAddr = NULL;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((params == NULL) || (params->size < sizeof(IVIDDEC2_DynamicParams)) ||
            (status == NULL) || (status->size < sizeof(IVIDDEC2_Status))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IVIDDEC2_EFAIL);
    }

    /*
     * Initialize extendedError to zero so we don't return something
     * uninitialized in extendedError.
     */
    status->extendedError = 0;

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + params->size +
            status->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        Log_print2(Diags_USER6,
                "[+6] control> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (IVIDDEC2_EUNSUPPORTED);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_VIDDEC2_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IVIDDEC2_EFAIL);
    }

    /* marshall the command */
    msg->visa.cmd = _VIDDEC2_CCONTROL;

    msg->cmd.control.id = id;

    /* params has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.control.params), params, params->size);

    /* unmarshall status based on the "size" of params */
    pMsgStatus = (IVIDDEC2_Status *)((UInt)(&(msg->cmd.control.params)) +
        params->size);

    /*
     * Initialize the .size and .data fields - the rest are filled in by
     * the codec.
     */
    pMsgStatus->size = status->size;

    if (status->data.buf != NULL) {
        pMsgStatus->data.bufSize = status->data.bufSize;

        /* save it for later */
        virtAddr = status->data.buf;

        pMsgStatus->data.buf = (XDAS_Int8 *)
            Memory_getBufferPhysicalAddress(status->data.buf,
                status->data.bufSize, NULL);

        if (pMsgStatus->data.buf == NULL) {
            retVal = IVIDDEC2_EFAIL;
            goto exit;
        }
    }
    else {
        /* Place null into the msg so the skel knows it's invalid */
        pMsgStatus->data.buf = NULL;
    }

    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */
    Assert_isTrue(msg->visa.cmd == _VIDDEC2_CCONTROL, (Assert_Id)NULL);

    /* unmarshall status */
    pMsgStatus = (IVIDDEC2_Status *)((UInt)(&(msg->cmd.control.params)) +
        params->size);

    if (VISA_isChecked()) {
        /* ensure codec didn't modify status->size */
        Assert_isTrue(pMsgStatus->size == status->size, (Assert_Id)NULL);

        /*
         * TODO:L  Should we also check that pMsgStatus->data.buf is the same
         * after the call as before?
         */
    }

    memcpy(status, pMsgStatus, status->size);

    /*
     * And finally, restore status->data.buf to its original value.  Note that
     * this works even when status->data.buf was NULL because virtAddr is
     * initialized to NULL.
     *
     * While potentially more confusing, this is just as correct as
     * (and faster than!) calling Memory_getVirtualBuffer().
     */
    status->data.buf = virtAddr;

    /* Clear .accessMask; the local processor didn't access the buffer */
    status->data.accessMask = 0;

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
/*
 *  ======== control ========
 *  This is the stub-implementation for the control method
 */
static XDAS_Int32 control(IVIDDEC2BACK_Handle h, XDM_Context *context,
     IVIDDEC2_Status *status)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _VIDDEC2BACK_Msg *msg;
//    IVIDDEC2_Status *pMsgStatus;
//    XDAS_Int8 *virtAddr = NULL;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((context == NULL) || (status == NULL) ||
            (status->size < sizeof(IVIDDEC2_Status))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IVIDDEC2_EFAIL);
    }

    if (/* size of "stuff to marshall" > message size */
        (sizeof(VISA_MsgHeader) + sizeof(*context) + status->size)
            > sizeof(_VIDDEC2BACK_Msg)) {

        /* Can't handle these large extended args. */
        Log_print0(Diags_USER6,
                "[+6] control> invalid arguments - validate .size fields");

        return (IVIDDEC2_EUNSUPPORTED);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_VIDDEC2BACK_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IVIDDEC2_EFAIL);
    }

    /* marshall the command */
    msg->visa.cmd = _VIDDEC2BACK_CCONTROL;

    /*
     * Initialize the .size and .data fields - the rest are filled in by
     * the codec.
     */
    msg->cmd.control.status.size = status->size;

#if 0
    if (status->data.buf != NULL) {
        pMsgStatus->data.bufSize = status->data.bufSize;

        /* save it for later */
        virtAddr = status->data.buf;

        pMsgStatus->data.buf = (XDAS_Int8 *)
            Memory_getBufferPhysicalAddress(status->data.buf,
                status->data.bufSize, NULL);

        if (pMsgStatus->data.buf == NULL) {
            retVal = IVIDDEC2_EFAIL;
            goto exit;
        }
    }
    else {
        /* Place null into the msg so the skel knows it's invalid */
        pMsgStatus->data.buf = NULL;
    }
#endif
    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */
    Assert_isTrue(msg->visa.cmd == _VIDDEC2BACK_CCONTROL, (Assert_Id)NULL);

    if (VISA_isChecked()) {
        /* ensure codec didn't modify status->size */
        Assert_isTrue(msg->cmd.control.status.size == status->size,
                (Assert_Id)NULL);

        /*
         * TODO:L  Should we also check that pMsgStatus->data.buf is the same
         * after the call as before?
         */
    }
    memcpy(status, &(msg->cmd.control.status), status->size);
#if 0
    /*
     * And finally, restore status->data.buf to its original value.  Note that
     * this works even when status->data.buf was NULL because virtAddr is
     * initialized to NULL.
     *
     * While potentially more confusing, this is just as correct as
     * (and faster than!) calling Memory_getVirtualBuffer().
     */
    status->data.buf = virtAddr;

    /* Clear .accessMask; the local processor didn't access the buffer */
    status->data.accessMask = 0;
#endif

//exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
/*
 *  ======== marshallMsg ========
 */
static XDAS_Int32 marshallMsg(IVIDDEC2BACK_Handle h, XDM_Context *context,
        IVIDDEC2_OutArgs *outArgs,  _VIDDEC2BACK_Msg **pmsg)
{
    XDAS_Int32 retVal = IVIDDEC2_EOK;
    VISA_Handle visa = (VISA_Handle)h;
    _VIDDEC2BACK_Msg *msg;
    Int numBufs;

    Assert_isTrue(pmsg != NULL, (Assert_Id)NULL);

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((context == NULL) || (outArgs == NULL) ||
            (outArgs->size < sizeof(IVIDDEC2_OutArgs))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IVIDDEC2_EFAIL);
    }

    if (/* size of "stuff to marshall" > message size */
        (sizeof(VISA_MsgHeader) + sizeof(XDM_Context) +
            outArgs->size) > sizeof(_VIDDEC2BACK_Msg)) {

        /* Can't handle these large extended args. */
        Log_print0(Diags_USER6,
                "[+6] process> invalid arguments - outArgs.size field is too"
                " large");

        return (IVIDDEC2_EUNSUPPORTED);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_VIDDEC2BACK_Msg *)VISA_allocMsg(visa)) == NULL) {
        Log_print0(Diags_USER6, "[+6] process> VISA_allocMsg failed");

        return (IVIDDEC2_EFAIL);
    }

    /* zero out msg->cmd (not msg->visa!) */
    memset(&(msg->cmd), 0, sizeof(msg->cmd));

    /*
     * Marshall the command: copy the client-passed arguments into flattened
     * message data structures, converting every pointer address to alg.
     * data buffer into physical address.
     */

    /* First specify the processing command that the skeleton should do */
    msg->visa.cmd = _VIDDEC2BACK_CPROCESS;

    /* address translation of XDM_Context buffers */
    if (context->algContext.buf != NULL) {
        msg->cmd.process.context.algContext.bufSize =
                context->algContext.bufSize;

        msg->cmd.process.context.algContext.buf = (XDAS_Int8 *)
                Memory_getBufferPhysicalAddress(context->algContext.buf,
                    context->algContext.bufSize, NULL);

            if (msg->cmd.process.context.algContext.buf == NULL) {
                retVal = IVIDDEC2_EFAIL;
                goto exit;
            }
    }

    /* context->num*Bufs are plain integers, just copy them */
    msg->cmd.process.context.numInBufs = context->numInBufs;
    msg->cmd.process.context.numOutBufs = context->numOutBufs;
    msg->cmd.process.context.numInOutBufs = context->numInOutBufs;

    /* address translate inBufs */
    numBufs =
        copySparseSingleBufDescArrayWithV2P(msg->cmd.process.context.inBufs,
                context->inBufs, context->numInBufs, XDM_MAX_CONTEXT_BUFFERS);

    if (numBufs == -1) {
        retVal = IVIDDEC2_EFAIL;
        goto exit;
    }

    if (VISA_isChecked()) {
        /* check that we found context->numInBufs in context->inBufs */
        Assert_isTrue(context->numInBufs == numBufs, (Assert_Id)NULL);
    }

    /* Repeat the procedure for outBufs and intermediateBufs. */
    numBufs =
        copySparseSingleBufDescArrayWithV2P(msg->cmd.process.context.outBufs,
                context->outBufs, context->numOutBufs, XDM_MAX_CONTEXT_BUFFERS);

    if (numBufs == -1) {
        retVal = IVIDDEC2_EFAIL;
        goto exit;
    }

    if (VISA_isChecked()) {
        /* check that we found context->numOutBufs in context->outBufs */
        Assert_isTrue(context->numOutBufs == numBufs, (Assert_Id)NULL);
    }

    numBufs =
        copySingleBufDescArrayWithV2P(msg->cmd.process.context.intermediateBufs,
                context->intermediateBufs, XDM_MAX_CONTEXT_BUFFERS);

    if (numBufs == -1) {
        retVal = IVIDDEC2_EFAIL;
        goto exit;
    }

    /* VIDDEC2BACK doesn't support any in/out buffers */
    if (VISA_isChecked()) {
        Assert_isTrue(context->numInOutBufs == 0, (Assert_Id)NULL);
    }

    /* outArgs has no 'inputs', so only .size needs marshalled */
    msg->cmd.process.outArgs.size = outArgs->size;

    *pmsg = msg;

    return (retVal);

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return retVal;
}
Ejemplo n.º 10
0
/*
 *  ======== marshallMsg ========
 */
static XDAS_Int32 marshallMsg(IVIDENC1_Handle h, IVIDEO1_BufDescIn *inBufs,
    XDM_BufDesc *outBufs, IVIDENC1_InArgs *inArgs, IVIDENC1_OutArgs *outArgs,
    _VIDENC1_Msg **pmsg)
{
    XDAS_Int32 retVal = IVIDENC1_EOK;
    VISA_Handle visa = (VISA_Handle)h;
    _VIDENC1_Msg *msg;
    Int i;
    IVIDENC1_OutArgs *pMsgOutArgs;
    Int numBufs;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((inArgs == NULL) || (inArgs->size < sizeof(IVIDENC1_InArgs)) ||
            (outArgs == NULL) || (outArgs->size < sizeof(IVIDENC1_OutArgs))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IVIDENC1_EFAIL);
    }

    /*
     * Initialize extendedError to zero so we don't return something
     * uninitialized in extendedError.
     */
    outArgs->extendedError = 0;

    if (pmsg == NULL) {
        return (IVIDENC1_EFAIL);
    }

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) + sizeof(*inBufs) +
            (sizeof(msg->cmd.process.outBufs) * XDM_MAX_IO_BUFFERS) +
            sizeof(msg->cmd.process.numOutBufs) +
            (sizeof(msg->cmd.process.outBufSizes[0]) * XDM_MAX_IO_BUFFERS) +
            inArgs->size + outArgs->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        Log_print2(Diags_USER6,
                "[+6] process> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (IVIDENC1_EUNSUPPORTED);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_VIDENC1_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IVIDENC1_EFAIL);
    }

    /* zero out msg->cmd (not msg->visa!) */
    memset(&(msg->cmd), 0, sizeof(msg->cmd));

    /*
     * Marshall the command: copy the client-passed arguments into flattened
     * message data structures, converting every pointer address to alg.
     * data buffer into physical address.
     */

    /* First specify the processing command that the skeleton should do */
    msg->visa.cmd = _VIDENC1_CPROCESS;

    /* commentary follows for marshalling the inBufs argument: */

    /* 1) copy integers */
    msg->cmd.process.inBufs.numBufs     = inBufs->numBufs;
    msg->cmd.process.inBufs.frameWidth  = inBufs->frameWidth;
    msg->cmd.process.inBufs.frameHeight = inBufs->frameHeight;
    msg->cmd.process.inBufs.framePitch  = inBufs->framePitch;

    /*
     * inBufs->bufDesc is a sparse array of buffer descriptors.  Convert them
     * if non-NULL.
     */
    for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) {
        if (inBufs->bufDesc[i].buf != NULL) {
            /* valid member of sparse array, copy .bufSize convert .buf */
            msg->cmd.process.inBufs.bufDesc[i].bufSize =
                inBufs->bufDesc[i].bufSize;

            msg->cmd.process.inBufs.bufDesc[i].buf = (XDAS_Int8 *)
                Memory_getBufferPhysicalAddress(inBufs->bufDesc[i].buf,
                    inBufs->bufDesc[i].bufSize, NULL);

            if (msg->cmd.process.inBufs.bufDesc[i].buf == NULL) {
                retVal = IVIDENC1_EFAIL;
                goto exit;
            }

            /* Clear .accessMask; the local processor won't access this buf */
            inBufs->bufDesc[i].accessMask = 0;

            /* found, and handled, another buffer.  See if it's the last one */
            if (++numBufs == inBufs->numBufs) {
                break;
            }
        }
        else {
            /* empty member of sparse array, no conversion needed. */
            msg->cmd.process.inBufs.bufDesc[i].bufSize = 0;
            msg->cmd.process.inBufs.bufDesc[i].buf = NULL;
        }
    }

    /* we're done (with inBufs). Because msg->cmd.process is non-cacheable
     * and contiguous (it has been allocated by MSGQ), we don't have to do
     * anything else.
     */

    /* Repeat the procedure for outBufs. */
    msg->cmd.process.numOutBufs = outBufs->numBufs;

    for (i = 0, numBufs = 0; i < XDM_MAX_IO_BUFFERS; i++) {
        if (outBufs->bufs[i] != NULL) {
            /* valid member of sparse array, convert it */
            msg->cmd.process.outBufSizes[i] = outBufs->bufSizes[i];

            msg->cmd.process.outBufs[i] = (XDAS_Int8 *)
                Memory_getBufferPhysicalAddress(outBufs->bufs[i],
                    outBufs->bufSizes[i], NULL);

            if (msg->cmd.process.outBufs[i] == NULL) {
                /* TODO:M - should add at least a trace statement when trace
                 * is supported.  Another good idea is to return something
                 * more clear than EFAIL.
                 */
                retVal = IVIDENC1_EFAIL;
                goto exit;
            }

            /* found, and handled, another buffer.  See if it's the last one */
            if (++numBufs == outBufs->numBufs) {
                break;
            }
        }
        else {
            /* empty member of sparse array, no conversion needed */
            msg->cmd.process.outBufSizes[i] = 0;
            msg->cmd.process.outBufs[i] = NULL;
        }
    }

    /* inArgs has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.process.inArgs), inArgs, inArgs->size);

    /* point at outArgs and set the "size" */
    pMsgOutArgs = (IVIDENC1_OutArgs *)((UInt)(&(msg->cmd.process.inArgs)) +
        inArgs->size);

    /* set the size field - the rest is filled in by the codec */
    pMsgOutArgs->size = outArgs->size;

    /*
     * Note that although outArgs contains pointers, they're not provided
     * by the application via the outArgs struct.  Rather the actual buffers
     * are provided by the application to the algorithm via outBufs.
     * So, the addresses in outArgs are output only, and do not require
     * address translation _before_ calling process().  They _do_ require
     * adress translation _after_ process(), as the algorithm may have written
     * physical addresses into the pointers.
     */

    *pmsg = msg;

    return (retVal);

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}
Ejemplo n.º 11
0
/*
 *  ======== control ========
 *  This is the stub-implementation for the control method
 */
static XDAS_Int32 control(IUNIVERSAL_Handle h, IUNIVERSAL_Cmd id,
    IUNIVERSAL_DynamicParams *dynParams, IUNIVERSAL_Status *status)
{
    XDAS_Int32 retVal;
    VISA_Handle visa = (VISA_Handle)h;
    _UNIVERSAL_Msg *msg;
    IUNIVERSAL_Status *pMsgStatus;
    XDAS_Int8 *virtAddr[XDM_MAX_IO_BUFFERS];
    Int i;
    Int numBufs;
    Int payloadSize;

    /*
     * Validate arguments.  Do we want to do this _every_ time, or just in
     * checked builds?
     */
    if ((dynParams == NULL) ||
            (dynParams->size < sizeof(IUNIVERSAL_DynamicParams)) ||
            (status == NULL) || (status->size < sizeof(IUNIVERSAL_Status))) {

        /* invalid args, could even assert here, it's a spec violation. */
        return (IUNIVERSAL_EFAIL);
    }

    /*
     * Initialize extendedError to zero so we don't return something
     * uninitialized in extendedError.
     */
    status->extendedError = 0;

    /* make sure it'll all fit! */
    payloadSize = sizeof(VISA_MsgHeader) + sizeof(id) + dynParams->size +
            status->size;

    if (payloadSize > VISA_getMaxMsgSize(visa)) {
        /* Can't handle these large extended args. */
        Log_print2(Diags_USER6,
                "[+6] control> invalid arguments - too big (0x%x > 0x%x).  "
                "Validate .size fields", payloadSize,
                VISA_getMaxMsgSize(visa));

        return (IUNIVERSAL_EUNSUPPORTED);
    }

    /* get a message appropriate for this algorithm */
    if ((msg = (_UNIVERSAL_Msg *)VISA_allocMsg(visa)) == NULL) {
        return (IUNIVERSAL_EFAIL);
    }

    /* marshall the command */
    msg->visa.cmd = _UNIVERSAL_CCONTROL;

    msg->cmd.control.id = id;

    /* dynParams has no pointers so simply memcpy "size" bytes into the msg */
    memcpy(&(msg->cmd.control.dynParams), dynParams, dynParams->size);

    /* point at status based on the "size" of dynParams */
    pMsgStatus =
        (IUNIVERSAL_Status *)((UInt)(&(msg->cmd.control.dynParams)) +
            dynParams->size);

    /*
     * Initialize the .size and .data fields - the rest are filled in by
     * the codec.
     */
    pMsgStatus->size = status->size;

    /* 1) pMsgStatus->data.numBufs is a plain integer, we just copy it */
    pMsgStatus->data.numBufs = status->data.numBufs;

    /*
     * status->data.descs[] is a sparse array of buffer descriptors.  Convert
     * them if non-NULL.
     */
    for (i = 0, numBufs = 0;
         ((numBufs < status->data.numBufs) && (i < XDM_MAX_IO_BUFFERS)); i++) {

        if (status->data.descs[i].buf != NULL) {
            /* valid member of sparse array, convert it */
            pMsgStatus->data.descs[i].bufSize = status->data.descs[i].bufSize;

            /* save it for later */
            virtAddr[i] = status->data.descs[i].buf;

            pMsgStatus->data.descs[i].buf = (XDAS_Int8 *)
                Memory_getBufferPhysicalAddress(status->data.descs[i].buf,
                    status->data.descs[i].bufSize, NULL);

            if (pMsgStatus->data.descs[i].buf == NULL) {
                retVal = IUNIVERSAL_EFAIL;
                goto exit;
            }

            /* found, and handled, another buffer. */
            numBufs++;
        }
        else {
            /* empty member of sparse array, no conversion needed. */
            pMsgStatus->data.descs[i].bufSize = 0;
            pMsgStatus->data.descs[i].buf = NULL;

            virtAddr[i] = NULL;

        }
    }

    if (VISA_isChecked()) {
        /* check that we found inBufs->numBufs pointers in inBufs->bufs[] */
        Assert_isTrue(status->data.numBufs == numBufs, (Assert_Id)NULL);
    }

    /* send the message to the skeleton and wait for completion */
    retVal = VISA_call(visa, (VISA_Msg *)&msg);

    /* ensure we get CCONTROL msg (ensure async CPROCESS pipeline drained) */
    Assert_isTrue(msg->visa.cmd == _UNIVERSAL_CCONTROL, (Assert_Id)NULL);

    /* unmarshall status */
    pMsgStatus =
        (IUNIVERSAL_Status *)((UInt)(&(msg->cmd.control.dynParams)) +
            dynParams->size);

    if (VISA_isChecked()) {
        /* ensure codec didn't modify status->size */
        Assert_isTrue(pMsgStatus->size == status->size, (Assert_Id)NULL);

        /*
         * TODO:L  Should we also check that pMsgStatus->data.buf is the same
         * after the call as before?
         */
    }

    memcpy(status, pMsgStatus, status->size);

    /*
     * And finally, restore status->data.descs[].buf's to their original values.
     *
     * While potentially more confusing, this is just as correct as
     * (and faster than!) calling Memory_getVirtualBuffer().
     */
    for (i = 0, numBufs = 0;
         (numBufs < status->data.numBufs) && (i < XDM_MAX_IO_BUFFERS); i++) {

        status->data.descs[i].buf = virtAddr[i];

        /* Clear .accessMask; the local processor didn't access the buffer */
        status->data.descs[i].accessMask = 0;

        if (virtAddr[i] != NULL) {
            numBufs++;
        }
    }

exit:
    VISA_freeMsg(visa, (VISA_Msg)msg);

    return (retVal);
}