/*
 * Copyright (c) 1991-1998 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef _SYS_PCI_VAR_H
#define	_SYS_PCI_VAR_H

#pragma ident	"@(#)pci_var.h	1.52	00/08/29 SMI"

#ifdef	__cplusplus
extern "C" {
#endif

#define	PSYCHO_MAX_INO		0x3f
#define	SCHIZO_MAX_INO		0x37

typedef enum { PSYCHO, SCHIZO } pci_bridge_t;

typedef enum { A, B } pci_side_t;

typedef uint16_t ib_ign_t;
typedef uint8_t ib_ino_t;
typedef uint16_t ib_mondo_t;
typedef enum { OBIO, SLOT, INTERNAL, UPA_PORT, NEWLINK } ib_ino_type_t;
typedef enum { MR_SHARED, MR_EXCLUSIVE } ib_map_reg_t;

typedef uint64_t window_t;

typedef struct ih ih_t;
typedef struct ib_ino_info ib_ino_info_t;

typedef uint8_t device_num_t;
typedef uint8_t interrupt_t;
typedef uint8_t pil_t;

typedef uchar_t context_t;
typedef struct config_header config_header_t;
typedef struct config_header_state config_header_state_t;
typedef struct iommu iommu_t;
typedef struct cb cb_t;
typedef struct sc sc_t;
typedef struct ecc ecc_t;
typedef struct ib ib_t;
typedef struct pbm pbm_t;

typedef struct pci pci_t;
typedef struct pci_common pci_common_t;

typedef enum { PCI_NEW, PCI_ATTACHED, PCI_DETACHED,
		PCI_SUSPENDED }	pci_state_t;

typedef enum { INO_FREE = 0, INO_SINGLE, INO_SHARED } ino_state_t;

typedef enum { PBM_SPEED_33MHZ, PBM_SPEED_66MHZ } pbm_speed_t;

/*
 * The following typedef is used to represent a
 * 1275 "bus-range" property of a PCI Bus node.
 */
typedef struct bus_range {
	uint32_t lo;
	uint32_t hi;
} pci_bus_range_t;

/*
 * The following typedef is used to represent an entry in the "ranges"
 * property of a device node.
 */
typedef struct ranges {
	uint32_t child_high;
	uint32_t child_mid;
	uint32_t child_low;
	uint32_t parent_high;
	uint32_t parent_low;
	uint32_t size_high;
	uint32_t size_low;
} pci_ranges_t;

struct fault_hdlr {
	struct fault_hdlr_info info;
	struct fault_hdlr_data data;
	struct fault_hdlr *next;
};

/*
 * The following typedef is used to represent the target of a dma operation.
 */
typedef struct dma_target {
	size_t npages;
#define	pfn_t	uint64_t
	pfn_t page_list[1];
} dma_target_t;


/*
 * pci common soft state structure:
 *
 * Each psycho or schizo is represented by a pair of pci nodes in the
 * device tree.  A single pci common soft state is allocated for each
 * pair.  The UPA (Safari) bus id of the psycho (schizo) is used for
 * the instance number.  The attach routine uses the existance of a
 * pci common soft state structure to determine if one node from the
 * pair has been attached.
 */
struct pci_common {

	/*
	 * Links to functional blocks that are shared between pci nodes:
	 */
	iommu_t *pci_common_iommu_p;
	cb_t *pci_common_cb_p;
	ib_t *pci_common_ib_p;
	ecc_t *pci_common_ecc_p;

	/*
	 * Pointers to pci bus segments:
	 */
	pci_t *pci_p[2];
};

/*
 * pci soft state structure:
 *
 * Each pci node has a pci soft state structure.
 */
struct pci {

	/*
	 * State flags and mutex:
	 */
	pci_state_t pci_state;
	uint_t pci_soft_state;
	uint_t pci_open_count;
#define	PCI_SOFT_STATE_OPEN		0x01
#define	PCI_SOFT_STATE_OPEN_EXCL	0x02
#define	PCI_SOFT_STATE_CLOSED		0x04
	kmutex_t pci_mutex;

