📄 c5509_usb_submit.c
字号:
/*
* 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)" */
/*
* ======== _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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -