Blame IbAccess/Common/Public/ipci.h

Packit 857059
/* BEGIN_ICS_COPYRIGHT3 ****************************************
Packit 857059
Packit 857059
Copyright (c) 2015, Intel Corporation
Packit 857059
Packit 857059
Redistribution and use in source and binary forms, with or without
Packit 857059
modification, are permitted provided that the following conditions are met:
Packit 857059
Packit 857059
    * Redistributions of source code must retain the above copyright notice,
Packit 857059
      this list of conditions and the following disclaimer.
Packit 857059
    * Redistributions in binary form must reproduce the above copyright
Packit 857059
      notice, this list of conditions and the following disclaimer in the
Packit 857059
     documentation and/or other materials provided with the distribution.
Packit 857059
    * Neither the name of Intel Corporation nor the names of its contributors
Packit 857059
      may be used to endorse or promote products derived from this software
Packit 857059
      without specific prior written permission.
Packit 857059
Packit 857059
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
Packit 857059
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit 857059
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
Packit 857059
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
Packit 857059
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit 857059
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 857059
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
Packit 857059
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
Packit 857059
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 857059
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 857059
Packit 857059
** END_ICS_COPYRIGHT3   ****************************************/
Packit 857059
Packit 857059
/* [ICS VERSION STRING: unknown] */
Packit 857059
Packit 857059
#ifndef _IBA_PUBLIC_IPCI_H_
Packit 857059
#define _IBA_PUBLIC_IPCI_H_
Packit 857059
Packit 857059
#include "iba/public/datatypes.h"
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
extern "C" {
Packit 857059
#endif
Packit 857059
Packit 857059
/* Enable and disables PciDmaMap debug */
Packit 857059
#ifndef PCIDMAMAP_DBG	/* allow to be set from CFLAGS */
Packit 857059
#define PCIDMAMAP_DBG	0					/* 0=no, 1=validate, 2=validate+log */
Packit 857059
#endif
Packit 857059
Packit 857059
struct _PCI_DEVICE;
Packit 857059
struct _PCI_DMA_FUNCS;
Packit 857059
Packit 857059
	/* return TRUE if interrupt has been handled */
Packit 857059
typedef boolean (*INTR_HANDLER)(IN struct _PCI_DEVICE *pDev, IN void *Context);
Packit 857059
Packit 857059
#define IBA_PCI_TYPE0_ADDRESSES			6
Packit 857059
#define IBA_PCI_BRIDGE_ADDRESSES		2
Packit 857059
Packit 857059
/* control fields in BaseAddress Registers */
Packit 857059
#define IBA_PCI_BAR_CNTL_MASK			0xF
Packit 857059
#define IBA_PCI_BAR_CNTL_TYPE_MASK		0x6
Packit 857059
#define IBA_PCI_BAR_CNTL_IO_SPACE		0x1
Packit 857059
#define IBA_PCI_BAR_CNTL_TYPE_32BIT		0x0	/* PCI */
Packit 857059
#define IBA_PCI_BAR_CNTL_TYPE_20BIT		0x2	/* obsolete */
Packit 857059
#define IBA_PCI_BAR_CNTL_TYPE_64BIT		0x4	/* PCI-X requires */
Packit 857059
#define IBA_PCI_BAR_CNTL_PREFETCHABLE	0x8
Packit 857059
Packit 857059
typedef struct _IBA_PCI_COMMON_CONFIG {
Packit 857059
	uint16		VendorID;
Packit 857059
	uint16		DeviceID;
Packit 857059
	uint16		Command;
Packit 857059
	uint16		Status;
Packit 857059
	uint8		RevisionID;
Packit 857059
	uint8		ProgIf;
Packit 857059
	uint8		SubClass;
Packit 857059
	uint8		BaseClass;
Packit 857059
	uint8		CacheLineSize;
Packit 857059
	uint8		LatencyTimer;
Packit 857059
	uint8		HeaderType;
Packit 857059
	uint8		BIST;
Packit 857059
	union  {
Packit 857059
		struct _pci_header_type0 {
Packit 857059
			uint32	BaseAddresses[IBA_PCI_TYPE0_ADDRESSES];
Packit 857059
			uint32	CIS;
Packit 857059
			uint16	SubVendorId;
Packit 857059
			uint16	SubSystemId;
Packit 857059
			uint32	RomBaseAddress;
Packit 857059
			uint8	CapabilitiesPtr;
Packit 857059
			uint8	Reserved1[3];
Packit 857059
			uint32	Reserved2;
Packit 857059
			uint8	InterruptLine;
Packit 857059
			uint8	InterruptPin;
Packit 857059
			uint8	MinimumGrant;
Packit 857059
			uint8	MaximumLatency;
Packit 857059
		} type0;
Packit 857059
		struct _pci_header_bridge {
Packit 857059
			uint32	BaseAddresses[IBA_PCI_BRIDGE_ADDRESSES];
Packit 857059
			uint8	PrimaryBusNumber;
Packit 857059
			uint8	SecondaryBusNumber;
Packit 857059
			uint8	SubordinateBusNumber;
Packit 857059
			uint8	SecondaryLatencyTimer;
Packit 857059
			uint8	IOBase;
Packit 857059
			uint8	IOLimit;
Packit 857059
			uint16	SecondaryStatus;
Packit 857059
			uint16	MemoryBase;
Packit 857059
			uint16	MemoryLimit;
Packit 857059
			uint16	PrefetchableMemoryBase_l;
Packit 857059
			uint16	PrefetchableMemoryLimit_l;
Packit 857059
			uint32	PrefetchableMemoryBase_h;
Packit 857059
			uint32	PrefetchableMemoryLimit_h;
Packit 857059
			uint16	IOBase_h;
Packit 857059
			uint16	IOLimit_h;
Packit 857059
			uint8	CapabilitiesPtr;
Packit 857059
			uint8	Reserved1[3];
Packit 857059
			uint32	RomBaseAddress;
Packit 857059
			uint8	InterruptLine;
Packit 857059
			uint8	InterruptPin;
Packit 857059
			uint16	BridgeControl;
Packit 857059
		} bridge;
Packit 857059
	} u;
Packit 857059
	uint8	DeviceSpecific[192];	/* 48 uint32's */
Packit 857059
} IBA_PCI_COMMON_CONFIG;
Packit 857059
Packit 857059
#define IBA_PCI_COMMON_HDR_LENGTH \
Packit 857059
							(offsetof(IBA_PCI_COMMON_CONFIG, DeviceSpecific))
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
}
Packit 857059
#endif
Packit 857059
Packit 857059
#endif /* defined(VXWORKS) */
Packit 857059
Packit 857059
#ifdef VXWORKS
Packit 857059
#include "iba/public/ipci_osd.h"
Packit 857059
#endif
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
extern "C" {
Packit 857059
#endif
Packit 857059
Packit 857059
/* Helper macros for reading and writing PCI memory
Packit 857059
 * Note these macros are for convenience, the memory may also be directly
Packit 857059
 * accessed
Packit 857059
 */
Packit 857059
Packit 857059
#define SUPPORT_ATOMIC_64BITS
Packit 857059
Packit 857059
/* use mmx for 64bit write for ia32 user space */
Packit 857059
#if defined(SUPPORT_ATOMIC_64BITS_MMX)
Packit 857059
#define DEV_WRITE64(Address, Value) \
Packit 857059
				mmx_write_64bits(Value,Address)
Packit 857059
#elif defined(SUPPORT_ATOMIC_64BITS_PPC)
Packit 857059
#define DEV_WRITE64(Address, Value) \
Packit 857059
				ppc_write_64bits(Value,Address)
Packit 857059
#else
Packit 857059
#define DEV_WRITE64(Address, Value) \
Packit 857059
				*(volatile uint64 *)(Address) = (Value)
Packit 857059
#endif
Packit 857059
Packit 857059
#define DEV_WRITE32(Address, Value) \
Packit 857059
				*(volatile uint32 *)(Address) = (Value)
Packit 857059
#define DEV_WRITE16(Address, Value) \
Packit 857059
				*(volatile uint16 *)(Address) = (Value)
Packit 857059
#define DEV_WRITE8(Address, Value) \
Packit 857059
				*(volatile uint8 *)(Address) = (Value)
Packit 857059
Packit 857059
/* read 64bit using mmx for ia32 user space*/
Packit 857059
#if  defined(SUPPORT_ATOMIC_64BITS_MMX)
Packit 857059
#define DEV_READ64(Address, pValue) \
Packit 857059
			*((uint64 *)pValue) = mmx_read_64bits((volatile uint64 *)Address)
Packit 857059
#elif  defined(SUPPORT_ATOMIC_64BITS_PPC)
Packit 857059
#define DEV_READ64(Address, pValue) \
Packit 857059
			*((uint64 *)pValue) = ppc_read_64bits((volatile uint64 *)Address)
Packit 857059
#else
Packit 857059
#define DEV_READ64(Address, pValue) \
Packit 857059
				*((uint64 *)pValue) = *(volatile uint64 *)(Address)
Packit 857059
#endif
Packit 857059
Packit 857059
#define DEV_READ32(Address, pValue) \
Packit 857059
				*((uint32 *)pValue) = *(volatile uint32 *)(Address)
Packit 857059
#define DEV_READ16(Address, pValue) \
Packit 857059
				*((uint16 *)pValue) = *(volatile uint16 *)(Address)
Packit 857059
#define DEV_READ8(Address, pValue) \
Packit 857059
				*((uint8 *)pValue) = *(volatile uint8 *)(Address)
Packit 857059
Packit 857059
#define DEV_WRITE64_TO_BE(Address, Value) \
Packit 857059
		*(volatile uint64 *)(Address) = hton64(Value)
Packit 857059
#define DEV_WRITE32_TO_BE(Address, Value) \
Packit 857059
		*(volatile uint32 *)(Address) = hton32(Value)
Packit 857059
#define DEV_WRITE16_TO_BE(Address, Value) \
Packit 857059
		*(volatile uint16 *)(Address) = hton16(Value)
Packit 857059
Packit 857059
#define DEV_READ64_FROM_BE(Address, pValue) \
Packit 857059
		do { \
Packit 857059
			*((uint64 *)pValue) = *(volatile uint64 *)(Address) ;\
Packit 857059
			*pValue = ntoh64(*pValue); \
Packit 857059
		} while (0)
Packit 857059
#define DEV_READ32_FROM_BE(Address, pValue) \
Packit 857059
		do { \
Packit 857059
			*((uint32 *)pValue) = *(volatile uint32 *)(Address) ;\
Packit 857059
			*pValue = ntoh32(*pValue); \
Packit 857059
		} while (0)
Packit 857059
#define DEV_READ16_FROM_BE(Address, pValue) \
Packit 857059
		do { \
Packit 857059
			*((uint16 *)pValue) = *(volatile uint16 *)(Address) ;\
Packit 857059
			*pValue = ntoh16(*pValue); \
Packit 857059
		} while (0)
Packit 857059
Packit 857059
Packit 857059
#if defined(VXWORKS)
Packit 857059
/* These functions implement create/destroy of PCI_DEVICE */
Packit 857059
extern void PciInitState(PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/*PciInit is supplied for Operating systems which provide a plug and play
Packit 857059
 * callback based PCI enumeration, in which case the OS specific arguments
Packit 857059
 * will be similar to the plag and play callback arguments for the OS
Packit 857059
 *extern FSTATUS PciInit( PCI_DEVICE *pDev,
Packit 857059
 *		OS specific arguments to describe device
Packit 857059
 *		)
Packit 857059
 */
Packit 857059
Packit 857059
/*PciFindDevice is supplied for Operating systems which do a driver initiated
Packit 857059
 *PCI enumeration (such as VxWorks)
Packit 857059
 * pDev - where to save information about device found
Packit 857059
 * vendorId - PCI vendor ID to search for
Packit 857059
 * deviceId - PCI device ID to search for
Packit 857059
 * pLastDev - previous device returned during this enumeration loop
Packit 857059
 *			(pass NULL for 1st interation of loop)
Packit 857059
 *
Packit 857059
 * returns:
Packit 857059
 *	FSUCCESS - a device was found, *pDev is initialized to refer to the device
Packit 857059
 *	others - no device found (or no more devices), *pDev undefined
Packit 857059
 *		FNOT_FOUND - no more devices of given vendor/device
Packit 857059
 *		FINSUFFICIENT_MEMORY - unable to allocate internal memory
Packit 857059
 *		others - error reading/accessing device
Packit 857059
 */
Packit 857059
extern FSTATUS PciFindDevice(IN uint16 vendorId, IN uint16 deviceId,
Packit 857059
							IN PCI_DEVICE *pLastDev, OUT PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/*PciGetBus locates the parent Bus of a given PCI Device
Packit 857059
 * pDev - Device whose parent we want to know
Packit 857059
 * pBusDev - where to save information about parent bus
Packit 857059
 *
Packit 857059
 * returns:
Packit 857059
 *	FSUCCESS - found parent
Packit 857059
 *	FNOT_FOUND - no parent
Packit 857059
 */
Packit 857059
extern FSTATUS PciGetBus(IN PCI_DEVICE *pDev, OUT PCI_DEVICE *pBusDev);
Packit 857059
Packit 857059
extern void PciDestroy(IN PCI_DEVICE *pDev);
Packit 857059
/*static _inline void PciSetContext(IN PCI_DEVICE *pDev, IN void *context); */
Packit 857059
/*static _inline void *PciGetContext(IN PCI_DEVICE *pDev); */
Packit 857059
Packit 857059
/* Get Basic PCI Device Information (location in system) */
Packit 857059
static _inline uint32 PciGetBusNumber(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint32 PciGetDeviceNumber(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint32 PciGetFuncNumber(IN PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/* Get Basic PCI Device Information (comes from PCI Config registers) */
Packit 857059
static _inline uint16 PciGetVendorId(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint16 PciGetDeviceId(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint8 PciGetRevisionId(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint16 PciGetSubsystemVendorId(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint16 PciGetSubsystemId(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint8 PciGetInterruptLine(IN PCI_DEVICE *pDev);
Packit 857059
static _inline uint8 PciGetInterruptPin(IN PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/* PCI Device Memory and BARs
Packit 857059
 * depending on device, there could be 6 32 bit BARs or 3 64 bit BARs
Packit 857059
 * however in either case we still use values of 0-5 for barNumber below
Packit 857059
 * Beware on VxWorks, PciGetMemoryLength always returns 0
Packit 857059
 */
Packit 857059
extern uint64 PciGetMemoryLength(IN PCI_DEVICE *pDev, IN uint8 barNumber);
Packit 857059
extern uint64 PciGetMemoryPciPhysAddr(IN PCI_DEVICE *pDev, IN uint8 barNumber);
Packit 857059
extern uint64 PciGetMemoryCpuPhysAddr(IN PCI_DEVICE *pDev, IN uint8 barNumber);
Packit 857059
Packit 857059
/* Mapping PCI memory to CPU Kernel Virtual
Packit 857059
 * These functions work with an opaque handle to a memory map object
Packit 857059
 */
Packit 857059
extern FSTATUS PciMapUncachedMemory(IN PCI_DEVICE *pDev,
Packit 857059
									IN uint8 barNumber,
Packit 857059
									OUT PCI_MAP_HANDLE *pMap,
Packit 857059
									OUT void** virt OPTIONAL);
Packit 857059
extern FSTATUS PciMapUncachedMemoryPartial(IN PCI_DEVICE *pDev,
Packit 857059
										IN uint8 barNumber,
Packit 857059
										IN uint64 offset,
Packit 857059
										IN uint64 length,
Packit 857059
										OUT PCI_MAP_HANDLE *pMap,
Packit 857059
										OUT void** virt OPTIONAL);
Packit 857059
extern void* PciMapGetVirtual(IN PCI_MAP_HANDLE pMap);
Packit 857059
extern void PciUnmapMemory(IN PCI_MAP_HANDLE pMap);
Packit 857059
Packit 857059
/* enable bus master operation by device */
Packit 857059
extern FSTATUS PciSetBusMaster(IN PCI_DEVICE *pDev, int bus_width);
Packit 857059
/* enable memory mapped access to device */
Packit 857059
extern FSTATUS PciSetMemoryEnable(IN PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/* PCI MSI (Message Signalled Interrupts) support
Packit 857059
 * At present only 1 MSI interrupt is supported per device
Packit 857059
 * The use of MSI by the driver is optional
Packit 857059
 * In the future MSI-X may be implemented and allow >1 MSI interrupt per device
Packit 857059
 */
Packit 857059
/* Enable use of MSI, must call before PciSetIntrHandler */
Packit 857059
extern FSTATUS PciEnableMsi(IN PCI_DEVICE *pDev);
Packit 857059
/* Disable use of MSI, must call after PciClearIntrHandler
Packit 857059
 * Noop if not enabled
Packit 857059
 */
Packit 857059
extern void PciDisableMsi(IN PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/* PCI Device Interrupts */
Packit 857059
/* Set Interrupt handler and enable interrupts */
Packit 857059
extern FSTATUS PciSetIntrHandler(IN PCI_DEVICE *pDev, IN const char* Name,
Packit 857059
							IN INTR_HANDLER Handler, IN void* Context);
Packit 857059
/* Clear Interrupt Handler and disable interrupts */
Packit 857059
extern void PciClearIntrHandler(IN PCI_DEVICE *pDev);
Packit 857059
Packit 857059
/*
Packit 857059
 * The following functions implement read/write to PCI config space
Packit 857059
 * to perform device specific configuration.
Packit 857059
 *
Packit 857059
 * PCI_DEVICE - is an opaque structure that makes sense only for that OS
Packit 857059
 * or platform that implements that abstraction.
Packit 857059
 *
Packit 857059
 * Offset - the offset into the space where the operation should be performed.
Packit 857059
 *
Packit 857059
 * Width  - The width of the IO to perform. It could be one of 1,2,4 bytes
Packit 857059
 *          in size. The memory provided to these function should be aligned
Packit 857059
 *          to the byte width to which the operation is being performed.
Packit 857059
 * 
Packit 857059
 * pVal   - Pointer to the location where the data should be read into, or 
Packit 857059
 *          the value that should be written to the pci device.
Packit 857059
 */
Packit 857059
extern boolean 
Packit 857059
PciReadConfig(
Packit 857059
	IN	PCI_DEVICE	*pDev,
Packit 857059
	IN	uint32		Offset,
Packit 857059
	IN	uint32		Width,
Packit 857059
	OUT void		*pVal
Packit 857059
	);
Packit 857059
extern boolean 
Packit 857059
PciWriteConfig(
Packit 857059
	IN	PCI_DEVICE	*pDev,
Packit 857059
	IN	uint32		Offset,
Packit 857059
	IN	uint32		Width,
Packit 857059
	IN	void		*pVal
Packit 857059
	);
Packit 857059
Packit 857059
/*
Packit 857059
 * The following function finds a device based on the Bus_Number/Slot_Number
Packit 857059
 * pair and returns a pointer to the PCI_DEVICE structure. This structure
Packit 857059
 * will be used by the ReadConfig and WriteConfig functions listed above.
Packit 857059
 *
Packit 857059
 * PCI_DEVICE - is an opaque structure that makes sense only for that OS or
Packit 857059
 * platform that implements the abstraction.
Packit 857059
 * 
Packit 857059
 * BusNumber: number of PCI bus on which desired PCI device resides
Packit 857059
 * Slot: PCI slot in which the desired PCI device residesdevice resides
Packit 857059
 *
Packit 857059
 * Return Value: 
Packit 857059
 * 	FSUCCESS - If a device at BusNumber and SlotNumber if found.
Packit 857059
 *	FNOT_FOUND - If a device cannot be found.
Packit 857059
 */
Packit 857059
Packit 857059
extern FSTATUS
Packit 857059
PciGetDevice(
Packit 857059
	IN OUT PCI_DEVICE 	*pDev,
Packit 857059
	IN uint16		BusNumber,
Packit 857059
	IN uint8		SlotNumber 
Packit 857059
	);
Packit 857059
Packit 857059
#if defined(HAVEIOMMU)
Packit 857059
/*
Packit 857059
 * The following functions create, manage and release pools of memory
Packit 857059
 * that are guaranteed to be accessible to PCI devices.
Packit 857059
 */
Packit 857059
extern void* PciPoolCreate(
Packit 857059
	IN const char *name,
Packit 857059
	IN PCI_DEVICE *pDev,
Packit 857059
	IN size_t size,
Packit 857059
	IN size_t align);
Packit 857059
Packit 857059
extern void PciPoolDestroy(IN void* pool);
Packit 857059
Packit 857059
/* 
Packit 857059
 * Returns the virtual address of the dma-able memory or NULL.
Packit 857059
 * The dma address of the dma-able memory is returned in dmaaddr.
Packit 857059
 */
Packit 857059
extern void* PciPoolAlloc(
Packit 857059
	IN void* pool, 
Packit 857059
	OUT uint64 *dmaaddr);
Packit 857059
Packit 857059
/* Free the dma-able memory. NOTE THAT YOU PASS BOTH THE VIRTUAL
Packit 857059
 * AND PHYSICAL (DMA) ADDRESSES OF THE MEMORY.
Packit 857059
 */
Packit 857059
extern void PciPoolFree(
Packit 857059
		IN void* pool,
Packit 857059
		IN void* vaddr,
Packit 857059
		IN uint64 dmaddr);
Packit 857059
#endif
Packit 857059
Packit 857059
// defined in OS specific header
Packit 857059
//#define PCI_DMA_BIDIR DMA_BIDIRECTIONAL
Packit 857059
//#define PCI_DMA_TODEV DMA_TODEVICE
Packit 857059
//#define PCI_DMA_FROMDEV DMA_FROMDEVICE
Packit 857059
//...
Packit 857059
Packit 857059
/*
Packit 857059
 * The following functions manage mapping memory for access by PCI devices.
Packit 857059
 * For each function, a function type is declared which can be used by
Packit 857059
 * PciSetDmaFuncs to specify device specific overrides which will be called
Packit 857059
 * by these functions.
Packit 857059
 */
Packit 857059
Packit 857059
/* map a kernel virtual address, returns Bus Physical address to be
Packit 857059
 * used by device for IO
Packit 857059
 * Virtual memory specified must be kernel virtual and physically contiguous
Packit 857059
 */
Packit 857059
typedef FSTATUS (PCI_DMA_MAP_VIRT_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN void *addr,
Packit 857059
	IN uint64 size,
Packit 857059
	IN int dir,
Packit 857059
	OUT uint64 *dma_address,
Packit 857059
	OUT uint64 *map_handle	/* opaque handle for use in Unmap below */
Packit 857059
	);
Packit 857059
extern PCI_DMA_MAP_VIRT_FUNC PciDmaMapVirt;
Packit 857059
Packit 857059
/* undoes a previous PciDmaMapVirt, must be called with map_handle = handle
Packit 857059
 * previously returned by PciDmaMapVirt
Packit 857059
 */
Packit 857059
typedef void (PCI_DMA_UNMAP_VIRT_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN uint64 size,
Packit 857059
	IN int dir,
Packit 857059
	IN uint64 map_handle
Packit 857059
	);
Packit 857059
extern PCI_DMA_UNMAP_VIRT_FUNC PciDmaUnmapVirt;
Packit 857059
Packit 857059
/* map a set of physically contiguous pages.
Packit 857059
 * physadd need not be page aligned, however some OS's may require this not
Packit 857059
 * span multiple pages
Packit 857059
 */
Packit 857059
typedef FSTATUS (PCI_DMA_MAP_PHYS_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN uint64 physaddr,
Packit 857059
	IN uint64 size,
Packit 857059
	IN int dir,
Packit 857059
	OUT uint64 *dma_address,
Packit 857059
	OUT uint64 *map_handle
Packit 857059
	);
Packit 857059
extern PCI_DMA_MAP_PHYS_FUNC PciDmaMapPhys;
Packit 857059
Packit 857059
/* undoes a previous PciDmaMapPhys, must be called with map_handle = handle
Packit 857059
 * previously returned by PciDmaMapPhys
Packit 857059
 */
Packit 857059
typedef void (PCI_DMA_UNMAP_PHYS_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN uint64 size,
Packit 857059
	IN int dir,
Packit 857059
	IN uint64 map_handle
Packit 857059
	);
Packit 857059
extern PCI_DMA_UNMAP_PHYS_FUNC PciDmaUnmapPhys;
Packit 857059
Packit 857059
/* map a scatter gather list of segments
Packit 857059
 * scatter gather list format is OS specific as is typically supplied to
Packit 857059
 * typical drivers on the given OS.  On some OSs an offset is also supplied by
Packit 857059
 * the OS for typical drivers.
Packit 857059
 * an OS specific ITERATOR is returned for use in walking the resulting
Packit 857059
 * list of DMA addresses/lengths.
Packit 857059
 * Note that on some OSs, the number of entries in the resulting iterator
Packit 857059
 * may be different than sg_len
Packit 857059
 */
Packit 857059
typedef FSTATUS (PCI_DMA_MAP_SG_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN PCI_DMA_SG_LIST *sg_list,
Packit 857059
	IN uint32 sg_len,
Packit 857059
	IN uint32 offset,
Packit 857059
	IN int dir,
Packit 857059
	OUT PCI_DMA_SG_ITERATOR *iterator,
Packit 857059
	OUT uint64 *map_handle
Packit 857059
	);
Packit 857059
extern PCI_DMA_MAP_SG_FUNC PciDmaMapSg;
Packit 857059
Packit 857059
/* return the next mapped SG entry's address and length and advance
Packit 857059
 * returns:
Packit 857059
 * 	FCOMPLETED - end of list, no address/length available
Packit 857059
 * 	FSUCCESS - address/length provided and advanced
Packit 857059
 */
Packit 857059
typedef FSTATUS (PCI_DMA_SG_NEXT_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN PCI_DMA_SG_LIST *sg_list,
Packit 857059
	IN PCI_DMA_SG_ITERATOR *iterator,
Packit 857059
	OUT uint64 *dma_address,
Packit 857059
	OUT uint64 *dma_length
Packit 857059
	);
Packit 857059
extern PCI_DMA_SG_NEXT_FUNC PciDmaSgNext;
Packit 857059
Packit 857059
/* return the number of unprocessed SG entries
Packit 857059
 * If called immediately after PciDmaMapSg, this is total mapped areas
Packit 857059
 * If called after one or more PciDmaSgNext calls, this is remaining areas
Packit 857059
 */
Packit 857059
extern uint32 PciDmaSgCountLeft(
Packit 857059
	IN PCI_DMA_SG_LIST *sg_list,
Packit 857059
	IN PCI_DMA_SG_ITERATOR *iterator
Packit 857059
	);
Packit 857059
Packit 857059
/* undoes a previous PciDmaMapSg, must be called with map_handle = handle
Packit 857059
 * previously returned by PciDmaMapSg
Packit 857059
 */
Packit 857059
typedef void (PCI_DMA_UNMAP_SG_FUNC)(
Packit 857059
	IN struct _PCI_DEVICE *pDev,
Packit 857059
	IN PCI_DMA_SG_LIST *sg_list,
Packit 857059
	IN uint32 sg_len,
Packit 857059
	IN uint32 offset,
Packit 857059
	IN int dir,
Packit 857059
	IN uint64 map_handle
Packit 857059
	);
Packit 857059
extern PCI_DMA_UNMAP_SG_FUNC PciDmaUnmapSg;
Packit 857059
Packit 857059
/* usage model for scatter/gather DMA:
Packit 857059
 * To start IO:
Packit 857059
 * 		status = PciDmaMapSg(.....)
Packit 857059
 * 		check status, fail if not FSUCCESS
Packit 857059
 * 		while (PciDmaSgNext(...) != FCOMPLETED)
Packit 857059
 * 			setup transfer to dma_address,length (typically added to WQE)
Packit 857059
 *
Packit 857059
 * when IO completes:
Packit 857059
 * 		PciDmaUnmapSg(...)
Packit 857059
 */
Packit 857059
Packit 857059
/* device specific functions which can be called as part of Pci DMA functions
Packit 857059
 * above
Packit 857059
 */
Packit 857059
typedef struct _PCI_DMA_FUNCS {
Packit 857059
	PCI_DMA_MAP_VIRT_FUNC *pMapVirt;
Packit 857059
	PCI_DMA_UNMAP_VIRT_FUNC *pUnmapVirt;
Packit 857059
	PCI_DMA_MAP_PHYS_FUNC *pMapPhys;
Packit 857059
	PCI_DMA_UNMAP_PHYS_FUNC *pUnmapPhys;
Packit 857059
	PCI_DMA_MAP_SG_FUNC *pMapSg;
Packit 857059
	PCI_DMA_UNMAP_SG_FUNC *pUnmapSg;
Packit 857059
	PCI_DMA_SG_NEXT_FUNC *pSgNext;
Packit 857059
} PCI_DMA_FUNCS;
Packit 857059
Packit 857059
/* specify DMA function overrides which should be called by the Pci DMA
Packit 857059
 * functions above.  The context supplied may be fetched via PciGetDmaContext
Packit 857059
 * it is distinct from the Interrupt context used in interrupt callbacks
Packit 857059
 */
Packit 857059
extern void PciSetDmaFuncs(
Packit 857059
	IN PCI_DEVICE *pDev,
Packit 857059
	IN PCI_DMA_FUNCS *funcs,
Packit 857059
	IN void *context);
Packit 857059
/*static _inline void *PciGetDmaContext(IN PCI_DEVICE *pDev); */
Packit 857059
Packit 857059
/* This function indicates if the given Device and/or OS requires
Packit 857059
 * calls to PciDmaMap functions above.
Packit 857059
 * If this returns TRUE, PciDmaMap functions are required.
Packit 857059
 * If this returns FALSE the calls above are benign but not necessary.
Packit 857059
 * In which case PciDmaMap functions will simply return CPU physical addresses.
Packit 857059
 * When FALSE is returned its up to the caller, who may be able to optimize
Packit 857059
 * by avoiding the PciDmaMap functions.
Packit 857059
 */
Packit 857059
//static _inline boolean PciNeedDmaMap(IN PCI_DEVICE *pDev);
Packit 857059
Packit 857059
#endif /* defined(VXWORKS) */
Packit 857059
Packit 857059
#ifdef __cplusplus
Packit 857059
}	/* extern "C" */
Packit 857059
#endif
Packit 857059
Packit 857059
#endif /* _IBA_PUBLIC_IPCI_H_ */