/*
 *  pci.h
 *
 *  Copyright by QNX Software Systems Limited 1994. All rights reserved.
 */
#ifndef __PCI_H_INCLUDED
#define __PCI_H_INCLUDED 1

#ifndef __TYPES_H_INCLUDED
 #include <i86.h>
#endif

#ifndef _INTTYPES_H_INCLUDED
 #include <inttypes.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif
#pragma pack(1)
struct _pci_regs {
        unsigned long eax, ebx, ecx, edx, esi, edi, es;
        } ;

typedef struct _pci_route_buffer {
        short unsigned  BufferSize;
        short unsigned  DataBufferOffset;
        short unsigned  DataBufferSeg;
        } IRQRoutingOptionsBuffer;

struct _pci_config_regs
{
        unsigned short          Vendor_ID;
        unsigned short          Device_ID;
        unsigned short          Command;
        unsigned short          Status;
        char                    Revision_ID;
        char                    Class_Code[3];
        char                    Cache_Line_Size;
        char                    Latency_Timer;
        char                    Header_Type;
        char                    BIST;
        unsigned long           Base_Address_Regs[6];
        unsigned long           CardBus_CIS;
		unsigned short          Sub_Vendor_ID;
		unsigned short          Sub_System_ID;
        unsigned long           ROM_Base_Address;
		char                    Capabilities_Pointer;
		char                    Reserved2 [3];
        unsigned long           Reserved3;
        char                    Interrupt_Line;
        char                    Interrupt_Pin;
        char                    Min_Gnt;
        char                    Max_Lat;
        char                    Device_Dependent_Regs[192];
};

struct _pci_bridge_config_regs
{
        unsigned short          Vendor_ID;
        unsigned short          Device_ID;
        unsigned short          Command;
        unsigned short          Status;
        unsigned char           Revision_ID;
        unsigned char           Class_Code[3];
        unsigned char           Cache_Line_Size;
        unsigned char           Latency_Timer;
        unsigned char           Header_Type;
        unsigned char           BIST;
        unsigned long          Base_Address_Regs[2];
		unsigned char           Primary_Bus_Number;
		unsigned char           Secondary_Bus_Number;
		unsigned char           Subordinate_Bus_Number;
        unsigned char           Secondary_Latency_Timer;
		unsigned char           IO_Base;
		unsigned char           IO_Limit;
		unsigned short          Secondary_Status;
		unsigned short          Memory_Base;
		unsigned short          Memory_Limit;
		unsigned short          Prefetchable_Memory_Base;
		unsigned short          Prefetchable_Memory_Limit;
		unsigned short          Prefetchable_Base_Upper32;
		unsigned short          Prefetchable_Limit_Upper32;
		unsigned short          IO_Base_Upper16;
		unsigned short          IO_Limit_Upper16;
		unsigned char           Capabilities_Pointer;
        unsigned char           Reserved1 [3];
        unsigned long          ROM_Base_Address;
        unsigned char           Interrupt_Line;
        unsigned char           Interrupt_Pin;
		unsigned short          Bridge_Control;
        unsigned char           Device_Dependent_Regs[192];
};

struct _pci_cardbus_config_regs
{
        unsigned short          Vendor_ID;
        unsigned short          Device_ID;
        unsigned short          Command;
        unsigned short          Status;
        char                    Revision_ID;
        char                    Class_Code[3];
        char                    Cache_Line_Size;
        char                    Latency_Timer;
        char                    Header_Type;
        char                    BIST;
        unsigned long           Socket_Exca_Base_Reg;
		char                    Capabilities_Pointer;
        char                    reserved1;
        unsigned short          Secondary_Status;
        char                    Pci_Bus_Num;
        char                    Cardbus_Bus_Num;
        char                    Sub_Bus_Num;
        char                    Cardbus_Latency_Timer;
        unsigned long           Mem_Base_Reg_0;
        unsigned long           Mem_Limit_Reg_0;
        unsigned long           Mem_Base_Reg_1;
        unsigned long           Mem_Limit_Reg_1;
        unsigned long           Io_Base_Reg_0;
        unsigned long           Io_Limit_Reg_0;
        unsigned long           Io_Base_Reg_1;
        unsigned long           Io_Limit_Reg_1;
        char                    Interrupt_Line;
        char                    Interrupt_Pin;
        unsigned short          Bridge_Control;
        unsigned short          Subsystem_Vendor_Id;
        unsigned short          Subsystem_Id;
        unsigned long           If_Legacy_Base_Reg;
        char                    reserved2[56];
        unsigned long           System_Control;
        char                    reserved3[8];
		unsigned long           Multifunction_Routing;
        unsigned char           Retry_Status;
        unsigned char           Card_Control;
        unsigned char           Device_Control;
        unsigned char           Buffer_Control;
        unsigned long           Dma_Reg_0;
        unsigned long           Dma_Reg_1;
        char                    Device_Dependent_Regs[100];
};

