1    /*
     2     * Copyright (c) 2014-2015, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== GIO.xdc ========
    34     *
    35     */
    36    
    37    import xdc.rov.ViewInfo;
    38    
    39    import xdc.runtime.Error;
    40    import xdc.runtime.Assert;
    41    import xdc.runtime.IHeap;
    42    import xdc.runtime.knl.Sync;
    43    import xdc.runtime.knl.ISync;
    44    
    45    import ti.sysbios.io.DEV;
    46    import ti.sysbios.knl.Queue;
    47    
    48    /*!
    49     *  ======== GIO ========
    50     *  General Purpose IO Manager.
    51     *
    52     *  The GIO Manager offers both the issue/reclaim model and the read/write
    53     *  model to send and receive data from drivers that implement the IOM
    54     *  interface as provided in ti/sysbios/io/iom.h. 
    55     *
    56     *  In the issue/reclaim model, the client calls {@link #issue} when he has
    57     *  a buffer of data.  issue() is non-blocking and returns -- it simply
    58     *  submits the buffer to the driver for I/O.  The client calls
    59     *  {@link #reclaim} to get the buffer back.  A call to reclaim() may block.
    60     *  Upon return from reclaim(), the client can re-use the buffer. 
    61     *
    62     *  The client can issue many buffers before reclaiming them.
    63     *  Buffers are always reclaimed in the order that they were issued.
    64     *  The client can optionally pass a user argument to issue().  This argument
    65     *  can be retrieved with reclaim().
    66     *
    67     *  In the read/write model, clients will call {@link #read} or {@link #write}
    68     *  to send/receive data. Here the client may block until buffer is ready or 
    69     *  a timeout occurs.
    70     *
    71     *  The GIO module also provides {@link #control} to send down driver specific
    72     *  control  commands.  The {@link #abort} function can be used to abort any
    73     *  pending I/O.
    74     *
    75     *  The {@link ti.sysbios.io.DEV} module maintains a name table of IOM drivers.
    76     *  This table is used by GIO to create an IO stack. The name passed to
    77     *  {@link #create} is usually of the form "/uart". This name may
    78     *  correspond to the following IO stack.
    79     *
    80     *         GIO Instance
    81     *
    82     *              |
    83     *              v
    84     *
    85     *         IOM Instance (/uart)
    86     *
    87     *  The GIO module uses the {@link xdc.runtime.knl.Sync} module for
    88     *  synchronization.  GIO will call {@link xdc.runtime.knl.Sync#signal} when 
    89     *  I/O completes and {@link xdc.runtime.knl.Sync#wait} to wait for I/O.
    90     *
    91     *  By default the I/O manager will create a semaphore for synchronization
    92     *  if no sync handle is passed to {@link #create}. 
    93     */
    94    
    95    @DirectCall
    96    @InstanceFinalize
    97    @InstanceInitError
    98    
    99    module GIO 
   100    {
   101        /*! Init function type definition. */
   102        typedef Void (*InitFxn)();
   103    
   104        /* these must stay in synch with modes in iom.h */
   105        const UInt INPUT  = 0x1;      /*! mode for input */
   106        const UInt OUTPUT = 0x2;      /*! mode for output */
   107        const UInt INOUT  = 0x3;      /*! mode for input & output */
   108        
   109        /*! 
   110         *  Error raised when name not found in DeviceTable.
   111         */
   112        config Error.Id E_notFound  = {
   113            msg: "E_notFound: %s name not found"
   114        };
   115    
   116        /*! 
   117         *  Error raised when driver's mdCreateChan() call fails
   118         */
   119        config Error.Id E_createFailed  = {
   120            msg: "E_createFailed: mdCreateChan returned error %d"
   121        };
   122    
   123        /*! 
   124         *  Asserted in GIO_read(), GIO_write() if I/O model is not
   125         *  STANDARD or in GIO_issue(), GIO_reclaim(), or GIO_prime() if the
   126         *  I/O model is not ISSUERECLAIM.
   127         */
   128        config Assert.Id A_badModel = {
   129            msg: "A_badModel: invalid use of API for current I/O model" 
   130        };
   131        
   132        /*!
   133         *  ======== deviceTableSize ========
   134         *  This configuration parameter has been deprecated.  Use DEV.tableSize.
   135         */
   136        config Int deviceTableSize = 8;
   137    
   138        metaonly struct BasicView {
   139            String              label;
   140            UInt                freeCount;
   141            UInt                doneCount;
   142            UInt                submitCount;
   143            String              model;
   144            String              mode;
   145            Bool                userSuppliedSync;
   146        }
   147        
   148        @Facet
   149        metaonly config ViewInfo.Instance rovViewInfo = 
   150            ViewInfo.create({
   151                viewMap: [
   152                    ['Basic', {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic', structName: 'BasicView'}],
   153                ]
   154            });
   155    
   156        /*! model for IO channel */
   157        enum Model {
   158            Model_STANDARD,        /*! used for read, write, submit */ 
   159            Model_ISSUERECLAIM     /*! used for issue, reclaim, prime */
   160        };
   161    
   162        /*! application callback function used with GIO_submit() */
   163        typedef Void (*TappCallBack)(Ptr, Int, Ptr, SizeT);
   164    
   165        /*!
   166         *  Application Callback Structure.
   167         *
   168         *  Used with GIO_submit() for asynchronous callback.
   169         */
   170        struct AppCallback {
   171            TappCallBack    fxn;
   172            Ptr             arg;
   173        };
   174    
   175        /*!
   176         *  ======== addDevice ========
   177         *  This API has been deprecated.  Use DEV_create().
   178         */
   179        Int addDevice(String name, Ptr fxns, InitFxn initFxn, Int devid, Ptr params);
   180    
   181        /*!
   182         *  ======== addDeviceMeta ========
   183         *  This API has been deprecated.  Use DEV.create().
   184         */
   185        metaonly Void addDeviceMeta(String name, String fxns, String initFxn, Int devid, String params);
   186    
   187        /*!
   188         *  ======== removeDevice ========
   189         *  This API has been deprecated.  Use DEV_match() and DEV_delete().
   190         */
   191        Int removeDevice(String name);
   192    
   193    instance:
   194    
   195        /*!
   196         *  ======== model ========
   197         *  I/O model
   198         *
   199         *  Set the model to STANDARD to use read(), write() and submit() APIs.   
   200         *  Set the model to ISSUERECLAIM to use issue(), reclaim(), and
   201         *  prime() APIs.   
   202         *
   203         *  The default for this parameter is STANDARD.
   204         */
   205        config Model model = Model_STANDARD;
   206    
   207        /*! Number of packets to use for asynchronous I/O */
   208        config Int numPackets = 2;
   209    
   210        /*! For blocking calls.  Default is BIOS_WAIT_FOREVER */
   211        config UInt timeout = ~(0);
   212    
   213        /*! ISync handle used to signal IO completion */
   214        config ISync.Handle sync = null;
   215    
   216        /*!
   217         *  ======== chanParams ========
   218         *  channel parameters
   219         *
   220         *  The chanParams parameter is a pointer that may be used to pass device
   221         *  or domain-specific arguments to the mini-driver. The contents at the
   222         *  specified address are interpreted by the mini-driver in a
   223         *  device-specific manner.  
   224         */
   225        config Ptr chanParams = null;
   226    
   227        /*!
   228         *  ======== packets ========
   229         *  The address of the buffer used for IOM packets.
   230         *
   231         *  If set to 'null', the packets will be allocated from the heap
   232         *  during runtime, otherwise the user may set this to a buffer of their
   233         *  creation to be used for the IOM packets.
   234         *
   235         *  The packets will be split into
   236         *  {@link ti.sysbios.io.GIO#numPackets} each the size of IOM_Packet.
   237         *
   238         *  Please note that if the packets is user supplied, then it is the user's
   239         *  responsibility to ensure that it is aligned properly and is also large
   240         *  enough to contain {@link ti.sysbios.io.GIO#numPackets} number of
   241         *  IOM_Packet packets.  The size of packets buffer, if provided,
   242         *  should be
   243         *
   244         *  @p(code)
   245         *      sizeof(IOM_Packet) * numPackets
   246         *  @p
   247         *
   248         *  Example:
   249         *  @p(code)
   250         *  #define NUMPACKETS  2
   251         *  IOM_Packet inPackets[NUMPACKETS];
   252         *
   253         *  GIO_Params params;
   254         *
   255         *  GIO_Params_init(&params);
   256         *  params.numPackets = NUMPACKETS;
   257         *  params.packets = inPackets;
   258         *  @p
   259         */
   260        config Ptr packets = null;
   261    
   262        /*!
   263         *  ======== abort ========
   264         *  Abort all pending IO.
   265         *
   266         *  An application calls GIO_abort to abort all input and output from
   267         *  the device. When this call is made, all pending calls are completed
   268         *  with a status of GIO_ABORTED. An application uses this call to
   269         *  return the device to its initial state. Usually this is done in
   270         *  response to an unrecoverable error at the device level.
   271         *
   272         *  GIO_abort returns IOM_COMPLETED upon successfully aborting all
   273         *  input and output requests. If an error occurs, the device returns a
   274         *  negative value.  The list of error values are defined in the 
   275         *  ti/sysbios/io/iom.h file.
   276         *
   277         *  A call to GIO_abort results in a call to the mdSubmit function of the
   278         *  associated mini-driver. The IOM_ABORT command is passed to the
   279         *  mdSubmit function. The mdSubmit call is typically a blocking call, so
   280         *  calling GIO_abort can result in the thread blocking.
   281         *
   282         *  If using ISSUERECLAIM IO model, the the underlying device
   283         *  connected to stream is idled as a result of calling abort and
   284         *  all buffers are ready for reclaim().  The client needs to call
   285         *  {@link #reclaim} to get back the buffers.  However the client will
   286         *  NOT block when calling reclaim() after an abort().
   287         *
   288         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   289         */
   290        Int abort();
   291    
   292        /*!
   293         *  ======== control ========
   294         *  Send a control command to the driver.
   295         *
   296         *  An application calls GIO_control to configure or perform control
   297         *  functionality on the communication channel.
   298         *
   299         *  The cmd parameter may be one of the command code constants listed in
   300         *  ti/sysbios/io/iom.h. A mini-driver may add command codes for
   301         *  additional functionality.
   302         *
   303         *  The args parameter points to a data structure defined by the device to
   304         *  allow control information to be passed between the device and the
   305         *  application. This structure can be generic across a domain or
   306         *  specific to a mini-driver. In some cases, this argument may point
   307         *  directly to a buffer holding control data. In other cases, there
   308         *  may be a level of indirection if the mini-driver expects a data
   309         *  structure to package many components of data required for the control
   310         *  operation. In the simple case where no data is required, this 
   311         *  parameter may just be a predefined command value.
   312         *
   313         *  GIO_control returns IOM_COMPLETED upon success. If an error occurs,
   314         *  the device returns a negative value. For a list of error values, see 
   315         *  ti/sysbios/io/iom.h.  A call to GIO_control results in a call to
   316         *  the mdControl function of the associated mini-driver. The mdControl
   317         *  call is typically a blocking call, so calling GIO_control can result
   318         *  in blocking.
   319         *
   320         *  @param(cmd)         device specific command
   321         *  @param(args)        pointer to device-specific arguments
   322         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   323         */
   324        Int control(UInt cmd, Ptr args);
   325    
   326        /*!
   327         *  ======== create ========
   328         *  Create a GIO Instance.
   329         *
   330         *  An application calls GIO_create to create a GIO_Obj object and open
   331         *  a communication channel. This function initializes the I/O channel
   332         *  and opens the lower-level device driver channel. The GIO_create call
   333         *  also creates the synchronization objects it uses and stores them in
   334         *  the GIO_Obj object.
   335         *
   336         *  The name argument is the name specified for the device when it was
   337         *  created in the configuration or at runtime.
   338         *
   339         *  The mode argument specifies the mode in which the device is to be
   340         *  opened. This may be IOM_INPUT, IOM_OUTPUT, or IOM_INOUT.  
   341         *
   342         *  If the status returned by the device is non-NULL, a status value is
   343         *  placed at the address specified by the status parameter.  
   344         *
   345         *  The GIO_create call allocates a list of IOM_Packet items as specified
   346         *  by the numPackets member of the params structure and stores them in
   347         *  the GIO_Obj object it creates.
   348         *
   349         *  @param(name)        name that identifies the IO stack
   350         *  @param(mode)        mode of channel
   351         */
   352        create(String name, UInt mode);
   353    
   354        /*!
   355         *  ======== flush ========
   356         *  Drain output buffers and discard any pending input
   357         * 
   358         *  An application calls GIO_flush to flush the input and output
   359         *  channels of the device.  All input data is discarded; all pending
   360         *  output requests are completed.  When this call is made, all pending
   361         *  input calls are completed with a status of IOM_FLUSHED, and all
   362         *  output calls are completed routinely.
   363         *
   364         *  This call returns IOM_COMPLETED upon successfully flushing all
   365         *  input and output.  If an error occurs, the device returns a negative
   366         *  value. For a list of error values, see ti/sysbios/io/iom.h.
   367         *
   368         *  A call to GIO_flush results in a call to the mdSubmit function of
   369         *  the associated mini-driver. The IOM_FLUSH command is passed to the
   370         *  mdSubmit function. The mdSubmit call is typically a blocking call,
   371         *  so calling GIO_flush can result in the thread blocking while waiting
   372         *  for output calls to be completed.
   373         *
   374         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   375         */
   376        Int flush();
   377    
   378        /*!
   379         *  ======== issue ========
   380         *  Issue a buffer to the stream.
   381         *
   382         *  This function issues a buffer to the stream for IO. This API is
   383         *  non-blocking.
   384         *
   385         *  Failure of issue() indicates that the stream was not able to accept the
   386         *  buffer being issued or that there was a error from the underlying
   387         *  driver. Note that the error could be driver specific.
   388         *  If issue() fails because of an underlying driver problem
   389         *  {@link #abort} should be called before attempting more I/O through the 
   390         *  stream.
   391         *
   392         *  The interpretation of the logical size of a buffer, is direction
   393         *  dependent.  For a stream opened in OUTPUT mode, the logical size
   394         *  of the buffer indicates the number of minimum addressable units of of 
   395         *  data it contains. 
   396         *
   397         *  For a stream opened in INPUT mode, the logical size 
   398         *  of a buffer indicates the number of minimum addressable units being 
   399         *  requested by the client. In either case, the logical size of the buffer 
   400         *  must be less than or equal to the physical size of the buffer.
   401         *
   402         *  issue() is used in conjunction with {@link #reclaim}. The issue() call 
   403         *  sends a buffer to a stream, and reclaim() retrieves a buffer 
   404         *  from a stream. In normal operation each issue() call is followed by an 
   405         *  reclaim() call.
   406         *
   407         *  Short bursts of multiple issue() calls can be made without an
   408         *  intervening reclaim() call followed by short bursts of reclaim() calls, 
   409         *  but over the life of the stream issue() and reclaim() must be called 
   410         *  the same number of times. The number of issue() calls can exceed the 
   411         *  number of reclaim() calls by {@link #maxIssues}.
   412         *
   413         *  The client argument is not interpreted by IO or the underlying 
   414         *  modules, but is offered as a service to the stream client. All compliant
   415         *  device drivers preserve the value of arg and maintain its association 
   416         *  with the data that it was issued with. arg provides a method for a 
   417         *  client to associate additional information with a particular buffer of 
   418         *  data. The arg is returned during reclaim().
   419         *
   420         *  @param(buf)         buffer pointer
   421         *  @param(size)        size of buffer
   422         *  @param(arg)         application arg
   423         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   424         *  
   425         */
   426        Int issue(Ptr buf, SizeT size, UArg arg);
   427    
   428        /*!
   429         *  ======== reclaim ========
   430         *  Reclaim a buffer that was previously issued by calling {@link #issue}.
   431         *
   432         *  reclaim() is used to request a buffer back from a stream. 
   433         *
   434         *  If a stream was created in OUTPUT mode, then reclaim() returns a
   435         *  processed buffer, and size is zero.  If a stream was opened in
   436         *  INPUT mode, reclaim() returns a full buffer, and size is the number
   437         *  of minimum addressable units of data in the buffer.
   438         *
   439         *  reclaim() calls Sync_wait() with the timeout specified when the 
   440         *  channel was created.  For the default SyncSem, reclaim() blocks
   441         *  until a buffer can be returned to the caller, or until a timeout occurs.
   442         *
   443         *  Failure of reclaim() indicates that no buffer was returned to 
   444         *  the  client. Therefore, if reclaim() fails, the client should 
   445         *  not attempt to de-reference pBuf, since it is not guaranteed to contain
   446         *  a valid buffer pointer.
   447         *
   448         *  reclaim() is used in conjunction with {@link #issue} to operate 
   449         *  a stream. The issue() call sends a buffer to a stream, and 
   450         *  reclaim() retrieves a  buffer from a stream. In normal operation
   451         *  each issue call is followed by an reclaim call.
   452         *
   453         *  Short bursts of multiple issue() calls can be made without an
   454         *  intervening reclaim() call followed by short bursts of reclaim() calls, 
   455         *  but over the life of the stream issue() and reclaim() must be called 
   456         *  the same number of times. The number of issue() calls can exceed the 
   457         *  number of reclaim() calls by {@link #maxIssues}.
   458         *
   459         *  A reclaim() call should not be made without at least one 
   460         *  outstanding issue() call. Calling reclaim() with no 
   461         *  outstanding issue() calls results in an error {@link #E_noBuffersIssued}
   462         *
   463         *  reclaim() only returns buffers that were passed in using issue(). It 
   464         *  also returns the buffers in the same order that they were issued.
   465         *
   466         *  reclaim() returns the size transferred in case of success.
   467         *  It returns zero when an error is caught. In case of timeout, the error 
   468         *  is {@link #E_timeout}.
   469         *
   470         *  @param(pBuf)        returned buffer pointer
   471         *  @param(pSize)       pointer to size of buffer (OUTPUT parameter)
   472         *  @param(pArg)        pointer to client arg. Can be null.
   473         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   474         *  
   475         */
   476        Int reclaim(Ptr *pBuf, SizeT *pSize, UArg *pArg);
   477    
   478        /*!
   479         *  ======== read ========
   480         *  Synchronous read command
   481         *
   482         *  An application calls GIO_read to read a specified number of MADUs
   483         *  (minimum addressable data units) from the communication channel.  
   484         *
   485         *  The buf parameter points to a device-defined data structure for
   486         *  passing buffer data between the device and the application. This
   487         *  structure may be generic across a domain or specific to a single
   488         *  mini-driver. In some cases, this parameter may point directly to a
   489         *  buffer that holds the read data. In other cases, this parameter may
   490         *  point to a structure that packages buffer information, size, offset
   491         *  to be read from, and other device-dependent data. For example, for
   492         *  video capture devices this structure may contain pointers to RGB
   493         *  buffers, their sizes, video format, and a host of data required for
   494         *  reading a frame from a video capture device.  Upon a successful read,
   495         *  this argument points to the returned data. 
   496         *
   497         *  The pSize parameter points to the size of the buffer or data
   498         *  structure pointed to by the buf parameter. When the function
   499         *  returns, this parameter points to the number of MADUs read from the
   500         *  device. This parameter is relevant only if the buf parameter points
   501         *  to a raw data buffer. In cases where it points to a device-defined
   502         *  structure it is redundant -- the size of the structure is known to
   503         *  the mini-driver and the application. At most, it can be used for
   504         *  error checking.
   505         *
   506         *  GIO_read returns IOM_COMPLETED upon successfully reading the
   507         *  requested number of MADUs from the device. If an error occurs,
   508         *  the device returns a negative value. For a list of error values,
   509         *  see ti/sybios/io/iom.h. 
   510         *
   511         *  A call to GIO_read results in a call to the mdSubmit function of
   512         *  the associated mini-driver. The IOM_READ command is passed to the
   513         *  mdSubmit function. The mdSubmit call is typically a blocking call,
   514         *  so calling GIO_read can result in the thread blocking.
   515         *
   516         *  @param(buf)         buffer pointer
   517         *  @param(pSize)       pointer to size of buffer (INPUT/OUTPUT parameter)
   518         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   519         */
   520        Int read(Ptr buf, SizeT *pSize);  
   521    
   522        /*!
   523         *  ======== write ========
   524         *  Synchronous write command
   525         *
   526         *  An application calls GIO_write to write a specified number of MADUs
   527         *  (minimum addressable data units) from the communication channel.  
   528         *
   529         *  The buf parameter points to a device-defined data structure for
   530         *  passing buffer data between the device and the application. This
   531         *  structure may be generic across a domain or specific to a single
   532         *  mini-driver. In some cases, this parameter may point directly to a
   533         *  buffer that holds the write data. In other cases, this parameter may
   534         *  point to a structure that packages buffer information, size, offset
   535         *  to be write from, and other device-dependent data. For example, for
   536         *  video capture devices this structure may contain pointers to RGB
   537         *  buffers, their sizes, video format, and a host of data required for
   538         *  reading a frame from a video capture device.
   539         *
   540         *  The pSize parameter points to the size of the buffer or data
   541         *  structure pointed to by the buf parameter. When the function
   542         *  returns, this parameter points to the number of MADUs written to the
   543         *  device. This parameter is relevant only if the buf parameter points
   544         *  to a raw data buffer. In cases where it points to a device-defined
   545         *  structure it is redundant -- the size of the structure is known to
   546         *  the mini-driver and the application. At most, it can be used for
   547         *  error checking.
   548         *
   549         *  GIO_write returns IOM_COMPLETED upon successfully writing the
   550         *  requested number of MADUs from the device. If an error occurs,
   551         *  the device returns a negative value. For a list of error values,
   552         *  see ti/sybios/io/iom.h. 
   553         *
   554         *  A call to GIO_write results in a call to the mdSubmit function of
   555         *  the associated mini-driver. The IOM_WRITE command is passed to the
   556         *  mdSubmit function. The mdSubmit call is typically a blocking call,
   557         *  so calling GIO_write can result in the thread blocking.
   558         *
   559         *  @param(buf)         buffer pointer
   560         *  @param(pSize)       pointer to size of buffer (INPUT/OUTPUT parameter)
   561         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   562         */
   563        Int write(Ptr buf, SizeT *pSize);  
   564    
   565        /*!
   566         *  ======== submit ========
   567         *  Submit an IO job to the mini-driver
   568         *
   569         *  GIO_submit is not typically called by applications. Instead, it is
   570         *  used internally and for user-defined extensions to the GIO module.
   571         *
   572         *  The cmd parameter is IOM_READ, IOM_WRITE, IOM_ABORT or IOM_FLUSH
   573         *  when used internally.  A mini driver may add command codes for 
   574         *  additional functionality.
   575         *
   576         *  The bufp parameter points to a device-defined data structure for
   577         *  passing buffer data between the device and the application. This
   578         *  structure may be generic across a domain or specific to a single
   579         *  mini-driver. In some cases, this parameter may point directly to
   580         *  a buffer that holds the data. In other cases, this parameter may
   581         *  point to a structure that packages buffer information, size, offset
   582         *  to be read from, and other device-dependent data.
   583         *
   584         *  The pSize parameter points to the size of the buffer or data structure
   585         *  pointed to by the bufp parameter. When the function returns, this
   586         *  parameter points to the number of MADUs transferred to or from the
   587         *  device. This parameter is relevant only if the bufp parameter points
   588         *  to a raw data buffer. In cases where it points to a device-defined
   589         *  structure it is redundant -- the size of the structure is known to
   590         *  the mini-driver and the application. At most, it can be used for
   591         *  error checking.
   592         *
   593         *  The appCallback parameter points to either a callback structure that
   594         *  contains the callback function to be called when the request completes.
   595         *  queued request is completed, the callback routine (if specified) is
   596         *  invoked (i.e. blocking).  If the appCallback parameter is NULL, then
   597         *  the call to GIO_submit() will be synchronous and will not return
   598         *  until IO is complete (or an error occurs).  
   599         *
   600         *  GIO_submit returns IOM_COMPLETED upon successfully carrying out
   601         *  the requested functionality. If the request is queued, then a status of
   602         *  IOM_PENDING is returned. If an error occurs, the device returns a
   603         *  negative value. For a list of error values, see ti/sysbios/io/iom.h.
   604         * 
   605         *  A call to GIO_submit results in a call to the mdSubmit function of
   606         *  the associated mini-driver. The specified command is passed to the
   607         *  mdSubmit function.
   608         *
   609         *  @param(cmd)         driver specific packet command
   610         *  @param(buf)         buffer pointer
   611         *  @param(pSize)       pointer to size of buffer (INPUT/OUTPUT parameter)
   612         *  @param(appCallBack) pointer to application callback structure
   613         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   614         */
   615        Int submit(UInt cmd, Ptr buf, SizeT *pSize, AppCallback *appCallback); 
   616        
   617        /*!
   618         *  ======== prime ========
   619         *  Prime an OUTPUT stream instance.
   620         *
   621         *  This API facilitates buffering of an output channel. Consider a
   622         *  task that constantly gets data from input channel and sends to an
   623         *  output channel. To start with it may want to issue buffers to the
   624         *  input channel and output channel to enable double buffering.
   625         *  For an input channel there is no problem. For an output channel however
   626         *  the buffer data is sent out through the peripheral and in the case of a
   627         *  heterogenous system, the data will be sent to the other processor.
   628         *
   629         *  In such cases where the driver cannot handle dummy buffers,
   630         *  IO_prime can be used to make buffers available instantly for
   631         *  reclaim without actually sending the buffers to the driver.
   632         *  This API is non-blocking.
   633         *
   634         *  The primary use of prime() is used when applications want to prime
   635         *  an output channel at startup, without sending data to the driver.
   636         *  This allows them to reclaim and issue in their task.
   637         *
   638         *  Failure of prime() indicates that the stream was not able to accept the
   639         *  buffer being issued  due to un-avaibailibity of IO packets.
   640         *
   641         *  The client argument is not interpreted by IO.
   642         *
   643         *  @param(buf)         buffer pointer
   644         *  @param(size)        size of buffer
   645         *  @param(arg)         app arg
   646         *  @b(returns)         IOM_COMPLETED on success, < 0 on failure  
   647         */
   648        Int prime(Ptr buf, SizeT size, UArg arg);
   649    
   650    internal:
   651    
   652        /* -------- Internal Structures -------- */
   653        struct Instance_State {
   654            String              name;           /* name used to create inst */
   655            UInt                mode;           /* input or output */
   656            UInt                model;          /* STANARD or ISSUERECLAIM */
   657            UInt                timeout;        /* STANARD or ISSUERECLAIM */
   658            IHeap.Handle        packetHeap;     /* heap used to alloc packets */
   659            ISync.Handle        sync;           /* completion sync */
   660            Bool                userSync;       /* user supplied sync handle */
   661            Bool                userPackets;    /* user supplied packets buffer */
   662            Queue.Object        doneList;       /* done packets */
   663            Queue.Object        freeList;       /* free packets */
   664            Ptr                 packets;        /* allocated packet block */
   665            Int                 numPackets;     /* total # of packets */
   666            Int                 freeCount;      /* # of free packets */
   667            Int                 doneCount;      /* # of completed packets */
   668            Int                 submitCount;    /* # packets submitted to driver */
   669    
   670            Ptr                 fxns;           /* device function table */
   671            Ptr                 mdChan;         /* pointer to driver chan object */
   672        };
   673    }