	/*
	 * Links to other state structures:
	 */
	pci_common_t *pci_common_p;	/* pointer common soft state */
	dev_info_t *pci_dip;		/* devinfo structure */
	ib_t *pci_ib_p;			/* interrupt block */
	cb_t *pci_cb_p;			/* control block */
	pbm_t *pci_pbm_p;		/* PBM block */
	iommu_t	*pci_iommu_p;		/* IOMMU block */
	sc_t *pci_sc_p;			/* streaming cache block */
	ecc_t *pci_ecc_p;		/* ECC error block */

	/*
	 * other state info:
	 */
	uint8_t pci_id;			/* UPA (or Safari) device id */
	pci_bridge_t pci_bridge_type;	/* psycho or schizo */
	pci_side_t pci_side;

	/*
	 * pci device node properties:
	 */
	pci_bus_range_t pci_bus_range;	/* "bus-range" */
	pci_ranges_t *pci_ranges;	/* "ranges" data & length */
	int pci_ranges_length;
	uint32_t *pci_interrupts;	/* "interrupts" data & length */
	int pci_interrupts_length;
	int pci_numproxy;		/* upa interrupt proxies */
	int pci_thermal_interrupt;	/* node has thermal interrupt */
	int pci_pwrbtn_interrupt;	/* node has power button interrupt */

	kmutex_t flt_lst_mutex;		/* Fault handler list mutex */
	struct fault_hdlr *flt_lst;	/* Fault handling list */

	/*
	 * register mapping:
	 */
	caddr_t pci_address[3];
	ddi_acc_handle_t pci_ac[3];

	/*
	 * dma handle data:
	 */
	uintptr_t pci_handle_pool_call_list_id;	/* call back list id */

	/*
	 * cpr support:
	 */
	uint_t pci_config_state_entries;
	config_header_state_t *pci_config_state_p;

	/* Interrupt support */
	int intr_map_size;
	struct intr_map *intr_map;
	struct intr_map_mask *intr_map_mask;

#ifdef _KAISER
	uint_t pci_errflag;              /* Error flag */
        uint_t pci_u2u_offline_enable;   /* U2U offline enable flag */
        uint_t pci_u2u_online_state;     /* U2U online state flag */

	/* register access check enable flag of child driver */
        uint_t pci_child_access_check;
#endif /* _KAISER */
};


/*
 * control block soft state structure:
 *
 * Each pci node contains shares a control block structure with its peer
 * node.  The control block node contains csr and id registers for chip
 * and acts as a "catch all" for other functionality that does not cleanly
 * fall into other functional blocks.  This block is also used to handle
 * software workarounds for known hardware bugs in different chip revs.
 */
struct cb {

	pci_t *cb_pci_p;	/* link back to pci soft state */

	/*
	 * cb operations:
	 */
	void (*cb_configure)(cb_t *cb_p, ddi_attach_cmd_t cmd);
	uint_t (*cb_thermal_intr)(caddr_t a);
	uint_t (*cb_pwrbtn_intr)(caddr_t a);

	/*
	 * virtual address of control block registers:
	 */
	volatile uint64_t *cb_id_reg;
	volatile uint64_t *cb_control_status_reg;

	/*
	 * thermal interrupt mondo and priority (if used):
	 */
	uint_t cb_thermal_mondo;
	uint_t cb_thermal_pil;
	uint_t cb_pwrbtn_mondo;
	uint_t cb_pwrbtn_pil;
};


/*
 * interrupt block soft state structure:
 *
 * Each pci node may share an interrupt block structure with its peer
 * node of have its own private interrupt block structure.
 */

struct ib {

	pci_t *ib_pci_p;	/* link back to pci soft state */

