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