//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
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:  

Abstract:

Platform dependent PCMCIA initialization functions

Notes: 
--*/
#ifndef __CARDBUS_H_
#define __CARDBUS_H_
#include "PCCard.h"
#include "PCTuple.h"

class CPCCardBusCard : public CPCCard
{
    // Declare friends
    friend class    CCBCardWindows;  // Declare a friend class
    friend class    CCBTuple;

public:
    // Intialization for CardBus
                    CPCCardBusCard( PSS_SOCKET_SERVICE pSocketService,
                                    PSS_SOCKET_STATE pSocketState,
                                    HANDLE hSocket,
                                    UINT16 uSocket,
                                    HANDLE hDevice,
                                    CPCCardBusCard* pPFunction = NULL,
                                    UINT uFuntion = 0 );
    virtual         ~CPCCardBusCard();
    virtual BOOL    Init( BOOL bRoot = FALSE );
    virtual BOOL IsCardBusCard()
    {
        return TRUE;
    };
    // Power Handling
private:
    BOOL                m_bSuspend; // Flag
    // Something we need save.
    PCI_COMMON_CONFIG   m_pciConfig;
    UINT8               m_uiZeroEntryIndex;

    void BackupConfigSpace()
    {
        PCI_SLOT_NUMBER slotNumber;
        slotNumber.u.AsULONG = 0;
        slotNumber.u.bits.DeviceNumber = m_DeviceNumber;
        slotNumber.u.bits.FunctionNumber = m_FunctionNumber;
        HalGetBusData( PCIConfiguration,
                       m_dwBusNumber,
                       slotNumber.u.AsULONG,
                       &m_pciConfig,
                       sizeof( m_pciConfig ) );
    }

    void RestoreConfigSpace()
    {
        PCI_SLOT_NUMBER slotNumber;
        slotNumber.u.AsULONG = 0;
        slotNumber.u.bits.DeviceNumber = m_DeviceNumber;
        slotNumber.u.bits.FunctionNumber = m_FunctionNumber;
        HalSetBusData( PCIConfiguration,
                       m_dwBusNumber,
                       slotNumber.u.AsULONG,
                       &m_pciConfig,
                       sizeof( m_pciConfig ) );
    }

public:
    virtual void        PowerUp();
    virtual void        PowerDown();
    virtual BOOL        SetPowerState( CEDEVICE_POWER_STATE ceState );
    virtual BOOL        AccessConfigurationSpace( DWORD dwSpace,
                                                  DWORD dwOffset,
                                                  BOOL bRead,
                                                  DWORD dwLength,
                                                  PVOID pBuffer ) ;
    // Card Operation
    //virtual STATUS DiableCard( CARD_CLIENT_HANDLE hCardClient,  CARD_SOCKET_HANDLE hSock  );
    //virtual STATUS EnableCard( CARD_CLIENT_HANDLE hCardClient,  CARD_SOCKET_HANDLE hSock  );
    virtual STATUS      CardGetStatus( PCARD_STATUS pStatus );
    virtual void        EventNotification( PSS_SOCKET_STATE pSocketState );


protected:
    // Internal Configuration space operation.
    //    DWORD MapBar(DWORD dwBarNumber,PDWORD pdwBridgeWinIndex,PBOOL pbIoFlag,PDWORD pdwBarSize);
    //    void UnMapBar(DWORD dwBarNumber,DWORD dwBridgeWinIndex,BOOL bIoFlag);
    void                PCIConfig_Write( DWORD dwOffset, DWORD dwValue );
    DWORD               PCIConfig_Read( DWORD dwOffset );
public:
    CPCTuple*           GetTupleObject();
    // WIndows Interface.
    virtual UINT16      CardRequestWindow( PCARD_WINDOW_PARMS pCardWinParms ) ;
    virtual STATUS      CardReleaseWindow( UINT16 uWindowIndex ) ;
    virtual STATUS      CardMapWindowPhysical( UINT16 uWindowIndex,
                                               PCARD_WINDOW_ADDRESS pCardWindowAddr );
    // IRQ Map
    virtual STATUS      CardRequestIRQLine( UINT16 dwIrqBit,
                                            PDWORD pdwIrqOrSysIntrNumber,
                                            PDWORD pdwIsSysIntr );
    virtual STATUS      CardReleaseIRQ() ;
    // Configure
    virtual STATUS      CardRequestConfiguration( PCARD_CONFIG_INFO pParms );
    virtual STATUS      CardReleaseConfiguration() ;

    DWORD               ConfigDump();

protected:
    DWORD               m_dwBusNumber;
    DWORD               m_DeviceNumber;
    DWORD               m_FunctionNumber;
private:
    SS_SOCKET_STATE     m_SocketState;
    BOOL                ScanBus();
    BOOL                DeInit();
    CCBTuple*           m_pTuple;
    BOOL                m_bRoot;
    BOOL                m_bPowered;

    CCBCardWindows**    m_ppCBCardWindows;
    // Internal Function.
    // Map and Unmap the specified window.
    DWORD               MapMemoryWindow( DWORD dwSize,
                                         BOOL isIoSpace,
                                         PDWORD pdwBridgeWindowIndex );
    void                FreeMemoryWindow( DWORD dwBridgeWinIndex );
};
class CCBTuple : public CPCTuple
{
public:
                            CCBTuple( CPCCardBusCard* pCBCard );
                            ~CCBTuple();
protected:
    virtual STATUS          GetDesiredTupe( PCARD_TUPLE_PARMS pGetTupleParms );
private:
    BYTE                    GetTupleByte( DWORD dwIndex ); 
    CPCCardBusCard * const  m_pCBCard;
    // Turple window Option.
    BYTE                    m_uCisOption;
    DWORD                   m_dwOffset;
    BYTE                    m_uRomNumber;

    // Turple window parameter
    volatile PBYTE          m_pTupleSpace;
    DWORD                   m_dwTupleMaxSize;
    // Window Attribute.
    BOOL                    m_bIoFlag;
    DWORD                   m_dwBarNumber;
    UINT16                  m_uWinIndex;
};

class CCBCardWindows
{
public:
                            CCBCardWindows( CPCCardBusCard* pCBCard,
                                            DWORD dwIndex )  ;
                            ~CCBCardWindows() ;
    BOOL                    CardRequestWindow( PCARD_WINDOW_PARMS pCardWinParms );
    BOOL                    CardReleaseWindow();
    BOOL                    CardMapWindowPhysical( PCARD_WINDOW_ADDRESS pCardWindowAddr );
private:
    CPCCardBusCard * const  m_pCBCard;
    SS_WINDOW_INFO          m_WinInfo;
    CARD_WINDOW_PARMS       m_CardWinParms;
    DWORD                   m_dwWinIndex;
    BOOL                    m_bRequested;
};
#endif

