c5509_usb_submit.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:6k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
  9. /*
  10.  *  ======== _C5509_USB_mdSubmitChan.c ========
  11.  *  This file implements C5509_USB_mdSubmitChan function
  12.  */
  13. #include <std.h>
  14. #include <csl.h>
  15. #include <hwi.h>
  16. #include <que.h>
  17. #include <iom.h>
  18. #include <csl.h>
  19. #include <csl_usb.h>
  20. #include <_c5509_usb.h>
  21. /* 
  22.  *  ======== _C5509_USB_removePackets ========
  23.  *  This function remove all pending packets and 
  24.  *  do IOM_cbck with the status IOM_ABORTED or IOM_FLUSHED 
  25.  *  Call with INTRs disabled.
  26.  */
  27. Void _C5509_USB_removePackets(Ptr chanp, Int status)
  28. {
  29.     QUE_Elem *elem;
  30.     C5509_USB_ChanHandle chan = (C5509_USB_ChanHandle)chanp;
  31.     
  32.     /* discard the current active packets */
  33.     if( !chan->dataPacket ) {
  34.         return; /* no pending IO packets to be removed */
  35.     }
  36.     else{
  37.         if( !USB_isTransactionDone(&chan->epObj) ) {
  38.             USB_abortTransaction(&chan->epObj);
  39.             chan->dataPacket->status = status;
  40.             (*chan->cbFxn)( chan->cbArg, chan->dataPacket );
  41.             chan->dataPacket = NULL;
  42.         }           
  43.     }
  44.     
  45.     /* remove packets in the queue and callback to class driver */
  46.     while (!QUE_empty(&chan->pendList)) {
  47.         elem = QUE_get(&chan->pendList);
  48.         ((IOM_Packet*)elem)->status = status;  
  49.         (*chan->cbFxn )( chan->cbArg, (IOM_Packet*)elem);
  50.     }
  51. }
  52. /*
  53.  *  ======== _C5509_USB_flushPacketHandler ========
  54.  *  This function handle IOM_FlUSH. 
  55.  *  Call with INTRs disabled.
  56.  */
  57. Void _C5509_USB_flushPacketHandler(C5509_USB_ChanHandle chan, 
  58.         IOM_Packet * flushPacket)
  59. {
  60.     if( flushPacket ) {
  61.         /* there is a flush packet */
  62.         flushPacket->status = IOM_COMPLETED;
  63.         ( *chan->cbFxn )( chan->cbArg, flushPacket );    /* IOM_cbck */
  64.         flushPacket = NULL;    /* chan->flushPacket is NULL */
  65.     }
  66. }
  67.  
  68. /*
  69.  *  ======== _C5509_USB_transactionHandler ========
  70.  *  This function performs the actual I/O and is invoked by lower
  71.  *   level USB CSL.
  72.  */
  73. Void _C5509_USB_transactionHandler(C5509_USB_ChanHandle chan) {
  74.     IOM_Packet *packet;
  75.        
  76.     if (!chan) {
  77.         return;        /*  chan has not been created */ 
  78.     }
  79.     packet = chan->dataPacket;
  80.     if (!packet) {    
  81.         return;    /* i/o request has not arrived  */
  82.     }
  83.     if (!USB_isTransactionDone(&chan->epObj) ) { 
  84.         return;    /* current transaction has not been finished */
  85.     }
  86.     /* current active I/O is finished */
  87.     packet->status = IOM_COMPLETED;
  88.     packet->size = *(Uns *)packet->addr >> 1; /* return actual size in madus */
  89.     (*chan->cbFxn )(chan->cbArg, packet);    /* IOM_cbck */
  90.     /* post the next I/O if there is any */
  91.     chan->dataPacket = QUE_get(&chan->pendList);
  92.     if (chan->dataPacket == (IOM_Packet*)&chan->pendList) {
  93.     
  94.         /* there is no I/O packet left */
  95.         chan->dataPacket = NULL;
  96.         /* handle flush cmd if any */
  97.         _C5509_USB_flushPacketHandler(chan, chan->flushPacket); 
  98.     }
  99.     else {
  100.         /* post the next I/O */
  101.         while( !USB_postTransaction(&chan->epObj,
  102.                 chan->dataPacket->size * 2, chan->dataPacket->addr, 
  103.                 USB_IOFLAG_NOSHORT ) );
  104.     }
  105. }
  106. /*
  107.  *  ======== _C5509_USB_mdSubmitChan ========
  108.  *  This function handles IOM_READ, IOM_WRITE, IOM_FLUSH AND IOM_ABORT
  109.  *  
  110.  *  chanp is the pointer to the chanObj
  111.  *  
  112.  *  packet is formated by IOM
  113.  *
  114.  *  IOM_READ/WRITE pends the packet into pendlist if previous I/O has
  115.  *  not been complete. Otherwise, it posts a transaction.
  116.  *
  117.  *  IOM_ABORT or IOM_FLUSH for an IOM_INPUT channel is handled similarly.
  118.  *  It cancels all pending I/Os with callback status IOM_ABORTED/FLUSHED. 
  119.  *  
  120.  *  IOM_FLUSH for an IOM_OUTPUT channel is handled differently. It returns
  121.  *  IOM_PENDING to IOM when there is any uncompleted write request. When
  122.  *  the last write request is completed, flushHandler calls back to notify 
  123.  *  IOM that IOM_FLUSH is completed. 
  124.  */
  125. Int _C5509_USB_mdSubmitChan(Ptr chanp, IOM_Packet *packet)
  126. {
  127.     C5509_USB_ChanHandle chan = (C5509_USB_ChanHandle)chanp;
  128.     Uns imask;
  129.     Int status = IOM_COMPLETED;
  130.     Int ioStatus = IOM_ABORTED;
  131.     imask=HWI_disable();    /* disable the interrrupt */
  132.     if (packet->cmd == IOM_READ || packet->cmd == IOM_WRITE) {
  133.     
  134.         status = IOM_PENDING;    /* always return IOM_PENDING */
  135.         
  136.         if (chan->dataPacket != NULL){
  137.             /* 
  138.              * current active I/O packet hasn't been completed
  139.              * queue the packet
  140.              */
  141.             QUE_enqueue(&chan->pendList, packet); 
  142.         }
  143.         else {
  144.             /* The USB device is expecting size in bytes mult size by 2 */
  145.             if (!USB_postTransaction(&chan->epObj, packet->size * 2, 
  146.                     packet->addr, USB_IOFLAG_NOSHORT) ) {
  147.                 /* 
  148.                  * no active I/O packet, so post the transaction.
  149.                  * if fail to post the transaction, return error
  150.                  */
  151.                 status = IOM_EBADIO;
  152.             }
  153.             else {          
  154.                 /* 
  155.                  * successfully post the transaction
  156.                  * chan->dataPacket points to current active packet
  157.                  */
  158.                 chan->dataPacket=packet;
  159.             }
  160.         }
  161.     
  162.     }
  163.     else if ( packet->cmd == IOM_FLUSH && chan->mode == IOM_INPUT ||
  164.             packet->cmd == IOM_ABORT) {
  165.         /* in this case, we discard all packets */       
  166.         if( packet->cmd == IOM_FLUSHED) {
  167.             ioStatus=IOM_FLUSHED;
  168.         }
  169.         /* discard all pending I/Os */
  170.         _C5509_USB_removePackets(chan, ioStatus);
  171.             
  172.     } 
  173.     else if ((packet->cmd ==IOM_FLUSH) && (chan->mode == IOM_OUTPUT)) {
  174.         if(chan->dataPacket) {
  175.             /* 
  176.              *  since there are pending requests, record the flush 
  177.              *  cmd. When the last write request is completed, 
  178.              *  flushHandler calls back to notify that flush cmd
  179.              *  is finished.
  180.              */
  181.             chan->flushPacket = packet;
  182.             status = IOM_PENDING;
  183.         }
  184.     }
  185.     else{
  186.         status = IOM_EBADARGS;
  187.     }
  188.     HWI_restore(imask);    /* restore the HWI */
  189.     
  190.     return (status); 
  191. }