//
// 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 independent PCMCIA(16-bit) card functions

Notes: 
--*/
#ifndef __PCMCIAC_H_
#define __PCMCIAC_H_
#include "PCCard.h"
#include "PCTuple.h"

class CPcmciaTuple;
class CPcmciaMemWindow;
#define NUM_OF_IO_WINDOW 4
#define START_OF_IO_WINDOW 0
#define NUM_OF_ATTR_MEM_WINDOW 1
#define START_OF_ATTR_MEM_WINDOW (START_OF_IO_WINDOW+NUM_OF_IO_WINDOW)
#define NUM_OF_COMMON_MEM_WINDOW 1
#define START_OF_COMMON_MEM_WINDOW ( START_OF_ATTR_MEM_WINDOW + NUM_OF_ATTR_MEM_WINDOW);
#define NUM_OF_PCMCIA_WINDOW (NUM_OF_IO_WINDOW + NUM_OF_ATTR_MEM_WINDOW + NUM_OF_COMMON_MEM_WINDOW)

class CPCPcmciaCard : public CPCCard
{
    // Declare friends
    friend class    CPcmciaWindows;  // Declare a friend class
    friend class    CPcmciaTuple;
public:
    // Intialization for CardBus
                    CPCPcmciaCard( PSS_SOCKET_SERVICE pSocketService,
                                   PSS_SOCKET_STATE pSocketState,
                                   HANDLE hSocket,
                                   UINT16 uSocket,
                                   HANDLE hDevice,
                                   CPCPcmciaCard* pPFunction = NULL,
                                   UINT uFuntion = 0 );
    virtual         ~CPCPcmciaCard();
    virtual BOOL    Init( BOOL bRoot = FALSE );
    virtual BOOL IsCardBusCard()
    {
        return FALSE;
    };
    SS_SOCKET_INFO GetSocketInfo()
    {
        return m_SocketInfo;
    };
    UINT16              CardRequestWindowNoSpecial( PCARD_WINDOW_PARMS pCardWinParms );

public:
    virtual BOOL        AccessConfigurationSpace( DWORD dwSpace,
                                                  DWORD dwOffset,
                                                  BOOL bRead,
                                                  DWORD dwLength,
                                                  PVOID pBuffer ) ;
    virtual void        PowerUp();
    virtual void        PowerDown();
    // Card Operation
    virtual STATUS      CardGetStatus( PCARD_STATUS pStatus );
    virtual void        EventNotification( PSS_SOCKET_STATE pSocketState );

    CPCTuple*           GetTupleObject();
    CPcmciaMemWindow*   GetMemoryWindow( BOOL bAttr = TRUE );
    DWORD GetMFTargetAddr()
    {
        return m_dwFunctionDest ;
    };

    // WIndows Interface.
    UINT16              CardRequestWindow( PCARD_WINDOW_PARMS pCardWinParms );
    virtual STATUS      CardReleaseWindow( UINT16 uWindowIndex ) ;
    virtual STATUS      CardMapWindowPhysical( UINT16 uWindowIndex,
                                               PCARD_WINDOW_ADDRESS pCardWindowAddr ) ;
    virtual STATUS      CardGetWindowInfo( UINT16 uWindowIndex,
                                           PSS_WINDOW_INFO pWinInfo );
    // IRQ Map
    virtual STATUS      CardReleaseIRQ() ;
    virtual STATUS      CardRequestIRQLine( UINT16 dwIrqBit,
                                            PDWORD pdwIrqOrSysIntrNumber,
                                            PDWORD pdwIsSysIntr ) ;
    //virtual STATUS CardReleaseIRQ() ; Use the implimentation in CPCCard;
    // Configure
    virtual STATUS      CardRequestConfiguration( PCARD_CONFIG_INFO pParms );
    virtual STATUS      CardReleaseConfiguration() ;
    virtual STATUS      CardModifyConfiguration( PUINT16 fAttributes ) ;
    virtual STATUS      CardAccessConfigurationRegister( UINT8 rw_flag,
                                                         UINT8 offset,
                                                         UINT8* pValue ) ;
    virtual STATUS      CardRequestConfigRegisterPhAddr( PCARD_WINDOW_ADDRESS pWindowAddr,
                                                         PDWORD pOffset );

    // Power Handling
private:
    BYTE                WriteCardRegister( DWORD dwRegisterOffset, BYTE bValue );
    BYTE                ReadCardRegister( DWORD dwRegisterOffset );
    BOOL                GetConfigureRegisterBase();
    BOOL                ScanBus();
    BOOL                DeInit();

