pio.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:9k
- /*
- * Copyright 2003 by Texas Instruments Incorporated.
- * All rights reserved. Property of Texas Instruments Incorporated.
- * Restricted rights to use, duplicate or disclose this code are
- * granted through contract.
- *
- */
- /* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
- /*
- * ======== pio.c ========
- */
- #include <std.h>
- #include <dev.h>
- #include <fxn.h>
- #include <hwi.h>
- #include <pip.h>
- #include <que.h>
- #include <sys.h>
- #include <iom.h>
- #include <pio.h>
- #include <string.h> /* for memset() */
- static Void rxCallback(Arg arg, IOM_Packet *packet);
- static Void txCallback(Arg arg, IOM_Packet *packet);
- static Void transfer (PIO_Handle pio, Uns numFrames);
- #pragma CODE_SECTION(PIO_init, ".text:init");
- #pragma CODE_SECTION(PIO_new, ".text:init");
- #pragma CODE_SECTION(PIO_rxPrime, ".text:PIO_rx");
- #pragma CODE_SECTION(PIO_rxStart, ".text:PIO_rx");
- #pragma CODE_SECTION(PIO_txPrime, ".text:PIO_tx");
- #pragma CODE_SECTION(PIO_txStart, ".text:PIO_tx");
- #pragma CODE_SECTION(txCallback, ".text:PIO_tx");
- #pragma CODE_SECTION(rxCallback, ".text:PIO_rx");
- /*
- * These macros are used to work-around a problem with 'notifyWriter'
- * calls from PIO_txStart() ...
- */
- #ifdef _55_
- /* PIP_Obj structure is defined differently for 55x */
- #define getNotifyWriterFxn(pip) ((pip)->readerSock.notifyFxn.fxn)
- #define setNotifyWriterFxn(pip, notify)
- ((pip)->readerSock.notifyFxn.fxn = (notify))
- #else
- #define getNotifyWriterFxn(pip) ((pip)->notifyWriter.fxn)
- #define setNotifyWriterFxn(pip, notify) ((pip)->notifyWriter.fxn = (notify))
- #endif
- /*
- * ======== PIO_ATTRS ========
- */
- PIO_Attrs PIO_ATTRS = {
- 0 // arg to mdCreateChan
- };
- /* ======== PIO_init ========
- *
- */
- Void PIO_init(Void)
- {
- /*
- * Module initialization
- */
- }
- /*
- * ======== PIO_new ========
- */
- Void PIO_new(PIO_Handle pio, PIP_Handle pip, String name, Int mode,
- PIO_Attrs *attrs)
- {
- IOM_TiomCallback cbFxn;
- DEV_Device *entry;
- Int i, status;
- if (attrs == NULL) {
- attrs = &PIO_ATTRS;
- }
- /*
- * 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_abort("PIO_new: DEV_match() failedn");
- }
- if (entry->type != DEV_IOMTYPE) {
- SYS_abort("PIO_new: invalid device typen");
- }
- pio->pip = pip;
- pio->fxns = (IOM_Fxns *)entry->fxns;
- pio->mode = mode;
- pio->submitCount = 0;
- /* Initialize queue structures */
- QUE_new(&pio->freeList);
- /* Initialize the freeList with packets */
- for (i=0; i < PIO_MAXPACKETS; i++) {
- QUE_put(&pio->freeList, &pio->packet[i]);
- }
- if (mode == IOM_INPUT) {
- cbFxn = (IOM_TiomCallback)rxCallback;
- pio->curdesc = PIP_getWriterCurdesc(pip);
- }
- else {
- cbFxn = (IOM_TiomCallback)txCallback;
- pio->curdesc = PIP_getReaderCurdesc(pip);
- }
- /* open the channel */
- status = pio->fxns->mdCreateChan(&pio->mdChan, entry->devp,
- name, mode, attrs->openArgs, cbFxn, pio);
- if (status != IOM_COMPLETED) {
- SYS_abort("PIO_new: mdCreateChan failed");
- }
- }
- /*
- * ======== transfer ========
- * pio->submitCount
- * The count of frames submitted to the IO mini-driver is stored
- * in pio->submitCount. Transfer() looks ahead in the pipe using
- * the pipe descriptor. The number of frames taken from the pipe
- * in this way is kept in pio->submitCount. Therefore the number of
- * frames available in the pipe is the number of frames indicated by
- * PIP_getReaderNumFrames() or PIP_getWriterNumFrames()
- * less the value of pio->submitCount.
- */
- static Void transfer (PIO_Handle pio, Uns numFrames)
- {
- PIP_Curdesc *curdesc;
- IOM_Packet *packet;
- IOM_TiomCallback cbFxn;
- Int status;
- /*
- * check to see if we have an available PIP frame and an IOM_Packet
- * so that we can submit the I/O request to the mini-driver
- */
- if ((numFrames > pio->submitCount) && (pio->submitCount < PIO_MAXPACKETS)) {
- packet = QUE_get(&pio->freeList);
- /* assert(packet != &pio->freeList); */
- curdesc = pio->curdesc; // pipe descriptor
- pio->curdesc = curdesc->next; // next pipe descriptor
- pio->submitCount++; // increment counter
- /* Initialize the packet */
- packet->addr = curdesc->addr;
- packet->size = curdesc->size * sizeof(Int);
- if (pio->mode == IOM_INPUT) {
- packet->cmd = IOM_READ;
- cbFxn = (IOM_TiomCallback)rxCallback;
- }
- else if (pio->mode == IOM_OUTPUT) {
- packet->cmd = IOM_WRITE;
- cbFxn = (IOM_TiomCallback)txCallback;
- }
- status = pio->fxns->mdSubmitChan(pio->mdChan, packet);
- if (status == IOM_COMPLETED) {
- /*
- * Since the mini-driver completed the I/O, the callback will
- * not be called. We need to handle the callback ourselves.
- * This call might cause recursive call back to transfer().
- */
- cbFxn(pio, packet);
- }
- else if (status < 0) {
- /*
- * This should never happen. IOM mini drivers must be able
- * to queue all submitted IOM_Packets.
- */
- SYS_abort("PIO: mdSubmitChan() failed!");
- }
- }
- }
- /*
- * ======== rxCallback ========
- */
- static Void rxCallback (Arg arg, IOM_Packet *packet)
- {
- PIO_Handle pio = (PIO_Handle)(arg);
- PIP_Handle pip = pio->pip;
- /*
- * Must update the pipe before calling submit again.
- * We have used the pointer to the next frame,
- * but PIP_alloc has not been called yet.
- */
- PIP_alloc(pip);
- /* set size and return completed frame - PIP needs size in words! */
- PIP_setWriterSize(pip, packet->size / sizeof(Int));
- PIP_put(pip);
- /* decrement count of submitted frames */
- pio->submitCount--;
- /* Must put the packet back of the freeList */
- QUE_put(&pio->freeList, packet);
- /* start next transfer */
- transfer(pio, PIP_getWriterNumFrames(pio->pip));
- }
- /*
- * ======== txCallback ========
- */
- static Void txCallback (Arg arg, IOM_Packet *packet)
- {
- PIO_Handle pio = (PIO_Handle)(arg);
- PIP_Handle pip = pio->pip;
- /*
- * Must update the pipe before calling submit again.
- * We have used the pointer to the next frame,
- * but PIP_get has not been called yet.
- */
- PIP_get(pip);
- /* return completed frame */
- PIP_free(pip);
- /* decrement count of submitted frames */
- pio->submitCount--;
- /* Must put the packet back of the freeList */
- QUE_put(&pio->freeList, packet);
- /* start next transfer */
- transfer(pio, PIP_getReaderNumFrames(pio->pip));
- }
- /*
- * ======== PIO_rxPrime ========
- * submit one frame if receive not busy
- */
- Void PIO_rxPrime (PIO_Handle pio)
- {
- Uns imask;
- imask = HWI_disable();
- transfer(pio, PIP_getWriterNumFrames(pio->pip));
- HWI_restore(imask);
- }
- /*
- * ======== PIO_rxStart ========
- * submit frames to receiver
- *
- * CONSTRAINTS:
- * - PIO_rxStart() may only be called in main() before interrupts
- * are enabled
- */
- Void PIO_rxStart (PIO_Handle pio, Uns frameCount)
- {
- for ( ; frameCount > 0; frameCount--) {
- transfer(pio, PIP_getWriterNumFrames(pio->pip));
- }
- }
- /*
- * ======== PIO_txPrime ========
- * submit one frame if transmit not busy
- */
- Void PIO_txPrime (PIO_Handle pio)
- {
- Uns imask;
- imask = HWI_disable();
- transfer(pio, PIP_getReaderNumFrames(pio->pip));
- HWI_restore(imask);
- }
- /*
- * ======== PIO_txStart ========
- * submit initialized frames to transmitter
- *
- * CONSTRAINTS:
- * - PIO_txStart() may only be called in main() before interrupts
- * are enabled
- */
- Void PIO_txStart (PIO_Handle pio, Uns frameCount, Uns initialValue)
- {
- PIP_Handle pip = pio->pip;
- char *buf;
- Fxn notifySave;
- /*
- * Work-around notifyWriter problem at startup.
- * Without this work-around, the PIP_alloc() calls below cause
- * notifyWriter to be called and the application to have incorrect
- * view of the PIP state (application thinks an empty output frame
- * is available when no frame is actually available).
- */
- notifySave = getNotifyWriterFxn(pip);
- setNotifyWriterFxn(pip, (Fxn)FXN_F_nop);
- for ( ; frameCount > 0; frameCount--) {
- if (PIP_getWriterNumFrames(pip) <= 0) break;
- PIP_alloc(pip);
- buf = PIP_getWriterAddr(pip);
- memset(buf, initialValue, PIP_getWriterSize(pip) * sizeof(Int));
- PIP_put(pip);
- }
- /* restore notifyWriter function to its' configured state */
- setNotifyWriterFxn(pip, notifySave);
- }