	/*
	 * ib operations:
	 */
	void (*ib_configure)(ib_t *ib_p, ddi_attach_cmd_t cmd);
	ib_ino_t (*ib_mondo_to_ino)(ib_mondo_t mondo);
	ib_mondo_t (*ib_make_mondo)(ib_t *ib_p, ib_ino_t ino);
	ib_ino_t (*ib_make_ino)(pci_t *pci_p, device_num_t dev,
			interrupt_t intr);
	uint64_t *(*ib_intr_map_reg_addr)(ib_t *ib_p, ib_ino_t ino);
	ib_map_reg_t (*ib_intr_map_reg_type)(ib_t *ib_p, ib_ino_t ino);
	uint_t *(*ib_intr_map_reg_counter)(ib_t *ib_p, ib_ino_t ino);
	uint64_t *(*ib_clear_intr_reg_addr)(ib_t *ib_p, ib_ino_t ino);
	void (*ib_intr_enable)(ib_t *ib_p, dev_info_t *dip, ib_ino_t ino);
	void (*ib_intr_disable)(ib_t *ib_p, ib_ino_t ino);
	void (*ib_intr_clear)(ib_t *ib_p, ib_ino_t ino);
	void (*ib_intr_dist)(void *arg, int mondo, uint_t cpuid);
	void (*ib_save_intr_map_regs)(ib_t *ib_p);
	void (*ib_restore_intr_map_regs)(ib_t *ib_p);

	/*
	 * PCI slot and onboard I/O interrupt mapping register blocks addresses:
	 */
	uintptr_t ib_slot_intr_map_regs;
#define	ib_intr_map_regs	ib_slot_intr_map_regs
	uintptr_t ib_obio_intr_map_regs;

	/*
	 * PCI slot and onboard I/O clear interrupt register block addresses:
	 */
	uintptr_t ib_slot_clear_intr_regs;
	uintptr_t ib_obio_clear_intr_regs;

	/*
	 * UPA expansion slot interrupt mapping register addresses:
	 */
	uint64_t *ib_upa_exp_intr_map_reg[2];
	uint64_t ib_upa_exp_intr_map_reg_state[2];

	/*
	 * Interrupt retry register address:
	 */
	volatile uint64_t *ib_intr_retry_timer_reg;

	/*
	 * PCI slot and onboard I/O interrupt state diag register addresses:
	 */
	volatile uint64_t *ib_slot_intr_state_diag_reg;
	volatile uint64_t *ib_obio_intr_state_diag_reg;

	ib_ign_t ib_ign;		/* interrupt group number */
	uint_t ib_max_ino;		/* largest supported INO */
	ib_ino_info_t *ib_ino_table;	/* ino table */
	uint_t ib_map_reg_counters[8];	/* counters for shared map registers */

#ifdef _STARFIRE
	caddr_t ib_ittrans_cookie;	/* intr tgt translation */
#endif /* _STARFIRE */

#ifdef _KAISER
	caddr_t ib_ittrans_cookie;  /* U2U intr tgt translation table */
#endif /* _KAISER */
};


/*
 * pbm block soft state structure:
 *
 * Each pci node has its own private pbm block structure.
 */

struct pbm {

	pci_t *pbm_pci_p;	/* link back to pci soft state */

	pbm_speed_t pbm_speed;	/* PCI bus speed (33 or 66 Mhz) */

	void (*pbm_configure)(pbm_t *pbm_p, ddi_attach_cmd_t cmd);
	void (*pbm_disable_pci_errors)(pbm_t *pbm_p);
	uint_t (*pbm_error_intr)(caddr_t a);
	void (*pbm_clear_error)(pbm_t *pbm_p);

	/*
	 * PBM control and error registers:
	 */
	volatile uint64_t *pbm_ctrl_reg;
	volatile uint64_t *pbm_async_flt_status_reg;
	volatile uint64_t *pbm_async_flt_addr_reg;
	volatile uint64_t *pbm_diag_reg;

	/*
	 * PCI configuration header block for the PBM:
	 */
	config_header_t *pbm_config_header;
	ddi_acc_handle_t pbm_config_ac;

	/*
	 * Memory address range on this PBM used to determine DMA on this pbm
	 */
	uint64_t pbm_base_addr;
	uint64_t pbm_last_addr;

	/*
	 * pbm error interrupt mondo and priority:
	 */
	uint_t pbm_bus_error_mondo;
	uint_t pbm_bus_error_pil;

	/*
	 * support for ddi_poke:
	 */
	ddi_nofault_data_t *nofault_data;
	kmutex_t pbm_pokefault_mutex;
};


/*
 * iommu block soft state structure:
 *
 * Each pci node may share an iommu block structure with its peer
 * node of have its own private iommu block structure.
 */

struct iommu {

	pci_t *iommu_pci_p;	/* link back to pci soft state */

	/*
	 * iommu operations:
	 */
	void (*iommu_configure)(iommu_t *iommu_p, ddi_attach_cmd_t cmd);
	void (*iommu_map_window)
			(iommu_t *iommu_p, dev_info_t *dip,
				ddi_dma_impl_t *mp, window_t window);
	void (*iommu_unmap_window)
			(iommu_t *iommu_p, dev_info_t *dip,
				ddi_dma_impl_t *mp);
	dvma_addr_t (*iommu_get_dvma_pages)
			(iommu_t *iommu_p, size_t npages,
				dvma_addr_t addrlo, dvma_addr_t addrhi,
				dvma_addr_t align, int cansleep);
	void (*iommu_free_dvma_pages)
			(iommu_t *iommu_p, size_t npages,
				dvma_addr_t dvma_addr);
	dvma_context_t (*iommu_get_dvma_context)
			(iommu_t *iommu_p, int cansleep);
	void (*iommu_free_dvma_context)(iommu_t *iommu_p);
	void (*iommu_page_flush)(iommu_t *iommu_p, dvma_addr_t dvma_addr);
	void (*iommu_load_tte)
			(iommu_t *iommu_p, ddi_dma_impl_t *mp,
				dvma_addr_t dvma_addr,
				dvma_context_t dvma_context, pfn_t pfn);
	void (*iommu_unload_tte)(iommu_t *iommu_p, dvma_addr_t dvma_addr);
	int (*iommu_create_bypass_cookies)
			(iommu_t *iommu_p, dev_info_t *dip, ddi_dma_impl_t *mp,
				ddi_dma_cookie_t *cookiep, uint_t *ccountp);
	dma_bypass_addr_t (*iommu_make_bypass_addr)
			(iommu_t *iommu_p, pfn_t pfn, size_t offset);
	dma_peer_addr_t (*iommu_make_peer_addr)(pfn_t pfn, size_t offset);

	/*
	 * control registers (psycho and schizo):
	 */
	volatile uint64_t *iommu_ctrl_reg;
	volatile uint64_t *iommu_tsb_base_addr_reg;
	volatile uint64_t *iommu_flush_page_reg;

	/*
	 * control registers (psycho and schizo):
	 */
	volatile uint64_t *iommu_flush_ctx_reg;

	/*
	 * diagnostic access registers:
	 */
	volatile uint64_t *iommu_tlb_tag_diag_acc;
	volatile uint64_t *iommu_tlb_data_diag_acc;

	/*
	 * virtual and physical addresses and size of the iommu tsb:
	 */
	uint64_t *iommu_tsb_vaddr;
	uint64_t iommu_tsb_paddr;
	uint_t iommu_tsb_entries;
	uint_t iommu_tsb_size;
	uint_t iommu_contexts;
#ifdef _KAISER
	uint16_t iommu_spare_slot;
#else
	uint8_t iommu_spare_slot;
#endif /* _KAISER */

	/*
	 * address ranges of dvma space:
	 */
	dvma_addr_t iommu_dvma_base;
	dvma_addr_t iommu_dvma_end;

	/*
	 * address ranges of dma bypass space:
	 */
	dma_bypass_addr_t iommu_dma_bypass_base;
	dma_bypass_addr_t iommu_dma_bypass_end;

	/*
	 * resource map and callback id for dvma space:
	 */
	struct map *iommu_dvma_map;
	uintptr_t iommu_dvma_call_list_id;
	char iommu_dvma_map_name[64];

	/*
	 * for iommus that support context flushing:
	 */
	struct map *iommu_context_map;
	char iommu_context_map_name[64];

	/*
	 * fields for fast dvma interfaces:
	 */
	ulong_t iommu_dvma_reserve;
};


/*
 * streaming cache (sc) block soft state structure:
 *
 * Each pci node contains has its own private sc block structure.
 */

struct sc {

	pci_t *sc_pci_p;	/* link back to pci soft state */

	/*
	 * streaming cache operations:
	 */
	void (*sc_configure)(sc_t *sc_p, ddi_attach_cmd_t cmd);
	void (*sc_flush)(sc_t *sc_p, ddi_dma_impl_t *mp,
			context_t context, off_t offset, size_t length);

	/*
	 * control registers (psycho and schizo):
	 */
	volatile uint64_t *sc_ctrl_reg;
	volatile uint64_t *sc_invl_reg;
	volatile uint64_t *sc_sync_reg;

	/*
	 * control registers (schizo only):
	 */
	volatile uint64_t *sc_ctx_invl_reg;
	volatile uint64_t *sc_ctx_match_reg;

	/*
	 * diagnostic access registers:
	 */
	volatile uint64_t *sc_data_diag_acc;
	volatile uint64_t *sc_tag_diag_acc;
	volatile uint64_t *sc_ltag_diag_acc;

	/*
	 * virtual and physical addresses of sync flag:
	 */
	caddr_t sc_sync_flag_base;
	volatile uint64_t *sc_sync_flag_vaddr;
	uint64_t sc_sync_flag_addr;

	kmutex_t sc_sync_mutex;		/* mutex for flush/sync register */
};


/*
 * The following structure represents the pci configuration header
 * for a psycho or schizo PBM.
 */

struct config_header {
	volatile uint16_t ch_device_id;
	volatile uint16_t ch_vendor_id;
	volatile uint16_t ch_command_reg;
	volatile uint16_t ch_status_reg;
	volatile uint8_t ch_revision_id_reg;
	volatile uint8_t ch_programming_if_code_reg;
	volatile uint8_t ch_sub_class_reg;
	volatile uint8_t ch_base_class_reg;
	volatile uint8_t ch_cache_line_size_reg;
	volatile uint8_t ch_latency_timer_reg;
	volatile uint8_t ch_header_type_reg;
};

struct config_header_state {
	dev_info_t *chs_dip;
	uint16_t chs_command;
	uint8_t chs_cache_line_size;
	uint8_t chs_latency_timer;
	uint8_t chs_header_type;
	uint8_t chs_sec_latency_timer;
	uint8_t chs_bridge_control;
};


/*
 * The following structure ...
 */

struct ecc {

	dev_info_t *ecc_dip;

	pci_t *ecc_pci_p;		/* link to PBM interrupt block */

	/*
	 * ECC cache operations:
	 */
	void (*ecc_configure)(ecc_t *ecc_p, ddi_attach_cmd_t cmd);
	void (*ecc_disable)(ecc_t *ecc_p);
	uint_t (*ecc_ue_intr)(caddr_t a);
	uint_t (*ecc_ce_intr)(caddr_t a);
	void (*ecc_log_ue_error)(struct async_flt *ecc, char *unum);
	void (*ecc_log_ce_error)(struct async_flt *ecc, char *unum);
	uint_t (*ecc_err_callback)(ecc_t *ecc_p);

	/*
	 * ECC control and status registers:
	 */
	volatile uint64_t *ecc_ctrl_reg;
	volatile uint64_t *ecc_ue_async_flt_status_reg;
	volatile uint64_t *ecc_ue_async_flt_addr_reg;
	volatile uint64_t *ecc_ce_async_flt_status_reg;
	volatile uint64_t *ecc_ce_async_flt_addr_reg;

	/*
	 * Mondo numbers and priority levels of UE and CE interrupts:
	 */
	uint_t ecc_ue_mondo;
	uint_t ecc_ue_pil;
	uint_t ecc_ce_mondo;
	uint_t ecc_ce_pil;

#ifdef _KAISER
	uint64_t ecc_ce_prev_afsr;
	uint64_t ecc_ce_prev_afar;
	clock_t ecc_ce_same_first_time;
	timeout_id_t ecc_ce_timeout_id;
	kmutex_t ecc_ce_to_mutex;
	uint_t ecc_ce_same_count;
	uint_t ecc_ce_intr_disable;
#endif /* _KAISER */	
};



/*
 * The following structure represents an interrupt entry for an INO.
 */
struct ih {
	dev_info_t *ih_dip;		/* devinfo structure */
	uint_t (*ih_handler)();		/* interrupt handler */
	caddr_t ih_handler_arg;		/* interrupt handler argument */
	ddi_acc_handle_t config_handle;	/* config space reg map handle */
	ih_t *ih_next;			/* next entry in list */
};


/*
 * per ino structure
 *
 * Each psycho ino has one of the following structures associate
 * with it.
 */
struct ib_ino_info {
	uint64_t *ino_clear_reg;	/* ino's clear interrupt register */
	uint64_t *ino_map_reg;		/* ino's interrupt map register */
	ib_map_reg_t ino_map_reg_type;	/* ino's type: shared or exclusive */
	uint_t *ino_map_reg_counter;	/* ino's map reg counter (if shared) */
	uint64_t ino_map_reg_state;	/* ino's interrupt map register state */
	ino_state_t ino_state;		/* state of ino handler list */
	ih_t *ino_head;			/* interrupt handler list head */
	ih_t *ino_tail;			/* interrupt handler list tail */
	ih_t *ino_start;		/* staring point in handler list */
	uint_t ino_size;			/* size of list */
	kmutex_t ino_mutex1;		/* for locking adds/deletes */
	kmutex_t ino_mutex2;		/* for locking adds/deletes/intrs */
	int ino_mutex2_initialized;	/* state of mutex2 */
	uint_t ino_idevice_cookie;	/* DDI interrupt device cookie */
	uint_t ino_ino;			/* INO number */
	ib_t *ino_ib_p;			/* link back to interrupt block state */
};



#define	PCI_SBUF_ENTRIES	16	/* number of i/o cache lines */
#define	PCI_SBUF_LINE_SIZE	64	/* size of i/o cache line */
#define	PCI_SYNC_FLAG_SIZE	64	/* size of i/o cache sync buffer */

#define	PCI_CACHE_LINE_SIZE	(PCI_SBUF_LINE_SIZE / 4)


/*
 * PSYCHO and PBM soft state macros:
 */
#define	get_pci_soft_state(i)	\
	((pci_t *)ddi_get_soft_state(per_pci_state, (i)))

#define	alloc_pci_soft_state(i)	\
	ddi_soft_state_zalloc(per_pci_state, (i))

#define	free_pci_soft_state(i)	\
	ddi_soft_state_free(per_pci_state, (i))

#define	get_pci_common_soft_state(i)	\
	((pci_common_t *)ddi_get_soft_state(per_pci_common_state, (i)))

#define	alloc_pci_common_soft_state(i)	\
	ddi_soft_state_zalloc(per_pci_common_state, (i))

#define	free_pci_common_soft_state(i)	\
	ddi_soft_state_free(per_pci_common_state, (i))

/*
 * misc macros for dma handles and cookies:
 */
#define	MAKE_DMA_COOKIE(cp, address, size)	\
	{					\
		(cp)->dmac_notused = 0;		\
		(cp)->dmac_type = 0;		\
		(cp)->dmac_laddress = (address);	\
		(cp)->dmac_size = (size);	\
	}

#define	HAS_REDZONE(mp)	(((mp)->dmai_rflags & DDI_DMA_REDZONE) ? 1 : 0)

#define	PCI_VALID_ID(id) ((id) < MAX_UPA)

/*
 * Contains a list of cookies created by create_bypass_cookies.
 */
typedef struct pci_dma_cookielist {
	uint_t ncookies;
	ddi_dma_cookie_t cookies[1];
} pci_dma_cookielist_t;

#define	COOKIELIST_SIZE(ncookies)				\
	(sizeof (pci_dma_cookielist_t) +			\
		(ncookies - 1) * sizeof (ddi_dma_cookie_t))

/*
 * This structure contains nexus private data that is held in the dma
 * handle.  The contract is that pci_dma_allochdl and pci_dma_map
 * will allocate this structure and set both pointers in it to NULL.
 * pci_dma_freehdl and the DDI_DMA_FREE request of pci_dma_mctl
 * will free this structure and any structures below it if they
 * exist.  Note that the fast dvma routines cannot be mixed with
 * the traditional dvma routines - the fast dvma routines have
 * their own use for the dmai_nexus_private pointer.
 */
typedef struct pci_dmai_nexus_private {
	dma_target_t *dma_targetp;
	pci_dma_cookielist_t *cookie_listp;	/* bypass cookies */
} pci_dmai_nexus_private_t;

/*
 * flags for overloading dmai_inuse field of the dma request
 * structure:
 */
#define	dmai_flags		dmai_inuse
#define	DMAI_FLAGS_INUSE	0x1
#define	DMAI_FLAGS_BYPASS	0x2
#define	DMAI_FLAGS_PEER_TO_PEER	0x4

#define	PCI_PULSE_INO		0x80000000

/*
 * debugging definitions:
 */
#if defined(DEBUG)
#define	DBG_ATTACH		0x00000001ull
#define	DBG_DETACH		0x00000002ull
#define	DBG_MAP			0x00000004ull
#define	DBG_G_ISPEC		0x00000008ull
#define	DBG_A_ISPEC		0x00000010ull
#define	DBG_R_ISPEC		0x00000020ull
#define	DBG_DMA_MAP		0x00000040ull
#define	DBG_DMA_ALLOCH		0x00000080ull
#define	DBG_DMA_FREEH		0x00000100ull
#define	DBG_DMA_BINDH		0x00000200ull
#define	DBG_DMA_UNBINDH		0x00000400ull
#define	DBG_DMA_FLUSH		0x00000800ull
#define	DBG_DMA_WIN		0x00001000ull
#define	DBG_DMA_CTL		0x00002000ull
#define	DBG_CTLOPS		0x00004000ull
#define	DBG_INIT_CLD		0x00008000ull
#define	DBG_FAST_DVMA		0x00010000ull
#define	DBG_CHK_TAR		0x00020000ull
#define	DBG_MAP_WIN		0x00040000ull
#define	DBG_UNMAP_WIN		0x00080000ull
#define	DBG_BYPASS		0x00100000ull
#define	DBG_IOMMU		0x00200000ull
#define	DBG_SC			0x00400000ull
#define	DBG_IB			0x00800000ull
#define	DBG_CB			0x01000000ull
#define	DBG_PBM			0x02000000ull
#define	DBG_INTR		0x04000000ull
#define	DBG_ERR_INTR		0x08000000ull
#define	DBG_CONT		0x10000000ull
#define	DBG_OPEN		0x20000000ull
#define	DBG_CLOSE		0x40000000ull
#define	DBG_IOCTL		0x80000000ull
#define	DBG_DMASYNC_FLUSH	0xC0000000ull

#define	DEBUG0(flag, dip, fmt)	\
	debug(flag, dip, fmt, 0, 0, 0, 0, 0);
#define	DEBUG1(flag, dip, fmt, a1)	\
	debug(flag, dip, fmt, (uintptr_t)(a1), 0, 0, 0, 0);
#define	DEBUG2(flag, dip, fmt, a1, a2)	\
	debug(flag, dip, fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
#define	DEBUG3(flag, dip, fmt, a1, a2, a3)	\
	debug(flag, dip, fmt, (uintptr_t)(a1),	\
		(uintptr_t)(a2), (uintptr_t)(a3), 0, 0);
#define	DEBUG4(flag, dip, fmt, a1, a2, a3, a4)	\
	debug(flag, dip, fmt, (uintptr_t)(a1),	\
		(uintptr_t)(a2), (uintptr_t)(a3), \
		(uintptr_t)(a4), 0);
#define	DEBUG5(flag, dip, fmt, a1, a2, a3, a4, a5)	\
	debug(flag, dip, fmt, (uintptr_t)(a1),	\
		(uintptr_t)(a2), (uintptr_t)(a3), \
		(uintptr_t)(a4), (uintptr_t)(a5));

static void debug(uint64_t, dev_info_t *, char *,
			uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t);
static void dump_dma_handle(uint64_t flag, dev_info_t *dip, ddi_dma_impl_t *hp);
#else
#define	DEBUG0(flag, dip, fmt)
#define	DEBUG1(flag, dip, fmt, a1)
#define	DEBUG2(flag, dip, fmt, a1, a2)
#define	DEBUG3(flag, dip, fmt, a1, a2, a3)
#define	DEBUG4(flag, dip, fmt, a1, a2, a3, a4)
#define	DEBUG5(flag, dip, fmt, a1, a2, a3, a4, a5)
#define	dump_dma_handle(flag, dip, hp)
#endif

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_PCI_VAR_H */
