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