struct  _pci_capability_pointer_32
{
		unsigned char                 Capability_ID;
		unsigned char                 Next_Pointer;
		unsigned short                Message_Control;
		unsigned long                Message_Address;
		unsigned short                Message_Data;
};

struct  _pci_capability_pointer_64
{
		unsigned char                 Capability_ID;
		unsigned char                 Next_Pointer;
		unsigned short                Message_Control;
		unsigned long                Message_Address;
		unsigned long                Message_Upper_Address;
		unsigned short                Message_Data;
};

#pragma pack()

#define PCI_IS_IO(address)              ((address) & 1)
#define PCI_IS_MEM(address)             (!PCI_IS_IO(address))
#define PCI_IO_ADDR(address)            ((address) & ~0x3)
#define PCI_MEM_ADDR(address)           ((address) & ~0xf)
#define PCI_ROM_ADDR(address)           ((address) & ~1)
#define PCI_IS_MMAP20(address)          ((address) & 0x2)
#define PCI_IS_MMAP32(address)          (!((address) & 0x6))
#define PCI_IS_MMAP64(address)          ((address) & 0x4)
#define	PCI_IS_PREFETCH(address)		((address) & 0x8)
#define	PCI_IS_MULTIFUNC(address)		((address) & 0x80)
#define	PCI_DEVNO(address)				((address) >> 3)
#define	PCI_FUNCNO(address)				((address) & 7)
#define	PCI_DEVFUNC(dev,func)			((dev<<3)|(func))
#define PCI_CLASS(class)				(((class) & 0xff0000) >> 16)
#define PCI_SUBCLASS(class)				(((class) & 0xff00) >> 8)
#define PCI_INTERFACE(class)			((class) & 0xff)

#define PCI_FUNCTION_ID                 0xb1
#define PCI_BIOS_PRESENT                0x01
#define PCI_FIND_DEVICE                 0x02
#define PCI_FIND_CLASS                  0x03
#define PCI_GENERATE_SPECIAL_CYCLE      0x06
#define PCI_READ_CONFIG_BYTE            0x08
#define PCI_READ_CONFIG_WORD            0x09
#define PCI_READ_CONFIG_DWORD           0x0a
#define PCI_WRITE_CONFIG_BYTE           0x0b
#define PCI_WRITE_CONFIG_WORD           0x0c
#define PCI_WRITE_CONFIG_DWORD          0x0d
#define PCI_GET_IRQ_ROUTING_OPTIONS     0x0e
#define PCI_SET_IRQ                     0x0f

#define PCI_SUCCESS                     0x00
#define PCI_UNSUPPORTED_FUNCT           0x81
#define PCI_BAD_VENDOR_ID               0x83
#define PCI_DEVICE_NOT_FOUND            0x86
#define PCI_BAD_REGISTER_NUMBER         0x87
#define PCI_SET_FAILED                  0x88
#define PCI_BUFFER_TOO_SMALL            0x89

/* PCI class defines*/
#define PCI_CLASS_PRE						0x00000000
	#define PCI_SUBCLASS_PRE_ALL			0x00000000
	#define PCI_SUBCLASS_PRE_VGA			0x00000100
#define PCI_CLASS_STORAGE					0x00010000
	#define PCI_SUBCLASS_STORAGE_SCSI		0x00000000
	#define PCI_SUBCLASS_STORAGE_IDE		0x00000100
	#define PCI_SUBCLASS_STORAGE_FLOPPY		0x00000200
	#define PCI_SUBCLASS_STORAGE_IPI		0x00000300
	#define PCI_SUBCLASS_STORAGE_OTHER		0x00000400
	#define PCI_PI_BUSMASTER				0x00000080
#define PCI_CLASS_NETWORK					0x00020000
	#define PCI_SUBCLASS_NETWORK_ETHERNET	0x00000000
	#define PCI_SUBCLASS_NETWORK_TOKENRING	0x00000100
	#define PCI_SUBCLASS_NETWORK_FDDI		0x00000200
	#define PCI_SUBCLASS_NETWORK_OTHER		0x00000300
#define PCI_CLASS_DISPLAY					0x00030000
	#define PCI_SUBCLASS_DISPLAY_VGA		0x00000000
	#define PCI_SUBCLASS_DISPLAY_XGA		0x00000100
	#define PCI_SUBCLASS_DISPLAY_OTHER		0x00000200
