/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (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 2006 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 "reg" property of a PCI nexus. */ typedef struct pci_nexus_regspec { uint64_t phys_addr; uint64_t size; } pci_nexus_regspec_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 */ #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 */