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