Ejemplo n.º 1
0
/*
 *  ======== tskMkPort ========
 *  Creates a DIO object and binds the controller.
 */
static DIO_Handle tskMkPort(DEV_Handle device, String name)
{
    DIO_Params *params = (DIO_Params *)device->params;
    DIO_Handle dio;
    DEV_Device  *entry;
    Uns         mode;
    Int         status;

    /* params should contain name of mini-driver */
    if (params == NULL) {
        return (NULL);
    }
    
    /*
     * check to see that name of mini-driver matches one in the device table
     * and its type is of DEV_IOMTYPE.
     */
    (void)DEV_match(params->name, &entry);
    if (entry == NULL || entry->type != DEV_IOMTYPE) {
        return (NULL);
    }

    /* allocate 0-initialized dio object */
    if ((dio = MEM_calloc(0, sizeof(DIO_Obj), 0)) == MEM_ILLEGAL) {
        return (NULL);
    }

    /*
     * Tasks will pend on dio->complete if there are no available frames on
     * the fromdevice queue.
     */
    dio->context.sems.complete = SEM_create(0, NULL);

    /* make sure SEM_create() succeeded ... */
    if (dio->context.sems.complete == NULL) {
        MEM_free(0, dio, sizeof(DIO_Obj));     /* free dio object */
        return (NULL);
    }

    dio->fxns = (IOM_Fxns *)entry->fxns;

    mode = (device->mode == DEV_INPUT) ? IOM_INPUT : IOM_OUTPUT;

    /* create a channel from the mini-driver */
    status = dio->fxns->mdCreateChan(&dio->chanp, entry->devp, name, mode,
                params->chanParams, DIO_tskCallback, device); 

    if (status != IOM_COMPLETED) {
        tskRmPort(dio);
        return (NULL);
    }

    return (dio);
}
Ejemplo n.º 2
0
/*
 *  ======== cbMkPort ========
 *  Creates a DIO object and binds the controller.
 */
static DIO_Handle cbMkPort(DEV_Handle device, String name)
{
    DIO_Params *params = (DIO_Params *)device->params;
    DEV_Callback  *callback = (DEV_Callback *)device->callback;
    DIO_Handle dio;
    DEV_Device  *entry;
    Uns         mode;
    Int         status;

    /* callback must not be NULL if using this version of DIO */
    if (callback == NULL) {
        return (NULL);
    }
    
    /* params must contain name of mini-driver */
    if (params == NULL) {
        return (NULL);
    }
    
    /*
     * check to see that name of mini-driver matches one in the device table
     * and its type is of DEV_IOMTYPE.
     */
    (void)DEV_match(params->name, &entry);
    if (entry == NULL || entry->type != DEV_IOMTYPE) {
        return (NULL);
    }

    /* allocate 0-initialized dio object */
    if ((dio = MEM_calloc(0, sizeof(DIO_Obj), 0)) == MEM_ILLEGAL) {
        return (NULL);
    }

    /* initialize the DIO callback values */
    dio->context.cb = *callback;

    dio->fxns = (IOM_Fxns *)entry->fxns;

    mode = (device->mode == DEV_INPUT) ? IOM_INPUT : IOM_OUTPUT;

    /* create a channel from the mini-driver */
    status = dio->fxns->mdCreateChan(&dio->chanp, entry->devp, name, mode,
                params->chanParams, DIO_cbCallback, device); 

    if (status != IOM_COMPLETED) {
        cbRmPort(dio);
        return (NULL);
    }

    return (dio);
}
Ejemplo n.º 3
0
/*
 *  ======== GIO_removeDevice ========
 */
Int GIO_removeDevice(String name)
{
    DEV_Handle  device;

    DEV_match(name, &device);
 
    if (device != NULL) {
        DEV_delete(&device);

        return (IOM_COMPLETED);
    }
    else {
        return (IOM_EBADIO);
    }
}
Ejemplo n.º 4
0
/*
 *  ======== GIO_Instance_init ========
 */
