xref: /illumos-gate/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h (revision c7402f0767d7a0360fabd0bd449c6baf9b282074)
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
32 extern "C" {
33 #endif
34 
35 /* Type for argument of event handler */
36 typedef	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 
81 typedef 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 
188 typedef 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 for buffer block */
287 #define	AHCI_CAP_BUF_32BIT_DMA		0x10
288 /* Supports Command List Override */
289 #define	AHCI_CAP_SCLO			0x20
290 /* 32-bit DMA addressing for communication memory descriptors */
291 #define	AHCI_CAP_COMMU_32BIT_DMA	0x40
292 
293 
294 /* Flags controlling the restart port behavior */
295 #define	AHCI_PORT_RESET		0x0001	/* Reset the port */
296 #define	AHCI_RESET_NO_EVENTS_UP	0x0002	/* Don't send reset events up */
297 
298 #define	ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)		\
299 	(ahci_portp->ahciport_flags &			\
300 	(AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
301 
302 #define	NON_NCQ_CMD_IN_PROGRESS(ahci_portp)		\
303 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
304 	ahci_portp->ahciport_pending_tags != 0 &&	\
305 	ahci_portp->ahciport_pending_ncq_tags == 0)
306 
307 #define	NCQ_CMD_IN_PROGRESS(ahci_portp)			\
308 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
309 	ahci_portp->ahciport_pending_ncq_tags != 0)
310 
311 /* Command type for ahci_claim_free_slot routine */
312 #define	AHCI_NON_NCQ_CMD	0x0
313 #define	AHCI_NCQ_CMD		0x1
314 #define	AHCI_ERR_RETRI_CMD	0x2
315 
316 /* State values for ahci_attach */
317 #define	AHCI_ATTACH_STATE_NONE			(0x1 << 0)
318 #define	AHCI_ATTACH_STATE_STATEP_ALLOC		(0x1 << 1)
319 #define	AHCI_ATTACH_STATE_REG_MAP		(0x1 << 2)
320 #define	AHCI_ATTACH_STATE_PCICFG_SETUP		(0x1 << 3)
321 #define	AHCI_ATTACH_STATE_INTR_ADDED		(0x1 << 4)
322 #define	AHCI_ATTACH_STATE_MUTEX_INIT		(0x1 << 5)
323 #define	AHCI_ATTACH_STATE_PORT_ALLOC		(0x1 << 6)
324 #define	AHCI_ATTACH_STATE_HW_INIT		(0x1 << 7)
325 #define	AHCI_ATTACH_STATE_TIMEOUT_ENABLED	(0x1 << 8)
326 
327 /* Interval used for delay */
328 #define	AHCI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 ms */
329 #define	AHCI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 ms */
330 #define	AHCI_100US_TICKS	(drv_usectohz(100))	/* ticks in 100 us */
331 #define	AHCI_10MS_USECS		(10000)		/* microsecs in 10 millisec */
332 #define	AHCI_1MS_USECS		(1000)		/* microsecs in 1 millisec */
333 #define	AHCI_100US_USECS	(100)
334 
335 /*
336  * The following values are the numbers of times to retry polled requests.
337  */
338 #define	AHCI_POLLRATE_HBA_RESET		100
339 #define	AHCI_POLLRATE_PORT_SSTATUS	10
340 #define	AHCI_POLLRATE_PORT_TFD_ERROR	1100
341 #define	AHCI_POLLRATE_PORT_IDLE		50
342 #define	AHCI_POLLRATE_PORT_SOFTRESET	100
343 #define	AHCI_POLLRATE_GET_SPKT		100
344 
345 
346 /* Clearing & setting the n'th bit in a given tag */
347 #define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
348 #define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
349 
350 
351 #if DEBUG
352 
353 #define	AHCI_DEBUG		1
354 
355 #define	AHCIDBG_INIT		0x0001
356 #define	AHCIDBG_ENTRY		0x0002
357 #define	AHCIDBG_PRDT		0x0004
358 #define	AHCIDBG_EVENT		0x0008
359 #define	AHCIDBG_POLL_LOOP	0x0010
360 #define	AHCIDBG_PKTCOMP		0x0020
361 #define	AHCIDBG_TIMEOUT		0x0040
362 #define	AHCIDBG_INFO		0x0080
363 #define	AHCIDBG_VERBOSE		0x0100
364 #define	AHCIDBG_INTR		0x0200
365 #define	AHCIDBG_ERRS		0x0400
366 #define	AHCIDBG_ATACMD		0x0800
367 #define	AHCIDBG_ATAPICMD	0x1000
368 #define	AHCIDBG_SENSEDATA	0x2000
369 #define	AHCIDBG_NCQ		0x4000
370 #define	AHCIDBG_PM		0x8000
371 #define	AHCIDBG_UNDERFLOW	0x10000
372 #define	AHCIDBG_MSI		0x20000
373 
374 extern uint32_t ahci_debug_flags;
375 
376 #define	AHCIDBG0(flag, ahci_ctlp, format)			\
377 	if (ahci_debug_flags & (flag)) {			\
378 		ahci_log(ahci_ctlp, CE_WARN, format);		\
379 	}
380 
381 #define	AHCIDBG1(flag, ahci_ctlp, format, arg1)			\
382 	if (ahci_debug_flags & (flag)) {			\
383 		ahci_log(ahci_ctlp, CE_WARN, format, arg1);	\
384 	}
385 
386 #define	AHCIDBG2(flag, ahci_ctlp, format, arg1, arg2)			\
387 	if (ahci_debug_flags & (flag)) {				\
388 		ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2);	\
389 	}
390 
391 #define	AHCIDBG3(flag, ahci_ctlp, format, arg1, arg2, arg3)		\
392 	if (ahci_debug_flags & (flag)) {				\
393 		ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2, arg3); \
394 	}
395 
396 #define	AHCIDBG4(flag, ahci_ctlp, format, arg1, arg2, arg3, arg4)	\
397 	if (ahci_debug_flags & (flag)) {				\
398 		ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2, arg3, arg4); \
399 	}
400 
401 #define	AHCIDBG5(flag, ahci_ctlp, format, arg1, arg2, arg3, arg4, arg5)	\
402 	if (ahci_debug_flags & (flag)) {				\
403 		ahci_log(ahci_ctlp, CE_WARN, format, arg1, arg2,	\
404 		    arg3, arg4, arg5); 					\
405 	}
406 #else
407 
408 #define	AHCIDBG0(flag, dip, frmt)
409 #define	AHCIDBG1(flag, dip, frmt, arg1)
410 #define	AHCIDBG2(flag, dip, frmt, arg1, arg2)
411 #define	AHCIDBG3(flag, dip, frmt, arg1, arg2, arg3)
412 #define	AHCIDBG4(flag, dip, frmt, arg1, arg2, arg3, arg4)
413 #define	AHCIDBG5(flag, dip, frmt, arg1, arg2, arg3, arg4, arg5)
414 
415 #endif /* DEBUG */
416 
417 
418 #ifdef	__cplusplus
419 }
420 #endif
421 
422 #endif /* _AHCIVAR_H */
423