c5509_usb_submit.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:6k
- /*
- * 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.10.00.23 07-02-03 (ddk-b12)" */
- /*
- * ======== _C5509_USB_mdSubmitChan.c ========
- * This file implements C5509_USB_mdSubmitChan function
- */
- #include <std.h>
- #include <csl.h>
- #include <hwi.h>
- #include <que.h>
- #include <iom.h>
- #include <csl.h>
- #include <csl_usb.h>
- #include <_c5509_usb.h>
- /*
- * ======== _C5509_USB_removePackets ========
- * This function remove all pending packets and
- * do IOM_cbck with the status IOM_ABORTED or IOM_FLUSHED
- * Call with INTRs disabled.
- */
- Void _C5509_USB_removePackets(Ptr chanp, Int status)
- {
- QUE_Elem *elem;
- C5509_USB_ChanHandle chan = (C5509_USB_ChanHandle)chanp;
-
- /* discard the current active packets */
- if( !chan->dataPacket ) {
- return; /* no pending IO packets to be removed */
- }
- else{
- if( !USB_isTransactionDone(&chan->epObj) ) {
- USB_abortTransaction(&chan->epObj);
- chan->dataPacket->status = status;
- (*chan->cbFxn)( chan->cbArg, chan->dataPacket );
- chan->dataPacket = NULL;
- }
- }
-
- /* remove packets in the queue and callback to class driver */
- while (!QUE_empty(&chan->pendList)) {
- elem = QUE_get(&chan->pendList);
- ((IOM_Packet*)elem)->status = status;
- (*chan->cbFxn )( chan->cbArg, (IOM_Packet*)elem);
- }
- }
- /*
- * ======== _C5509_USB_flushPacketHandler ========
- * This function handle IOM_FlUSH.
- * Call with INTRs disabled.
- */
- Void _C5509_USB_flushPacketHandler(C5509_USB_ChanHandle chan,
- IOM_Packet * flushPacket)
- {
- if( flushPacket ) {
- /* there is a flush packet */
- flushPacket->status = IOM_COMPLETED;
- ( *chan->cbFxn )( chan->cbArg, flushPacket ); /* IOM_cbck */
- flushPacket = NULL; /* chan->flushPacket is NULL */
- }
- }
-
- /*
- * ======== _C5509_USB_transactionHandler ========
- * This function performs the actual I/O and is invoked by lower
- * level USB CSL.
- */
- Void _C5509_USB_transactionHandler(C5509_USB_ChanHandle chan) {
- IOM_Packet *packet;
-
- if (!chan) {
- return; /* chan has not been created */
- }
- packet = chan->dataPacket;
- if (!packet) {
- return; /* i/o request has not arrived */
- }
- if (!USB_isTransactionDone(&chan->epObj) ) {
- return; /* current transaction has not been finished */
- }
- /* current active I/O is finished */
- packet->status = IOM_COMPLETED;
- packet->size = *(Uns *)packet->addr >> 1; /* return actual size in madus */
- (*chan->cbFxn )(chan->cbArg, packet); /* IOM_cbck */
- /* post the next I/O if there is any */
- chan->dataPacket = QUE_get(&chan->pendList);
- if (chan->dataPacket == (IOM_Packet*)&chan->pendList) {
-
- /* there is no I/O packet left */
- chan->dataPacket = NULL;
- /* handle flush cmd if any */
- _C5509_USB_flushPacketHandler(chan, chan->flushPacket);
- }
- else {
- /* post the next I/O */
- while( !USB_postTransaction(&chan->epObj,
- chan->dataPacket->size * 2, chan->dataPacket->addr,
- USB_IOFLAG_NOSHORT ) );
- }
- }
- /*
- * ======== _C5509_USB_mdSubmitChan ========
- * This function handles IOM_READ, IOM_WRITE, IOM_FLUSH AND IOM_ABORT
- *
- * chanp is the pointer to the chanObj
- *
- * packet is formated by IOM
- *
- * IOM_READ/WRITE pends the packet into pendlist if previous I/O has
- * not been complete. Otherwise, it posts a transaction.
- *
- * IOM_ABORT or IOM_FLUSH for an IOM_INPUT channel is handled similarly.
- * It cancels all pending I/Os with callback status IOM_ABORTED/FLUSHED.
- *
- * IOM_FLUSH for an IOM_OUTPUT channel is handled differently. It returns
- * IOM_PENDING to IOM when there is any uncompleted write request. When
- * the last write request is completed, flushHandler calls back to notify
- * IOM that IOM_FLUSH is completed.
- */
- Int _C5509_USB_mdSubmitChan(Ptr chanp, IOM_Packet *packet)
- {
- C5509_USB_ChanHandle chan = (C5509_USB_ChanHandle)chanp;
- Uns imask;
- Int status = IOM_COMPLETED;
- Int ioStatus = IOM_ABORTED;
- imask=HWI_disable(); /* disable the interrrupt */
- if (packet->cmd == IOM_READ || packet->cmd == IOM_WRITE) {
-
- status = IOM_PENDING; /* always return IOM_PENDING */
-
- if (chan->dataPacket != NULL){
- /*
- * current active I/O packet hasn't been completed
- * queue the packet
- */
- QUE_enqueue(&chan->pendList, packet);
- }
- else {
- /* The USB device is expecting size in bytes mult size by 2 */
- if (!USB_postTransaction(&chan->epObj, packet->size * 2,
- packet->addr, USB_IOFLAG_NOSHORT) ) {
- /*
- * no active I/O packet, so post the transaction.
- * if fail to post the transaction, return error
- */
- status = IOM_EBADIO;
- }
- else {
- /*
- * successfully post the transaction
- * chan->dataPacket points to current active packet
- */
- chan->dataPacket=packet;
- }
- }
-
- }
- else if ( packet->cmd == IOM_FLUSH && chan->mode == IOM_INPUT ||
- packet->cmd == IOM_ABORT) {
- /* in this case, we discard all packets */
- if( packet->cmd == IOM_FLUSHED) {
- ioStatus=IOM_FLUSHED;
- }
- /* discard all pending I/Os */
- _C5509_USB_removePackets(chan, ioStatus);
-
- }
- else if ((packet->cmd ==IOM_FLUSH) && (chan->mode == IOM_OUTPUT)) {
- if(chan->dataPacket) {
- /*
- * since there are pending requests, record the flush
- * cmd. When the last write request is completed,
- * flushHandler calls back to notify that flush cmd
- * is finished.
- */
- chan->flushPacket = packet;
- status = IOM_PENDING;
- }
- }
- else{
- status = IOM_EBADARGS;
- }
- HWI_restore(imask); /* restore the HWI */
-
- return (status);
- }