⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trans.cpp

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// 
// Module Name:  
//     Trans.cpp
// 
// Abstract: Provides interface to UHCI host controller
// 
// Notes: 
//
//------------------------------------------------------------------------------
//
//  Copyright (C) 2005-2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//------------------------------------------------------------------------------


#include <windows.h>
#include <Cphysmem.hpp>
#include "trans.h"
#include "cpipe.h"
#include "chw.h"
#include "cehcd.h"

#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif

//***********************************************************************************
static void 
memdump(unsigned char * data,   unsigned short num_bytes, unsigned short offset    )
//
// Purpose: Dump the memory content to the console
//
// Parameters: data - pointer to the data to be dumped
//             num_bytes - size of data buffer
//             offset - the index where it starts with
//
// Returns: Nothing
//
// Notes:
//
// ******************************************************************
{       
    unsigned short i,j,l;
    unsigned char tmp_str[100]; 
    unsigned char tmp_str1[10];    
    for (i = 0; i < num_bytes; i += 16)    {        
        unsigned short n ;      
        tmp_str[0]='\0';        
        n = i+offset ;        
        for (j=0; j<4; j++) {
            l=n%16;
            if (l>=10)              
                tmp_str[3-j]=(unsigned char)('A'+l-10);         
            else                
                tmp_str[3-j]=(unsigned char)(l+'0');            
            n >>= 4 ;       
        }       
        tmp_str[4]='\0';        
        strcat ( (char *)tmp_str, ": ");        
        /*          Output the hex bytes        */        
        for (j = i; j < (i+16); j++) {          
            int m ;            
            if (j < num_bytes)  {  
                m=((unsigned int)((unsigned char)*(data+j)))/16 ;               
                if (m>=10)                  
                    tmp_str1[0]='A'+(unsigned char)m-10;                
                else                    
                    tmp_str1[0]=(unsigned char)m+'0';               
                m=((unsigned int)((unsigned char)*(data+j)))%16 ;               
                if (m>=10)                  
                    tmp_str1[1]='A'+(unsigned char)m-10;                
                else                    
                    tmp_str1[1]=(unsigned char)m+'0';               
                tmp_str1[2]='\0';               
                strcat ((char *)tmp_str, (char *)tmp_str1);             
                strcat ((char *)tmp_str, " ");            
            }            
            else {                
                strcat((char *)tmp_str,"   ");            
            }        
        }        
        strcat((char *)tmp_str, "  ");      
        l=(unsigned short)strlen((char *)tmp_str);        

        /*         * Output the ASCII bytes        */        
        for (j = i; j < (i+16); j++){            
            if (j < num_bytes){
                char c = *(data+j);                
                if (c < ' ' || c > 'z') 
                    c = '.';                
                tmp_str[l++]=c;            
            }            
            else            
                tmp_str[l++]=' ';
        }       
        tmp_str[l++]='\r';        tmp_str[l++]='\n';        tmp_str[l++]='\0';     
        RETAILMSG(1, (L"%S", tmp_str));    
    }
    RETAILMSG(1, (TEXT("\r\n")));
}

//********************************************************************************************
DWORD CTransfer::m_dwGlobalTransferID=0;
CTransfer::CTransfer(IN CPipe * const pCPipe, IN CPhysMem * const pCPhysMem,STransfer sTransfer) 
    : m_sTransfer( sTransfer)
    , m_pCPipe(pCPipe)
    , m_pCPhysMem(pCPhysMem)
//
// Purpose: Constructor of CTransfer class
//
// Parameters: pCPipe - Pointer to CPipe object to be associated with
//             pCPhysMem - Pointer to CPhysMem to be used
//             sTransfer - STransfer containing all the information for USB transfer
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
    m_pNextTransfer=NULL;
    m_paControlHeader=0;
    m_pAllocatedForControl=NULL;
    m_pAllocatedForClient=NULL;
    memcpy(&m_sTransfer, &sTransfer,sizeof(STransfer));
    m_DataTransferred =0 ;
    m_dwTransferID = m_dwGlobalTransferID++;
    m_fDoneTransferCalled = FALSE;

}