Int GIO_Instance_init(GIO_Object *obj, String name, UInt mode,
    const GIO_Params *params, Error_Block *eb)
{
    Int                 i, status;
    Queue_Handle        doneList;
    Queue_Handle        freeList;
    DEV_Handle          device;
    IOM_Packet          *packets;
    IOM_Fxns            *iomFxns;
    Ptr                 devp;
    
    obj->name = name;
    obj->numPackets = params->numPackets;
    obj->doneCount = 0;
    obj->freeCount = 0;
    obj->submitCount = 0;
    obj->mode = mode;
    obj->model = params->model;
    obj->timeout = params->timeout;

    if (params->sync == NULL) {       
        obj->userSync = FALSE;
        obj->sync = SyncSemThread_Handle_upCast(SyncSemThread_create(NULL, eb));
        if (obj->sync == NULL) {
            return (1);
        }
    }
    else {
        obj->sync = params->sync;
        obj->userSync = TRUE;
    }

    doneList = GIO_Instance_State_doneList(obj);
    Queue_construct(Queue_struct(doneList), NULL);
    
    freeList = GIO_Instance_State_freeList(obj);
    Queue_construct(Queue_struct(freeList), NULL);
    
    /* allocate packets */
    packets = Memory_alloc(NULL, sizeof(IOM_Packet) * (obj->numPackets), 0, eb);

    if (packets == NULL) {
        return (2);
    }

    obj->packets = packets;
    obj->freeCount = obj->numPackets;
   
    /* 
     * Split the buffer into packets and add to freeList
     */
    for (i = 0; i < obj->numPackets; i++) {
        Queue_enqueue(freeList, (Queue_Elem *)&packets[i]);
    }
    
    name = DEV_match(name, &device);    
        
    if (device == NULL) {
        /* The name was not found */
        Error_raise(eb, GIO_E_notFound, obj->name, 0);
        return (3);
    }

    obj->fxns = DEV_getFxns(device);
    iomFxns = (IOM_Fxns *)obj->fxns;       

    devp = DEV_getDevp(device);

    status = iomFxns->mdCreateChan(&obj->mdChan, devp, name, mode,
        params->chanParams, callback, obj);
  
    if (status != IOM_COMPLETED) {
        Error_raise(eb, GIO_E_createFailed, status, 0);
        return (4);
    }
    
    return (0);
}
Ejemplo n.º 5
0
/*
 *  ======== GIO_new ========
 */
GIO_Handle GIO_new(GIO_Handle gioChan, String name, Int mode, Int *status, Ptr optArgs,
        IOM_Packet packetBuf[], Ptr syncObject, GIO_Attrs *attrs)
{
    DEV_Device  *entry;
    Int         i;
    Int         tmpStat;

    if (attrs == NULL) {
        attrs = &GIO_ATTRS;
    }

    /*
     * status param is used to pass additional device status back to caller.
     */
    if (status == NULL) {
        status = &tmpStat;    /* no longer need to check if status valid ptr */
    }

    *status = IOM_COMPLETED;
    
    /*
     *  Find device structure in device table for device with name 'name'.
     *  DEV_match() returns the remaining name string for use by the
     *  mini-driver's create() function.
     */
    name = DEV_match(name, &entry);
    if (entry == NULL) {
        SYS_error(name, SYS_ENODEV); /* sys error - no device found */
        return (NULL);
    }
    
    if (entry->type != DEV_IOMTYPE) {
        SYS_error("IOM", SYS_EINVAL); /* sys error - invalid device parameter */
        return (NULL);
    }

    /* initialize queue structures */
    QUE_new(&gioChan->freeList);

    /* zero out the packet buffers */
    memset(packetBuf, 0, attrs->nPackets * sizeof(IOM_Packet));

    /* Put packets into freeList. */
    for (i=0; i < attrs->nPackets; i++) {
        QUE_put(&gioChan->freeList, &packetBuf[i]);
    }

    /*
     * Plug semaphore or other synchronization object.  'gioChan->syncObj' is
     * used to wait for I/O to complete when GIO_submit() is called with
     * NULL *appCallback parameter. 
     */
    gioChan->syncObj = syncObject;

    gioChan->fxns = (IOM_Fxns *)entry->fxns;
    gioChan->mode = mode;
    gioChan->timeout = attrs->timeout;

    *status = gioChan->fxns->mdCreateChan(&gioChan->mdChan, entry->devp,
            name, mode, optArgs, _GIO_iomCallback, gioChan);

    if (gioChan->mdChan == NULL) {
        return (NULL);
    }

    return (gioChan);
}
Ejemplo n.º 6
0
/*
 *  ======== GIO_create ========
 */
