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

📄 cpipe.hpp

📁 此压缩包为杰得开发得z228的BSP的源代码,可以实现很多功能,尤其是视频解码有很好的效果.
💻 HPP
📖 第 1 页 / 共 3 页
字号:
//
// 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:  
//     CPipe.hpp
// 
// Abstract: Implements class for managing open pipes for UHCI
//
//                             CPipe (ADT)
//                           /             \
//                  CQueuedPipe (ADT)       CIsochronousPipe
//                /         |       \ 
//              /           |         \
//   CControlPipe    CInterruptPipe    CBulkPipe
// 
// Notes: 
// 

#ifndef __CPIPE_HPP__
#define __CPIPE_HPP__

#include <globals.hpp>
#include <cphysmem.hpp>
#include <pipeabs.hpp>

class CPipe;
class CIsochronousPipe;
class CQueuedPipe;
class CControlPipe;
class CInterruptPipe;
class CBulkPipe;
class CUHCIFrame;
class CUhcd;
struct _UHCD_TD;
struct _UHCD_QH;

//
// Frame List (Section 3.1 of UHCI spec)
//
// number of entries in the frame list - 1024 
#define FRAME_LIST_LENGTH                   DWORD(0x400)
#define FRAME_LIST_LENGTH_MASK              DWORD(0x3FF)
// each of the 1024 entries of the frame list is 32 bits
typedef ULONG FRAME_LIST_POINTER;
// this should come out to be 4Kb, and will be debug checked in the code
#define FRAME_LIST_SIZE_IN_BYTES            DWORD(FRAME_LIST_LENGTH * sizeof(FRAME_LIST_POINTER))
// UHCI spec section 3.1.1 defines the structure of the Frame List Pointer
#define FRAME_LIST_POINTER_MASK             DWORD(0xFFFFFFF0)
#define FRAME_LIST_POINTER_TERMINATE        DWORD(1 << 0)
#define FRAME_LIST_POINTER_VALID            DWORD(0 << 0)
#define FRAME_LIST_POINTER_QH               DWORD(1 << 1)
#define FRAME_LIST_POINTER_TD               DWORD(0 << 1)

//
// Transfer Descriptor for UHCI (Section 3.2 of UHCI spec)
//
typedef ULONG TD_LINK_POINTER_PHYSICAL_ADDRESS;
#define TD_LINK_POINTER_MASK                DWORD(0xFFFFFFF0)
#define TD_LINK_POINTER_TERMINATE           DWORD(1 << 0)
#define TD_LINK_POINTER_VALID               DWORD(0 << 0)
#define TD_LINK_POINTER_QH                  DWORD(1 << 1)
#define TD_LINK_POINTER_TD                  DWORD(0 << 1)
#define TD_LINK_POINTER_DEPTH_FIRST         DWORD(1 << 2)
#define TD_LINK_POINTER_BREADTH_FIRST       DWORD(0 << 2)
typedef ULONG TD_BUFFER_PHYSICAL_ADDRESS;
typedef ULONG TD_PHYSICAL_ADDRESS;

typedef struct  _UHCD_TD  *PUHCD_TD;
typedef struct _UHCD_QH   *PUHCD_QH;
typedef struct _UHCD_TD {
    TD_LINK_POINTER_PHYSICAL_ADDRESS HW_paLink;     // DWORD1 - link used by host controller
                                                    // to find next TD/QH to process
    DWORD    ActualLength:11;         // DWORD2, 0 ..10 - actual amount of data transferred
                                      //                  encoded in (n-1) form
    DWORD    Reserved_1:1;            // DWORD2, 11
    DWORD    fIsFinalTD:1;               // DWORD2, 12 - indicates if it is a last TD
    DWORD    bTransferType:2;         // DWORD2,13...14 - Transfer Type
    DWORD    bPipeType:2;                // DWORD2,15...16 - Pipe Type
    DWORD    StatusField:6;           // DWORD2, 17..22 - used to indicate done transfer's status
    DWORD    Active:1;                // DWORD2, 23 - indicates whether transfer is active
    DWORD    InterruptOnComplete:1;   // DWORD2, 24 - indicates to send USB interrupt when finished
    DWORD    Isochronous:1;           // DWORD2, 25 - indicates Isochronous vs Queued transfer
    DWORD    LowSpeedControl:1;       // DWORD2, 26 - indicates transfer to low speed device
    DWORD    ErrorCounter:2;          // DWORD2, 27..28 - this field is decremented every time
                                      //                  there is an error on the transfer
    DWORD    ShortPacketDetect:1;     // DWORD2, 29 - indicates to allow ActualLength < MaxLength
    DWORD    ReservedMBZ:2;           // DWORD2, 30..31
    
    DWORD    PID:8;                   // DWORD3, 0..7 - indicates SETUP/IN/OUT transfer
    DWORD    Address:7;               // DWORD3, 8..14 - address of device to send transfer to
    DWORD    Endpoint:4;              // DWORD3, 15..18 - endpoint on device to send transfer to
    DWORD    DataToggle:1;            // DWORD3, 19 - used to send multipacket transfers
    DWORD    Reserved_2:1;            // DWORD3, 20
    DWORD    MaxLength:11;            // DWORD3, 21..31 - maximum data size to send/receive
    //TD_BUFFER_PHYSICAL_ADDRESS      HW_paBuffer;    // DWORD4 - phys addr of data buffer
    PUCHAR   HW_vaBuffer;                // DWORD4 - virtual addr of data buffer
   

    // These 4 DWORDs are for software use
    PUHCD_TD                            vaPrevIsochTD;  // prev TD (only for Isoch)
    PUHCD_TD                            vaNextTD;       // next TD
    PUHCD_QH                            pPipeQH;  
    UCHAR				ezPort;  		//port number
    UCHAR				bUNUSED1;    
    USHORT                         wUNUSED2; 
} UHCD_TD;