#define PCI_CLASS_MULTIMEDIA				0x00040000
	#define PCI_SUBCLASS_MULTIMEDIA_VIDEO	0x00000000
	#define PCI_SUBCLASS_MULTIMEDIA_AUDIO	0x00000100
	#define PCI_SUBCLASS_MULTIMEDIA_OTHER	0x00000200
#define PCI_CLASS_MEMORY					0x00050000
	#define PCI_SUBCLASS_MEMORY_RAM			0x00000000
	#define PCI_SUBCLASS_MEMORY_FLASH		0x00000100
	#define PCI_SUBCLASS_MEMORY_OTHER		0x00000200
#define PCI_CLASS_BRIDGE					0x00060000
	#define PCI_SUBCLASS_BRIDGE_HOST		0x00000000
	#define PCI_SUBCLASS_BRIDGE_ISA			0x00000100
	#define PCI_SUBCLASS_BRIDGE_EISA		0x00000200
	#define PCI_SUBCLASS_BRIDGE_MC			0x00000300
	#define PCI_SUBCLASS_BRIDGE_PCI			0x00000400
	#define PCI_SUBCLASS_BRIDGE_PCMCIA		0x00000500
	#define	PCI_SUBCLASS_BRIDGE_CARDBUS		0x00000700
	#define PCI_SUBCLASS_BRIDGE_OTHER		0x00008000
/* 0x07-0xFE are reserved*/
#define PCI_CLASS_UNDEFINED					0xFF0000

#define	PCI_COMMAND_IO_ENABLE			0x0001
#define	PCI_COMMAND_MEM_ENABLE			0x0002
#define	PCI_COMMAND_MASTER_ENABLE		0x0004
#define	PCI_COMMAND_SPECIAL_ENABLE		0x0008
#define	PCI_COMMAND_INVALIDATE_ENABLE	0x0010
#define	PCI_COMMAND_PALETTE_ENABLE		0x0020
#define	PCI_COMMAND_PARITY_ENABLE		0x0040
#define	PCI_COMMAND_STEPPING_ENABLE		0x0080
#define	PCI_COMMAND_SERR_ENABLE			0x0100
#define	PCI_COMMAND_BACKTOBACK_ENABLE	0x0200

#define	PCI_STATUS_CAPABILITIES			0x0010
#define	PCI_STATUS_66MHZ_OKAY			0x0020
#define	PCI_STATUS_UDF_SUPPORTED		0x0040
#define	PCI_STATUS_BACKTOBACK_OKAY		0x0080
#define	PCI_STATUS_PARITY_ERROR			0x0100
#define	PCI_STATUS_DEVSEL_FAST			0x0000
#define	PCI_STATUS_DEVSEL_MEDIUM		0x0200
#define	PCI_STATUS_DEVSEL_SLOW			0x0400
#define	PCI_STATUS_DEVSEL_MASK			0x0600
#define	PCI_STATUS_DEVSEL_SHIFT			9
#define	PCI_STATUS_TARGET_TARGET_ABORT	0x0800
#define	PCI_STATUS_MASTER_TARGET_ABORT	0x1000
#define	PCI_STATUS_MASTER_ABORT			0x2000
#define	PCI_STATUS_SPECIAL_ERROR		0x4000
#define	PCI_STATUS_PARITY_DETECT		0x8000

#define PCI_ISPACEEN					0x00000001		// IO space enable
#define PCI_MSPACEEN					0x00000002		// Memory space enable
#define PCI_MASTEREN					0x00000004		// Master enable

/* pci capability defines */

#define	PCI_CAP_POWER_MANAGEMENT        0x01
#define	PCI_CAP_AGP                     0x02	//Accelerated Graphics Port
#define	PCI_CAP_VPD                     0x03	//Vital Product Data
#define PCI_CAP_SLOT_ID                 0x04	//Slot Identification
#define PCI_CAP_MSI                     0x05	//Message Signalled Interrupts
#define PCI_CAP_CPCI_HOT_SWAP           0x06	//CompactPCI Hot Swap
#define	PCI_CAP_PCIX					0x07	/* PCI-X */
#define	PCI_CAP_HT						0x08	/* HyperTransport */
#define	PCI_CAP_VENDSPEC				0x09	/* Vendor Specific */
#define	PCI_CAP_DEBUG_PORT				0x0a	/* Debug port */
#define	PCI_CAP_COMPACT_PCI				0x0b	/* Compact PCI */
#define	PCI_CAP_PCI_HOT_PLUG			0x0c	/* PCI Hot Plug */
#define	PCI_CAP_PCI_BRIDGE_SUBSYSTEM	0x0d	/* PCI Bridge Subsystem Vendor ID */
#define	PCI_CAP_AGP_8X					0x0e	/* AGP 8x */
#define	PCI_CAP_SECURE_DEVICE			0x0f	/* Secure Device */
#define	PCI_CAP_PCI_EXPRESS				0x10	/* PCI Express */
#define	PCI_CAP_MSI_X					0x11	/* MSI-X */