//********************************************************************
CTransfer::~CTransfer()
//
// Purpose: Destructor of CTransfer class
//
// Parameters: None
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
    if (m_pAllocatedForControl!=NULL) 
        m_pCPhysMem->FreeMemory( PUCHAR(m_pAllocatedForControl),m_paControlHeader,  CPHYSMEM_FLAG_NOBLOCK );
    if (m_pAllocatedForClient!=NULL)
        m_pCPhysMem->FreeMemory( PUCHAR(m_pAllocatedForClient), m_sTransfer.paBuffer,  CPHYSMEM_FLAG_NOBLOCK );
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE , (TEXT("CTransfer::~CTransfer() (this=0x%x,m_pAllocatedForControl=0x%x,m_pAllocatedForClient=0x%x)\r\n"),
        this,m_pAllocatedForControl,m_pAllocatedForClient));

}

//*******************************************************************
BOOL CTransfer::Init(void)
//
// Purpose: Initialize routine for the CTransfer class
//          This includes allocation of memory and setup the CTransfer class
//          necessary to do the transfer.  Finally, it calls AddTransfer() to do
//          the transfer
//
// Parameters: None
//
// Returns: TRUE - success, FALSE - failure
//
// Notes:
// ******************************************************************
{
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("CTransfer::Init (this=0x%x,id=0x%x)\r\n"),this,m_dwTransferID));
    // We must allocate the control header memory here so that cleanup works later.
    if (m_sTransfer.lpvControlHeader != NULL &&  m_pAllocatedForControl == NULL ) {
        // This must be a control transfer. It is asserted elsewhere,
        // but the worst case is we needlessly allocate some physmem.
        if ( !m_pCPhysMem->AllocateMemory(
                                   DEBUG_PARAM( TEXT("IssueTransfer SETUP Buffer") )
                                   sizeof(USB_DEVICE_REQUEST),
                                   &m_pAllocatedForControl,
                                   CPHYSMEM_FLAG_NOBLOCK ) ) {
            DEBUGMSG( ZONE_WARNING, (TEXT("CPipe(%s)::IssueTransfer - no memory for SETUP buffer\n"), m_pCPipe->GetPipeType() ) );
            m_pAllocatedForControl=NULL;
            return FALSE;
        }
        m_paControlHeader = m_pCPhysMem->VaToPa( m_pAllocatedForControl );
        DEBUGCHK( m_pAllocatedForControl != NULL && m_paControlHeader != 0 );

        __try {
            memcpy(m_pAllocatedForControl,m_sTransfer.lpvControlHeader,sizeof(USB_DEVICE_REQUEST));
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
            // bad lpvControlHeader
            return FALSE;
        }
    }
#ifdef DEBUG
    if ( m_sTransfer.dwFlags & USB_IN_TRANSFER ) {
        // I am leaving this in for two reasons:
        //  1. The memset ought to work even on zero bytes to NULL.
        //  2. Why would anyone really want to do a zero length IN?
        DEBUGCHK( m_sTransfer.dwBufferSize > 0 &&
                  m_sTransfer.lpvBuffer != NULL );
        __try { // IN buffer, trash it
            memset( PUCHAR( m_sTransfer.lpvBuffer ), GARBAGE, m_sTransfer.dwBufferSize );
        } __except( EXCEPTION_EXECUTE_HANDLER ) {
        }
    }
#endif // DEBUG
      
    if ( m_sTransfer.dwBufferSize > 0 && m_sTransfer.paBuffer == 0 ) { 

        // ok, there's data on this transfer and the client
        // did not specify a physical address for the
        // buffer. So, we need to allocate our own.

        if ( !m_pCPhysMem->AllocateMemory(
                                   DEBUG_PARAM( TEXT("IssueTransfer Buffer") )
                                   m_sTransfer.dwBufferSize,
                                   &m_pAllocatedForClient, 
                                   CPHYSMEM_FLAG_NOBLOCK ) ) {
            DEBUGMSG( ZONE_WARNING, (TEXT("CPipe(%s)::IssueTransfer - no memory for TD buffer\n"), m_pCPipe->GetPipeType() ) );
            m_pAllocatedForClient = NULL;
            return FALSE;
        }
        m_sTransfer.paBuffer = m_pCPhysMem->VaToPa( m_pAllocatedForClient );
        PREFAST_DEBUGCHK( m_pAllocatedForClient != NULL);
        PREFAST_DEBUGCHK( m_sTransfer.lpvBuffer!=NULL);
        DEBUGCHK(m_sTransfer.paBuffer != 0 );

        if ( !(m_sTransfer.dwFlags & USB_IN_TRANSFER) ) {
            __try { // copying client buffer for OUT transfer
                memcpy( m_pAllocatedForClient, m_sTransfer.lpvBuffer, m_sTransfer.dwBufferSize );               
                //if ((m_sTransfer.dwBufferSize == 512) || (m_sTransfer.dwBufferSize == 31))
                //DEBUGMSG(1, (TEXT("Out Transaction size %d\r\n"), m_sTransfer.dwBufferSize));
                //memdump(m_pAllocatedForClient, (USHORT)m_sTransfer.dwBufferSize, 0);
            } __except( EXCEPTION_EXECUTE_HANDLER ) {
                  // bad lpvClientBuffer
                  RETAILMSG(1, (TEXT("CQTransfer:Init: Exception handler\r\n")));
                  return FALSE;
            }
        }
    }
    
    DEBUGMSG(  ZONE_TRANSFER && ZONE_VERBOSE , (TEXT("CQTransfer::Init (this=0x%x,id=0x%x),m_pAllocatedForControl=0x%x,m_pAllocatedForClient=0x%x\r\n"),
        this,m_dwTransferID,m_pAllocatedForControl,m_pAllocatedForClient));
    return AddTransfer();
}

