9815 Want basic AHCI enclosure services
[unleashed.git] / usr / src / uts / common / sys / sata / adapters / ahci / ahcivar.h
blob8195242dd3fe4cd6ff156ea7be88502cae80d9a9
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
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.
29 #ifndef _AHCIVAR_H
30 #define _AHCIVAR_H
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
36 #include <sys/sata/adapters/ahci/ahciem.h>
39 * AHCI address qualifier flags (in qual field of ahci_addr struct).
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)
50 * AHCI address structure.
52 struct ahci_addr {
54 /* HBA port number */
55 uint8_t aa_port;
57 /* Port multiplier port number */
58 uint8_t aa_pmport;
61 * AHCI_ADDR_NULL
62 * AHCI_ADDR_PORT
63 * AHCI_ADDR_PMPORT
64 * AHCI_ADDR_PMULT
66 uint8_t aa_qual;
68 typedef struct ahci_addr ahci_addr_t;
70 _NOTE(SCHEME_PROTECTS_DATA("unshared data", ahci_addr))
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)
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; \
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)
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;
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))
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.
115 struct ahci_pmult_info {
117 /* Number of the device ports */
118 int ahcipmi_num_dev_ports;
120 /* Device type of the sub-devices of the port multipler */
121 uint8_t ahcipmi_device_type[SATA_MAX_PMPORTS];
123 /* State of port multiplier port */
124 uint32_t ahcipmi_port_state[SATA_MAX_PMPORTS];
127 * Port multiplier port on which there is outstanding NCQ
128 * commands. Only make sense in command based switching mode.
130 uint8_t ahcipmi_ncq_pmport;
132 /* Pending asynchronous notification events tags */
133 uint32_t ahcipmi_snotif_tags;
135 typedef struct ahci_pmult_info ahci_pmult_info_t;
138 * flags for ahciport_flags
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.
144 * AHCI_PORT_FLAG_POLLING: this flag will be set when the interrupt is
145 * disabled, and the command is executed in POLLING mode.
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.
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'.
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.
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.
160 * AHCI_PORT_FLAG_RDWR_PMULT: this flag will be set when a READ/WRITE
161 * PORTMULT command is being executed.
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.
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.
170 * AHCI_PORT_FLAG_HOTPLUG: this flag will be set when a hot plug event is
171 * being handled.
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.
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
189 typedef struct ahci_port {
190 /* The physical port number */
191 uint8_t ahciport_port_num;
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;
198 /* Port multiplier struct */
199 ahci_pmult_info_t *ahciport_pmult_info;
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
214 int ahciport_flags;
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;
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;
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];
236 /* Condition variable used for sync mode commands */
237 kcondvar_t ahciport_cv;
239 /* The whole mutex for the port structure */
240 kmutex_t ahciport_mutex;
242 /* The maximum number of tags for native queuing command transfers */
243 int ahciport_max_ncq_tags;
245 /* Keep the tags of all pending non-ncq commands */
246 uint32_t ahciport_pending_tags;
249 * Keep the tags of all pending ncq commands
250 * (READ/WRITE FPDMA QUEUED)
252 uint32_t ahciport_pending_ncq_tags;
254 /* Keep all the pending sata packets */
255 sata_pkt_t *ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS];
257 /* Used to check whether corresponding packet is timeout */
258 int ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS];
260 /* Queue of completed (done) sata packet */
261 sata_pkt_t *ahciport_doneq;
263 /* Pointer of the tail of completed sata packet queue */
264 sata_pkt_t **ahciport_doneqtail;
266 /* the length of the completed sata packet queue */
267 uint32_t ahciport_doneq_len;
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];
273 /* Keep the error retrieval sata packet */
274 sata_pkt_t *ahciport_err_retri_pkt;
276 /* Keep the read/write port multiplier packet */
277 sata_pkt_t *ahciport_rdwr_pmult_pkt;
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.
285 int ahciport_reset_in_progress;
287 /* Taskq for handling event */
288 ddi_taskq_t *ahciport_event_taskq;
290 /* This is for error recovery handler */
291 ahci_event_arg_t *ahciport_event_args;
293 /* This is to calculate how many mops are in progress */
294 int ahciport_mop_in_progress;
295 } ahci_port_t;
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))
326 #define AHCI_NUM_PORTS(ctlp) \
327 (ctlp)->ahcictl_num_ports
329 #define AHCIPORT_NUM_PMPORTS(portp) \
330 (portp)->ahciport_pmult_info->ahcipmi_num_dev_ports
332 #define AHCIPORT_NCQ_PMPORT(ahci_portp) \
333 (ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport)
335 #define AHCIPORT_DEV_TYPE(portp, addrp) \
336 (portp)->ahciport_device_type
338 #define AHCIPORT_PMDEV_TYPE(portp, addrp) \
339 (portp)->ahciport_pmult_info->ahcipmi_device_type \
340 [(addrp)->aa_pmport]
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))
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;
353 #define AHCIPORT_STATE(portp, addrp) \
354 (portp)->ahciport_port_state
356 #define AHCIPORT_PMSTATE(portp, addrp) \
357 (portp)->ahciport_pmult_info->ahcipmi_port_state \
358 [(addrp)->aa_pmport]
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))
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;
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;
378 #define AHCI_EM_USABLE (AHCI_EM_PRESENT | AHCI_EM_READY)
380 typedef struct ahci_ctl {
381 dev_info_t *ahcictl_dip;
383 ushort_t ahcictl_venid;
384 ushort_t ahcictl_devid;
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];
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];
401 int ahcictl_flags;
402 int ahcictl_power_level;
403 off_t ahcictl_pmcsr_offset;
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
419 int ahcictl_cap;
421 /* Pci configuration space handle */
422 ddi_acc_handle_t ahcictl_pci_conf_handle;
424 /* Mapping into bar 5 - AHCI base address */
425 ddi_acc_handle_t ahcictl_ahci_acc_handle;
426 uintptr_t ahcictl_ahci_addr;
428 /* Pointer used for sata hba framework registration */
429 struct sata_hba_tran *ahcictl_sata_hba_tran;
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;
440 /* Used for watchdog handler */
441 timeout_id_t ahcictl_timeout_id;
443 /* Per controller mutex */
444 kmutex_t ahcictl_mutex;
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 */
454 /* FMA capabilities */
455 int ahcictl_fm_cap;
458 * Enclosure information
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;
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))
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))
480 #define AHCI_SUCCESS (0) /* Successful return */
481 #define AHCI_TIMEOUT (1) /* Timed out */
482 #define AHCI_FAILURE (-1) /* Unsuccessful return */
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
490 /* Values for ahcictl_cap */
491 /* PIO Multiple DRQ Block */
492 #define AHCI_CAP_PIO_MDRQ 0x1
494 * Multiple command slots in the command list cannot be used for
495 * non-queued commands
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
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 */
525 #define ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) \
526 (ahci_portp->ahciport_flags & \
527 (AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
529 #define RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) \
530 (ahci_portp->ahciport_flags & \
531 AHCI_PORT_FLAG_RDWR_PMULT)
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)
538 #define NCQ_CMD_IN_PROGRESS(ahci_portp) \
539 (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) && \
540 ahci_portp->ahciport_pending_ncq_tags != 0)
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
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)
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)
570 * The following values are the numbers of times to retry polled requests.
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
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))
586 #if DEBUG
588 #define AHCI_DEBUG 1
590 #endif
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
612 extern uint32_t ahci_debug_flags;
614 #if DEBUG
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); \
626 #else
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); \
637 #endif /* DEBUG */
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.
643 #define AHCI_EM_BUFFER_MIN 2
646 * Enclosure Management LED message format values
648 #define AHCI_LED_OFF 0
649 #define AHCI_LED_ON 1
651 #define AHCI_LED_ACTIVITY_OFF 0
652 #define AHCI_LED_IDENT_OFF 3
653 #define AHCI_LED_FAULT_OFF 6
655 #define AHCI_LED_MASK 0x7
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
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;
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()
677 #ifdef __cplusplus
679 #endif
681 #endif /* _AHCIVAR_H */