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 * This file provides prototype function definitions. 27 */ 28 #ifndef _PMCS_PROTO_H 29 #define _PMCS_PROTO_H 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 35 typedef enum { 36 PMCS_PRT_DEBUG = 0, 37 PMCS_PRT_DEBUG1, 38 PMCS_PRT_DEBUG2, 39 PMCS_PRT_DEBUG3, 40 PMCS_PRT_DEBUG_CONFIG, 41 PMCS_PRT_DEBUG_IPORT, 42 PMCS_PRT_DEBUG_MAP, 43 PMCS_PRT_DEBUG_UNDERFLOW, 44 PMCS_PRT_DEBUG_SCSI_STATUS, 45 PMCS_PRT_DEBUG_PHY_LOCKING, 46 PMCS_PRT_DEBUG_DEV_STATE, 47 PMCS_PRT_DEBUG_DEVEL, 48 PMCS_PRT_INFO, 49 PMCS_PRT_WARN, 50 PMCS_PRT_ERR 51 } pmcs_prt_level_t; 52 53 #define pmcs_prt(pwp, level, fmt...) { \ 54 int lvl = level; \ 55 if (((pwp->debug_mask & (1 << lvl)) != 0) || \ 56 (lvl > PMCS_PRT_DEBUG_DEVEL)) { \ 57 pmcs_prt_impl(pwp, lvl, fmt); \ 58 } \ 59 } 60 61 /*PRINTFLIKE3*/ 62 void 63 pmcs_prt_impl(pmcs_hw_t *, pmcs_prt_level_t, const char *, ...) 64 __KPRINTFLIKE(3); 65 66 boolean_t pmcs_assign_device(pmcs_hw_t *, pmcs_xscsi_t *); 67 void pmcs_remove_device(pmcs_hw_t *, pmcs_phy_t *); 68 void pmcs_handle_dead_phys(pmcs_hw_t *); 69 70 int pmcs_acquire_scratch(pmcs_hw_t *, boolean_t); 71 void pmcs_release_scratch(pmcs_hw_t *); 72 73 /* get a work structure */ 74 pmcwork_t *pmcs_gwork(pmcs_hw_t *, uint32_t, pmcs_phy_t *); 75 76 /* put a work structure */ 77 void pmcs_pwork(pmcs_hw_t *, struct pmcwork *); 78 79 /* given a tag, find a work structure */ 80 pmcwork_t *pmcs_tag2wp(pmcs_hw_t *, uint32_t); 81 82 /* 83 * Abort function 84 */ 85 int pmcs_abort(pmcs_hw_t *, pmcs_phy_t *, uint32_t, int, int); 86 87 /* 88 * SSP Task Management Function 89 */ 90 int pmcs_ssp_tmf(pmcs_hw_t *, pmcs_phy_t *, uint8_t, uint32_t, uint64_t, 91 uint32_t *); 92 93 /* 94 * Abort NCQ function 95 */ 96 int pmcs_sata_abort_ncq(pmcs_hw_t *, pmcs_phy_t *); 97 98 /* 99 * Interrupt Functions 100 */ 101 void pmcs_general_intr(pmcs_hw_t *); 102 void pmcs_iodone_intr(pmcs_hw_t *); 103 void pmcs_event_intr(pmcs_hw_t *); 104 void pmcs_timed_out(pmcs_hw_t *, uint32_t, const char *); 105 106 /* 107 * Abort handler 108 */ 109 int pmcs_abort_handler(pmcs_hw_t *); 110 111 /* 112 * Deregister all expander connected devices 113 */ 114 void pmcs_deregister_devices(pmcs_hw_t *, pmcs_phy_t *); 115 int pmcs_register_device(pmcs_hw_t *, pmcs_phy_t *); 116 void pmcs_deregister_device(pmcs_hw_t *, pmcs_phy_t *); 117 118 /* 119 * endian transform a data structure 120 */ 121 void pmcs_endian_transform(pmcs_hw_t *, void *, void *, const uint8_t *); 122 123 /* get the connection rate string */ 124 const char *pmcs_get_rate(unsigned int); 125 126 /* get the device type string */ 127 const char *pmcs_get_typename(pmcs_dtype_t pmcs_dtype); 128 129 /* get the SAS Task Management function name */ 130 const char *pmcs_tmf2str(int); 131 132 /* get the PMC status string */ 133 const char *pmcs_status_str(uint32_t); 134 135 /* 136 * WWN to Byte Array and vice versa conversion 137 */ 138 uint64_t pmcs_barray2wwn(uint8_t[8]); 139 void pmcs_wwn2barray(uint64_t, uint8_t[8]); 140 141 /* 142 * Print f/w version 143 */ 144 void pmcs_report_fwversion(pmcs_hw_t *); 145 146 /* 147 * Build a device name. 148 */ 149 void pmcs_phy_name(pmcs_hw_t *, pmcs_phy_t *, char *, size_t); 150 151 /* 152 * Find a PHY by device_id 153 */ 154 pmcs_phy_t *pmcs_find_phy_by_devid(pmcs_hw_t *, uint32_t); 155 156 /* 157 * Find a PHY by wwn 158 */ 159 pmcs_phy_t *pmcs_find_phy_by_wwn(pmcs_hw_t *, uint64_t); 160 161 /* 162 * Find a PHY by sas_address 163 */ 164 pmcs_phy_t *pmcs_find_phy_by_sas_address(pmcs_hw_t *, pmcs_iport_t *, 165 pmcs_phy_t *, char *); 166 167 /* 168 * Print out a FIS 169 */ 170 void pmcs_fis_dump(pmcs_hw_t *, fis_t); 171 172 /* 173 * Print an IOMB 174 */ 175 void pmcs_print_entry(pmcs_hw_t *, int, char *, void *); 176 177 void pmcs_spinup_release(pmcs_hw_t *, pmcs_phy_t *phyp); 178 179 /* 180 * Handler for events - can be called from interrupt level or from worker thread 181 */ 182 void pmcs_ack_events(pmcs_hw_t *); 183 184 /* 185 * This function does some initial setup and hardware validation 186 */ 187 int pmcs_setup(pmcs_hw_t *); 188 189 /* 190 * These functions start and stop the MPI (message passing interface) 191 */ 192 int pmcs_start_mpi(pmcs_hw_t *); 193 int pmcs_stop_mpi(pmcs_hw_t *); 194 195 /* 196 * This function checks firmware revisions against required revisions 197 * and attempts to flash new firmware (if possible). 198 */ 199 int pmcs_firmware_update(pmcs_hw_t *); 200 201 /* 202 * This function runs ECHO commands to test both interrupts and queues 203 */ 204 int pmcs_echo_test(pmcs_hw_t *); 205 206 /* 207 * These functions start, reset, and stop the physical chip PHYs 208 */ 209 int pmcs_start_phy(pmcs_hw_t *, int, int, int); 210 int pmcs_start_phys(pmcs_hw_t *); 211 void pmcs_stop_phy(pmcs_hw_t *, int); 212 void pmcs_stop_phys(pmcs_hw_t *); 213 214 /* 215 * These functions setup/teardown iport tgtmap 216 */ 217 int pmcs_iport_tgtmap_create(pmcs_iport_t *); 218 int pmcs_iport_tgtmap_destroy(pmcs_iport_t *); 219 220 /* 221 * Utility and wrapper functions for SAS_DIAG_EXECUTE 222 */ 223 int pmcs_sas_diag_execute(pmcs_hw_t *, uint32_t, uint32_t, uint8_t); 224 int pmcs_get_diag_report(pmcs_hw_t *, uint32_t, uint8_t); 225 int pmcs_clear_diag_counters(pmcs_hw_t *, uint8_t); 226 227 /* 228 * Get current firmware timestamp 229 */ 230 int pmcs_get_time_stamp(pmcs_hw_t *, uint64_t *); 231 232 /* 233 * Register Dump (including "internal" registers) 234 */ 235 void pmcs_register_dump(pmcs_hw_t *); 236 void pmcs_iqp_trace(pmcs_hw_t *, uint32_t); 237 void pmcs_register_dump_int(pmcs_hw_t *); 238 int pmcs_dump_binary(pmcs_hw_t *, uint32_t *, uint32_t, 239 uint32_t, caddr_t, uint32_t); 240 int pmcs_dump_feregs(pmcs_hw_t *, uint32_t *, uint8_t, 241 caddr_t, uint32_t); 242 243 /* 244 * This function perform a soft reset. 245 * Hard reset is platform specific. 246 */ 247 int pmcs_soft_reset(pmcs_hw_t *, boolean_t); 248 249 /* 250 * Some more reset functions 251 */ 252 int pmcs_reset_dev(pmcs_hw_t *, pmcs_phy_t *, uint64_t); 253 int pmcs_reset_phy(pmcs_hw_t *, pmcs_phy_t *, uint8_t); 254 255 /* 256 * These functions do topology configuration changes 257 */ 258 void pmcs_discover(pmcs_hw_t *); 259 void pmcs_set_changed(pmcs_hw_t *, pmcs_phy_t *, boolean_t, int); 260 void pmcs_kill_changed(pmcs_hw_t *, pmcs_phy_t *, int); 261 void pmcs_clear_phy(pmcs_hw_t *, pmcs_phy_t *); 262 int pmcs_kill_device(pmcs_hw_t *, pmcs_phy_t *); 263 264 /* 265 * Firmware flash function 266 */ 267 int pmcs_fw_flash(pmcs_hw_t *, pmcs_fw_hdr_t *, uint32_t); 268 269 /* 270 * Set a new value for the interrupt coalescing timer. If it's being set 271 * to zero (disabling), then re-enable auto clear if necessary. If it's 272 * being changed from zero, turn off auto clear if it was on. 273 */ 274 typedef enum { 275 DECREASE_TIMER = 0, 276 INCREASE_TIMER 277 } pmcs_coal_timer_adj_t; 278 279 void pmcs_check_intr_coal(void *arg); 280 void pmcs_set_intr_coal_timer(pmcs_hw_t *pwp, pmcs_coal_timer_adj_t adj); 281 282 /* 283 * Misc supporting routines 284 */ 285 void pmcs_check_iomb_status(pmcs_hw_t *pwp, uint32_t *iomb); 286 void pmcs_clear_xp(pmcs_hw_t *, pmcs_xscsi_t *); 287 288 int pmcs_run_sata_cmd(pmcs_hw_t *, pmcs_phy_t *, fis_t, uint32_t, 289 uint32_t, uint32_t); 290 int pmcs_sata_identify(pmcs_hw_t *, pmcs_phy_t *); 291 void pmcs_sata_work(pmcs_hw_t *); 292 boolean_t pmcs_dma_setup(pmcs_hw_t *pwp, ddi_dma_attr_t *dma_attr, 293 ddi_acc_handle_t *acch, ddi_dma_handle_t *dmah, size_t length, 294 caddr_t *kvp, uint64_t *dma_addr); 295 void pmcs_fm_ereport(pmcs_hw_t *pwp, char *detail); 296 int pmcs_check_dma_handle(ddi_dma_handle_t handle); 297 int pmcs_check_acc_handle(ddi_acc_handle_t handle); 298 int pmcs_check_acc_dma_handle(pmcs_hw_t *pwp); 299 int pmcs_get_nvmd(pmcs_hw_t *pwp, pmcs_nvmd_type_t nvmd_type, uint8_t nvmd, 300 uint32_t offset, char *buf, uint32_t size_left); 301 boolean_t pmcs_set_nvmd(pmcs_hw_t *pwp, pmcs_nvmd_type_t nvmd_type, 302 uint8_t *buf, size_t len); 303 void pmcs_complete_work_impl(pmcs_hw_t *pwp, pmcwork_t *pwrk, uint32_t *iomb, 304 size_t amt); 305 void pmcs_flush_target_queues(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t); 306 boolean_t pmcs_iport_has_targets(pmcs_hw_t *, pmcs_iport_t *); 307 void pmcs_free_dma_chunklist(pmcs_hw_t *); 308 int pmcs_get_dev_state(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t *); 309 int pmcs_set_dev_state(pmcs_hw_t *, pmcs_xscsi_t *, uint8_t); 310 void pmcs_dev_state_recovery(pmcs_hw_t *, pmcs_phy_t *); 311 int pmcs_send_err_recovery_cmd(pmcs_hw_t *, uint8_t, pmcs_xscsi_t *); 312 void pmcs_start_ssp_event_recovery(pmcs_hw_t *pwp, pmcwork_t *pwrk, 313 uint32_t *iomb, size_t amt); 314 void pmcs_ssp_event_recovery(pmcs_hw_t *); 315 316 pmcs_iport_t *pmcs_get_iport_by_phy(pmcs_hw_t *pwp, pmcs_phy_t *pptr); 317 void pmcs_rele_iport(pmcs_iport_t *iport); 318 int pmcs_iport_configure_phys(pmcs_iport_t *iport); 319 320 void pmcs_lock_phy(pmcs_phy_t *); 321 void pmcs_unlock_phy(pmcs_phy_t *); 322 323 void pmcs_destroy_target(pmcs_xscsi_t *); 324 void pmcs_phymap_activate(void *, char *, void **); 325 void pmcs_phymap_deactivate(void *, char *, void *); 326 void pmcs_add_phy_to_iport(pmcs_iport_t *, pmcs_phy_t *); 327 void pmcs_remove_phy_from_iport(pmcs_iport_t *, pmcs_phy_t *); 328 void pmcs_free_all_phys(pmcs_hw_t *, pmcs_phy_t *); 329 void pmcs_free_phys(pmcs_hw_t *, pmcs_phy_t *); 330 331 int pmcs_phy_constructor(void *, void *, int); 332 void pmcs_phy_destructor(void *, void *); 333 334 void pmcs_inc_phy_ref_count(pmcs_phy_t *); 335 void pmcs_dec_phy_ref_count(pmcs_phy_t *); 336 337 /* Worker thread */ 338 void pmcs_worker(void *); 339 340 pmcs_phy_t *pmcs_get_root_phy(pmcs_phy_t *); 341 pmcs_xscsi_t *pmcs_get_target(pmcs_iport_t *, char *); 342 343 void pmcs_fatal_handler(pmcs_hw_t *); 344 345 /* 346 * Schedule device state recovery for this device immediately 347 */ 348 void pmcs_start_dev_state_recovery(pmcs_xscsi_t *, pmcs_phy_t *); 349 350 #ifdef __cplusplus 351 } 352 #endif 353 #endif /* _PMCS_PROTO_H */ 354