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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 28 #ifndef _AHCIVAR_H 29 #define _AHCIVAR_H 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 /* Type for argument of event handler */ 38 typedef struct ahci_event_arg { 39 void *ahciea_ctlp; 40 void *ahciea_portp; 41 uint32_t ahciea_event; 42 } ahci_event_arg_t; 43 44 /* Warlock annotation */ 45 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_ctlp)) 46 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_portp)) 47 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_event)) 48 49 /* 50 * flags for ahciport_flags 51 * 52 * AHCI_PORT_FLAG_SPINUP: this flag will be set when a HBA which supports 53 * staggered spin-up needs to do a spin-up. 54 * 55 * AHCI_PORT_FLAG_MOPPING: this flag will be set when the HBA is stopped, 56 * and all the outstanding commands need to be aborted and sent to upper 57 * layers. 58 * 59 * AHCI_PORT_FLAG_POLLING: this flag will be set when the interrupt is 60 * disabled, and the command is executed in POLLING mode. 61 * 62 * AHCI_PORT_FLAG_RQSENSE: this flag will be set when a REQUEST SENSE which 63 * is used to retrieve sense data is being executed. 64 * 65 * AHCI_PORT_FLAG_STARTED: this flag will be set when the port is started, 66 * that is PxCMD.ST is set with '1', and be cleared when the port is put into 67 * idle, that is PxCMD.ST is changed from '1' to '0'. 68 * 69 * AHCI_PORT_FLAG_RDLOGEXT: this flag will be set when a READ LOG EXT which 70 * is used to retrieve NCQ failure context is being executed. 71 * 72 * AHCI_PORT_FLAG_NODEV: this flag will be set when a device is found gone 73 * during ahci_restart_port_wait_till_ready process. 74 */ 75 #define AHCI_PORT_FLAG_SPINUP 0x01 76 #define AHCI_PORT_FLAG_MOPPING 0x02 77 #define AHCI_PORT_FLAG_POLLING 0x04 78 #define AHCI_PORT_FLAG_RQSENSE 0x08 79 #define AHCI_PORT_FLAG_STARTED 0x10 80 #define AHCI_PORT_FLAG_RDLOGEXT 0x20 81 #define AHCI_PORT_FLAG_NODEV 0x40 82 83 typedef struct ahci_port { 84 /* The physical port number */ 85 uint8_t ahciport_port_num; 86 87 /* Type of the device attached to the port */ 88 uint8_t ahciport_device_type; 89 /* State of the port */ 90 uint32_t ahciport_port_state; 91 92 /* 93 * AHCI_PORT_FLAG_SPINUP 94 * AHCI_PORT_FLAG_MOPPING 95 * AHCI_PORT_FLAG_POLLING 96 * AHCI_PORT_FLAG_RQSENSE 97 * AHCI_PORT_FLAG_STARTED 98 * AHCI_PORT_FLAG_RDLOGEXT 99 * AHCI_PORT_FLAG_NODEV 100 */ 101 int ahciport_flags; 102 103 /* Pointer to received FIS structure */ 104 ahci_rcvd_fis_t *ahciport_rcvd_fis; 105 ddi_dma_handle_t ahciport_rcvd_fis_dma_handle; 106 ddi_acc_handle_t ahciport_rcvd_fis_acc_handle; 107 ddi_dma_cookie_t ahciport_rcvd_fis_dma_cookie; 108 109 /* Pointer to command list structure */ 110 ahci_cmd_header_t *ahciport_cmd_list; 111 ddi_dma_handle_t ahciport_cmd_list_dma_handle; 112 ddi_acc_handle_t ahciport_cmd_list_acc_handle; 113 ddi_dma_cookie_t ahciport_cmd_list_dma_cookie; 114 115 /* Pointer to cmmand table structure */ 116 ahci_cmd_table_t \ 117 *ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS]; 118 ddi_dma_handle_t \ 119 ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS]; 120 ddi_acc_handle_t \ 121 ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS]; 122 123 /* Condition variable used for sync mode commands */ 124 kcondvar_t ahciport_cv; 125 126 /* The whole mutex for the port structure */ 127 kmutex_t ahciport_mutex; 128 129 /* The maximum number of tags for native queuing command transfers */ 130 int ahciport_max_ncq_tags; 131 132 /* Keep the tags of all pending non-ncq commands */ 133 uint32_t ahciport_pending_tags; 134 135 /* 136 * Keep the tags of all pending ncq commands 137 * (READ/WRITE FPDMA QUEUED) 138 */ 139 uint32_t ahciport_pending_ncq_tags; 140 141 /* Keep all the pending sata packets */ 142 sata_pkt_t *ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS]; 143 144 /* Keep the error retrieval sata packet */ 145 sata_pkt_t *ahciport_err_retri_pkt; 146 147 /* 148 * SATA HBA driver is supposed to remember and maintain device 149 * reset state. While the reset is in progress, it doesn't accept 150 * any more commands until receiving the command with 151 * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE. 152 */ 153 int ahciport_reset_in_progress; 154 155 /* This is for error recovery handler */ 156 ahci_event_arg_t *ahciport_event_args; 157 158 /* This is to calculate how many mops are in progress */ 159 int ahciport_mop_in_progress; 160 } ahci_port_t; 161 162 /* Warlock annotation */ 163 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle)) 164 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle)) 165 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle)) 166 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 167 ahci_port_t::ahciport_device_type)) 168 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 169 ahci_port_t::ahciport_port_state)) 170 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 171 ahci_port_t::ahciport_flags)) 172 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 173 ahci_port_t::ahciport_pending_tags)) 174 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 175 ahci_port_t::ahciport_slot_pkts)) 176 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 177 ahci_port_t::ahciport_reset_in_progress)) 178 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 179 ahci_port_t::ahciport_mop_in_progress)) 180 181 typedef struct ahci_ctl { 182 dev_info_t *ahcictl_dip; 183 /* To map port number to cport number */ 184 uint8_t ahcictl_port_to_cport[AHCI_MAX_PORTS]; 185 /* To map cport number to port number */ 186 uint8_t ahcictl_cport_to_port[AHCI_MAX_PORTS]; 187 188 /* Number of controller ports */ 189 int ahcictl_num_ports; 190 /* Number of command slots */ 191 int ahcictl_num_cmd_slots; 192 /* Number of implemented ports */ 193 int ahcictl_num_implemented_ports; 194 /* Bit map to indicate which port is implemented */ 195 uint32_t ahcictl_ports_implemented; 196 ahci_port_t *ahcictl_ports[AHCI_MAX_PORTS]; 197 198 int ahcictl_flags; 199 int ahcictl_power_level; 200 off_t ahcictl_pmcsr_offset; 201 202 /* 203 * AHCI_CAP_PIO_MDRQ 204 * AHCI_CAP_NO_MCMDLIST_NONQUEUE 205 * AHCI_CAP_NCQ 206 * AHCI_CAP_PM 207 * AHCI_CAP_32BIT_DMA 208 */ 209 int ahcictl_cap; 210 211 /* Pci configuration space handle */ 212 ddi_acc_handle_t ahcictl_pci_conf_handle; 213 214 /* Mapping into bar 5 - AHCI base address */ 215 ddi_acc_handle_t ahcictl_ahci_acc_handle; 216 uintptr_t ahcictl_ahci_addr; 217 218 /* Pointer used for sata hba framework registration */ 219 struct sata_hba_tran *ahcictl_sata_hba_tran; 220 221 /* DMA attributes for the data buffer */ 222 ddi_dma_attr_t ahcictl_buffer_dma_attr; 223 /* DMA attributes for the rcvd FIS */ 224 ddi_dma_attr_t ahcictl_rcvd_fis_dma_attr; 225 /* DMA attributes for the command list */ 226 ddi_dma_attr_t ahcictl_cmd_list_dma_attr; 227 /* DMA attributes for command tables */ 228 ddi_dma_attr_t ahcictl_cmd_table_dma_attr; 229 230 /* Used for watchdog handler */ 231 timeout_id_t ahcictl_timeout_id; 232 233 /* Per controller mutex */ 234 kmutex_t ahcictl_mutex; 235 236 /* Components for interrupt */ 237 ddi_intr_handle_t *ahcictl_intr_htable; /* For array of intrs */ 238 int ahcictl_intr_type; /* What type of interrupt */ 239 int ahcictl_intr_cnt; /* # of intrs returned */ 240 size_t ahcictl_intr_size; /* Size of intr array */ 241 uint_t ahcictl_intr_pri; /* Intr priority */ 242 int ahcictl_intr_cap; /* Intr capabilities */ 243 244 /* Taskq for handling event */ 245 ddi_taskq_t *ahcictl_event_taskq; 246 } ahci_ctl_t; 247 248 /* Warlock annotation */ 249 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports)) 250 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port)) 251 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport)) 252 253 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, 254 ahci_ctl_t::ahcictl_power_level)) 255 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, 256 ahci_ctl_t::ahcictl_flags)) 257 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, 258 ahci_ctl_t::ahcictl_timeout_id)) 259 260 #define AHCI_SUCCESS (0) /* Successful return */ 261 #define AHCI_TIMEOUT (1) /* Timed out */ 262 #define AHCI_FAILURE (-1) /* Unsuccessful return */ 263 264 /* Flags for ahcictl_flags */ 265 #define AHCI_ATTACH 0x1 266 #define AHCI_DETACH 0x2 267 #define AHCI_SUSPEND 0x4 268 269 /* Values for ahcictl_cap */ 270 /* PIO Multiple DRQ Block */ 271 #define AHCI_CAP_PIO_MDRQ 0x1 272 /* 273 * Multiple command slots in the command list cannot be used for 274 * non-queued commands 275 */ 276 #define AHCI_CAP_NO_MCMDLIST_NONQUEUE 0x2 277 /* Native Command Queuing (NCQ) */ 278 #define AHCI_CAP_NCQ 0x4 279 /* Power Management (PM) */ 280 #define AHCI_CAP_PM 0x8 281 /* 32-bit DMA addressing */ 282 #define AHCI_CAP_32BIT_DMA 0x10 283 284 /* Flags controlling the restart port behavior */ 285 #define AHCI_PORT_RESET 0x0001 /* Reset the port */ 286 #define AHCI_PORT_INIT 0x0002 /* Initialize port */ 287 #define AHCI_RESET_NO_EVENTS_UP 0x0004 /* Don't send reset events up */ 288 289 #define ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) \ 290 (ahci_portp->ahciport_flags & \ 291 (AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT)) 292 293 #define NON_NCQ_CMD_IN_PROGRESS(ahci_portp) \ 294 (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) && \ 295 ahci_portp->ahciport_pending_tags != 0 && \ 296 ahci_portp->ahciport_pending_ncq_tags == 0) 297 298 #define NCQ_CMD_IN_PROGRESS(ahci_portp) \ 299 (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) && \ 300 ahci_portp->ahciport_pending_ncq_tags != 0) 301 302 /* Command type for ahci_claim_free_slot routine */ 303 #define AHCI_NON_NCQ_CMD 0x0 304 #define AHCI_NCQ_CMD 0x1 305 #define AHCI_ERR_RETRI_CMD 0x2 306 307 /* State values for ahci_attach */ 308 #define AHCI_ATTACH_STATE_NONE (0x1 << 0) 309 #define AHCI_ATTACH_STATE_STATEP_ALLOC (0x1 << 1) 310 #define AHCI_ATTACH_STATE_REG_MAP (0x1 << 2) 311 #define AHCI_ATTACH_STATE_PCICFG_SETUP (0x1 << 3) 312 #define AHCI_ATTACH_STATE_INTR_ADDED (0x1 << 4) 313 #define AHCI_ATTACH_STATE_MUTEX_INIT (0x1 << 5) 314 #define AHCI_ATTACH_STATE_PORT_ALLOC (0x1 << 6) 315 #define AHCI_ATTACH_STATE_ERR_RECV_TASKQ (0x1 << 7) 316 #define AHCI_ATTACH_STATE_HW_INIT (0x1 << 8) 317 #define AHCI_ATTACH_STATE_TIMEOUT_ENABLED (0x1 << 9) 318 319 /* Interval used for delay */ 320 #define AHCI_10MS_TICKS (drv_usectohz(10000)) /* ticks in 10 millisec */ 321 #define AHCI_1MS_TICKS (drv_usectohz(1000)) /* ticks in 1 millisec */ 322 #define AHCI_100US_TICKS (drv_usectohz(100)) /* ticks in 100 */ 323 #define AHCI_1MS_USECS (1000) /* usecs in 1 millisec */ 324 325 /* 326 * The following values are the numbers of times to retry polled requests. 327 */ 328 #define AHCI_POLLRATE_HBA_RESET 100 329 #define AHCI_POLLRATE_PORT_SSTATUS 10 330 #define AHCI_POLLRATE_PORT_TFD_ERROR 1100 331 #define AHCI_POLLRATE_PORT_IDLE 50 332 #define AHCI_POLLRATE_PORT_SOFTRESET 100 333 #define AHCI_POLLRATE_GET_SPKT 100 334 335 336 /* Clearing & setting the n'th bit in a given tag */ 337 #define CLEAR_BIT(tag, bit) (tag &= ~(0x1<<bit)) 338 #define SET_BIT(tag, bit) (tag |= (0x1<<bit)) 339 340 341 #if DEBUG 342 343 #define AHCI_DEBUG 1 344 345 #define AHCIDBG_INIT 0x0001 346 #define AHCIDBG_ENTRY 0x0002 347 #define AHCIDBG_DUMP_PRB 0x0004 348 #define AHCIDBG_EVENT 0x0008 349 #define AHCIDBG_POLL_LOOP 0x0010 350 #define AHCIDBG_PKTCOMP 0x0020 351 #define AHCIDBG_TIMEOUT 0x0040 352 #define AHCIDBG_INFO 0x0080 353 #define AHCIDBG_VERBOSE 0x0100 354 #define AHCIDBG_INTR 0x0200 355 #define AHCIDBG_ERRS 0x0400 356 #define AHCIDBG_COOKIES 0x0800 357 #define AHCIDBG_POWER 0x1000 358 #define AHCIDBG_COMMAND 0x2000 359 #define AHCIDBG_SENSEDATA 0x4000 360 #define AHCIDBG_NCQ 0x8000 361 #define AHCIDBG_PM 0x10000 362 363 extern int ahci_debug_flag; 364 365 #define AHCIDBG0(flag, ahci_ctlp, format) \ 366 if (ahci_debug_flags & (flag)) { \ 367 ahci_log(ahci_ctlp, CE_WARN, format); \ 368 } 369 370 #define AHCIDBG1(flag, ahci_ctlp, format, arg1) \ 371 if (ahci_debug_flags & (flag)) { \ 372 ahci_log(ahci_ctlp, CE_WARN, format, arg1); \ 373 } 374 375 #define AHCIDBG2(flag, ahci_ctlp, format, arg1, arg2) \ 376 if (ahci_debug_flags & (flag)) { \ 377 ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2); \ 378 } 379 380 #define AHCIDBG3(flag, ahci_ctlp, format, arg1, arg2, arg3) \ 381 if (ahci_debug_flags & (flag)) { \ 382 ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2, arg3); \ 383 } 384 385 #define AHCIDBG4(flag, ahci_ctlp, format, arg1, arg2, arg3, arg4) \ 386 if (ahci_debug_flags & (flag)) { \ 387 ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2, arg3, arg4); \ 388 } 389 390 #define AHCIDBG5(flag, ahci_ctlp, format, arg1, arg2, arg3, arg4, arg5) \ 391 if (ahci_debug_flags & (flag)) { \ 392 ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2, \ 393 arg3, arg4, arg5); \ 394 } 395 #else 396 397 #define AHCIDBG0(flag, dip, frmt) 398 #define AHCIDBG1(flag, dip, frmt, arg1) 399 #define AHCIDBG2(flag, dip, frmt, arg1, arg2) 400 #define AHCIDBG3(flag, dip, frmt, arg1, arg2, arg3) 401 #define AHCIDBG4(flag, dip, frmt, arg1, arg2, arg3, arg4) 402 #define AHCIDBG5(flag, dip, frmt, arg1, arg2, arg3, arg4, arg5) 403 404 #endif /* DEBUG */ 405 406 407 #ifdef __cplusplus 408 } 409 #endif 410 411 #endif /* _AHCIVAR_H */ 412