// Status bits for StatusField in UHCD_TD
// Reserved bit is taken care of by Reserved_1 above
#define TD_STATUS_NO_ERROR                  DWORD(0)
#define TD_STATUS_BITSTUFF_ERROR            DWORD(1 << 0)
#define TD_STATUS_CRC_TIMEOUT_ERROR         DWORD(1 << 1)
#define TD_STATUS_NAK_RECEIVED              DWORD(1 << 2)
#define TD_STATUS_BABBLE_DETECTED           DWORD(1 << 3)
#define TD_STATUS_DATA_BUFFER_ERROR         DWORD(1 << 4)
#define TD_STATUS_STALLED                   DWORD(1 << 5)
#define TD_STATUS_EVERY_ERROR               DWORD(TD_STATUS_BITSTUFF_ERROR | TD_STATUS_CRC_TIMEOUT_ERROR | TD_STATUS_NAK_RECEIVED | TD_STATUS_BABBLE_DETECTED | TD_STATUS_DATA_BUFFER_ERROR | TD_STATUS_STALLED)
// For ErrorCounter field
#define TD_ERRORCOUNTER_NEVER_INTERRUPT              DWORD(0)
#define TD_ERRORCOUNTER_INTERRUPT_AFTER_ONE          DWORD(1)
#define TD_ERRORCOUNTER_INTERRUPT_AFTER_TWO          DWORD(2)
#define TD_ERRORCOUNTER_INTERRUPT_AFTER_THREE        DWORD(3)
// Active bit has its own field above
// TDs are 32 bytes long
#define TD_REQUIRED_SIZE_IN_BYTES           DWORD(32)
// TDs must be aligned on 16 byte boundaries
#define TD_ALIGNMENT_BOUNDARY               DWORD(16)
#define TD_ENDPOINT_MASK                    DWORD(0xF)
// constants for MaxLength field
#define TD_MAXLENGTH_MAX                    DWORD(0x4FF)
#define TD_MAXLENGTH_INVALID                DWORD(0x7FE)
#define TD_MAXLENGTH_NULL_BUFFER            DWORD(0x7FF)
// constants for ActualLength field (used for SW to maintain data integrity)
#define TD_ACTUALLENGTH_INVALID             TD_MAXLENGTH_INVALID
// constants for the PID (Packet Identifcation) field
// see UHCI spec 3.2.3
#define TD_IN_PID                           DWORD(0x69)
#define TD_OUT_PID                          DWORD(0xE1)
#define TD_SETUP_PID                        DWORD(0x2D)

// Queue Head for UHCI (Section 3.3 of UHCI spec)
typedef ULONG QUEUE_HEAD_LINK_POINTER_PHYSICAL_ADDRESS;
#define QUEUE_HEAD_LINK_POINTER_MASK         DWORD(0xFFFFFFF0)
#define QUEUE_HEAD_LINK_POINTER_TERMINATE    DWORD(1 << 0)
#define QUEUE_HEAD_LINK_POINTER_VALID        DWORD(0 << 0)
#define QUEUE_HEAD_LINK_POINTER_QH           DWORD(1 << 1)
// #define QUEUE_HEAD_LINK_POINTER_TD        DWORD(0 << 1) <- our QH's never point horizontally to TDs
typedef ULONG QUEUE_ELEMENT_LINK_POINTER_PHYSICAL_ADDRESS; 
#define QUEUE_ELEMENT_LINK_POINTER_MASK      DWORD(0xFFFFFFF0)
#define QUEUE_ELEMENT_LINK_POINTER_TERMINATE DWORD(1 << 0)
#define QUEUE_ELEMENT_LINK_POINTER_VALID     DWORD(0 << 0)
// #define QUEUE_ELEMENT_LINK_POINTER_QH     DWORD(1 << 1) <- our QH's never point vertically to QHs
#define QUEUE_ELEMENT_LINK_POINTER_TD        DWORD(0 << 1)