//********************************************************************************
CQTransfer::~CQTransfer()
//
// Purpose: Destructor of CQTransfer
//
// Parameters: None
//
// Returns: Nothing
//
// Notes:
// ******************************************************************
{
    CQTD * pCurTD = m_pCQTDList;
    while (pCurTD!=NULL) {
         CQTD * pNextTD = pCurTD->GetNextTD();
         pCurTD->~CQTD();
         m_pCPhysMem->FreeMemory((PBYTE)pCurTD,m_pCPhysMem->VaToPa((PBYTE)pCurTD), CPHYSMEM_FLAG_HIGHPRIORITY |CPHYSMEM_FLAG_NOBLOCK );
         pCurTD = pNextTD;
    }
}

//********************************************************************
BOOL CQTransfer::AddTransfer() 
//
// Purpose: Setup all the queue transfer descriptor and do the actual transfer
//          of the data through IssueTransfer
//
// Parameters: None
//
// Returns: TRUE - success, FALSE - failure
//
// Notes:
// ******************************************************************
{
    DEBUGMSG( ZONE_TRANSFER && ZONE_VERBOSE, (TEXT("CQTransfer::AddTransfer (this=0x%x,id=0x%x)\r\n"),this,m_dwTransferID));
    if (m_pCQTDList) { // Has been created. Somthing wrong.
        ASSERT(FALSE);
        return FALSE;
    }
    BOOL bDataToggle1= FALSE;
    CQTD * pStatusTD = NULL;
    if (m_paControlHeader!=NULL && m_sTransfer.lpvControlHeader!=NULL) { 
        // This is setup packet.
        if (m_pCQTDList = new(m_pCPhysMem) CQTD(this, ((CQueuedPipe * const)m_pCPipe)->GetQHead())) {            
            PhysBufferArray bufferArray;
            bufferArray.dwNumOfBlock=1;
            bufferArray.dwStartOffset=m_paControlHeader & EHCI_PAGE_OFFSET_MASK;
            bufferArray.dwBlockSize=min(bufferArray.dwStartOffset + sizeof(USB_DEVICE_REQUEST),EHCI_PAGE_SIZE );
            bufferArray.dwArrayBlockAddr[0]=(m_paControlHeader & EHCI_PAGE_ADDR_MASK);
            bufferArray.dwArrayBlockAddr[1]=((m_paControlHeader+sizeof(USB_DEVICE_REQUEST)) & EHCI_PAGE_ADDR_MASK ); // Terminate
            m_pCQTDList->IssueTransfer( TD_SETUP_PID, bDataToggle1, sizeof(USB_DEVICE_REQUEST),&bufferArray,TRUE);
            bDataToggle1 = !bDataToggle1;
        }
        else 
            return FALSE;
        // Status Packet
        pStatusTD = new(m_pCPhysMem) CQTD(this, ((CQueuedPipe * const)m_pCPipe)->GetQHead());
        if (pStatusTD) {            
            PhysBufferArray bufferArray;
            bufferArray.dwNumOfBlock=0;
            bufferArray.dwBlockSize=0;
            bufferArray.dwStartOffset=0;
            bufferArray.dwArrayBlockAddr[0]=0;
            bufferArray.dwArrayBlockAddr[1]=0;// Terminate
            pStatusTD->IssueTransfer( (m_sTransfer.dwFlags & USB_IN_TRANSFER)!=0?TD_OUT_PID:TD_IN_PID,
                TRUE, 0 ,&bufferArray,TRUE);
        }
        else 
            return FALSE;
    };

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -