pci_var.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_PCI_VAR_H
#define _SYS_PCI_VAR_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* 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 a
* 1275 "reg" property of a PCI nexus.
*/
typedef struct pci_nexus_regspec {
uint64_t phys_addr;
uint64_t size;
} pci_nexus_regspec_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;
typedef enum { PSYCHO, SCHIZO } pci_bridge_t;
typedef enum { A, B } pci_side_t;
typedef enum { PCI_NEW, PCI_ATTACHED, PCI_DETACHED, PCI_SUSPENDED } pci_state_t;
typedef enum { PCI_PBM_OBJ, PCI_ECC_OBJ, PCI_CB_OBJ } pci_obj_t;
typedef enum { PCI_OBJ_INTR_ADD, PCI_OBJ_INTR_REMOVE } pci_obj_op_t;
#define PCI_ATTACH_RETCODE(obj, op, err) \
((err) ? (obj) << 8 | (op) << 4 | (err) & 0xf : DDI_SUCCESS)
#define PCI_OTHER_SIDE(side) ((side) ^ 1)
/*
* the sequence of the chip_type appearance is significant. There are code
* depending on it: CHIP_TYPE(pci_p) < PCI_CHIP_SCHIZO.
*/
typedef enum {
PCI_CHIP_UNIDENTIFIED = 0,
PCI_CHIP_PSYCHO = 1,
PCI_CHIP_SABRE,
PCI_CHIP_HUMMINGBIRD,
PCI_CHIP_SCHIZO = 0x11,
PCI_CHIP_XMITS,
PCI_CHIP_TOMATILLO
} pci_chip_id_t;
/*
* [msb] [lsb]
* 0x00 <chip_type> <version#> <module-revision#>
*/
#define CHIP_ID(t, v, m) (((t) << 16) | ((v) << 8) | (m))
#define ID_CHIP_TYPE(id) ((id) >> 16)
#define PCI_CHIP_ID(pci_p) ((pci_p)->pci_common_p->pci_chip_id)
#define CHIP_TYPE(pci_p) ID_CHIP_TYPE(PCI_CHIP_ID(pci_p))
#define CHIP_REV(pci_p) (PCI_CHIP_ID(pci_p) & 0xFF)
#define CHIP_VER(pci_p) ((PCI_CHIP_ID(pci_p) >> 8) & 0xFF)
#define CB_CHIP_TYPE(cb_p) ((cb_p)->cb_pci_cmn_p->pci_chip_id >> 16)
/*
* 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 {
uint_t pci_common_id;
/* pointers & counters to facilitate attach/detach & suspend/resume */
ushort_t pci_common_refcnt; /* # of sides suspended + attached */
ushort_t pci_common_attachcnt; /* # of sides attached */
uint16_t pci_common_tsb_cookie; /* IOMMU TSB allocation */
pci_t *pci_p[2]; /* pci soft states of both sides */
uint32_t pci_chip_id; /* Bus bridge chip identification */
/* Links to functional blocks potentially 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;
/*
* Performance counters kstat.
*/
pci_cntr_pa_t pci_cmn_uks_pa;
kstat_t *pci_common_uksp; /* ptr to upstream kstat */
kmutex_t pci_fm_mutex; /* per chip error handling mutex */
};
/*
* 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;
#define PCI_SOFT_STATE_OPEN 0x01
#define PCI_SOFT_STATE_OPEN_EXCL 0x02
#define PCI_SOFT_STATE_CLOSED 0x04
uint_t pci_open_count;
uint16_t pci_tsb_cookie; /* IOMMU TSB allocation */
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:
*/
uint_t pci_id; /* UPA (or Safari) device id */
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_inos; /* inos from "interrupts" prop */
int pci_inos_len; /* "interrupts" length */
int pci_numproxy; /* upa interrupt proxies */
int pci_thermal_interrupt; /* node has thermal interrupt */
/*
* register mapping:
*/
caddr_t pci_address[4];
ddi_acc_handle_t pci_ac[4];
/* Interrupt support */
int intr_map_size;
struct intr_map *intr_map;
struct intr_map_mask *intr_map_mask;
/* performance counters */
pci_cntr_addr_t pci_ks_addr;
kstat_t *pci_ksp;
/* Hotplug information */
boolean_t hotplug_capable;
/* Fault Management support */
int pci_fm_cap;
ddi_iblock_cookie_t pci_fm_ibc;
};
/*
* 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))
#define DEV_TO_SOFTSTATE(dev) ((pci_t *)ddi_get_soft_state(per_pci_state, \
PCIHP_AP_MINOR_NUM_TO_INSTANCE(getminor(dev))))
extern void *per_pci_state; /* per-pbm soft state pointer */
extern void *per_pci_common_state; /* per-psycho soft state pointer */
extern kmutex_t pci_global_mutex; /* attach/detach common struct lock */
extern kmutex_t dvma_active_list_mutex;
/*
* function prototypes for bus ops routines:
*/
extern int
pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
off_t offset, off_t len, caddr_t *addrp);
extern int
pci_dma_setup(dev_info_t *dip, dev_info_t *rdip,
ddi_dma_req_t *dmareq, ddi_dma_handle_t *handlep);
extern int
pci_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *attrp,
int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep);
extern int
pci_dma_bindhdl(dev_info_t *dip, dev_info_t *rdip,
ddi_dma_handle_t handle, ddi_dma_req_t *dmareq,
ddi_dma_cookie_t *cookiep, uint_t *ccountp);
extern int
pci_dma_unbindhdl(dev_info_t *dip, dev_info_t *rdip,
ddi_dma_handle_t handle);
extern int
pci_dma_flush(dev_info_t *dip, dev_info_t *rdip,
ddi_dma_handle_t handle, off_t off, size_t len,
uint_t cache_flags);
extern int
pci_dma_ctlops(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle,
enum ddi_dma_ctlops cmd, off_t *offp, size_t *lenp, caddr_t *objp,
uint_t cache_flags);
extern int
pci_ctlops(dev_info_t *dip, dev_info_t *rdip,
ddi_ctl_enum_t op, void *arg, void *result);
extern int
pci_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
ddi_intr_handle_impl_t *handle, void *result);
#ifdef __cplusplus
}
#endif
#endif /* _SYS_PCI_VAR_H */