Exemple #1
0
/*
 *  ======== GIO_reclaim ========
 */
Int GIO_reclaim(GIO_Object *obj, Ptr *pBuf, SizeT *pSize, UArg *pArg)
{
    IOM_Packet          *packet;
    Queue_Handle        doneList;
    Queue_Handle        freeList;
    UInt                key;
    Int                 status;
    Error_Block         eb;
    
    doneList = GIO_Instance_State_doneList(obj);
    freeList = GIO_Instance_State_freeList(obj);

    Error_init(&eb);

    while (obj->doneCount == 0) {
        if (Sync_wait(obj->sync, obj->timeout, &eb) == 
                Sync_WaitStatus_TIMEOUT) {

            return (IOM_ETIMEOUT);
        }
    }

    key = Hwi_disable();
    obj->doneCount--;
    packet = Queue_dequeue(doneList);
    Hwi_restore(key);

    if (pArg != NULL) {
        *pArg = packet->arg;
    }

    /* pBuf is set to NULL by GIO_read() and GIO_write() */
    if (pBuf != NULL) {
        *pBuf = packet->addr;
    }

    if (pSize != NULL) {
        *pSize = packet->size;
    }

    status = packet->status;

    /* 
     * re-signal if more buffers are ready
     * This is required in the case of ISyncEvent and ISyncSwi to allow 
     * clients to reclaim a single buffer and not force them to bleed the 
     * stream.
     */
    if (obj->doneCount > 0) {
        Sync_signal(obj->sync);
    }

    /* recycle packet back onto free list */
    key = Hwi_disable();
    obj->freeCount++;
    Queue_enqueue(freeList, (Queue_Elem *)packet);
    Hwi_restore(key);

    return (status);
}
Exemple #2
0
/*
 *  ======== callback ========
 *  This function is called by the underlying IOM driver.
 */
static Void callback(Ptr cbArg, IOM_Packet *packet)
{
    GIO_Handle       obj = (GIO_Handle)cbArg;
    GIO_AppCallback  *appCallback = (GIO_AppCallback *)packet->misc;
    Int              status;
    Ptr              addr;
    SizeT            size;
    Queue_Handle     list;
    UInt             key;

    key = Hwi_disable();
    obj->submitCount--;
    Hwi_restore(key);

    if (appCallback == NULL) {
        Sync_signal(obj->sync);
    }
    else {
        if (obj->model == GIO_Model_ISSUERECLAIM) {
            /* put packet on doneList where GIO_reclaim() will find it */
            list = GIO_Instance_State_doneList(obj);
    
            key = Hwi_disable();
            obj->doneCount++;
            Queue_enqueue(list, (Queue_Elem *)packet);
            Hwi_restore(key);

            Sync_signal(obj->sync);
        }
        else {
            list = GIO_Instance_State_freeList(obj);

            status = packet->status; 
            addr = packet->addr;
            size = packet->size;    

            key = Hwi_disable();
            obj->freeCount++;
            Queue_enqueue(list, (Queue_Elem *)packet);
            Hwi_restore(key);

            (*appCallback->fxn)(appCallback->arg, status, addr, size);
        }
    }
}
Exemple #3
0
/*
 *  ======== Stream_internalCallback ========
 *  This function is called by the underlying IConverter when IO completes.
 */
Void Stream_internalCallback(UArg cbArg)
{
    Stream_Handle obj = (Stream_Handle)cbArg;
    
    /*
     * Increment of ready not atomic because the callback is in the
     * context of an ISR and reclaim cannot preempt. reclaim can only be called
     * within the context the the same isr or by a single swi or task.
     */

    obj->ready++;

    Sync_signal(obj->complete);
}
Exemple #4
0
/*
 *  ======== Stream_reclaim ========
 */
SizeT Stream_reclaim(Stream_Object *obj, Ptr *bufp, UInt timeout, UArg *arg, 
    Error_Block *eb)
{
    DriverTypes_Packet  *packet = NULL;
    List_Handle         freeList;
    UInt                key;
    
    if (obj->issued == 0) {
        Error_raise(eb, Stream_E_noBuffersIssued, 0, 0);
        return (0);
    }

    while (obj->ready == 0) {
        if (!Sync_wait(obj->complete, timeout, eb)) {
            if (timeout != 0) {
                Error_raise(eb, Stream_E_timeout, timeout, 0);
            }
            return (0);
        }
    };
    IConverter_reclaim(obj->convHandle, &packet, eb);

    if (arg != NULL) {
        *arg = packet->arg;
    }

    /* bufp is NULL in Stream_read and Stream_write. */
    if (bufp != NULL) {
        *bufp = packet->addr;
    }

    key = Hwi_disable();
    obj->ready--;
    Hwi_restore(key);

    obj->issued--;

    /* 
     * re-signal if more buffers are ready
     * This is required in the case of ISyncEvent and ISyncSwi to allow 
     * clients to reclaim a single buffer and not force them to bleed the 
     * Stream. In the case of ISyncSem , this re-signal is an overhead
     */

    if (obj->ready > 0) {
        Sync_signal(obj->complete);
    }

    freeList = Stream_Instance_State_freeList(obj);

    /* recycle packet back onto free list */
    List_put(freeList, (List_Elem *)packet);

    if ((packet->error != NULL) &&
        (packet->error != DriverTypes_EABORTED)) {
        Error_raise(eb, packet->error, packet->status, 0);
        return (0);
    }
    else {
        return (packet->size);
    }
}