1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_PCIE_HP_H 27 #define _SYS_PCIE_HP_H 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #ifdef _KERNEL 34 #include <sys/ddi_hp.h> 35 #include <sys/pcie_impl.h> 36 #endif /* _KERNEL */ 37 #include "../../../../../common/pci/pci_strings.h" 38 #include <sys/hotplug/pci/pcihp.h> 39 40 #define PCIEHPC_PROP_HELP "help" 41 #define PCIEHPC_PROP_ALL "all" 42 #define PCIEHPC_PROP_LED_FAULT "fault_led" 43 #define PCIEHPC_PROP_LED_POWER "power_led" 44 #define PCIEHPC_PROP_LED_ATTN "attn_led" 45 #define PCIEHPC_PROP_LED_ACTIVE "active_led" 46 #define PCIEHPC_PROP_CARD_TYPE "card_type" 47 #define PCIEHPC_PROP_BOARD_TYPE "board_type" 48 #define PCIEHPC_PROP_SLOT_CONDITION "slot_condition" 49 50 #define PCIEHPC_PROP_VALUE_UNKNOWN "unknown" 51 #define PCIEHPC_PROP_VALUE_ON "on" 52 #define PCIEHPC_PROP_VALUE_OFF "off" 53 #define PCIEHPC_PROP_VALUE_BLINK "blink" 54 #define PCIEHPC_PROP_VALUE_PCIHOTPLUG "pci hotplug" 55 #define PCIEHPC_PROP_VALUE_OK "ok" 56 #define PCIEHPC_PROP_VALUE_FAILING "failing" 57 #define PCIEHPC_PROP_VALUE_FAILED "failed" 58 #define PCIEHPC_PROP_VALUE_UNUSABLE "unusable" 59 #define PCIEHPC_PROP_VALUE_LED "<on|off|blink>" 60 #define PCIEHPC_PROP_VALUE_TYPE "<type description>" 61 #define PCIEHPC_PROP_VALUE_CONDITION "<unknown|ok|failing|failed|unusable>" 62 63 /* condition */ 64 #define PCIEHPC_PROP_COND_OK "ok" 65 #define PCIEHPC_PROP_COND_FAILING "failing" 66 #define PCIEHPC_PROP_COND_FAILED "failed" 67 #define PCIEHPC_PROP_COND_UNUSABLE "unusable" 68 #define PCIEHPC_PROP_COND_UNKNOWN "unknown" 69 70 #ifdef _KERNEL 71 72 #define PCIE_HP_MAX_SLOTS 31 /* Max # of slots */ 73 #define PCIE_HP_CMD_WAIT_TIME 10000 /* Delay in microseconds */ 74 #define PCIE_HP_CMD_WAIT_RETRY 100 /* Max retry count */ 75 #define PCIE_HP_DLL_STATE_CHANGE_TIMEOUT 1 /* Timeout in seconds */ 76 #define PCIE_HP_POWER_GOOD_WAIT_TIME 220000 /* Wait time after issuing a */ 77 /* cmd to change slot state */ 78 79 /* definations for PCIEHPC/PCISHPC */ 80 #define PCIE_NATIVE_HP_TYPE "PCIe-Native" /* PCIe Native type */ 81 #define PCIE_ACPI_HP_TYPE "PCIe-ACPI" /* PCIe ACPI type */ 82 #define PCIE_PROP_HP_TYPE "PCIe-Proprietary" /* PCIe Prop type */ 83 #define PCIE_PCI_HP_TYPE "PCI-SHPC" /* PCI (SHPC) type */ 84 85 #define PCIE_GET_HP_CTRL(dip) \ 86 (pcie_hp_ctrl_t *)PCIE_DIP2BUS(dip)->bus_hp_ctrl 87 88 #define PCIE_SET_HP_CTRL(dip, ctrl_p) \ 89 (PCIE_DIP2BUS(dip)->bus_hp_ctrl) = (pcie_hp_ctrl_t *)ctrl_p 90 91 #define PCIE_IS_PCIE_HOTPLUG_CAPABLE(bus_p) \ 92 ((bus_p->bus_hp_sup_modes & PCIE_ACPI_HP_MODE) || \ 93 (bus_p->bus_hp_sup_modes & PCIE_NATIVE_HP_MODE)) 94 95 #define PCIE_IS_PCI_HOTPLUG_CAPABLE(bus_p) \ 96 (bus_p->bus_hp_sup_modes & PCIE_PCI_HP_MODE) 97 98 #define PCIE_IS_PCIE_HOTPLUG_ENABLED(bus_p) \ 99 ((bus_p->bus_hp_curr_mode == PCIE_ACPI_HP_MODE) || \ 100 (bus_p->bus_hp_curr_mode == PCIE_NATIVE_HP_MODE)) 101 102 #define PCIE_IS_PCI_HOTPLUG_ENABLED(bus_p) \ 103 (bus_p->bus_hp_curr_mode & PCIE_PCI_HP_MODE) 104 105 typedef struct pcie_hp_ctrl pcie_hp_ctrl_t; 106 typedef struct pcie_hp_slot pcie_hp_slot_t; 107 108 /* 109 * Maximum length of the string converted from the digital number of pci device 110 * number and function number, including the string's end mark. For example, 111 * device number 0 and function number 255 (ARI case), then the length is 112 * (1 + 3 + 1). 113 */ 114 #define PCIE_HP_DEV_FUNC_NUM_STRING_LEN 5 115 116 /* 117 * Length of the characters in a PCI port name. 118 * The format of the PCI port name is: pci.d,f where d is device number, f is 119 * function number. The constant string and characters are "pci." and ",". 120 */ 121 #define PCIE_HP_PORT_NAME_STRING_LEN 5 122 123 /* Platform specific ops (Native HP, ACPI, etc.) */ 124 typedef struct pcie_hp_ops { 125 /* initialize/setup hot plug controller hw */ 126 int (*init_hpc_hw)(pcie_hp_ctrl_t *ctrl_p); 127 128 /* uninitialize hot plug controller hw */ 129 int (*uninit_hpc_hw)(pcie_hp_ctrl_t *ctrl_p); 130 131 /* initialize slot information structure */ 132 int (*init_hpc_slotinfo)(pcie_hp_ctrl_t *ctrl_p); 133 134 /* uninitialize slot information structure */ 135 int (*uninit_hpc_slotinfo)(pcie_hp_ctrl_t *ctrl_p); 136 137 /* slot poweron */ 138 int (*poweron_hpc_slot)(pcie_hp_slot_t *slot_p, 139 ddi_hp_cn_state_t *result); 140 141 /* slot poweroff */ 142 /* uninitialize hot plug controller hw */ 143 int (*poweroff_hpc_slot)(pcie_hp_slot_t *slot_p, 144 ddi_hp_cn_state_t *result); 145 146 /* enable hot plug interrupts/events */ 147 int (*enable_hpc_intr)(pcie_hp_ctrl_t *ctrl_p); 148 149 /* disable hot plug interrupts/events */ 150 int (*disable_hpc_intr)(pcie_hp_ctrl_t *ctrl_p); 151 } pcie_hp_ops_t; 152 153 /* Slot occupant information structure */ 154 #define PCIE_HP_MAX_OCCUPANTS 128 155 typedef struct pcie_hp_occupant_info { 156 int i; 157 char *id[PCIE_HP_MAX_OCCUPANTS]; 158 } pcie_hp_occupant_info_t; 159 160 /* 161 * pcie_hp_led_t 162 * 163 * Type definitions for LED type 164 */ 165 typedef enum { 166 PCIE_HP_FAULT_LED, 167 PCIE_HP_POWER_LED, 168 PCIE_HP_ATTN_LED, 169 PCIE_HP_ACTIVE_LED 170 } pcie_hp_led_t; 171 172 /* 173 * pcie_hp_led_state_t 174 * 175 * Type definitions for LED state 176 */ 177 typedef enum { 178 PCIE_HP_LED_OFF, 179 PCIE_HP_LED_ON, 180 PCIE_HP_LED_BLINK 181 } pcie_hp_led_state_t; 182 183 /* 184 * PCI and PCI Express Hotplug slot structure 185 */ 186 struct pcie_hp_slot { 187 uint32_t hs_num; /* Logical slot number */ 188 uint32_t hs_phy_slot_num; /* Physical slot number */ 189 uint32_t hs_device_num; /* PCI device num for slot */ 190 uint16_t hs_minor; /* Minor num for this slot */ 191 ddi_hp_cn_info_t hs_info; /* Slot information */ 192 ddi_hp_cn_state_t hs_state; /* Slot state */ 193 194 pcie_hp_led_state_t hs_power_led_state; /* Power LED state */ 195 pcie_hp_led_state_t hs_attn_led_state; /* Attn LED state */ 196 pcie_hp_led_state_t hs_active_led_state; /* Active LED state */ 197 pcie_hp_led_state_t hs_fault_led_state; /* Fault LED state */ 198 199 ap_condition_t hs_condition; /* Condition of the slot. */ 200 /* For cfgadm condition. */ 201 202 /* Synchronization variable(s) for hot plug events */ 203 kcondvar_t hs_attn_btn_cv; /* ATTN button pressed intr */ 204 boolean_t hs_attn_btn_pending; 205 kthread_t *hs_attn_btn_threadp; /* ATTN button event thread */ 206 boolean_t hs_attn_btn_thread_exit; 207 kcondvar_t hs_dll_active_cv; /* DLL State Changed intr */ 208 209 pcie_hp_ctrl_t *hs_ctrl; /* Hotplug ctrl for this slot */ 210 }; 211 212 /* 213 * Register ops for read/write of non-standard HPC (e.g: OPL platform). 214 */ 215 typedef struct pcie_hp_regops { 216 uint_t (*get)(void *cookie, off_t offset); 217 uint_t (*put)(void *cookie, off_t offset, uint_t val); 218 void *cookie; 219 } pcie_hp_regops_t; 220 221 /* 222 * PCI and PCI Express Hotplug controller structure 223 */ 224 struct pcie_hp_ctrl { 225 dev_info_t *hc_dip; /* DIP for HP controller */ 226 kmutex_t hc_mutex; /* Mutex for this ctrl */ 227 uint_t hc_flags; /* Misc flags */ 228 229 /* Slot information */ 230 pcie_hp_slot_t *hc_slots[PCIE_HP_MAX_SLOTS]; /* Slot pointers */ 231 boolean_t hc_has_attn; /* Do we have attn btn? */ 232 boolean_t hc_has_mrl; /* Do we have MRL? */ 233 kcondvar_t hc_cmd_comp_cv; /* Command Completion intr */ 234 boolean_t hc_cmd_pending; /* Command completion pending */ 235 236 /* PCI Express Hotplug specific fields */ 237 boolean_t hc_has_emi_lock; /* Do we have EMI Lock? */ 238 boolean_t hc_dll_active_rep; /* Report DLL DL_Active state */ 239 pcie_hp_ops_t hc_ops; /* Platform specific ops */ 240 /* (Native, ACPI) */ 241 242 /* PCI Hotplug (SHPC) specific fields */ 243 uint32_t hc_num_slots_impl; /* # of HP Slots Implemented */ 244 uint32_t hc_num_slots_connected; /* # of HP Slots Connected */ 245 int hc_curr_bus_speed; /* Current Bus Speed */ 246 uint32_t hc_device_start; /* 1st PCI Device # */ 247 uint32_t hc_phys_start; /* 1st Phys Device # */ 248 uint32_t hc_device_increases; /* Device # Increases */ 249 boolean_t hc_arbiter_timeout; /* Got a Arb timeout IRQ */ 250 251 /* Register read/write ops for non-standard HPC (e.g: OPL) */ 252 pcie_hp_regops_t hc_regops; 253 254 /* Platform implementation specific data if any: ACPI, CK804,... */ 255 void *hc_misc_data; 256 }; 257 258 /* 259 * Control structure for tree walk during configure/unconfigure operation. 260 */ 261 typedef struct pcie_hp_cn_cfg_t { 262 void *slotp; 263 boolean_t flag; /* Flag to ignore errors */ 264 int rv; /* Return error code */ 265 dev_info_t *dip; /* dip at which the (first) */ 266 /* error occurred */ 267 void *cn_private; /* Connection specific data */ 268 } pcie_hp_cn_cfg_t; 269 270 /* 271 * arg for unregistering port of a pci bridge 272 */ 273 typedef struct pcie_hp_unreg_port { 274 /* pci bridge dip to which the port is associated */ 275 dev_info_t *nexus_dip; 276 /* 277 * Connector number of the physical slot whose dependent ports will be 278 * unregistered. If NULL, then all the ports of the pci bridge dip will 279 * be unregistered. 280 */ 281 int connector_num; 282 int rv; 283 } pcie_hp_unreg_port_t; 284 285 /* 286 * arg for getting a port's state 287 */ 288 typedef struct pcie_hp_port_state { 289 char *cn_name; 290 ddi_hp_cn_state_t cn_state; 291 int rv; 292 } pcie_hp_port_state_t; 293 294 /* hc_flags */ 295 #define PCIE_HP_INITIALIZED_FLAG (1 << 0) /* HPC initialized */ 296 297 /* PCIe hotplug friendly functions */ 298 extern int pcie_hp_init(dev_info_t *dip, caddr_t arg); 299 extern int pcie_hp_uninit(dev_info_t *dip); 300 extern int pcie_hp_intr(dev_info_t *dip); 301 extern int pcie_hp_probe(pcie_hp_slot_t *slot_p); 302 extern int pcie_hp_unprobe(pcie_hp_slot_t *slot_p); 303 extern int pcie_hp_common_ops(dev_info_t *dip, char *cn_name, ddi_hp_op_t op, 304 void *arg, void *result); 305 extern dev_info_t *pcie_hp_devi_find(dev_info_t *dip, uint_t device, 306 uint_t function); 307 extern void pcie_hp_create_occupant_props(dev_info_t *self, dev_t dev, 308 int pci_dev); 309 extern void pcie_hp_create_occupant_props(dev_info_t *self, dev_t dev, 310 int pci_dev); 311 extern void pcie_hp_delete_occupant_props(dev_info_t *dip, dev_t dev); 312 extern int pcie_copyin_nvlist(char *packed_buf, size_t packed_sz, 313 nvlist_t **nvlp); 314 extern int pcie_copyout_nvlist(nvlist_t *nvl, char *packed_buf, 315 size_t *packed_sz); 316 extern char *pcie_led_state_text(pcie_hp_led_state_t state); 317 extern char *pcie_slot_condition_text(ap_condition_t condition); 318 extern int pcie_create_minor_node(pcie_hp_ctrl_t *, int); 319 extern void pcie_remove_minor_node(pcie_hp_ctrl_t *, int); 320 extern void pcie_hp_gen_sysevent_req(char *slot_name, int hint, 321 dev_info_t *self, int kmflag); 322 323 extern const struct pci_class_strings_s class_pci[]; 324 extern int class_pci_items; 325 326 #endif /* _KERNEL */ 327 328 #ifdef __cplusplus 329 } 330 #endif 331 332 #endif /* _SYS_PCIE_HP_H */ 333