GIO_Handle GIO_create(String name, Int mode, Int *status, Ptr optArgs, \
        GIO_Attrs *attrs)
{
    GIO_Handle  gioChan;
    IOM_Packet  *packet;
    DEV_Device  *entry;
    Int         i;
    Int         tmpStat;

    if (attrs == NULL) {
        attrs = &GIO_ATTRS;
    }

    /*
     * status param is used to pass additional device status back to caller.
     */
    if (status == NULL) {
        status = &tmpStat;    /* no longer need to check if status valid ptr */
    }

    *status = IOM_COMPLETED;
    
    /*
     *  Find device structure in device table for device with name 'name'.
     *  DEV_match() returns the remaining name string for use by the
     *  mini-driver's create() function.
     */
    name = DEV_match(name, &entry);
    if (entry == NULL) {
        SYS_error(name, SYS_ENODEV); /* sys error - no device found */

        return (NULL);
    }
    
    if (entry->type != DEV_IOMTYPE) {
        SYS_error("IOM", SYS_EINVAL); /* sys error - invalid device parameter */

        return (NULL);
    }

    /*  allocate and 0-fill IOM object */
    gioChan = MEM_calloc(0, sizeof(GIO_Obj), 0);
    if (gioChan == NULL) {
        *status = IOM_EALLOC;  
       
        return (NULL);
    }

    /* initialize queue structures */
    QUE_new(&gioChan->freeList);

    /*
     * Allocate packets for asynch I/O.
     */
    for (i=0; i < attrs->nPackets; i++) {

        packet = _GIO_mkPacket();

        if (packet == NULL) {
           
            *status = IOM_EALLOC;

            GIO_delete(gioChan);
            return (NULL);
        }

        QUE_put(&gioChan->freeList, packet);
    }

    /*
     * Create semaphore or other synchronization object.  'gioChan->syncObj' is
     * used to wait for I/O to complete when GIO_submit() is called with
     * NULL *appCallback parameter. 
     */
    gioChan->syncObj = GIO->SEMCREATE(0, NULL);

    if (gioChan->syncObj == NULL) {

        *status = IOM_EALLOC;
 
        GIO_delete(gioChan);
        return (NULL);
    }

    gioChan->fxns = (IOM_Fxns *)entry->fxns;
    gioChan->mode = mode;
    gioChan->timeout = attrs->timeout;

    *status = gioChan->fxns->mdCreateChan(&gioChan->mdChan, entry->devp,
            name, mode, optArgs, _GIO_iomCallback, gioChan);

    if (gioChan->mdChan == NULL) {
        
        GIO_delete(gioChan);
        return (NULL);
    }

    return (gioChan);
}
Ejemplo n.º 7
0
/*
 *  ======== DOV_open ========
 */
static Int DOV_open(DEV_Handle device, String name)
{
    DOV_CopyObj *copy;
    DEV_Device  *entry;
    Int         status = SYS_EALLOC;
    DEV_Frame   *frame;
    size_t      size;

    if (device->mode != DEV_INPUT) {
        return (SYS_EINVAL);
    }

    /*
     * If devid is nonzero, it holds the 'size' of the overlap buffer.
     */
    if (device->devid > 0) {
        size = device->devid;
    }
    else {
        size = atoi(name);

        /*
         * Skip the numeric characters to get to the underlying
         * device's name.
         */
        while (isdigit(*name)) {
            name++;
        }
    }

    if (size <= 0 || size >= device->bufsize) {
        return (SYS_EINVAL);
    }

    /*
     * find underlying device in device table
     */
    name = DEV_match(name, &entry);
    if (entry == NULL) {
        return (SYS_ENODEV);
    }

    /* allocate copy object */
    if ((copy = MEM_alloc(0, sizeof(DOV_CopyObj), 0)) == MEM_ILLEGAL) {
        return (SYS_EALLOC);
    }

    copy->size = size;

    /* allocate and initialize overlap buffer */
    if ((copy->overlap = MEM_valloc(0, size, 0, DOV->INITIAL)) == MEM_ILLEGAL) {
        goto e1;
    }

    copy->dobj = *device;       /* copy descriptor fields */
    copy->dobj.fxns = *(DEV_Fxns *)(entry->fxns);
    copy->dobj.devid = entry->devid;
    copy->dobj.params = entry->params;

    /* size of underlying buffers */
    copy->dobj.bufsize = device->bufsize - size;

    /*
     * create queues and frames for underlying device.
     */
    if ((copy->dobj.todevice = QUE_create(NULL)) == NULL) {
        goto e2;
    }
    if ((copy->dobj.fromdevice = QUE_create(NULL)) == NULL) {
        goto e3;
    }

    /*
     * adjust frame size and address according to the overlap size before
     * copying frames to underlying device's 'todevice' queue
     */
    while (!QUE_empty(device->todevice)) {
        frame = QUE_get(device->todevice);

        frame->size = frame->size - size;
        frame->addr = (Char *)frame->addr + size;

        QUE_put(copy->dobj.todevice, frame);
    }

    /* open underlying device */
    if ((status = DEV_open((&copy->dobj), name)) != SYS_OK) {
        goto e4;
    }

    device->object = (Ptr)copy;

    return (SYS_OK);            /* all is well */


    /* free memory and return error code */
e4:
    QUE_delete(copy->dobj.fromdevice);
e3:
    QUE_delete(copy->dobj.todevice);
e2:
    MEM_free(0, copy->overlap, copy->size);
e1:
    MEM_free(0, copy, sizeof(DOV_CopyObj));

    return (status);
}