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 (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 25 * Copyright (c) 2018, Joyent, Inc. 26 * Copyright 2021 RackTop Systems, Inc. 27 */ 28 29 30 #ifndef _AHCIVAR_H 31 #define _AHCIVAR_H 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <sys/sata/adapters/ahci/ahciem.h> 38 39 /* 40 * AHCI address qualifier flags (in qual field of ahci_addr struct). 41 */ 42 #define AHCI_ADDR_NULL 0x00 43 #define AHCI_ADDR_PORT 0x01 44 #define AHCI_ADDR_PMPORT 0x02 45 #define AHCI_ADDR_PMULT 0x04 46 #define AHCI_ADDR_VALID (AHCI_ADDR_PORT | \ 47 AHCI_ADDR_PMULT | \ 48 AHCI_ADDR_PMPORT) 49 50 /* 51 * AHCI address structure. 52 */ 53 struct ahci_addr { 54 55 /* HBA port number */ 56 uint8_t aa_port; 57 58 /* Port multiplier port number */ 59 uint8_t aa_pmport; 60 61 /* 62 * AHCI_ADDR_NULL 63 * AHCI_ADDR_PORT 64 * AHCI_ADDR_PMPORT 65 * AHCI_ADDR_PMULT 66 */ 67 uint8_t aa_qual; 68 }; 69 typedef struct ahci_addr ahci_addr_t; 70 71 _NOTE(SCHEME_PROTECTS_DATA("unshared data", ahci_addr)) 72 73 #define AHCI_ADDR_IS_PORT(addrp) \ 74 ((addrp)->aa_qual & AHCI_ADDR_PORT) 75 #define AHCI_ADDR_IS_PMPORT(addrp) \ 76 ((addrp)->aa_qual & AHCI_ADDR_PMPORT) 77 #define AHCI_ADDR_IS_PMULT(addrp) \ 78 ((addrp)->aa_qual & AHCI_ADDR_PMULT) 79 #define AHCI_ADDR_IS_VALID(addrp) \ 80 ((addrp)->aa_port < SATA_MAX_CPORTS) && \ 81 ((addrp)->aa_pmport < SATA_MAX_PMPORTS) && \ 82 ((addrp)->aa_qual & AHCI_ADDR_VALID) 83 84 #define AHCI_ADDR_SET(addrp, port, pmport, qual) \ 85 { \ 86 (addrp)->aa_port = port; \ 87 (addrp)->aa_pmport = pmport; \ 88 (addrp)->aa_qual = qual; \ 89 } 90 #define AHCI_ADDR_SET_PORT(addrp, port) \ 91 AHCI_ADDR_SET(addrp, port, 0, AHCI_ADDR_PORT) 92 #define AHCI_ADDR_SET_PMPORT(addrp, port, pmport) \ 93 AHCI_ADDR_SET(addrp, port, pmport, AHCI_ADDR_PMPORT) 94 #define AHCI_ADDR_SET_PMULT(addrp, port) \ 95 AHCI_ADDR_SET(addrp, port, SATA_PMULT_HOSTPORT, AHCI_ADDR_PMULT) 96 97 /* Type for argument of event handler */ 98 typedef struct ahci_event_arg { 99 void *ahciea_ctlp; 100 void *ahciea_portp; 101 void *ahciea_addrp; 102 uint32_t ahciea_event; 103 } ahci_event_arg_t; 104 105 /* Warlock annotation */ 106 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_ctlp)) 107 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_portp)) 108 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_addrp)) 109 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_event)) 110 111 112 /* 113 * ahci_pmult_info stores the information of a port multiplier and its 114 * sub-devices in case a port multiplier is attached to an HBA port. 115 */ 116 struct ahci_pmult_info { 117 118 /* Number of the device ports */ 119 int ahcipmi_num_dev_ports; 120 121 /* Device type of the sub-devices of the port multipler */ 122 uint8_t ahcipmi_device_type[SATA_MAX_PMPORTS]; 123 124 /* State of port multiplier port */ 125 uint32_t ahcipmi_port_state[SATA_MAX_PMPORTS]; 126 127 /* 128 * Port multiplier port on which there is outstanding NCQ 129 * commands. Only make sense in command based switching mode. 130 */ 131 uint8_t ahcipmi_ncq_pmport; 132 133 /* Pending asynchronous notification events tags */ 134 uint32_t ahcipmi_snotif_tags; 135 }; 136 typedef struct ahci_pmult_info ahci_pmult_info_t; 137 138 /* 139 * flags for ahciport_flags 140 * 141 * AHCI_PORT_FLAG_MOPPING: this flag will be set when the HBA is stopped, 142 * and all the outstanding commands need to be aborted and sent to upper 143 * layers. 144 * 145 * AHCI_PORT_FLAG_POLLING: this flag will be set when the interrupt is 146 * disabled, and the command is executed in POLLING mode. 147 * 148 * AHCI_PORT_FLAG_RQSENSE: this flag will be set when a REQUEST SENSE which 149 * is used to retrieve sense data is being executed. 150 * 151 * AHCI_PORT_FLAG_STARTED: this flag will be set when the port is started, 152 * that is PxCMD.ST is set with '1', and be cleared when the port is put into 153 * idle, that is PxCMD.ST is changed from '1' to '0'. 154 * 155 * AHCI_PORT_FLAG_RDLOGEXT: this flag will be set when a READ LOG EXT which 156 * is used to retrieve NCQ failure context is being executed. 157 * 158 * AHCI_PORT_FLAG_NODEV: this flag will be set when a device is found gone 159 * during ahci_restart_port_wait_till_ready process. 160 * 161 * AHCI_PORT_FLAG_RDWR_PMULT: this flag will be set when a READ/WRITE 162 * PORTMULT command is being executed. 163 * 164 * AHCI_PORT_FLAG_IGNORE_IPMS: this flag will be set when enumerating a port 165 * multiplier. According AHCI spec, IPMS error should be ignore during 166 * enumeration of port multiplier. 167 * 168 * AHCI_PORT_FLAG_PMULT_SNTF: this flag will be set when the a asynchronous 169 * notification event on the port multiplier is being handled. 170 * 171 * AHCI_PORT_FLAG_HOTPLUG: this flag will be set when a hot plug event is 172 * being handled. 173 * 174 * AHCI_PORT_FLAG_ERRPRINT: this flag will be set when error recovery message 175 * will be printed. Note that, for INDENTIFY DEVICE command sent to ATAPI 176 * device or ATAPI PACKET command, this flag won't be set. 177 */ 178 #define AHCI_PORT_FLAG_MOPPING 0x02 179 #define AHCI_PORT_FLAG_POLLING 0x04 180 #define AHCI_PORT_FLAG_RQSENSE 0x08 181 #define AHCI_PORT_FLAG_STARTED 0x10 182 #define AHCI_PORT_FLAG_RDLOGEXT 0x20 183 #define AHCI_PORT_FLAG_NODEV 0x40 184 #define AHCI_PORT_FLAG_RDWR_PMULT 0x80 185 #define AHCI_PORT_FLAG_IGNORE_IPMS 0x100 186 #define AHCI_PORT_FLAG_PMULT_SNTF 0x200 187 #define AHCI_PORT_FLAG_HOTPLUG 0x400 188 #define AHCI_PORT_FLAG_ERRPRINT 0x800 189 190 typedef struct ahci_port { 191 /* The physical port number */ 192 uint8_t ahciport_port_num; 193 194 /* Type of the device attached to the port */ 195 uint8_t ahciport_device_type; 196 /* State of the port */ 197 uint32_t ahciport_port_state; 198 199 /* Port multiplier struct */ 200 ahci_pmult_info_t *ahciport_pmult_info; 201 202 /* 203 * AHCI_PORT_FLAG_MOPPING 204 * AHCI_PORT_FLAG_POLLING 205 * AHCI_PORT_FLAG_RQSENSE 206 * AHCI_PORT_FLAG_STARTED 207 * AHCI_PORT_FLAG_RDLOGEXT 208 * AHCI_PORT_FLAG_NODEV 209 * AHCI_PORT_FLAG_RDWR_PMULT 210 * AHCI_PORT_FLAG_IGNORE_IPMS 211 * AHCI_PORT_FLAG_PMULT_SNTF 212 * AHCI_PORT_FLAG_HOTPLUG 213 * AHCI_PORT_FLAG_ERRPRINT 214 */ 215 int ahciport_flags; 216 217 /* Pointer to received FIS structure */ 218 ahci_rcvd_fis_t *ahciport_rcvd_fis; 219 ddi_dma_handle_t ahciport_rcvd_fis_dma_handle; 220 ddi_acc_handle_t ahciport_rcvd_fis_acc_handle; 221 ddi_dma_cookie_t ahciport_rcvd_fis_dma_cookie; 222 223 /* Pointer to command list structure */ 224 ahci_cmd_header_t *ahciport_cmd_list; 225 ddi_dma_handle_t ahciport_cmd_list_dma_handle; 226 ddi_acc_handle_t ahciport_cmd_list_acc_handle; 227 ddi_dma_cookie_t ahciport_cmd_list_dma_cookie; 228 229 /* Pointer to cmmand table structure */ 230 ahci_cmd_table_t \ 231 *ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS]; 232 ddi_dma_handle_t \ 233 ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS]; 234 ddi_acc_handle_t \ 235 ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS]; 236 237 /* Condition variable used for sync mode commands */ 238 kcondvar_t ahciport_cv; 239 240 /* The whole mutex for the port structure */ 241 kmutex_t ahciport_mutex; 242 243 /* The maximum number of tags for native queuing command transfers */ 244 int ahciport_max_ncq_tags; 245 246 /* Keep the tags of all pending non-ncq commands */ 247 uint32_t ahciport_pending_tags; 248 249 /* 250 * Keep the tags of all pending ncq commands 251 * (READ/WRITE FPDMA QUEUED) 252 */ 253 uint32_t ahciport_pending_ncq_tags; 254 255 /* Keep all the pending sata packets */ 256 sata_pkt_t *ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS]; 257 258 /* Used to check whether corresponding packet is timeout */ 259 int ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS]; 260 261 /* Queue of completed (done) sata packet */ 262 sata_pkt_t *ahciport_doneq; 263 264 /* Pointer of the tail of completed sata packet queue */ 265 sata_pkt_t **ahciport_doneqtail; 266 267 /* the length of the completed sata packet queue */ 268 uint32_t ahciport_doneq_len; 269 270 /* Keep the byte count of all PRD entries for every sata packet */ 271 uint32_t \ 272 ahciport_prd_bytecounts[AHCI_PORT_MAX_CMD_SLOTS]; 273 274 /* Keep the error retrieval sata packet */ 275 sata_pkt_t *ahciport_err_retri_pkt; 276 277 /* Keep the read/write port multiplier packet */ 278 sata_pkt_t *ahciport_rdwr_pmult_pkt; 279 280 /* 281 * SATA HBA driver is supposed to remember and maintain device 282 * reset state. While the reset is in progress, it doesn't accept 283 * any more commands until receiving the command with 284 * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE. 285 */ 286 int ahciport_reset_in_progress; 287 288 /* Taskq for handling event */ 289 ddi_taskq_t *ahciport_event_taskq; 290 291 /* This is for error recovery handler */ 292 ahci_event_arg_t *ahciport_event_args; 293 294 /* This is to calculate how many mops are in progress */ 295 int ahciport_mop_in_progress; 296 } ahci_port_t; 297 298 /* Warlock annotation */ 299 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle)) 300 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle)) 301 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle)) 302 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 303 ahci_port_t::ahciport_device_type)) 304 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 305 ahci_port_t::ahciport_port_state)) 306 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 307 ahci_port_t::ahciport_flags)) 308 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 309 ahci_port_t::ahciport_pending_tags)) 310 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 311 ahci_port_t::ahciport_slot_pkts)) 312 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 313 ahci_port_t::ahciport_slot_timeout)) 314 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 315 ahci_port_t::ahciport_doneq)) 316 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 317 ahci_port_t::ahciport_doneqtail)) 318 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 319 ahci_port_t::ahciport_doneq_len)) 320 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 321 ahci_port_t::ahciport_reset_in_progress)) 322 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 323 ahci_port_t::ahciport_mop_in_progress)) 324 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex, 325 ahci_port_t::ahciport_event_taskq)) 326 327 #define AHCI_NUM_PORTS(ctlp) \ 328 (ctlp)->ahcictl_num_ports 329 330 #define AHCIPORT_NUM_PMPORTS(portp) \ 331 (portp)->ahciport_pmult_info->ahcipmi_num_dev_ports 332 333 #define AHCIPORT_NCQ_PMPORT(ahci_portp) \ 334 (ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport) 335 336 #define AHCIPORT_DEV_TYPE(portp, addrp) \ 337 (portp)->ahciport_device_type 338 339 #define AHCIPORT_PMDEV_TYPE(portp, addrp) \ 340 (portp)->ahciport_pmult_info->ahcipmi_device_type \ 341 [(addrp)->aa_pmport] 342 343 #define AHCIPORT_GET_DEV_TYPE(portp, addrp) \ 344 (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ? \ 345 AHCIPORT_DEV_TYPE(portp, addrp) : \ 346 AHCIPORT_PMDEV_TYPE(portp, addrp)) 347 348 #define AHCIPORT_SET_DEV_TYPE(portp, addrp, type) \ 349 if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp)) \ 350 AHCIPORT_DEV_TYPE(portp, addrp) = type; \ 351 else \ 352 AHCIPORT_PMDEV_TYPE(portp, addrp) = type; 353 354 #define AHCIPORT_STATE(portp, addrp) \ 355 (portp)->ahciport_port_state 356 357 #define AHCIPORT_PMSTATE(portp, addrp) \ 358 (portp)->ahciport_pmult_info->ahcipmi_port_state \ 359 [(addrp)->aa_pmport] 360 361 #define AHCIPORT_GET_STATE(portp, addrp) \ 362 (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ? \ 363 AHCIPORT_STATE(portp, addrp) : AHCIPORT_PMSTATE(portp, addrp)) 364 365 #define AHCIPORT_SET_STATE(portp, addrp, state) \ 366 if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp)) \ 367 AHCIPORT_STATE(portp, addrp) = state; \ 368 else \ 369 AHCIPORT_PMSTATE(portp, addrp) = state; 370 371 typedef enum ahci_em_flags { 372 AHCI_EM_PRESENT = 1 << 0, 373 AHCI_EM_RESETTING = 1 << 1, 374 AHCI_EM_TIMEOUT = 1 << 2, 375 AHCI_EM_QUIESCE = 1 << 3, 376 AHCI_EM_READY = 1 << 4, 377 } ahci_em_flags_t; 378 379 #define AHCI_EM_USABLE (AHCI_EM_PRESENT | AHCI_EM_READY) 380 381 typedef struct ahci_ctl { 382 dev_info_t *ahcictl_dip; 383 384 ushort_t ahcictl_venid; 385 ushort_t ahcictl_devid; 386 387 /* To map port number to cport number */ 388 uint8_t ahcictl_port_to_cport[AHCI_MAX_PORTS]; 389 /* To map cport number to port number */ 390 uint8_t ahcictl_cport_to_port[AHCI_MAX_PORTS]; 391 392 /* Number of controller ports */ 393 int ahcictl_num_ports; 394 /* Number of command slots */ 395 int ahcictl_num_cmd_slots; 396 /* Number of implemented ports */ 397 int ahcictl_num_implemented_ports; 398 /* Bit map to indicate which port is implemented */ 399 uint32_t ahcictl_ports_implemented; 400 ahci_port_t *ahcictl_ports[AHCI_MAX_PORTS]; 401 402 int ahcictl_flags; 403 int ahcictl_power_level; 404 off_t ahcictl_pmcsr_offset; 405 406 /* 407 * AHCI_CAP_PIO_MDRQ 408 * AHCI_CAP_NO_MCMDLIST_NONQUEUE 409 * AHCI_CAP_NCQ 410 * AHCI_CAP_PM 411 * AHCI_CAP_BUF_32BIT_DMA 412 * AHCI_CAP_SCLO 413 * AHCI_CAP_COMMU_32BIT_DMA 414 * AHCI_CAP_INIT_PORT_RESET 415 * AHCI_CAP_SNTF 416 * AHCI_CAP_PMULT_CBSS 417 * AHCI_CAP_PMULT_FBSS 418 * AHCI_CAP_SRST_NO_HOSTPORT 419 */ 420 int ahcictl_cap; 421 422 /* Pci configuration space handle */ 423 ddi_acc_handle_t ahcictl_pci_conf_handle; 424 425 /* Mapping into bar 5 - AHCI base address */ 426 ddi_acc_handle_t ahcictl_ahci_acc_handle; 427 uintptr_t ahcictl_ahci_addr; 428 429 /* Pointer used for sata hba framework registration */ 430 struct sata_hba_tran *ahcictl_sata_hba_tran; 431 432 /* DMA attributes for the data buffer */ 433 ddi_dma_attr_t ahcictl_buffer_dma_attr; 434 /* DMA attributes for the rcvd FIS */ 435 ddi_dma_attr_t ahcictl_rcvd_fis_dma_attr; 436 /* DMA attributes for the command list */ 437 ddi_dma_attr_t ahcictl_cmd_list_dma_attr; 438 /* DMA attributes for command tables */ 439 ddi_dma_attr_t ahcictl_cmd_table_dma_attr; 440 441 /* Used for watchdog handler */ 442 timeout_id_t ahcictl_timeout_id; 443 444 /* Per controller mutex */ 445 kmutex_t ahcictl_mutex; 446 447 /* Components for interrupt */ 448 ddi_intr_handle_t *ahcictl_intr_htable; /* For array of intrs */ 449 int ahcictl_intr_type; /* What type of interrupt */ 450 int ahcictl_intr_cnt; /* # of intrs returned */ 451 size_t ahcictl_intr_size; /* Size of intr array */ 452 uint_t ahcictl_intr_pri; /* Intr priority */ 453 int ahcictl_intr_cap; /* Intr capabilities */ 454 455 /* FMA capabilities */ 456 int ahcictl_fm_cap; 457 458 /* 459 * Enclosure information 460 */ 461 uint32_t ahcictl_em_loc; 462 uint32_t ahcictl_em_ctl; 463 uintptr_t ahcictl_em_tx_off; 464 ahci_em_flags_t ahcictl_em_flags; 465 ddi_taskq_t *ahcictl_em_taskq; 466 ahci_em_led_state_t ahcictl_em_state[AHCI_MAX_PORTS]; 467 } ahci_ctl_t; 468 469 /* Warlock annotation */ 470 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports)) 471 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port)) 472 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport)) 473 474 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, 475 ahci_ctl_t::ahcictl_power_level)) 476 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, 477 ahci_ctl_t::ahcictl_flags)) 478 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex, 479 ahci_ctl_t::ahcictl_timeout_id)) 480 481 #define AHCI_SUCCESS (0) /* Successful return */ 482 #define AHCI_TIMEOUT (1) /* Timed out */ 483 #define AHCI_FAILURE (-1) /* Unsuccessful return */ 484 485 /* Flags for ahcictl_flags */ 486 #define AHCI_ATTACH 0x1 487 #define AHCI_DETACH 0x2 488 #define AHCI_SUSPEND 0x4 489 #define AHCI_QUIESCE 0x8 490 491 /* Values for ahcictl_cap */ 492 /* PIO Multiple DRQ Block */ 493 #define AHCI_CAP_PIO_MDRQ 0x1 494 /* 495 * Multiple command slots in the command list cannot be used for 496 * non-queued commands 497 */ 498 #define AHCI_CAP_NO_MCMDLIST_NONQUEUE 0x2 499 /* Native Command Queuing (NCQ) */ 500 #define AHCI_CAP_NCQ 0x4 501 /* Power Management (PM) */ 502 #define AHCI_CAP_PM 0x8 503 /* 32-bit DMA addressing for buffer block */ 504 #define AHCI_CAP_BUF_32BIT_DMA 0x10 505 /* Supports Command List Override */ 506 #define AHCI_CAP_SCLO 0x20 507 /* 32-bit DMA addressing for communication memory descriptors */ 508 #define AHCI_CAP_COMMU_32BIT_DMA 0x40 509 /* Port reset is needed for initialization */ 510 #define AHCI_CAP_INIT_PORT_RESET 0x80 511 /* Port Asychronous Notification */ 512 #define AHCI_CAP_SNTF 0x100 513 /* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */ 514 #define AHCI_CAP_PMULT_CBSS 0x200 515 /* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */ 516 #define AHCI_CAP_PMULT_FBSS 0x400 517 /* Software Reset FIS cannot set pmport with 0xf for direct access device */ 518 #define AHCI_CAP_SRST_NO_HOSTPORT 0x800 519 /* Enclosure Management Services available */ 520 #define AHCI_CAP_EMS 0x1000 521 /* DevSleep Supported */ 522 #define AHCI_CAP_SDS 0x2000 523 524 /* Flags controlling the restart port behavior */ 525 #define AHCI_PORT_RESET 0x0001 /* Reset the port */ 526 #define AHCI_RESET_NO_EVENTS_UP 0x0002 /* Don't send reset events up */ 527 528 #define ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) \ 529 (ahci_portp->ahciport_flags & \ 530 (AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT)) 531 532 #define RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) \ 533 (ahci_portp->ahciport_flags & \ 534 AHCI_PORT_FLAG_RDWR_PMULT) 535 536 #define NON_NCQ_CMD_IN_PROGRESS(ahci_portp) \ 537 (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) && \ 538 ahci_portp->ahciport_pending_tags != 0 && \ 539 ahci_portp->ahciport_pending_ncq_tags == 0) 540 541 #define NCQ_CMD_IN_PROGRESS(ahci_portp) \ 542 (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) && \ 543 ahci_portp->ahciport_pending_ncq_tags != 0) 544 545 /* Command type for ahci_claim_free_slot routine */ 546 #define AHCI_NON_NCQ_CMD 0x0 547 #define AHCI_NCQ_CMD 0x1 548 #define AHCI_ERR_RETRI_CMD 0x2 549 #define AHCI_RDWR_PMULT_CMD 0x4 550 551 /* State values for ahci_attach */ 552 #define AHCI_ATTACH_STATE_NONE (0x1 << 0) 553 #define AHCI_ATTACH_STATE_STATEP_ALLOC (0x1 << 1) 554 #define AHCI_ATTACH_STATE_FMA (0x1 << 2) 555 #define AHCI_ATTACH_STATE_REG_MAP (0x1 << 3) 556 #define AHCI_ATTACH_STATE_PCICFG_SETUP (0x1 << 4) 557 #define AHCI_ATTACH_STATE_INTR_ADDED (0x1 << 5) 558 #define AHCI_ATTACH_STATE_MUTEX_INIT (0x1 << 6) 559 #define AHCI_ATTACH_STATE_PORT_ALLOC (0x1 << 7) 560 #define AHCI_ATTACH_STATE_HW_INIT (0x1 << 8) 561 #define AHCI_ATTACH_STATE_TIMEOUT_ENABLED (0x1 << 9) 562 #define AHCI_ATTACH_STATE_ENCLOSURE (0x1 << 10) 563 564 /* Interval used for delay */ 565 #define AHCI_10MS_TICKS (drv_usectohz(10000)) /* ticks in 10 ms */ 566 #define AHCI_1MS_TICKS (drv_usectohz(1000)) /* ticks in 1 ms */ 567 #define AHCI_100US_TICKS (drv_usectohz(100)) /* ticks in 100 us */ 568 #define AHCI_10MS_USECS (10000) /* microsecs in 10 millisec */ 569 #define AHCI_1MS_USECS (1000) /* microsecs in 1 millisec */ 570 #define AHCI_100US_USECS (100) 571 572 /* 573 * The following values are the numbers of times to retry polled requests. 574 */ 575 #define AHCI_POLLRATE_HBA_RESET 100 576 #define AHCI_POLLRATE_PORT_SSTATUS 10 577 #define AHCI_POLLRATE_PORT_TFD_ERROR 1100 578 #define AHCI_POLLRATE_PORT_IDLE 50 579 #define AHCI_POLLRATE_PORT_SOFTRESET 100 580 #define AHCI_POLLRATE_GET_SPKT 100 581 #define AHCI_POLLRATE_PORT_IDLE_FR 500 582 583 584 /* Clearing & setting the n'th bit in a given tag */ 585 #define CLEAR_BIT(tag, bit) (tag &= ~(0x1<<bit)) 586 #define SET_BIT(tag, bit) (tag |= (0x1<<bit)) 587 588 589 #if DEBUG 590 591 #define AHCI_DEBUG 1 592 593 #endif 594 595 #define AHCIDBG_INIT 0x0001 596 #define AHCIDBG_ENTRY 0x0002 597 #define AHCIDBG_PRDT 0x0004 598 #define AHCIDBG_EVENT 0x0008 599 #define AHCIDBG_POLL_LOOP 0x0010 600 #define AHCIDBG_PKTCOMP 0x0020 601 #define AHCIDBG_TIMEOUT 0x0040 602 #define AHCIDBG_INFO 0x0080 603 #define AHCIDBG_VERBOSE 0x0100 604 #define AHCIDBG_INTR 0x0200 605 #define AHCIDBG_ERRS 0x0400 606 #define AHCIDBG_ATACMD 0x0800 607 #define AHCIDBG_ATAPICMD 0x1000 608 #define AHCIDBG_SENSEDATA 0x2000 609 #define AHCIDBG_NCQ 0x4000 610 #define AHCIDBG_PM 0x8000 611 #define AHCIDBG_UNDERFLOW 0x10000 612 #define AHCIDBG_MSI 0x20000 613 #define AHCIDBG_PMULT 0x40000 614 615 extern uint32_t ahci_debug_flags; 616 617 #if DEBUG 618 619 #define AHCIDBG(flag, ahci_ctlp, fmt, args ...) \ 620 if (ahci_debug_flags & (flag)) { \ 621 ahci_log(ahci_ctlp, CE_WARN, fmt, ## args); \ 622 if (ahci_ctlp == NULL) \ 623 sata_trace_debug(NULL, fmt, ## args); \ 624 else \ 625 sata_trace_debug(ahci_ctlp->ahcictl_dip,\ 626 fmt, ## args); \ 627 } 628 629 #else 630 631 #define AHCIDBG(flag, ahci_ctlp, fmt, args ...) \ 632 if (ahci_debug_flags & (flag)) { \ 633 if (ahci_ctlp == NULL) \ 634 sata_trace_debug(NULL, fmt, ## args); \ 635 else \ 636 sata_trace_debug(ahci_ctlp->ahcictl_dip,\ 637 fmt, ## args); \ 638 } 639 640 #endif /* DEBUG */ 641 642 /* 643 * Minimum size required for the enclosure message buffer. This value is in 644 * 4-byte quantities. So we need to multiply it by two. 645 */ 646 #define AHCI_EM_BUFFER_MIN 2 647 648 /* 649 * Enclosure Management LED message format values 650 */ 651 #define AHCI_LED_OFF 0 652 #define AHCI_LED_ON 1 653 654 #define AHCI_LED_ACTIVITY_OFF 0 655 #define AHCI_LED_IDENT_OFF 3 656 #define AHCI_LED_FAULT_OFF 6 657 658 #define AHCI_LED_MASK 0x7 659 660 #define AHCI_EM_MSG_TYPE_LED 0 661 #define AHCI_EM_MSG_TYPE_SAFTE 1 662 #define AHCI_EM_MSG_TYPE_SES 2 663 #define AHCI_EM_MSG_TYPE_SGPIO 3 664 665 #pragma pack(1) 666 typedef struct ahci_em_led_msg { 667 uint8_t alm_hba; 668 uint8_t alm_pminfo; 669 uint16_t alm_value; 670 } ahci_em_led_msg_t; 671 672 typedef struct ahci_em_msg_hdr { 673 uint8_t aemh_rsvd; 674 uint8_t aemh_mlen; 675 uint8_t aemh_dlen; 676 uint8_t aemh_mtype; 677 } ahci_em_msg_hdr_t; 678 #pragma pack() 679 680 #ifdef __cplusplus 681 } 682 #endif 683 684 #endif /* _AHCIVAR_H */ 685