/* interface type */

typedef	enum {
	PCI_TYPE_STANDARD,
	PCI_TYPE_BRIDGE,
	PCI_TYPE_CARDBUS
	};

/* prototypes */

extern int _CA_PCI_Find_Device(unsigned devid, unsigned venid, unsigned index,
                                                                unsigned *busnum, unsigned *devfuncnum);
extern int _CA_PCI_Read_Config_Byte(unsigned busnum, unsigned devfuncnum,
                                                                unsigned offset, unsigned cnt, char *bufptr);
extern int _CA_PCI_Read_Config_Word(unsigned busnum, unsigned devfuncnum,
                                                                unsigned offset, unsigned cnt, char *bufptr);
extern int _CA_PCI_Read_Config_DWord(unsigned busnum, unsigned devfuncnum,
                                                                unsigned offset, unsigned cnt, char *bufptr);

extern int _CA_PCI_Write_Config_Byte(unsigned busnum, unsigned devfuncnum,
                                                                unsigned offset, unsigned cnt, char *bufptr);
extern int _CA_PCI_Write_Config_Word(unsigned busnum, unsigned devfuncnum,
                                                                unsigned offset, unsigned cnt, char *bufptr);
extern int _CA_PCI_Write_Config_DWord(unsigned busnum, unsigned devfuncnum,
                                                                unsigned offset, unsigned cnt, char *bufptr);
extern int _CA_PCI_Generate_Special_Cycle(unsigned Busnum,
                                                                unsigned long SpecialCycleData);
extern int _CA_PCI_Set_Hardware_Interrupt(unsigned Busnum, unsigned devfuncnum,
                                                                unsigned IntPin, unsigned IRQNum);
extern int _CA_PCI_Get_Routing_Options(struct _pci_route_buffer *rbufptr,
                                                                unsigned *IRQForPCI);
extern int _CA_PCI_Find_Class(unsigned long ClassCode, unsigned index,
                                                                unsigned *busnum, unsigned *devfuncnum);
extern int _CA_PCI_BIOS_Present(unsigned *lastbus, unsigned *version,
                                                                unsigned *hardware);
extern int Check_Capabilities (unsigned long busnum, unsigned long devfn, char type);


#if defined __WATCOMC__ 
#if defined __386__

extern int _PCI_INT(unsigned func, struct _pci_regs *regset);
#pragma aux _PCI_INT = \
        "push es" \
        "mov ecx,8[ebx]" \
        "mov edx,12[ebx]" \
        "mov esi,16[ebx]" \
        "mov edi,20[ebx]" \
        "mov  es,24[ebx]" \
        "push ebx" \
        "mov ebx,4[ebx]" \
        "push ds" \
        "push 0d0h" \
        "pop ds" \
        "mov ah,0b1h" \
        "int 1ah" \
        "pop ds" \
        "xchg eax,0[esp]" \
        "mov 4[eax],ebx" \
        "pop ebx" \
        "mov 0[eax],ebx"\
        "mov 8[eax],ecx" \
        "mov 12[eax],edx" \
        "mov 16[eax],esi" \
        "mov 20[eax],edi" \
        "mov al,bh" \
        "and eax,0ffh" \
        "pop es" \
        __parm [al] [ebx] \
        __modify __exact [eax ebx ecx edx esi edi] \
        __value [eax];

#else

extern int _PCI_INT(unsigned func, struct _pci_regs *regset);
#pragma aux _PCI_INT = \
        ".386" \
        "mov ecx,8[bx]" \
        "mov edx,12[bx]" \
        "mov esi,16[bx]" \
        "mov edi,20[bx]" \
        "mov  es,24[bx]" \
        "push bx" \
        "mov ebx,4[bx]" \
        "push ds" \
        "push 0d0h" \
        "pop ds" \
        "mov ah,0b1h" \
        "int 1ah" \
        "pop ds" \
        "xchg bx,0[esp]" \
        "mov 0[bx],eax" \
        "mov eax,ebx" \
        "pop ax" \
        "mov 4[bx],eax" \
        "mov 8[bx],ecx" \
        "mov 12[bx],edx" \
        "mov 16[bx],esi" \
        "mov 20[bx],edi" \
        "mov al,1[bx]" \
        "mov ah,0" \
        __parm [al] [bx] \
        __modify __exact [ax bx cx dx si di es] \
        __value [ax];

#endif
#endif


#ifdef __cplusplus
}
#endif

#endif

