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