    BOOL                m_bSuspend; // Flag
    BOOL                m_bRoot;
    BOOL                m_bPowered;
    CPcmciaMemWindow*   m_pCommonWindow;
    CPcmciaMemWindow*   m_pAttributeWindow;
    DWORD               m_dwCardRegisterBase;
    DWORD               m_dwCardRegisterMask;
    DWORD               m_dwFunctionDest ;
    CARD_CONFIG_INFO    m_BackupConfig ;
    CPcmciaTuple*       m_pTurple;
    CPcmciaWindows**    m_ppPcmciaWindows;
    // Current state
    SS_SOCKET_STATE     m_SocketState;

    DWORD               m_dwZeroEntryIndex;
    BOOL                m_bPrimaryAttrMemMapped;
    BOOL                m_bPrimaryCommonMemMapped;
    BOOL                m_bSysInterAllocated;
};
class CPcmciaMemWindow
{
public:
            CPcmciaMemWindow( CPCPcmciaCard* pPcmciaCard,
                              BOOL bAttr = TRUE,
                              DWORD dwSize = 0x2000 );
            ~CPcmciaMemWindow();
    BOOL    Init();
    BOOL GetByte( DWORD dwAddress, PBYTE pbData )
    {
        return AccessByte( dwAddress, pbData, TRUE );
    };
    BOOL SetByte( DWORD dwAddress, BYTE bData )
    {
        return AccessByte( dwAddress, &bData, FALSE );
    };

    BOOL IsFixedWindow()
    {
        return m_bFixedWindow;
    };
    CARD_WINDOW_ADDRESS GetWindowPhAddr()
    {
        return m_WindowAddr ;
    };
    BOOL    MapWindowPhysical( PCARD_WINDOW_ADDRESS pCardWindowAddr );
    BOOL GetWindowInfo( PSS_WINDOW_INFO pWinInfo )
    {
        if( m_pPcmciaCard && m_uWinIndex != -1 )
        {
            return m_pPcmciaCard->CardGetWindowInfo( m_uWinIndex, pWinInfo );
        }
        else
        {
            return FALSE;
        }
    }

private:
    BOOL                    AccessByte( DWORD dwAddress,
                                        PBYTE pbData,
                                        BOOL bRead );
    BOOL                    MapWindowView( DWORD dwOffset );
    CPCPcmciaCard * const   m_pPcmciaCard;
    BOOL const              m_bAttrMem;
    DWORD                   m_dwWinSize;
    UINT16                  m_uWinIndex;
    CARD_WINDOW_PARMS       m_WinParms;
    CARD_WINDOW_ADDRESS     m_WindowAddr;
    PBYTE                   m_pVirtualAddr;
    BOOL                    m_bFixedWindow;
    BOOL                    m_b16bitAccess;
};

class CPcmciaTuple : public CPCTuple
{
public:
    CPcmciaTuple( CPCPcmciaCard* pCard ) : m_pPcmciaCard( pCard )
    {
        // Default Long Link According PC Card Standard Metaformat Spec 3.1
        m_dwLongLinkAddr = TUPLE_COMMON_MEMORY_FLAG;
        m_fValidLongLink = TRUE;
    }
    ~CPcmciaTuple()
    {
        ;}
protected:
    virtual STATUS          GetDesiredTupe( PCARD_TUPLE_PARMS pGetTupleParms );
private:
    BYTE                    GetTupleByte( DWORD dwIndex ); 
    CPCPcmciaCard * const   m_pPcmciaCard;
    BOOL        m_fValidLongLink;
    DWORD       m_dwLongLinkAddr;
};


class CPcmciaWindows
{
public:
            CPcmciaWindows( CPCPcmciaCard* pPcmciaCard, DWORD dwIndex )  ;
            ~CPcmciaWindows() ;
    BOOL    CardRequestWindow( PCARD_WINDOW_PARMS pCardWinParms );
    BOOL    CardReleaseWindow();
    BOOL    CardMapWindowPhysical( PCARD_WINDOW_ADDRESS pCardWindowAddr );
    SS_WINDOW_INFO CardGetWindowInfo()
    {
        return m_WinInfo;
    };

private:
    CPCPcmciaCard * const   m_pPcmciaCard;
    SS_WINDOW_INFO          m_WinInfo;
    CARD_WINDOW_PARMS       m_CardWinParms;
    DWORD                   m_dwWinIndex;
    BOOL                    m_bRequested;
    DWORD                   m_dwIoResourceBase;
    DWORD                   m_dwIoResourceLen;
};

#endif