typedef struct _UHCD_QH {
    QUEUE_HEAD_LINK_POINTER_PHYSICAL_ADDRESS    HW_paHLink; // phys addr of next QH
    QUEUE_ELEMENT_LINK_POINTER_PHYSICAL_ADDRESS HW_paVLink; // phys addr of queued TD
    
    // queue heads must be aligned on 16 byte boundaries. We'll make
    // them 32 bytes long. These fields are for SW use only.

    PUHCD_QH                                    vaPrevQH;       // virt addr of prev QH
    PUHCD_QH                                    vaNextQH;       // virt addr of next QH
    PUHCD_TD                                    vaVertTD;       // virt addr of queued TD

    // dwInterruptTree is used for interrupt transfer QHs.
    // For m_interruptQHTree members, which are just placeholders and 
    // do not actually carry transfers, the Load field will describe
    // how much interrupt traffic follows the QH branch. For other 
    // QHs, the BranchIndex field will describe where in the tree the
    // QH is located

    union {
        DWORD                                   Load;
        DWORD                                   BranchIndex;
    }                                           dwInterruptTree;

	UCHAR										ezPort;			//port number
	UCHAR										bTransferType;
    UCHAR                                       fPipeIsHalted;
    UCHAR                                       fIsFinalQH;      
    PUHCD_TD                                    pLoadedTD;      // used for the EZ-Host
} UHCD_QH;

// QHs must be aligned on 16 byte boundaries
#define QH_ALIGNMENT_BOUNDARY               DWORD(16)

// THIS ***MUST*** BE A POWER OF TWO!!! It is the maximum number of milliseconds
// that can go between polling for an interrupt on a device. We use this
// to set up the interrupt queue tree. This tree contains 2*MAX_INTERRUPT_INTERVAL - 1
// nodes, and allows us to specify intervals of 1, 2, 4, 8, ..., MAX_INTERRUPT_INTERVAL
#define UHCD_MAX_INTERRUPT_INTERVAL UCHAR(32)

// structure used for managing busy pipes
typedef struct _PIPE_LIST_ELEMENT {
    CPipe*                      pPipe;
    struct _PIPE_LIST_ELEMENT * pNext;
} PIPE_LIST_ELEMENT, *PPIPE_LIST_ELEMENT;

struct STransfer {
    // These are the IssueTransfer parameters
    UCHAR                     address;
    LPTRANSFER_NOTIFY_ROUTINE lpfnCallback;
    LPVOID                    lpvCallbackParameter;
    DWORD                     dwFlags;
    LPCVOID                   lpvControlHeader;
    DWORD                     paControlHeader;
    DWORD                     dwStartingFrame;
    DWORD                     dwFrames;
    LPCDWORD                  aLengths;
    DWORD                     dwBufferSize;     
    LPVOID                    lpvClientBuffer;
    ULONG                     paClientBuffer;
    LPCVOID                   lpvCancelId;
    LPDWORD                   adwIsochErrors;
    LPDWORD                   adwIsochLengths;
    LPBOOL                    lpfComplete;
    LPDWORD                   lpdwBytesTransferred;
    LPDWORD                   lpdwError;
    // additional parameters/data
    PUCHAR                    vaTDList;         // TD list for the transfer
    USHORT                    numTDsInList;     // # TDs in pTDListHead list
    PUCHAR                    vaActualBuffer;   // virt addr of buffer used by TD list
    ULONG                     paActualBuffer;   // phys addr of buffer used by TD list
    DWORD                     dwCurrentPermissions;
    struct STransfer *        lpNextTransfer;
};
void     InitializeTD( OUT PUHCD_TD const pTD,
                              IN const TD_LINK_POINTER_PHYSICAL_ADDRESS HW_paLink,
                              IN const PUHCD_TD vaNextTD,
                              IN const UCHAR InterruptOnComplete,
                              IN const UCHAR Isochronous,
                              IN const BOOL  LowSpeedControl,
                              IN const DWORD PID,
                              IN const UCHAR Address,

⌨️ 快捷键说明

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