Unleashed v1.4
[unleashed.git] / usr / src / uts / common / io / sata / adapters / ahci / ahci.c
blob475f8bd96e2e96c9f0648baf3b3158b142385690
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 2018 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
26 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
30 * AHCI (Advanced Host Controller Interface) SATA HBA Driver
32 * Power Management Support
33 * ------------------------
35 * At the moment, the ahci driver only implements suspend/resume to
36 * support Suspend to RAM on X86 feature. Device power management isn't
37 * implemented, link power management is disabled, and hot plug isn't
38 * allowed during the period from suspend to resume.
40 * For s/r support, the ahci driver only need to implement DDI_SUSPEND
41 * and DDI_RESUME entries, and don't need to take care of new requests
42 * sent down after suspend because the target driver (sd) has already
43 * handled these conditions, and blocked these requests. For the detailed
44 * information, please check with sdopen, sdclose and sdioctl routines.
47 * Enclosure Management Support
48 * ----------------------------
50 * The ahci driver has basic support for AHCI Enclosure Management (EM)
51 * services. The AHCI specification provides an area in the primary ahci BAR for
52 * posting data to send out to the enclosure management and provides a register
53 * that provides both information and control about this. While the
54 * specification allows for multiple forms of enclosure management, the only
55 * supported, and commonly found form, is the AHCI specified LED format. The LED
56 * format is often implemented as a one-way communication mechanism. Software
57 * can write out what it cares about into the aforementioned data buffer and
58 * then we wait for the transmission to be sent.
60 * This has some drawbacks. It means that we cannot know whether or not it has
61 * succeeded. This means we cannot ask hardware what it thinks the LEDs are
62 * set to. There's also the added unfortunate reality that firmware on the
63 * microcontroller driving this will often not show the LEDs if no drive is
64 * present and that actions taken may potentially cause this to get out of sync
65 * with what we expect it to be. For example, the specification does not
66 * describe what should happen if a drive is removed from the enclosure while
67 * this is set and what should happen when it returns. We can only infer that it
68 * should be the same.
70 * Because only a single command can be sent at any time and we don't want to
71 * interfere with controller I/O, we create a taskq dedicated to this that has a
72 * single thread. Both resets (which occur on attach and resume) and normal
73 * changes to the LED state will be driven through this taskq. Because the taskq
74 * has a single thread, this guarantees serial processing.
76 * Each userland-submitted task (basically not resets) has a reference counted
77 * task structure. This allows the thread that called it to be cancelled and
78 * have the system clean itself up. The user thread in ioctl blocks on a CV that
79 * can receive signals as it waits for completion. Note, there is no guarantee
80 * provided by the kernel that the first thread to enter the kernel will be the
81 * first one to change state.
84 #include <sys/note.h>
85 #include <sys/scsi/scsi.h>
86 #include <sys/pci.h>
87 #include <sys/disp.h>
88 #include <sys/sata/sata_hba.h>
89 #include <sys/sata/adapters/ahci/ahcireg.h>
90 #include <sys/sata/adapters/ahci/ahcivar.h>
93 * FMA header files
95 #include <sys/ddifm.h>
96 #include <sys/fm/protocol.h>
97 #include <sys/fm/util.h>
98 #include <sys/fm/io/ddi.h>
101 * EM Control header files
103 #include <sys/types.h>
104 #include <sys/file.h>
105 #include <sys/errno.h>
106 #include <sys/open.h>
107 #include <sys/cred.h>
108 #include <sys/ddi.h>
109 #include <sys/sunddi.h>
112 * This is the string displayed by modinfo, etc.
114 static char ahci_ident[] = "ahci driver";
117 * Function prototypes for driver entry points
119 static int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
120 static int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
121 static int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
122 static int ahci_quiesce(dev_info_t *);
125 * Function prototypes for SATA Framework interfaces
127 static int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
128 static int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
130 static int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
131 static int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);
132 static int ahci_tran_abort(dev_info_t *, sata_pkt_t *, int);
133 static int ahci_tran_reset_dport(dev_info_t *, sata_device_t *);
134 static int ahci_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
135 static int ahci_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
136 #if defined(__lock_lint)
137 static int ahci_selftest(dev_info_t *, sata_device_t *);
138 #endif
141 * FMA Prototypes
143 static void ahci_fm_init(ahci_ctl_t *);
144 static void ahci_fm_fini(ahci_ctl_t *);
145 static int ahci_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void*);
146 int ahci_check_acc_handle(ddi_acc_handle_t);
147 int ahci_check_dma_handle(ddi_dma_handle_t);
148 void ahci_fm_ereport(ahci_ctl_t *, char *);
149 static int ahci_check_all_handle(ahci_ctl_t *);
150 static int ahci_check_ctl_handle(ahci_ctl_t *);
151 static int ahci_check_port_handle(ahci_ctl_t *, int);
152 static int ahci_check_slot_handle(ahci_port_t *, int);
155 * Local function prototypes
157 static int ahci_setup_port_base_addresses(ahci_ctl_t *, ahci_port_t *);
158 static int ahci_alloc_ports_state(ahci_ctl_t *);
159 static void ahci_dealloc_ports_state(ahci_ctl_t *);
160 static int ahci_alloc_port_state(ahci_ctl_t *, uint8_t);
161 static void ahci_dealloc_port_state(ahci_ctl_t *, uint8_t);
162 static int ahci_alloc_rcvd_fis(ahci_ctl_t *, ahci_port_t *);
163 static void ahci_dealloc_rcvd_fis(ahci_port_t *);
164 static int ahci_alloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
165 static void ahci_dealloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
166 static int ahci_alloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
167 static void ahci_dealloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
168 static void ahci_alloc_pmult(ahci_ctl_t *, ahci_port_t *);
169 static void ahci_dealloc_pmult(ahci_ctl_t *, ahci_port_t *);
171 static int ahci_initialize_controller(ahci_ctl_t *);
172 static void ahci_uninitialize_controller(ahci_ctl_t *);
173 static int ahci_initialize_port(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
174 static int ahci_config_space_init(ahci_ctl_t *);
175 static void ahci_staggered_spin_up(ahci_ctl_t *, uint8_t);
177 static void ahci_drain_ports_taskq(ahci_ctl_t *);
178 static int ahci_rdwr_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *,
179 uint8_t);
180 static int ahci_read_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *);
181 static int ahci_write_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t);
182 static int ahci_update_pmult_pscr(ahci_ctl_t *, ahci_addr_t *,
183 sata_device_t *);
184 static int ahci_update_pmult_gscr(ahci_ctl_t *, ahci_addr_t *,
185 sata_pmult_gscr_t *);
186 static int ahci_initialize_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
187 sata_device_t *);
188 static int ahci_initialize_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
189 static int ahci_probe_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
190 static int ahci_probe_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
191 sata_device_t *);
193 static void ahci_disable_interface_pm(ahci_ctl_t *, uint8_t);
194 static int ahci_start_port(ahci_ctl_t *, ahci_port_t *, uint8_t);
195 static void ahci_find_dev_signature(ahci_ctl_t *, ahci_port_t *,
196 ahci_addr_t *);
197 static void ahci_update_sata_registers(ahci_ctl_t *, uint8_t, sata_device_t *);
198 static int ahci_deliver_satapkt(ahci_ctl_t *, ahci_port_t *,
199 ahci_addr_t *, sata_pkt_t *);
200 static int ahci_do_sync_start(ahci_ctl_t *, ahci_port_t *,
201 ahci_addr_t *, sata_pkt_t *);
202 static int ahci_claim_free_slot(ahci_ctl_t *, ahci_port_t *,
203 ahci_addr_t *, int);
204 static void ahci_copy_err_cnxt(sata_cmd_t *, ahci_fis_d2h_register_t *);
205 static void ahci_copy_ncq_err_page(sata_cmd_t *,
206 struct sata_ncq_error_recovery_page *);
207 static void ahci_copy_out_regs(sata_cmd_t *, ahci_fis_d2h_register_t *);
208 static void ahci_add_doneq(ahci_port_t *, sata_pkt_t *, int);
209 static void ahci_flush_doneq(ahci_port_t *);
211 static int ahci_software_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
212 static int ahci_hba_reset(ahci_ctl_t *);
213 static int ahci_port_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
214 static int ahci_pmport_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
215 static void ahci_reject_all_abort_pkts(ahci_ctl_t *, ahci_port_t *, uint8_t);
216 static int ahci_reset_device_reject_pkts(ahci_ctl_t *, ahci_port_t *,
217 ahci_addr_t *);
218 static int ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *, ahci_port_t *,
219 ahci_addr_t *);
220 static int ahci_reset_port_reject_pkts(ahci_ctl_t *, ahci_port_t *,
221 ahci_addr_t *);
222 static int ahci_reset_hba_reject_pkts(ahci_ctl_t *);
223 static int ahci_put_port_into_notrunning_state(ahci_ctl_t *, ahci_port_t *,
224 uint8_t);
225 static int ahci_restart_port_wait_till_ready(ahci_ctl_t *, ahci_port_t *,
226 uint8_t, int, int *);
227 static void ahci_mop_commands(ahci_ctl_t *, ahci_port_t *, uint32_t,
228 uint32_t, uint32_t, uint32_t, uint32_t);
229 static uint32_t ahci_get_rdlogext_data(ahci_ctl_t *, ahci_port_t *, uint8_t);
230 static void ahci_get_rqsense_data(ahci_ctl_t *, ahci_port_t *,
231 uint8_t, sata_pkt_t *);
232 static void ahci_fatal_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
233 ahci_addr_t *, uint32_t);
234 static void ahci_pmult_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
235 uint8_t, uint32_t);
236 static void ahci_timeout_pkts(ahci_ctl_t *, ahci_port_t *,
237 uint8_t, uint32_t);
238 static void ahci_events_handler(void *);
239 static void ahci_watchdog_handler(ahci_ctl_t *);
241 static uint_t ahci_intr(caddr_t, caddr_t);
242 static void ahci_port_intr(ahci_ctl_t *, ahci_port_t *, uint8_t);
243 static int ahci_add_intrs(ahci_ctl_t *, int);
244 static void ahci_rem_intrs(ahci_ctl_t *);
245 static void ahci_enable_all_intrs(ahci_ctl_t *);
246 static void ahci_disable_all_intrs(ahci_ctl_t *);
247 static void ahci_enable_port_intrs(ahci_ctl_t *, uint8_t);
248 static void ahci_disable_port_intrs(ahci_ctl_t *, uint8_t);
250 static int ahci_intr_cmd_cmplt(ahci_ctl_t *, ahci_port_t *, uint8_t);
251 static int ahci_intr_set_device_bits(ahci_ctl_t *, ahci_port_t *, uint8_t);
252 static int ahci_intr_ncq_events(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
253 static int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
254 static int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
255 static int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
256 ahci_port_t *, uint8_t);
257 static int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
258 static int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
259 uint8_t, uint32_t);
260 static int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
261 uint8_t, uint32_t);
262 static int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
264 static void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
265 static int ahci_get_num_implemented_ports(uint32_t);
266 static void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
267 static void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
268 static void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
269 #if AHCI_DEBUG
270 static void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
271 #endif
273 static boolean_t ahci_em_init(ahci_ctl_t *);
274 static void ahci_em_fini(ahci_ctl_t *);
275 static void ahci_em_suspend(ahci_ctl_t *);
276 static void ahci_em_resume(ahci_ctl_t *);
277 static int ahci_em_ioctl(dev_info_t *, int, intptr_t);
281 * DMA attributes for the data buffer
283 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
284 * does not support 64-bit addressing
286 static ddi_dma_attr_t buffer_dma_attr = {
287 DMA_ATTR_V0, /* dma_attr_version */
288 0x0ull, /* dma_attr_addr_lo: lowest bus address */
289 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
290 0x3fffffull, /* dma_attr_count_max i.e. for one cookie */
291 0x2ull, /* dma_attr_align: word aligned */
292 1, /* dma_attr_burstsizes */
293 1, /* dma_attr_minxfer */
294 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
295 0xffffffffull, /* dma_attr_seg */
296 AHCI_PRDT_NUMBER, /* dma_attr_sgllen */
297 512, /* dma_attr_granular */
298 0, /* dma_attr_flags */
302 * DMA attributes for the rcvd FIS
304 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
305 * does not support 64-bit addressing
307 static ddi_dma_attr_t rcvd_fis_dma_attr = {
308 DMA_ATTR_V0, /* dma_attr_version */
309 0x0ull, /* dma_attr_addr_lo: lowest bus address */
310 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
311 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
312 0x100ull, /* dma_attr_align: 256-byte aligned */
313 1, /* dma_attr_burstsizes */
314 1, /* dma_attr_minxfer */
315 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
316 0xffffffffull, /* dma_attr_seg */
317 1, /* dma_attr_sgllen */
318 1, /* dma_attr_granular */
319 0, /* dma_attr_flags */
323 * DMA attributes for the command list
325 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
326 * does not support 64-bit addressing
328 static ddi_dma_attr_t cmd_list_dma_attr = {
329 DMA_ATTR_V0, /* dma_attr_version */
330 0x0ull, /* dma_attr_addr_lo: lowest bus address */
331 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
332 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
333 0x400ull, /* dma_attr_align: 1K-byte aligned */
334 1, /* dma_attr_burstsizes */
335 1, /* dma_attr_minxfer */
336 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
337 0xffffffffull, /* dma_attr_seg */
338 1, /* dma_attr_sgllen */
339 1, /* dma_attr_granular */
340 0, /* dma_attr_flags */
344 * DMA attributes for cmd tables
346 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
347 * does not support 64-bit addressing
349 static ddi_dma_attr_t cmd_table_dma_attr = {
350 DMA_ATTR_V0, /* dma_attr_version */
351 0x0ull, /* dma_attr_addr_lo: lowest bus address */
352 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
353 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
354 0x80ull, /* dma_attr_align: 128-byte aligned */
355 1, /* dma_attr_burstsizes */
356 1, /* dma_attr_minxfer */
357 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
358 0xffffffffull, /* dma_attr_seg */
359 1, /* dma_attr_sgllen */
360 1, /* dma_attr_granular */
361 0, /* dma_attr_flags */
365 /* Device access attributes */
366 static ddi_device_acc_attr_t accattr = {
367 DDI_DEVICE_ATTR_V1,
368 DDI_STRUCTURE_LE_ACC,
369 DDI_STRICTORDER_ACC,
370 DDI_DEFAULT_ACC
373 static struct dev_ops ahcictl_dev_ops = {
374 DEVO_REV, /* devo_rev */
375 0, /* refcnt */
376 ahci_getinfo, /* info */
377 nulldev, /* identify */
378 nulldev, /* probe */
379 ahci_attach, /* attach */
380 ahci_detach, /* detach */
381 nodev, /* no reset */
382 NULL, /* driver operations */
383 NULL, /* bus operations */
384 NULL, /* power */
385 ahci_quiesce, /* quiesce */
388 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
389 SATA_TRAN_HOTPLUG_OPS_REV_1,
390 ahci_tran_hotplug_port_activate,
391 ahci_tran_hotplug_port_deactivate
394 extern struct mod_ops mod_driverops;
396 static struct modldrv modldrv = {
397 &mod_driverops, /* driverops */
398 ahci_ident, /* short description */
399 &ahcictl_dev_ops, /* driver ops */
402 static struct modlinkage modlinkage = {
403 MODREV_1,
404 &modldrv,
405 NULL
408 /* The following variables are watchdog handler related */
409 static clock_t ahci_watchdog_timeout = 5; /* 5 seconds */
410 static clock_t ahci_watchdog_tick;
413 * This static variable indicates the size of command table,
414 * and it's changeable with prdt number, which ahci_dma_prdt_number
415 * indicates.
417 static size_t ahci_cmd_table_size;
420 * The below global variables are tunable via /etc/system
422 * ahci_dma_prdt_number
423 * ahci_msi_enabled
424 * ahci_buf_64bit_dma
425 * ahci_commu_64bit_dma
428 /* The number of Physical Region Descriptor Table(PRDT) in Command Table */
429 int ahci_dma_prdt_number = AHCI_PRDT_NUMBER;
431 /* AHCI MSI is tunable */
432 boolean_t ahci_msi_enabled = B_TRUE;
435 * 64-bit dma addressing for data buffer is tunable
437 * The variable controls only the below value:
438 * DBAU (upper 32-bits physical address of data block)
440 boolean_t ahci_buf_64bit_dma = B_TRUE;
443 * 64-bit dma addressing for communication system descriptors is tunable
445 * The variable controls the below three values:
447 * PxCLBU (upper 32-bits for the command list base physical address)
448 * PxFBU (upper 32-bits for the received FIS base physical address)
449 * CTBAU (upper 32-bits of command table base)
451 boolean_t ahci_commu_64bit_dma = B_TRUE;
454 * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
455 * chipset. If the users want to have a try with 64-bit dma, please change
456 * the below variable value to enable it.
458 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
461 * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
462 * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
463 * please change the below value to enable it.
465 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
468 * These values control the default delay and default number of times to wait
469 * for an enclosure message to complete.
471 uint_t ahci_em_reset_delay_ms = 1;
472 uint_t ahci_em_reset_delay_count = 1000;
473 uint_t ahci_em_tx_delay_ms = 1;
474 uint_t ahci_em_tx_delay_count = 1000;
478 * End of global tunable variable definition
481 #if AHCI_DEBUG
482 uint32_t ahci_debug_flags = 0;
483 #else
484 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
485 #endif
488 #if AHCI_DEBUG
489 /* The following is needed for ahci_log() */
490 static kmutex_t ahci_log_mutex;
491 static char ahci_log_buf[512];
492 #endif
494 /* Opaque state pointer initialized by ddi_soft_state_init() */
495 static void *ahci_statep = NULL;
498 * ahci module initialization.
501 _init(void)
503 int ret;
505 ret = ddi_soft_state_init(&ahci_statep, sizeof (ahci_ctl_t), 0);
506 if (ret != 0) {
507 goto err_out;
510 #if AHCI_DEBUG
511 mutex_init(&ahci_log_mutex, NULL, MUTEX_DRIVER, NULL);
512 #endif
514 if ((ret = sata_hba_init(&modlinkage)) != 0) {
515 #if AHCI_DEBUG
516 mutex_destroy(&ahci_log_mutex);
517 #endif
518 ddi_soft_state_fini(&ahci_statep);
519 goto err_out;
522 /* watchdog tick */
523 ahci_watchdog_tick = drv_usectohz(
524 (clock_t)ahci_watchdog_timeout * 1000000);
526 ret = mod_install(&modlinkage);
527 if (ret != 0) {
528 sata_hba_fini(&modlinkage);
529 #if AHCI_DEBUG
530 mutex_destroy(&ahci_log_mutex);
531 #endif
532 ddi_soft_state_fini(&ahci_statep);
533 goto err_out;
536 return (ret);
538 err_out:
539 cmn_err(CE_WARN, "!ahci: Module init failed");
540 return (ret);
544 * ahci module uninitialize.
547 _fini(void)
549 int ret;
551 ret = mod_remove(&modlinkage);
552 if (ret != 0) {
553 return (ret);
556 /* Remove the resources allocated in _init(). */
557 sata_hba_fini(&modlinkage);
558 #if AHCI_DEBUG
559 mutex_destroy(&ahci_log_mutex);
560 #endif
561 ddi_soft_state_fini(&ahci_statep);
563 return (ret);
567 * _info entry point
570 _info(struct modinfo *modinfop)
572 return (mod_info(&modlinkage, modinfop));
576 * The attach entry point for dev_ops.
578 static int
579 ahci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
581 ahci_ctl_t *ahci_ctlp = NULL;
582 int instance = ddi_get_instance(dip);
583 int status;
584 int attach_state;
585 uint32_t cap_status, ahci_version;
586 uint32_t ghc_control;
587 int intr_types;
588 int i;
589 pci_regspec_t *regs;
590 int regs_length;
591 int rnumber;
592 #if AHCI_DEBUG
593 int speed;
594 #endif
596 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "ahci_attach enter",
597 NULL);
599 switch (cmd) {
600 case DDI_ATTACH:
601 break;
603 case DDI_RESUME:
606 * During DDI_RESUME, the hardware state of the device
607 * (power may have been removed from the device) must be
608 * restored, allow pending requests to continue, and
609 * service new requests.
611 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
612 mutex_enter(&ahci_ctlp->ahcictl_mutex);
615 * GHC.AE must be set to 1 before any other AHCI register
616 * is accessed
618 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
619 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
620 ghc_control |= AHCI_HBA_GHC_AE;
621 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
622 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
624 /* Restart watch thread */
625 if (ahci_ctlp->ahcictl_timeout_id == 0)
626 ahci_ctlp->ahcictl_timeout_id = timeout(
627 (void (*)(void *))ahci_watchdog_handler,
628 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
630 mutex_exit(&ahci_ctlp->ahcictl_mutex);
633 * Re-initialize the controller and enable the interrupts and
634 * restart all the ports.
636 * Note that so far we don't support hot-plug during
637 * suspend/resume.
639 if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
640 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
641 "Failed to initialize the controller "
642 "during DDI_RESUME", NULL);
643 return (DDI_FAILURE);
647 * Reset the enclosure services.
649 ahci_em_resume(ahci_ctlp);
651 mutex_enter(&ahci_ctlp->ahcictl_mutex);
652 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
653 mutex_exit(&ahci_ctlp->ahcictl_mutex);
655 return (DDI_SUCCESS);
657 default:
658 return (DDI_FAILURE);
661 attach_state = AHCI_ATTACH_STATE_NONE;
663 /* Allocate soft state */
664 status = ddi_soft_state_zalloc(ahci_statep, instance);
665 if (status != DDI_SUCCESS) {
666 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
667 instance);
668 goto err_out;
671 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
672 ahci_ctlp->ahcictl_flags |= AHCI_ATTACH;
673 ahci_ctlp->ahcictl_dip = dip;
675 /* Initialize the cport/port mapping */
676 for (i = 0; i < AHCI_MAX_PORTS; i++) {
677 ahci_ctlp->ahcictl_port_to_cport[i] = 0xff;
678 ahci_ctlp->ahcictl_cport_to_port[i] = 0xff;
681 attach_state |= AHCI_ATTACH_STATE_STATEP_ALLOC;
683 /* Initialize FMA properties */
684 ahci_fm_init(ahci_ctlp);
686 attach_state |= AHCI_ATTACH_STATE_FMA;
689 * Now map the AHCI base address; which includes global
690 * registers and port control registers
692 * According to the spec, the AHCI Base Address is BAR5,
693 * but BAR0-BAR4 are optional, so we need to check which
694 * rnumber is used for BAR5.
698 * search through DDI "reg" property for the AHCI register set
700 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
701 DDI_PROP_DONTPASS, "reg", (int **)&regs,
702 (uint_t *)&regs_length) != DDI_PROP_SUCCESS) {
703 cmn_err(CE_WARN, "!ahci%d: Cannot lookup reg property",
704 instance);
705 goto err_out;
708 /* AHCI Base Address is located at 0x24 offset */
709 for (rnumber = 0; rnumber < regs_length; ++rnumber) {
710 if ((regs[rnumber].pci_phys_hi & PCI_REG_REG_M)
711 == AHCI_PCI_RNUM)
712 break;
715 ddi_prop_free(regs);
717 if (rnumber == regs_length) {
718 cmn_err(CE_WARN, "!ahci%d: Cannot find AHCI register set",
719 instance);
720 goto err_out;
723 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "rnumber = %d", rnumber);
725 status = ddi_regs_map_setup(dip,
726 rnumber,
727 (caddr_t *)&ahci_ctlp->ahcictl_ahci_addr,
730 &accattr,
731 &ahci_ctlp->ahcictl_ahci_acc_handle);
732 if (status != DDI_SUCCESS) {
733 cmn_err(CE_WARN, "!ahci%d: Cannot map register space",
734 instance);
735 goto err_out;
738 attach_state |= AHCI_ATTACH_STATE_REG_MAP;
741 * GHC.AE must be set to 1 before any other AHCI register
742 * is accessed
744 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
745 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
746 ghc_control |= AHCI_HBA_GHC_AE;
747 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
748 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
750 /* Get the AHCI version information */
751 ahci_version = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
752 (uint32_t *)AHCI_GLOBAL_VS(ahci_ctlp));
754 cmn_err(CE_NOTE, "!ahci%d: hba AHCI version = %x.%x", instance,
755 (ahci_version & 0xffff0000) >> 16,
756 ((ahci_version & 0x0000ff00) >> 4 |
757 (ahci_version & 0x000000ff)));
759 /* We don't support controllers whose versions are lower than 1.0 */
760 if (!(ahci_version & 0xffff0000)) {
761 cmn_err(CE_WARN, "ahci%d: Don't support AHCI HBA with lower "
762 "than version 1.0", instance);
763 goto err_out;
766 /* Get the HBA capabilities information */
767 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
768 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
770 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
771 cap_status);
773 /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
774 if (ahci_version >= 0x00010200) {
775 uint32_t cap2_status;
777 /* Get the HBA capabilities extended information */
778 cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
779 (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
781 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
782 "hba capabilities extended = 0x%x", cap2_status);
785 if (cap_status & AHCI_HBA_CAP_EMS) {
786 ahci_ctlp->ahcictl_cap |= AHCI_CAP_EMS;
787 ahci_ctlp->ahcictl_em_loc =
788 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
789 (uint32_t *)AHCI_GLOBAL_EM_LOC(ahci_ctlp));
790 ahci_ctlp->ahcictl_em_ctl =
791 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
792 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
795 #if AHCI_DEBUG
796 /* Get the interface speed supported by the HBA */
797 speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
798 if (speed == 0x01) {
799 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
800 "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
801 } else if (speed == 0x10) {
802 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
803 "hba interface speed support: Gen 2 (3 Gbps)", NULL);
804 } else if (speed == 0x11) {
805 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
806 "hba interface speed support: Gen 3 (6 Gbps)", NULL);
808 #endif
810 /* Get the number of command slots supported by the HBA */
811 ahci_ctlp->ahcictl_num_cmd_slots =
812 ((cap_status & AHCI_HBA_CAP_NCS) >>
813 AHCI_HBA_CAP_NCS_SHIFT) + 1;
815 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of cmd slots: %d",
816 ahci_ctlp->ahcictl_num_cmd_slots);
818 /* Get the bit map which indicates ports implemented by the HBA */
819 ahci_ctlp->ahcictl_ports_implemented =
820 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
821 (uint32_t *)AHCI_GLOBAL_PI(ahci_ctlp));
823 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba implementation of ports: 0x%x",
824 ahci_ctlp->ahcictl_ports_implemented);
826 /* Max port number implemented */
827 ahci_ctlp->ahcictl_num_ports =
828 ddi_fls(ahci_ctlp->ahcictl_ports_implemented);
830 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of ports: %d",
831 (cap_status & AHCI_HBA_CAP_NP) + 1);
833 /* Get the number of implemented ports by the HBA */
834 ahci_ctlp->ahcictl_num_implemented_ports =
835 ahci_get_num_implemented_ports(
836 ahci_ctlp->ahcictl_ports_implemented);
838 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
839 "hba number of implemented ports: %d",
840 ahci_ctlp->ahcictl_num_implemented_ports);
842 /* Check whether HBA supports 64bit DMA addressing */
843 if (!(cap_status & AHCI_HBA_CAP_S64A)) {
844 ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
845 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
846 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
847 "hba does not support 64-bit addressing", NULL);
850 /* Checking for the support of Port Multiplier */
851 if (cap_status & AHCI_HBA_CAP_SPM) {
852 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_CBSS;
853 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
854 "hba supports port multiplier (CBSS)", NULL);
856 /* Support FIS-based switching ? */
857 if (cap_status & AHCI_HBA_CAP_FBSS) {
858 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_FBSS;
859 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
860 "hba supports FIS-based switching (FBSS)", NULL);
864 /* Checking for Support Command List Override */
865 if (cap_status & AHCI_HBA_CAP_SCLO) {
866 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SCLO;
867 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
868 "hba supports command list override.", NULL);
871 /* Checking for Asynchronous Notification */
872 if (cap_status & AHCI_HBA_CAP_SSNTF) {
873 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SNTF;
874 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
875 "hba supports asynchronous notification.", NULL);
878 if (pci_config_setup(dip, &ahci_ctlp->ahcictl_pci_conf_handle)
879 != DDI_SUCCESS) {
880 cmn_err(CE_WARN, "!ahci%d: Cannot set up pci configure space",
881 instance);
882 goto err_out;
885 attach_state |= AHCI_ATTACH_STATE_PCICFG_SETUP;
888 * Check the pci configuration space, and set caps. We also
889 * handle the hardware defect in this function.
891 * For example, force ATI SB600 to use 32-bit dma addressing
892 * since it doesn't support 64-bit dma though its CAP register
893 * declares it support.
895 if (ahci_config_space_init(ahci_ctlp) == AHCI_FAILURE) {
896 cmn_err(CE_WARN, "!ahci%d: ahci_config_space_init failed",
897 instance);
898 goto err_out;
902 * Disable the whole controller interrupts before adding
903 * interrupt handlers(s).
905 ahci_disable_all_intrs(ahci_ctlp);
907 /* Get supported interrupt types */
908 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
909 cmn_err(CE_WARN, "!ahci%d: ddi_intr_get_supported_types failed",
910 instance);
911 goto err_out;
914 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
915 "ddi_intr_get_supported_types() returned: 0x%x",
916 intr_types);
918 if (ahci_msi_enabled && (intr_types & DDI_INTR_TYPE_MSI)) {
920 * Try MSI first, but fall back to FIXED if failed
922 if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_MSI) ==
923 DDI_SUCCESS) {
924 ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_MSI;
925 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
926 "Using MSI interrupt type", NULL);
927 goto intr_done;
930 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
931 "MSI registration failed, "
932 "trying FIXED interrupts", NULL);
935 if (intr_types & DDI_INTR_TYPE_FIXED) {
936 if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_FIXED) ==
937 DDI_SUCCESS) {
938 ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_FIXED;
939 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
940 "Using FIXED interrupt type", NULL);
941 goto intr_done;
944 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
945 "FIXED interrupt registration failed", NULL);
948 cmn_err(CE_WARN, "!ahci%d: Interrupt registration failed", instance);
950 goto err_out;
952 intr_done:
954 attach_state |= AHCI_ATTACH_STATE_INTR_ADDED;
956 /* Initialize the controller mutex */
957 mutex_init(&ahci_ctlp->ahcictl_mutex, NULL, MUTEX_DRIVER,
958 (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
960 attach_state |= AHCI_ATTACH_STATE_MUTEX_INIT;
962 if (ahci_dma_prdt_number < AHCI_MIN_PRDT_NUMBER) {
963 ahci_dma_prdt_number = AHCI_MIN_PRDT_NUMBER;
964 } else if (ahci_dma_prdt_number > AHCI_MAX_PRDT_NUMBER) {
965 ahci_dma_prdt_number = AHCI_MAX_PRDT_NUMBER;
968 ahci_cmd_table_size = (sizeof (ahci_cmd_table_t) +
969 (ahci_dma_prdt_number - AHCI_PRDT_NUMBER) *
970 sizeof (ahci_prdt_item_t));
972 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
973 "ahci_attach: ahci_dma_prdt_number set by user is 0x%x,"
974 " ahci_cmd_table_size is 0x%x",
975 ahci_dma_prdt_number, ahci_cmd_table_size);
977 if (ahci_dma_prdt_number != AHCI_PRDT_NUMBER)
978 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_sgllen =
979 ahci_dma_prdt_number;
981 ahci_ctlp->ahcictl_buffer_dma_attr = buffer_dma_attr;
982 ahci_ctlp->ahcictl_rcvd_fis_dma_attr = rcvd_fis_dma_attr;
983 ahci_ctlp->ahcictl_cmd_list_dma_attr = cmd_list_dma_attr;
984 ahci_ctlp->ahcictl_cmd_table_dma_attr = cmd_table_dma_attr;
987 * enable 64bit dma for data buffer for SB600 if
988 * sb600_buf_64bit_dma_disable is B_FALSE
990 if ((ahci_buf_64bit_dma == B_FALSE) ||
991 ((ahci_ctlp->ahcictl_cap & AHCI_CAP_BUF_32BIT_DMA) &&
992 !(sb600_buf_64bit_dma_disable == B_FALSE &&
993 ahci_ctlp->ahcictl_venid == 0x1002 &&
994 ahci_ctlp->ahcictl_devid == 0x4380))) {
995 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_addr_hi =
996 0xffffffffull;
1000 * enable 64bit dma for command buffer for SB600/700/710/800
1001 * if sbxxx_commu_64bit_dma_disable is B_FALSE
1003 if ((ahci_commu_64bit_dma == B_FALSE) ||
1004 ((ahci_ctlp->ahcictl_cap & AHCI_CAP_COMMU_32BIT_DMA) &&
1005 !(sbxxx_commu_64bit_dma_disable == B_FALSE &&
1006 ahci_ctlp->ahcictl_venid == 0x1002 &&
1007 (ahci_ctlp->ahcictl_devid == 0x4380 ||
1008 ahci_ctlp->ahcictl_devid == 0x4391)))) {
1009 ahci_ctlp->ahcictl_rcvd_fis_dma_attr.dma_attr_addr_hi =
1010 0xffffffffull;
1011 ahci_ctlp->ahcictl_cmd_list_dma_attr.dma_attr_addr_hi =
1012 0xffffffffull;
1013 ahci_ctlp->ahcictl_cmd_table_dma_attr.dma_attr_addr_hi =
1014 0xffffffffull;
1017 /* Allocate the ports structure */
1018 status = ahci_alloc_ports_state(ahci_ctlp);
1019 if (status != AHCI_SUCCESS) {
1020 cmn_err(CE_WARN, "!ahci%d: Cannot allocate ports structure",
1021 instance);
1022 goto err_out;
1025 attach_state |= AHCI_ATTACH_STATE_PORT_ALLOC;
1028 * Initialize the controller and ports.
1030 status = ahci_initialize_controller(ahci_ctlp);
1031 if (status != AHCI_SUCCESS) {
1032 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
1033 instance);
1034 goto err_out;
1037 attach_state |= AHCI_ATTACH_STATE_HW_INIT;
1039 /* Start one thread to check packet timeouts */
1040 ahci_ctlp->ahcictl_timeout_id = timeout(
1041 (void (*)(void *))ahci_watchdog_handler,
1042 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
1044 attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
1046 if (!ahci_em_init(ahci_ctlp)) {
1047 cmn_err(CE_WARN, "!ahci%d: failed to initialize enclosure "
1048 "services", instance);
1049 goto err_out;
1051 attach_state |= AHCI_ATTACH_STATE_ENCLOSURE;
1053 if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
1054 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
1055 instance);
1056 goto err_out;
1059 /* Check all handles at the end of the attach operation. */
1060 if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
1061 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
1062 instance);
1063 goto err_out;
1066 ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
1068 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
1070 return (DDI_SUCCESS);
1072 err_out:
1073 /* FMA message */
1074 ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
1075 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
1077 if (attach_state & AHCI_ATTACH_STATE_ENCLOSURE) {
1078 ahci_em_fini(ahci_ctlp);
1081 if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
1082 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1083 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1084 ahci_ctlp->ahcictl_timeout_id = 0;
1085 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1088 if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1089 ahci_uninitialize_controller(ahci_ctlp);
1092 if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1093 ahci_dealloc_ports_state(ahci_ctlp);
1096 if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1097 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1100 if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {
1101 ahci_rem_intrs(ahci_ctlp);
1104 if (attach_state & AHCI_ATTACH_STATE_PCICFG_SETUP) {
1105 pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1108 if (attach_state & AHCI_ATTACH_STATE_REG_MAP) {
1109 ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1112 if (attach_state & AHCI_ATTACH_STATE_FMA) {
1113 ahci_fm_fini(ahci_ctlp);
1116 if (attach_state & AHCI_ATTACH_STATE_STATEP_ALLOC) {
1117 ddi_soft_state_free(ahci_statep, instance);
1120 return (DDI_FAILURE);
1124 * The detach entry point for dev_ops.
1126 static int
1127 ahci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1129 ahci_ctl_t *ahci_ctlp;
1130 int instance;
1131 int ret;
1133 instance = ddi_get_instance(dip);
1134 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1136 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1138 switch (cmd) {
1139 case DDI_DETACH:
1141 /* disable the interrupts for an uninterrupted detach */
1142 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1143 ahci_disable_all_intrs(ahci_ctlp);
1144 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1146 /* unregister from the sata framework. */
1147 ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1148 if (ret != AHCI_SUCCESS) {
1149 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1150 ahci_enable_all_intrs(ahci_ctlp);
1151 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1152 return (DDI_FAILURE);
1155 ahci_em_fini(ahci_ctlp);
1157 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1159 /* stop the watchdog handler */
1160 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1161 ahci_ctlp->ahcictl_timeout_id = 0;
1163 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1165 /* uninitialize the controller */
1166 ahci_uninitialize_controller(ahci_ctlp);
1168 /* remove the interrupts */
1169 ahci_rem_intrs(ahci_ctlp);
1171 /* deallocate the ports structures */
1172 ahci_dealloc_ports_state(ahci_ctlp);
1174 /* destroy mutex */
1175 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1177 /* teardown the pci config */
1178 pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1180 /* remove the reg maps. */
1181 ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1183 /* release fma resource */
1184 ahci_fm_fini(ahci_ctlp);
1186 /* free the soft state. */
1187 ddi_soft_state_free(ahci_statep, instance);
1189 return (DDI_SUCCESS);
1191 case DDI_SUSPEND:
1194 * The steps associated with suspension must include putting
1195 * the underlying device into a quiescent state so that it
1196 * will not generate interrupts or modify or access memory.
1198 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1199 if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1200 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1201 return (DDI_SUCCESS);
1204 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1206 ahci_em_suspend(ahci_ctlp);
1208 /* stop the watchdog handler */
1209 if (ahci_ctlp->ahcictl_timeout_id) {
1210 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1211 ahci_ctlp->ahcictl_timeout_id = 0;
1214 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1217 * drain the taskq
1219 ahci_drain_ports_taskq(ahci_ctlp);
1222 * Disable the interrupts and stop all the ports.
1224 ahci_uninitialize_controller(ahci_ctlp);
1226 return (DDI_SUCCESS);
1228 default:
1229 return (DDI_FAILURE);
1234 * The info entry point for dev_ops.
1237 static int
1238 ahci_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
1240 _NOTE(ARGUNUSED(dip))
1242 ahci_ctl_t *ahci_ctlp;
1243 int instance;
1244 dev_t dev;
1246 dev = (dev_t)arg;
1247 instance = getminor(dev);
1249 switch (infocmd) {
1250 case DDI_INFO_DEVT2DEVINFO:
1251 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1252 if (ahci_ctlp != NULL) {
1253 *result = ahci_ctlp->ahcictl_dip;
1254 return (DDI_SUCCESS);
1255 } else {
1256 *result = NULL;
1257 return (DDI_FAILURE);
1259 case DDI_INFO_DEVT2INSTANCE:
1260 *(int *)result = instance;
1261 break;
1262 default:
1263 break;
1266 return (DDI_SUCCESS);
1270 * Registers the ahci with sata framework.
1272 static int
1273 ahci_register_sata_hba_tran(ahci_ctl_t *ahci_ctlp, uint32_t cap_status)
1275 struct sata_hba_tran *sata_hba_tran;
1277 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
1278 "ahci_register_sata_hba_tran enter", NULL);
1280 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1282 /* Allocate memory for the sata_hba_tran */
1283 sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1285 sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1286 sata_hba_tran->sata_tran_hba_dip = ahci_ctlp->ahcictl_dip;
1287 sata_hba_tran->sata_tran_hba_dma_attr =
1288 &ahci_ctlp->ahcictl_buffer_dma_attr;
1290 /* Report the number of implemented ports */
1291 sata_hba_tran->sata_tran_hba_num_cports =
1292 ahci_ctlp->ahcictl_num_implemented_ports;
1294 /* Support ATAPI device */
1295 sata_hba_tran->sata_tran_hba_features_support = SATA_CTLF_ATAPI;
1297 /* Get the data transfer capability for PIO command by the HBA */
1298 if (cap_status & AHCI_HBA_CAP_PMD) {
1299 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PIO_MDRQ;
1300 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports multiple "
1301 "DRQ block data transfer for PIO command protocol", NULL);
1305 * According to the AHCI spec, the ATA/ATAPI-7 queued feature set
1306 * is not supported by AHCI (including the READ QUEUED (EXT), WRITE
1307 * QUEUED (EXT), and SERVICE commands). Queued operations are
1308 * supported in AHCI using the READ FPDMA QUEUED and WRITE FPDMA
1309 * QUEUED commands when the HBA and device support native command
1310 * queuing(NCQ).
1312 * SATA_CTLF_NCQ will be set to sata_tran_hba_features_support if the
1313 * CAP register of the HBA indicates NCQ is supported.
1315 * SATA_CTLF_NCQ cannot be set if AHCI_CAP_NO_MCMDLIST_NONQUEUE is
1316 * set because the previous register content of PxCI can be re-written
1317 * in the register write.
1319 if ((cap_status & AHCI_HBA_CAP_SNCQ) &&
1320 !(ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE)) {
1321 sata_hba_tran->sata_tran_hba_features_support |= SATA_CTLF_NCQ;
1322 ahci_ctlp->ahcictl_cap |= AHCI_CAP_NCQ;
1323 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports Native "
1324 "Command Queuing", NULL);
1327 /* Support port multiplier? */
1328 if (cap_status & AHCI_HBA_CAP_SPM) {
1329 sata_hba_tran->sata_tran_hba_features_support |=
1330 SATA_CTLF_PORT_MULTIPLIER;
1332 /* Support FIS-based switching for port multiplier? */
1333 if (cap_status & AHCI_HBA_CAP_FBSS) {
1334 sata_hba_tran->sata_tran_hba_features_support |=
1335 SATA_CTLF_PMULT_FBS;
1339 /* Report the number of command slots */
1340 sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1342 sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1343 sata_hba_tran->sata_tran_start = ahci_tran_start;
1344 sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1345 sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1346 sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1347 #ifdef __lock_lint
1348 sata_hba_tran->sata_tran_selftest = ahci_selftest;
1349 #endif
1351 * When SATA framework adds support for pwrmgt the
1352 * pwrmgt_ops needs to be updated
1354 sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1355 sata_hba_tran->sata_tran_ioctl = ahci_em_ioctl;
1357 ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1359 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1361 /* Attach it to SATA framework */
1362 if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1363 != DDI_SUCCESS) {
1364 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1365 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1366 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1367 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1368 return (AHCI_FAILURE);
1371 return (AHCI_SUCCESS);
1375 * Unregisters the ahci with sata framework.
1377 static int
1378 ahci_unregister_sata_hba_tran(ahci_ctl_t *ahci_ctlp)
1380 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1381 "ahci_unregister_sata_hba_tran enter", NULL);
1383 /* Detach from the SATA framework. */
1384 if (sata_hba_detach(ahci_ctlp->ahcictl_dip, DDI_DETACH) !=
1385 DDI_SUCCESS) {
1386 return (AHCI_FAILURE);
1389 /* Deallocate sata_hba_tran. */
1390 kmem_free((void *)ahci_ctlp->ahcictl_sata_hba_tran,
1391 sizeof (sata_hba_tran_t));
1393 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1394 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1395 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1397 return (AHCI_SUCCESS);
1400 #define SET_PORTSTR(str, addrp) \
1401 if (AHCI_ADDR_IS_PORT(addrp)) \
1402 (void) sprintf((str), "%d", (addrp)->aa_port); \
1403 else if (AHCI_ADDR_IS_PMULT(addrp)) \
1404 (void) sprintf((str), "%d (pmult)", (addrp)->aa_port); \
1405 else \
1406 (void) sprintf((str), "%d:%d", (addrp)->aa_port, \
1407 (addrp)->aa_pmport);
1410 * ahci_tran_probe_port is called by SATA framework. It returns port state,
1411 * port status registers and an attached device type via sata_device
1412 * structure.
1414 * We return the cached information from a previous hardware probe. The
1415 * actual hardware probing itself was done either from within
1416 * ahci_initialize_controller() during the driver attach or from a phy
1417 * ready change interrupt handler.
1419 static int
1420 ahci_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1422 ahci_ctl_t *ahci_ctlp;
1423 ahci_port_t *ahci_portp;
1424 ahci_addr_t addr, pmult_addr;
1425 uint8_t cport = sd->satadev_addr.cport;
1426 char portstr[10];
1427 uint8_t device_type;
1428 uint32_t port_state;
1429 uint8_t port;
1430 int rval = SATA_SUCCESS, rval_init;
1432 ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1433 port = ahci_ctlp->ahcictl_cport_to_port[cport];
1435 ahci_portp = ahci_ctlp->ahcictl_ports[port];
1437 mutex_enter(&ahci_portp->ahciport_mutex);
1439 ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
1440 ASSERT(AHCI_ADDR_IS_VALID(&addr));
1441 SET_PORTSTR(portstr, &addr);
1443 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1444 "ahci_tran_probe_port enter: port %s", portstr);
1446 if ((AHCI_ADDR_IS_PMULT(&addr) || AHCI_ADDR_IS_PMPORT(&addr)) &&
1447 (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1448 ahci_portp->ahciport_pmult_info == NULL)) {
1449 /* port mutliplier is removed. */
1450 AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1451 "ahci_tran_probe_port: "
1452 "pmult is removed from port %s", portstr);
1453 mutex_exit(&ahci_portp->ahciport_mutex);
1454 return (SATA_FAILURE);
1458 * The sata_device may refer to
1459 * 1. A controller port.
1460 * A controller port should be ready here.
1461 * 2. A port multiplier.
1462 * SATA_ADDR_PMULT_SPEC - if it is not initialized yet, initialize
1463 * it and register the port multiplier to the framework.
1464 * SATA_ADDR_PMULT - check the status of all its device ports.
1465 * 3. A port multiplier port.
1466 * If it has not been initialized, initialized it.
1468 * A port multiplier or a port multiplier port may require some
1469 * initialization because we cannot do these time-consuming jobs in an
1470 * interrupt context.
1472 if (sd->satadev_addr.qual & SATA_ADDR_PMULT_SPEC) {
1473 AHCI_ADDR_SET_PMULT(&pmult_addr, port);
1474 /* Initialize registers on a port multiplier */
1475 rval_init = ahci_initialize_pmult(ahci_ctlp,
1476 ahci_portp, &pmult_addr, sd);
1477 if (rval_init != AHCI_SUCCESS) {
1478 AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1479 "ahci_tran_probe_port: "
1480 "pmult initialization failed.", NULL);
1481 mutex_exit(&ahci_portp->ahciport_mutex);
1482 return (SATA_FAILURE);
1484 } else if (sd->satadev_addr.qual & SATA_ADDR_PMULT) {
1485 /* Check pmports hotplug events */
1486 (void) ahci_probe_pmult(ahci_ctlp, ahci_portp, &addr);
1487 } else if (sd->satadev_addr.qual & (SATA_ADDR_PMPORT |
1488 SATA_ADDR_DPMPORT)) {
1489 if (ahci_probe_pmport(ahci_ctlp, ahci_portp,
1490 &addr, sd) != AHCI_SUCCESS) {
1491 rval = SATA_FAILURE;
1492 goto out;
1496 /* Update port state and device type */
1497 port_state = AHCIPORT_GET_STATE(ahci_portp, &addr);
1499 switch (port_state) {
1501 case SATA_PSTATE_FAILED:
1502 sd->satadev_state = SATA_PSTATE_FAILED;
1503 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1504 "ahci_tran_probe_port: port %s PORT FAILED", portstr);
1505 goto out;
1507 case SATA_PSTATE_SHUTDOWN:
1508 sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1509 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1510 "ahci_tran_probe_port: port %s PORT SHUTDOWN", portstr);
1511 goto out;
1513 case SATA_PSTATE_PWROFF:
1514 sd->satadev_state = SATA_PSTATE_PWROFF;
1515 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1516 "ahci_tran_probe_port: port %s PORT PWROFF", portstr);
1517 goto out;
1519 case SATA_PSTATE_PWRON:
1520 sd->satadev_state = SATA_PSTATE_PWRON;
1521 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1522 "ahci_tran_probe_port: port %s PORT PWRON", portstr);
1523 break;
1525 default:
1526 sd->satadev_state = port_state;
1527 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1528 "ahci_tran_probe_port: port %s PORT NORMAL %x",
1529 portstr, port_state);
1530 break;
1533 device_type = AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1535 switch (device_type) {
1537 case SATA_DTYPE_ATADISK:
1538 sd->satadev_type = SATA_DTYPE_ATADISK;
1539 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1540 "ahci_tran_probe_port: port %s DISK found", portstr);
1541 break;
1543 case SATA_DTYPE_ATAPI:
1545 * HBA driver only knows it's an ATAPI device, and don't know
1546 * it's CD/DVD, tape or ATAPI disk because the ATAPI device
1547 * type need to be determined by checking IDENTIFY PACKET
1548 * DEVICE data
1550 sd->satadev_type = SATA_DTYPE_ATAPI;
1551 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1552 "ahci_tran_probe_port: port %s ATAPI found", portstr);
1553 break;
1555 case SATA_DTYPE_PMULT:
1556 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr));
1557 sd->satadev_type = SATA_DTYPE_PMULT;
1559 /* Update the number of pmports. */
1560 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
1561 sd->satadev_add_info = ahci_portp->
1562 ahciport_pmult_info->ahcipmi_num_dev_ports;
1564 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1565 "ahci_tran_probe_port: port %s Port Multiplier found",
1566 portstr);
1567 break;
1569 case SATA_DTYPE_UNKNOWN:
1570 sd->satadev_type = SATA_DTYPE_UNKNOWN;
1571 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1572 "ahci_tran_probe_port: port %s Unknown device found",
1573 portstr);
1574 break;
1576 default:
1577 /* we don't support any other device types */
1578 sd->satadev_type = SATA_DTYPE_NONE;
1579 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1580 "ahci_tran_probe_port: port %s No device found", portstr);
1581 break;
1584 out:
1585 /* Register update only fails while probing a pmult/pmport */
1586 if (AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr)) {
1587 ahci_update_sata_registers(ahci_ctlp, port, sd);
1588 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
1589 if (port_state & SATA_STATE_READY)
1590 if (ahci_update_pmult_pscr(ahci_ctlp,
1591 &addr, sd) != AHCI_SUCCESS)
1592 rval = SATA_FAILURE;
1595 /* Check handles for the sata registers access */
1596 if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
1597 (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
1598 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1599 DDI_SERVICE_UNAFFECTED);
1600 rval = SATA_FAILURE;
1603 mutex_exit(&ahci_portp->ahciport_mutex);
1604 return (rval);
1608 * There are four operation modes in sata framework:
1609 * SATA_OPMODE_INTERRUPTS
1610 * SATA_OPMODE_POLLING
1611 * SATA_OPMODE_ASYNCH
1612 * SATA_OPMODE_SYNCH
1614 * Their combined meanings as following:
1616 * SATA_OPMODE_SYNCH
1617 * The command has to be completed before sata_tran_start functions returns.
1618 * Either interrupts or polling could be used - it's up to the driver.
1619 * Mode used currently for internal, sata-module initiated operations.
1621 * SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS
1622 * It is the same as the one above.
1624 * SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING
1625 * The command has to be completed before sata_tran_start function returns.
1626 * No interrupt used, polling only. This should be the mode used for scsi
1627 * packets with FLAG_NOINTR.
1629 * SATA_OPMODE_ASYNCH | SATA_OPMODE_INTERRUPTS
1630 * The command may be queued (callback function specified). Interrupts could
1631 * be used. It's normal operation mode.
1634 * Called by sata framework to transport a sata packet down stream.
1636 static int
1637 ahci_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1639 ahci_ctl_t *ahci_ctlp;
1640 ahci_port_t *ahci_portp;
1641 ahci_addr_t addr;
1642 uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
1643 uint8_t port;
1644 char portstr[10];
1646 ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1647 port = ahci_ctlp->ahcictl_cport_to_port[cport];
1649 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1650 "ahci_tran_start enter: cport %d satapkt 0x%p",
1651 cport, (void *)spkt);
1653 ahci_portp = ahci_ctlp->ahcictl_ports[port];
1655 mutex_enter(&ahci_portp->ahciport_mutex);
1656 ahci_get_ahci_addr(ahci_ctlp, &spkt->satapkt_device, &addr);
1657 SET_PORTSTR(portstr, &addr);
1659 /* Sanity check */
1660 if (AHCI_ADDR_IS_PMPORT(&addr)) {
1661 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1662 ahci_portp->ahciport_pmult_info == NULL) {
1664 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1665 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1666 spkt->satapkt_device.satadev_state = SATA_STATE_UNKNOWN;
1667 ahci_update_sata_registers(ahci_ctlp, port,
1668 &spkt->satapkt_device);
1669 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1670 "ahci_tran_start returning PORT_ERROR while "
1671 "pmult removed: port: %s", portstr);
1672 mutex_exit(&ahci_portp->ahciport_mutex);
1673 return (SATA_TRAN_PORT_ERROR);
1676 if (!(AHCIPORT_GET_STATE(ahci_portp, &addr) &
1677 SATA_STATE_READY)) {
1678 if (!ddi_in_panic() ||
1679 ahci_initialize_pmport(ahci_ctlp,
1680 ahci_portp, &addr) != AHCI_SUCCESS) {
1681 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1682 spkt->satapkt_device.satadev_type =
1683 AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1684 spkt->satapkt_device.satadev_state =
1685 AHCIPORT_GET_STATE(ahci_portp, &addr);
1686 ahci_update_sata_registers(ahci_ctlp, port,
1687 &spkt->satapkt_device);
1688 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1689 "ahci_tran_start returning PORT_ERROR "
1690 "while sub-link is not initialized "
1691 "at port: %s", portstr);
1692 mutex_exit(&ahci_portp->ahciport_mutex);
1693 return (SATA_TRAN_PORT_ERROR);
1698 if (AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_FAILED ||
1699 AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_SHUTDOWN||
1700 AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_PWROFF) {
1702 * In case the target driver would send the packet before
1703 * sata framework can have the opportunity to process those
1704 * event reports.
1706 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1707 spkt->satapkt_device.satadev_state =
1708 ahci_portp->ahciport_port_state;
1709 ahci_update_sata_registers(ahci_ctlp, port,
1710 &spkt->satapkt_device);
1711 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1712 "ahci_tran_start returning PORT_ERROR while "
1713 "port in FAILED/SHUTDOWN/PWROFF state: "
1714 "port: %s", portstr);
1715 mutex_exit(&ahci_portp->ahciport_mutex);
1716 return (SATA_TRAN_PORT_ERROR);
1719 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) == SATA_DTYPE_NONE) {
1721 * ahci_intr_phyrdy_change() may have rendered it to
1722 * SATA_DTYPE_NONE.
1724 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1725 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1726 spkt->satapkt_device.satadev_state =
1727 ahci_portp->ahciport_port_state;
1728 ahci_update_sata_registers(ahci_ctlp, port,
1729 &spkt->satapkt_device);
1730 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1731 "ahci_tran_start returning PORT_ERROR while "
1732 "no device attached: port: %s", portstr);
1733 mutex_exit(&ahci_portp->ahciport_mutex);
1734 return (SATA_TRAN_PORT_ERROR);
1737 /* R/W PMULT command will occupy the whole HBA port */
1738 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
1739 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1740 "ahci_tran_start returning BUSY while "
1741 "executing READ/WRITE PORT-MULT command: "
1742 "port: %s", portstr);
1743 spkt->satapkt_reason = SATA_PKT_BUSY;
1744 mutex_exit(&ahci_portp->ahciport_mutex);
1745 return (SATA_TRAN_BUSY);
1748 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
1749 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1750 "ahci_tran_start returning BUSY while "
1751 "hot-plug in progress: port: %s", portstr);
1752 spkt->satapkt_reason = SATA_PKT_BUSY;
1753 mutex_exit(&ahci_portp->ahciport_mutex);
1754 return (SATA_TRAN_BUSY);
1758 * SATA HBA driver should remember that a device was reset and it
1759 * is supposed to reject any packets which do not specify either
1760 * SATA_IGNORE_DEV_RESET_STATE or SATA_CLEAR_DEV_RESET_STATE.
1762 * This is to prevent a race condition when a device was arbitrarily
1763 * reset by the HBA driver (and lost it's setting) and a target
1764 * driver sending some commands to a device before the sata framework
1765 * has a chance to restore the device setting (such as cache enable/
1766 * disable or other resettable stuff).
1769 * It is unnecessary to use specific flags to indicate
1770 * reset_in_progress for a pmport. While mopping, all command will be
1771 * mopped so that the entire HBA port is being dealt as a single
1772 * object.
1774 if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1775 ahci_portp->ahciport_reset_in_progress = 0;
1776 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1777 "ahci_tran_start [CLEAR] the "
1778 "reset_in_progress for port: %d", port);
1781 if (ahci_portp->ahciport_reset_in_progress &&
1782 ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1783 ! ddi_in_panic()) {
1784 spkt->satapkt_reason = SATA_PKT_BUSY;
1785 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1786 "ahci_tran_start returning BUSY while "
1787 "reset in progress: port: %d", port);
1788 mutex_exit(&ahci_portp->ahciport_mutex);
1789 return (SATA_TRAN_BUSY);
1792 #ifdef AHCI_DEBUG
1793 if (spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset) {
1794 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1795 "ahci_tran_start: packet 0x%p [PASSTHRU] at port %d",
1796 spkt, port);
1798 #endif
1800 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
1801 spkt->satapkt_reason = SATA_PKT_BUSY;
1802 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1803 "ahci_tran_start returning BUSY while "
1804 "mopping in progress: port: %d", port);
1805 mutex_exit(&ahci_portp->ahciport_mutex);
1806 return (SATA_TRAN_BUSY);
1809 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
1810 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1811 DDI_SERVICE_UNAFFECTED);
1812 mutex_exit(&ahci_portp->ahciport_mutex);
1813 return (SATA_TRAN_BUSY);
1816 if (spkt->satapkt_op_mode &
1817 (SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING)) {
1819 * If a SYNC command to be executed in interrupt context,
1820 * bounce it back to sata module.
1822 if (!(spkt->satapkt_op_mode & SATA_OPMODE_POLLING) &&
1823 servicing_interrupt()) {
1824 spkt->satapkt_reason = SATA_PKT_BUSY;
1825 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1826 "ahci_tran_start returning BUSY while "
1827 "sending SYNC mode under interrupt context: "
1828 "port : %d", port);
1829 mutex_exit(&ahci_portp->ahciport_mutex);
1830 return (SATA_TRAN_BUSY);
1833 /* We need to do the sync start now */
1834 if (ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr,
1835 spkt) == AHCI_FAILURE) {
1836 goto fail_out;
1838 } else {
1839 /* Async start, using interrupt */
1840 if (ahci_deliver_satapkt(ahci_ctlp, ahci_portp, &addr, spkt)
1841 == AHCI_FAILURE) {
1842 spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1843 goto fail_out;
1847 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_tran_start "
1848 "sata tran accepted: port %s", portstr);
1850 mutex_exit(&ahci_portp->ahciport_mutex);
1851 return (SATA_TRAN_ACCEPTED);
1853 fail_out:
1855 * Failed to deliver packet to the controller.
1856 * Check if it's caused by invalid handles.
1858 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS ||
1859 ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
1860 spkt->satapkt_device.satadev_type =
1861 AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1862 spkt->satapkt_device.satadev_state =
1863 AHCIPORT_GET_STATE(ahci_portp, &addr);
1864 spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
1865 mutex_exit(&ahci_portp->ahciport_mutex);
1866 return (SATA_TRAN_PORT_ERROR);
1869 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_tran_start "
1870 "return QUEUE_FULL: port %d", port);
1871 mutex_exit(&ahci_portp->ahciport_mutex);
1872 return (SATA_TRAN_QUEUE_FULL);
1876 * SATA_OPMODE_SYNCH flag is set
1878 * If SATA_OPMODE_POLLING flag is set, then we must poll the command
1879 * without interrupt, otherwise we can still use the interrupt.
1881 static int
1882 ahci_do_sync_start(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1883 ahci_addr_t *addrp, sata_pkt_t *spkt)
1885 int pkt_timeout_ticks;
1886 uint32_t timeout_tags;
1887 int rval;
1888 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1889 uint8_t port = addrp->aa_port;
1891 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1893 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1894 "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1896 if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1897 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1898 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1899 addrp, spkt)) == AHCI_FAILURE) {
1900 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1901 return (rval);
1904 pkt_timeout_ticks =
1905 drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1907 while (spkt->satapkt_reason == SATA_PKT_BUSY) {
1908 /* Simulate the interrupt */
1909 mutex_exit(&ahci_portp->ahciport_mutex);
1910 ahci_port_intr(ahci_ctlp, ahci_portp, port);
1911 mutex_enter(&ahci_portp->ahciport_mutex);
1913 if (spkt->satapkt_reason != SATA_PKT_BUSY)
1914 break;
1916 mutex_exit(&ahci_portp->ahciport_mutex);
1917 drv_usecwait(AHCI_1MS_USECS);
1918 mutex_enter(&ahci_portp->ahciport_mutex);
1920 pkt_timeout_ticks -= AHCI_1MS_TICKS;
1921 if (pkt_timeout_ticks < 0) {
1922 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1923 "port %d satapkt 0x%p timed out\n",
1924 instance, port, (void *)spkt);
1925 timeout_tags = (0x1 << rval);
1926 mutex_exit(&ahci_portp->ahciport_mutex);
1927 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1928 port, timeout_tags);
1929 mutex_enter(&ahci_portp->ahciport_mutex);
1933 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1934 return (AHCI_SUCCESS);
1936 } else {
1937 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1938 addrp, spkt)) == AHCI_FAILURE)
1939 return (rval);
1941 #if AHCI_DEBUG
1943 * Note that the driver always uses the slot 0 to deliver
1944 * REQUEST SENSE or READ LOG EXT command
1946 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1947 ASSERT(rval == 0);
1948 #endif
1950 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1951 cv_wait(&ahci_portp->ahciport_cv,
1952 &ahci_portp->ahciport_mutex);
1954 return (AHCI_SUCCESS);
1959 * Searches for and claims a free command slot.
1961 * Returns value:
1963 * AHCI_FAILURE returned only if
1964 * 1. No empty slot left
1965 * 2. Non-queued command requested while queued command(s) is outstanding
1966 * 3. Queued command requested while non-queued command(s) is outstanding
1967 * 4. HBA doesn't support multiple-use of command list while already a
1968 * non-queued command is oustanding
1969 * 5. Queued command requested while some queued command(s) has been
1970 * outstanding on a different port multiplier port. (AHCI spec 1.2,
1971 * 9.1.2)
1973 * claimed slot number returned if succeeded
1975 * NOTE: it will always return slot 0 for following commands to simplify the
1976 * algorithm.
1977 * 1. REQUEST SENSE or READ LOG EXT command during error recovery process
1978 * 2. READ/WRITE PORTMULT command
1980 static int
1981 ahci_claim_free_slot(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1982 ahci_addr_t *addrp, int command_type)
1984 uint32_t port_cmd_issue;
1985 uint32_t free_slots;
1986 int slot;
1988 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1990 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_claim_free_slot enter "
1991 "ahciport_pending_tags = 0x%x "
1992 "ahciport_pending_ncq_tags = 0x%x",
1993 ahci_portp->ahciport_pending_tags,
1994 ahci_portp->ahciport_pending_ncq_tags);
1997 * According to the AHCI spec, system software is responsible to
1998 * ensure that queued and non-queued commands are not mixed in
1999 * the command list.
2001 if (command_type == AHCI_NON_NCQ_CMD) {
2002 /* Non-NCQ command request */
2003 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2004 AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
2005 "ahci_claim_free_slot: there is still pending "
2006 "queued command(s) in the command list, "
2007 "so no available slot for the non-queued "
2008 "command", NULL);
2009 return (AHCI_FAILURE);
2011 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
2012 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
2013 "ahci_claim_free_slot: there is still pending "
2014 "read/write port-mult command(s) in command list, "
2015 "so no available slot for the non-queued command",
2016 NULL);
2017 return (AHCI_FAILURE);
2019 if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE) &&
2020 NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2021 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2022 "ahci_claim_free_slot: HBA cannot support multiple-"
2023 "use of the command list for non-queued commands",
2024 NULL);
2025 return (AHCI_FAILURE);
2027 free_slots = (~ahci_portp->ahciport_pending_tags) &
2028 AHCI_SLOT_MASK(ahci_ctlp);
2029 } else if (command_type == AHCI_NCQ_CMD) {
2030 /* NCQ command request */
2031 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2032 AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
2033 "ahci_claim_free_slot: there is still pending "
2034 "non-queued command(s) in the command list, "
2035 "so no available slot for the queued command",
2036 NULL);
2037 return (AHCI_FAILURE);
2041 * NCQ commands cannot be sent to different port multiplier
2042 * ports in Command-Based Switching mode
2045 * NOTE: In Command-Based Switching mode, AHCI controller
2046 * usually reports a 'Handshake Error' when multiple NCQ
2047 * commands are outstanding simultaneously.
2049 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
2050 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2051 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS) &&
2052 NCQ_CMD_IN_PROGRESS(ahci_portp) &&
2053 AHCIPORT_NCQ_PMPORT(ahci_portp) !=
2054 addrp->aa_pmport) {
2055 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2056 "ahci_claim_free_slot: there is still "
2057 "pending queued command(s) in the "
2058 "command list for another Port Multiplier "
2059 "port, so no available slot.", NULL);
2060 return (AHCI_FAILURE);
2064 free_slots = (~ahci_portp->ahciport_pending_ncq_tags) &
2065 AHCI_NCQ_SLOT_MASK(ahci_portp);
2066 } else if (command_type == AHCI_ERR_RETRI_CMD) {
2067 /* Error retrieval command request */
2068 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2069 "ahci_claim_free_slot: slot 0 is allocated for REQUEST "
2070 "SENSE or READ LOG EXT command", NULL);
2071 slot = 0;
2072 goto out;
2073 } else if (command_type == AHCI_RDWR_PMULT_CMD) {
2075 * An extra check on PxCI. Sometimes PxCI bits may not be
2076 * cleared during hot-plug or error recovery process.
2078 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2079 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, addrp->aa_port));
2081 if (port_cmd_issue != 0) {
2082 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
2083 "ahci_claim_free_slot: there is still pending "
2084 "command(s) in command list (0x%x/0x%x, PxCI %x),"
2085 "so no available slot for R/W PMULT command.",
2086 NON_NCQ_CMD_IN_PROGRESS(ahci_portp),
2087 NCQ_CMD_IN_PROGRESS(ahci_portp),
2088 port_cmd_issue);
2089 return (AHCI_FAILURE);
2092 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2093 "ahci_claim_free_slot: slot 0 is allocated for "
2094 "READ/WRITE PORTMULT command", NULL);
2095 slot = 0;
2096 goto out;
2099 slot = ddi_ffs(free_slots) - 1;
2100 if (slot == -1) {
2101 AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2102 "ahci_claim_free_slot: no empty slots", NULL);
2103 return (AHCI_FAILURE);
2107 * According to the AHCI spec, to allow a simple mechanism for the
2108 * HBA to map command list slots to queue entries, software must
2109 * match the tag number it uses to the slot it is placing the command
2110 * in. For example, if a queued command is placed in slot 5, the tag
2111 * for that command must be 5.
2113 if (command_type == AHCI_NCQ_CMD) {
2114 ahci_portp->ahciport_pending_ncq_tags |= (0x1 << slot);
2115 if (AHCI_ADDR_IS_PMPORT(addrp)) {
2116 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2117 AHCIPORT_NCQ_PMPORT(ahci_portp) = addrp->aa_pmport;
2121 ahci_portp->ahciport_pending_tags |= (0x1 << slot);
2123 out:
2124 AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2125 "ahci_claim_free_slot: found slot: 0x%x", slot);
2127 return (slot);
2131 * Builds the Command Table for the sata packet and delivers it to controller.
2133 * Returns:
2134 * slot number if we can obtain a slot successfully
2135 * otherwise, return AHCI_FAILURE
2137 static int
2138 ahci_deliver_satapkt(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
2139 ahci_addr_t *addrp, sata_pkt_t *spkt)
2141 int cmd_slot;
2142 sata_cmd_t *scmd;
2143 ahci_fis_h2d_register_t *h2d_register_fisp;
2144 ahci_cmd_table_t *cmd_table;
2145 ahci_cmd_header_t *cmd_header;
2146 int ncookies;
2147 int i;
2148 int command_type = AHCI_NON_NCQ_CMD;
2149 int ncq_qdepth;
2150 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
2151 uint8_t port, pmport;
2152 #if AHCI_DEBUG
2153 uint32_t *ptr;
2154 uint8_t *ptr2;
2155 #endif
2157 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2159 port = addrp->aa_port;
2160 pmport = addrp->aa_pmport;
2162 spkt->satapkt_reason = SATA_PKT_BUSY;
2164 scmd = &spkt->satapkt_cmd;
2166 /* Check if the command is a NCQ command */
2167 if (scmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED ||
2168 scmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) {
2169 command_type = AHCI_NCQ_CMD;
2172 * When NCQ is support, system software must determine the
2173 * maximum tag allowed by the device and the HBA, and it
2174 * must use a value not beyond of the lower bound of the two.
2176 * Sata module is going to calculate the qdepth and send
2177 * down to HBA driver via sata_cmd.
2179 ncq_qdepth = scmd->satacmd_flags.sata_max_queue_depth + 1;
2182 * At the moment, the driver doesn't support the dynamic
2183 * setting of the maximum ncq depth, and the value can be
2184 * set either during the attach or after hot-plug insertion.
2186 if (ahci_portp->ahciport_max_ncq_tags == 0) {
2187 ahci_portp->ahciport_max_ncq_tags = ncq_qdepth;
2188 AHCIDBG(AHCIDBG_NCQ, ahci_ctlp,
2189 "ahci_deliver_satapkt: port %d the max tags for "
2190 "NCQ command is %d", port, ncq_qdepth);
2191 } else {
2192 if (ncq_qdepth != ahci_portp->ahciport_max_ncq_tags) {
2193 cmn_err(CE_WARN, "!ahci%d: ahci_deliver_satapkt"
2194 " port %d the max tag for NCQ command is "
2195 "requested to change from %d to %d, at the"
2196 " moment the driver doesn't support the "
2197 "dynamic change so it's going to "
2198 "still use the previous tag value",
2199 instance, port,
2200 ahci_portp->ahciport_max_ncq_tags,
2201 ncq_qdepth);
2206 /* Check if the command is an error retrieval command */
2207 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
2208 command_type = AHCI_ERR_RETRI_CMD;
2210 /* Check if the command is an read/write pmult command */
2211 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2212 command_type = AHCI_RDWR_PMULT_CMD;
2214 /* Check if there is an empty command slot */
2215 cmd_slot = ahci_claim_free_slot(ahci_ctlp, ahci_portp,
2216 addrp, command_type);
2217 if (cmd_slot == AHCI_FAILURE) {
2218 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "no free command slot", NULL);
2219 return (AHCI_FAILURE);
2222 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INFO, ahci_ctlp,
2223 "ahci_deliver_satapkt enter: cmd_reg: 0x%x, cmd_slot: 0x%x, "
2224 "port: %d, satapkt: 0x%p", scmd->satacmd_cmd_reg,
2225 cmd_slot, port, (void *)spkt);
2227 cmd_table = ahci_portp->ahciport_cmd_tables[cmd_slot];
2228 bzero((void *)cmd_table, ahci_cmd_table_size);
2230 /* For data transfer operations, it is the H2D Register FIS */
2231 h2d_register_fisp =
2232 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
2234 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
2237 * PMP field only make sense when target is a port multiplier or a
2238 * device behind a port multiplier. Otherwise should set it to 0.
2240 if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2241 SET_FIS_PMP(h2d_register_fisp, pmport);
2243 SET_FIS_CDMDEVCTL(h2d_register_fisp, 1);
2244 SET_FIS_COMMAND(h2d_register_fisp, scmd->satacmd_cmd_reg);
2245 SET_FIS_FEATURES(h2d_register_fisp, scmd->satacmd_features_reg);
2246 SET_FIS_SECTOR_COUNT(h2d_register_fisp, scmd->satacmd_sec_count_lsb);
2248 switch (scmd->satacmd_addr_type) {
2250 case 0:
2252 * satacmd_addr_type will be 0 for the commands below:
2253 * ATAPI command
2254 * SATAC_IDLE_IM
2255 * SATAC_STANDBY_IM
2256 * SATAC_DOWNLOAD_MICROCODE
2257 * SATAC_FLUSH_CACHE
2258 * SATAC_SET_FEATURES
2259 * SATAC_SMART
2260 * SATAC_ID_PACKET_DEVICE
2261 * SATAC_ID_DEVICE
2262 * SATAC_READ_PORTMULT
2263 * SATAC_WRITE_PORTMULT
2265 /* FALLTHRU */
2267 case ATA_ADDR_LBA:
2268 /* FALLTHRU */
2270 case ATA_ADDR_LBA28:
2271 /* LBA[7:0] */
2272 SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2274 /* LBA[15:8] */
2275 SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2277 /* LBA[23:16] */
2278 SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2280 /* LBA [27:24] (also called dev_head) */
2281 SET_FIS_DEV_HEAD(h2d_register_fisp, scmd->satacmd_device_reg);
2283 break;
2285 case ATA_ADDR_LBA48:
2286 /* LBA[7:0] */
2287 SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2289 /* LBA[15:8] */
2290 SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2292 /* LBA[23:16] */
2293 SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2295 /* LBA [31:24] */
2296 SET_FIS_SECTOR_EXP(h2d_register_fisp,
2297 scmd->satacmd_lba_low_msb);
2299 /* LBA [39:32] */
2300 SET_FIS_CYL_LOW_EXP(h2d_register_fisp,
2301 scmd->satacmd_lba_mid_msb);
2303 /* LBA [47:40] */
2304 SET_FIS_CYL_HI_EXP(h2d_register_fisp,
2305 scmd->satacmd_lba_high_msb);
2307 /* Set dev_head */
2308 SET_FIS_DEV_HEAD(h2d_register_fisp,
2309 scmd->satacmd_device_reg);
2311 /* Set the extended sector count and features */
2312 SET_FIS_SECTOR_COUNT_EXP(h2d_register_fisp,
2313 scmd->satacmd_sec_count_msb);
2314 SET_FIS_FEATURES_EXP(h2d_register_fisp,
2315 scmd->satacmd_features_reg_ext);
2316 break;
2320 * For NCQ command (READ/WRITE FPDMA QUEUED), sector count 7:0 is
2321 * filled into features field, and sector count 8:15 is filled into
2322 * features (exp) field. The hba driver doesn't need to anything
2323 * special with regard to this, since sata framework has already
2324 * done so.
2326 * However the driver needs to make sure TAG is filled into sector
2327 * field.
2329 if (command_type == AHCI_NCQ_CMD) {
2330 SET_FIS_SECTOR_COUNT(h2d_register_fisp,
2331 (cmd_slot << SATA_TAG_QUEUING_SHIFT));
2334 ncookies = scmd->satacmd_num_dma_cookies;
2335 AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2336 "ncookies = 0x%x, ahci_dma_prdt_number = 0x%x",
2337 ncookies, ahci_dma_prdt_number);
2339 ASSERT(ncookies <= ahci_dma_prdt_number);
2340 ahci_portp->ahciport_prd_bytecounts[cmd_slot] = 0;
2342 /* *** now fill the scatter gather list ******* */
2343 for (i = 0; i < ncookies; i++) {
2344 cmd_table->ahcict_prdt[i].ahcipi_data_base_addr =
2345 scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[0];
2346 cmd_table->ahcict_prdt[i].ahcipi_data_base_addr_upper =
2347 scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[1];
2348 cmd_table->ahcict_prdt[i].ahcipi_descr_info =
2349 scmd->satacmd_dma_cookie_list[i].dmac_size - 1;
2350 ahci_portp->ahciport_prd_bytecounts[cmd_slot] +=
2351 scmd->satacmd_dma_cookie_list[i].dmac_size;
2354 AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2355 "ahciport_prd_bytecounts 0x%x for cmd_slot 0x%x",
2356 ahci_portp->ahciport_prd_bytecounts[cmd_slot], cmd_slot);
2358 /* The ACMD field is filled in for ATAPI command */
2359 if (scmd->satacmd_cmd_reg == SATAC_PACKET) {
2360 bcopy(scmd->satacmd_acdb, cmd_table->ahcict_atapi_cmd,
2361 SATA_ATAPI_MAX_CDB_LEN);
2364 /* Set Command Header in Command List */
2365 cmd_header = &ahci_portp->ahciport_cmd_list[cmd_slot];
2366 BZERO_DESCR_INFO(cmd_header);
2367 BZERO_PRD_BYTE_COUNT(cmd_header);
2369 /* Set the number of entries in the PRD table */
2370 SET_PRD_TABLE_LENGTH(cmd_header, ncookies);
2372 /* Set the length of the command in the CFIS area */
2373 SET_COMMAND_FIS_LENGTH(cmd_header, AHCI_H2D_REGISTER_FIS_LENGTH);
2376 * PMP field only make sense when target is a port multiplier or a
2377 * device behind a port multiplier. Otherwise should set it to 0.
2379 if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2380 SET_PORT_MULTI_PORT(cmd_header, pmport);
2382 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "command data direction is "
2383 "sata_data_direction = 0x%x",
2384 scmd->satacmd_flags.sata_data_direction);
2386 /* Set A bit if it is an ATAPI command */
2387 if (scmd->satacmd_cmd_reg == SATAC_PACKET)
2388 SET_ATAPI(cmd_header, AHCI_CMDHEAD_ATAPI);
2390 /* Set W bit if data is going to the device */
2391 if (scmd->satacmd_flags.sata_data_direction == SATA_DIR_WRITE)
2392 SET_WRITE(cmd_header, AHCI_CMDHEAD_DATA_WRITE);
2395 * Set the prefetchable bit - this bit is only valid if the PRDTL
2396 * field is non-zero or the ATAPI 'A' bit is set in the command
2397 * header. This bit cannot be set when using native command
2398 * queuing commands or when using FIS-based switching with a Port
2399 * multiplier.
2401 if (command_type != AHCI_NCQ_CMD)
2402 SET_PREFETCHABLE(cmd_header, AHCI_CMDHEAD_PREFETCHABLE);
2405 * Now remember the sata packet in ahciport_slot_pkts[].
2406 * Error retrieval command and r/w port multiplier command will
2407 * be stored specifically for each port.
2409 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
2410 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2411 ahci_portp->ahciport_slot_pkts[cmd_slot] = spkt;
2414 * Keep the timeout value
2416 ahci_portp->ahciport_slot_timeout[cmd_slot] = spkt->satapkt_time;
2419 * If the intial timout is less than 1 tick, then make it longer by
2420 * 1 tick to avoid immediate timeout
2422 if (ahci_portp->ahciport_slot_timeout[cmd_slot] <=
2423 ahci_watchdog_timeout)
2424 ahci_portp->ahciport_slot_timeout[cmd_slot] +=
2425 ahci_watchdog_timeout;
2427 #if AHCI_DEBUG
2428 if (ahci_debug_flags & AHCIDBG_ATACMD &&
2429 scmd->satacmd_cmd_reg != SATAC_PACKET ||
2430 ahci_debug_flags & AHCIDBG_ATAPICMD &&
2431 scmd->satacmd_cmd_reg == SATAC_PACKET) {
2433 /* Dump the command header and table */
2434 ahci_log(ahci_ctlp, CE_WARN, "\n");
2435 ahci_log(ahci_ctlp, CE_WARN, "Command header&table for spkt "
2436 "0x%p cmd_reg 0x%x port %d", spkt,
2437 scmd->satacmd_cmd_reg, port);
2438 ptr = (uint32_t *)cmd_header;
2439 ahci_log(ahci_ctlp, CE_WARN,
2440 " Command Header:%8x %8x %8x %8x",
2441 ptr[0], ptr[1], ptr[2], ptr[3]);
2443 /* Dump the H2D register FIS */
2444 ptr = (uint32_t *)h2d_register_fisp;
2445 ahci_log(ahci_ctlp, CE_WARN,
2446 " Command FIS: %8x %8x %8x %8x",
2447 ptr[0], ptr[1], ptr[2], ptr[3]);
2449 /* Dump the ACMD register FIS */
2450 ptr2 = (uint8_t *)&(cmd_table->ahcict_atapi_cmd);
2451 for (i = 0; i < SATA_ATAPI_MAX_CDB_LEN/8; i++)
2452 if (ahci_debug_flags & AHCIDBG_ATAPICMD)
2453 ahci_log(ahci_ctlp, CE_WARN,
2454 " ATAPI command: %2x %2x %2x %2x "
2455 "%2x %2x %2x %2x",
2456 ptr2[8 * i], ptr2[8 * i + 1],
2457 ptr2[8 * i + 2], ptr2[8 * i + 3],
2458 ptr2[8 * i + 4], ptr2[8 * i + 5],
2459 ptr2[8 * i + 6], ptr2[8 * i + 7]);
2461 /* Dump the PRDT */
2462 for (i = 0; i < ncookies; i++) {
2463 ptr = (uint32_t *)&(cmd_table->ahcict_prdt[i]);
2464 ahci_log(ahci_ctlp, CE_WARN,
2465 " Cookie %d: %8x %8x %8x %8x",
2466 i, ptr[0], ptr[1], ptr[2], ptr[3]);
2469 #endif
2471 (void) ddi_dma_sync(
2472 ahci_portp->ahciport_cmd_tables_dma_handle[cmd_slot],
2474 ahci_cmd_table_size,
2475 DDI_DMA_SYNC_FORDEV);
2477 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
2478 cmd_slot * sizeof (ahci_cmd_header_t),
2479 sizeof (ahci_cmd_header_t),
2480 DDI_DMA_SYNC_FORDEV);
2482 if ((ahci_check_dma_handle(ahci_portp->
2483 ahciport_cmd_tables_dma_handle[cmd_slot]) != DDI_FM_OK) ||
2484 ahci_check_dma_handle(ahci_portp->
2485 ahciport_cmd_list_dma_handle) != DDI_FM_OK) {
2486 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2487 DDI_SERVICE_UNAFFECTED);
2488 return (AHCI_FAILURE);
2491 /* Set the corresponding bit in the PxSACT.DS for queued command */
2492 if (command_type == AHCI_NCQ_CMD) {
2493 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2494 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port),
2495 (0x1 << cmd_slot));
2498 /* Indicate to the HBA that a command is active. */
2499 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2500 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
2501 (0x1 << cmd_slot));
2503 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_deliver_satapkt "
2504 "exit: port %d", port);
2506 /* Make sure the command is started by the PxSACT/PxCI */
2507 if (ahci_check_acc_handle(ahci_ctlp->
2508 ahcictl_ahci_acc_handle) != DDI_FM_OK) {
2509 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2510 DDI_SERVICE_UNAFFECTED);
2511 return (AHCI_FAILURE);
2514 return (cmd_slot);
2518 * Called by the sata framework to abort the previously sent packet(s).
2520 * Reset device to abort commands.
2522 static int
2523 ahci_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
2525 ahci_ctl_t *ahci_ctlp;
2526 ahci_port_t *ahci_portp;
2527 uint32_t slot_status = 0;
2528 uint32_t aborted_tags = 0;
2529 uint32_t finished_tags = 0;
2530 uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
2531 uint8_t port;
2532 int tmp_slot;
2533 int instance = ddi_get_instance(dip);
2535 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
2536 port = ahci_ctlp->ahcictl_cport_to_port[cport];
2538 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2539 "ahci_tran_abort enter: port %d", port);
2541 ahci_portp = ahci_ctlp->ahcictl_ports[port];
2542 mutex_enter(&ahci_portp->ahciport_mutex);
2545 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2546 * commands are being mopped, therefore there is nothing else to do
2548 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2549 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2550 "ahci_tran_abort: port %d is in "
2551 "mopping process, so just return directly ", port);
2552 mutex_exit(&ahci_portp->ahciport_mutex);
2553 return (SATA_SUCCESS);
2557 * If AHCI_PORT_FLAG_RDWR_PMULT flag is set, it means a R/W PMULT
2558 * command is being executed so no other commands is outstanding,
2559 * nothing to do.
2561 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_RDWR_PMULT) {
2562 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2563 "ahci_tran_abort: port %d is reading/writing "
2564 "port multiplier, so just return directly ", port);
2565 mutex_exit(&ahci_portp->ahciport_mutex);
2566 return (SATA_SUCCESS);
2569 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
2570 ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
2571 ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
2573 * In case the targer driver would send the request before
2574 * sata framework can have the opportunity to process those
2575 * event reports.
2577 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2578 spkt->satapkt_device.satadev_state =
2579 ahci_portp->ahciport_port_state;
2580 ahci_update_sata_registers(ahci_ctlp, port,
2581 &spkt->satapkt_device);
2582 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2583 "ahci_tran_abort returning SATA_FAILURE while "
2584 "port in FAILED/SHUTDOWN/PWROFF state: "
2585 "port: %d", port);
2586 mutex_exit(&ahci_portp->ahciport_mutex);
2587 return (SATA_FAILURE);
2590 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
2592 * ahci_intr_phyrdy_change() may have rendered it to
2593 * AHCI_PORT_TYPE_NODEV.
2595 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2596 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
2597 spkt->satapkt_device.satadev_state =
2598 ahci_portp->ahciport_port_state;
2599 ahci_update_sata_registers(ahci_ctlp, port,
2600 &spkt->satapkt_device);
2601 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2602 "ahci_tran_abort returning SATA_FAILURE while "
2603 "no device attached: port: %d", port);
2604 mutex_exit(&ahci_portp->ahciport_mutex);
2605 return (SATA_FAILURE);
2608 if (flag == SATA_ABORT_ALL_PACKETS) {
2609 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2610 aborted_tags = ahci_portp->ahciport_pending_tags;
2611 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2612 aborted_tags = ahci_portp->ahciport_pending_ncq_tags;
2614 cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort all packets",
2615 instance, port);
2616 } else {
2617 aborted_tags = 0xffffffff;
2619 * Aborting one specific packet, first search the
2620 * ahciport_slot_pkts[] list for matching spkt.
2622 for (tmp_slot = 0;
2623 tmp_slot < ahci_ctlp->ahcictl_num_cmd_slots; tmp_slot++) {
2624 if (ahci_portp->ahciport_slot_pkts[tmp_slot] == spkt) {
2625 aborted_tags = (0x1 << tmp_slot);
2626 break;
2630 if (aborted_tags == 0xffffffff) {
2631 /* request packet is not on the pending list */
2632 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2633 "Cannot find the aborting pkt 0x%p on the "
2634 "pending list", (void *)spkt);
2635 ahci_update_sata_registers(ahci_ctlp, port,
2636 &spkt->satapkt_device);
2637 mutex_exit(&ahci_portp->ahciport_mutex);
2638 return (SATA_FAILURE);
2640 cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort satapkt 0x%p",
2641 instance, port, (void *)spkt);
2644 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2645 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2646 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2647 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2648 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2649 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2651 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2652 ahci_portp->ahciport_mop_in_progress++;
2655 * To abort the packet(s), first we are trying to clear PxCMD.ST
2656 * to stop the port, and if the port can be stopped
2657 * successfully with PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0',
2658 * then we just send back the aborted packet(s) with ABORTED flag
2659 * and then restart the port by setting PxCMD.ST and PxCMD.FRE.
2660 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then we
2661 * perform a COMRESET.
2663 (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
2664 ahci_portp, port, 0, NULL);
2667 * Compute which have finished and which need to be retried.
2669 * The finished tags are ahciport_pending_tags/ahciport_pending_ncq_tags
2670 * minus the slot_status. The aborted_tags has to be deducted by
2671 * finished_tags since we can't possibly abort a tag which had finished
2672 * already.
2674 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2675 finished_tags = ahci_portp->ahciport_pending_tags &
2676 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2677 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2678 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2679 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2681 aborted_tags &= ~finished_tags;
2683 ahci_mop_commands(ahci_ctlp,
2684 ahci_portp,
2685 slot_status,
2686 0, /* failed tags */
2687 0, /* timeout tags */
2688 aborted_tags,
2689 0); /* reset tags */
2691 ahci_update_sata_registers(ahci_ctlp, port, &spkt->satapkt_device);
2692 mutex_exit(&ahci_portp->ahciport_mutex);
2694 return (SATA_SUCCESS);
2698 * Used to do device reset and reject all the pending packets on a device
2699 * during the reset operation.
2701 * NOTE: ONLY called by ahci_tran_reset_dport
2703 static int
2704 ahci_reset_device_reject_pkts(ahci_ctl_t *ahci_ctlp,
2705 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2707 uint32_t slot_status = 0;
2708 uint32_t reset_tags = 0;
2709 uint32_t finished_tags = 0;
2710 uint8_t port = addrp->aa_port;
2711 sata_device_t sdevice;
2712 int ret;
2714 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2716 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2717 "ahci_reset_device_reject_pkts on port: %d", port);
2720 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2721 * commands are being mopped, therefore there is nothing else to do
2723 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2724 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2725 "ahci_reset_device_reject_pkts: port %d is in "
2726 "mopping process, so return directly ", port);
2727 return (SATA_SUCCESS);
2730 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2731 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2732 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2733 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2734 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2735 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2736 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2737 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2740 if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2741 != AHCI_SUCCESS) {
2742 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2743 "Try to do a port reset after software "
2744 "reset failed", port);
2745 ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
2746 if (ret != AHCI_SUCCESS) {
2747 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2748 "ahci_reset_device_reject_pkts: port %d "
2749 "failed", port);
2750 return (SATA_FAILURE);
2753 /* Set the reset in progress flag */
2754 ahci_portp->ahciport_reset_in_progress = 1;
2756 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2757 ahci_portp->ahciport_mop_in_progress++;
2759 /* Indicate to the framework that a reset has happened */
2760 bzero((void *)&sdevice, sizeof (sata_device_t));
2761 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2762 sdevice.satadev_addr.pmport = 0;
2763 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
2764 sdevice.satadev_state = SATA_DSTATE_RESET |
2765 SATA_DSTATE_PWR_ACTIVE;
2766 mutex_exit(&ahci_portp->ahciport_mutex);
2767 sata_hba_event_notify(
2768 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2769 &sdevice,
2770 SATA_EVNT_DEVICE_RESET);
2771 mutex_enter(&ahci_portp->ahciport_mutex);
2773 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2774 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
2776 /* Next try to mop the pending commands */
2777 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2778 finished_tags = ahci_portp->ahciport_pending_tags &
2779 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2780 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2781 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2782 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2784 reset_tags &= ~finished_tags;
2786 ahci_mop_commands(ahci_ctlp,
2787 ahci_portp,
2788 slot_status,
2789 0, /* failed tags */
2790 0, /* timeout tags */
2791 0, /* aborted tags */
2792 reset_tags); /* reset tags */
2794 return (SATA_SUCCESS);
2798 * Used to do device reset and reject all the pending packets on a device
2799 * during the reset operation.
2801 * NOTE: ONLY called by ahci_tran_reset_dport
2803 static int
2804 ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *ahci_ctlp,
2805 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2807 uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
2808 uint8_t port = addrp->aa_port;
2809 uint8_t pmport = addrp->aa_pmport;
2810 sata_device_t sdevice;
2812 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2814 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_PMULT, ahci_ctlp,
2815 "ahci_reset_pmdevice_reject_pkts at port %d:%d", port, pmport);
2817 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2818 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2819 "ahci_reset_pmdevice_reject_pkts: port %d is in "
2820 "mopping process, so return directly ", port);
2821 return (SATA_SUCCESS);
2824 /* Checking for outstanding commands */
2825 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2826 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2827 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2828 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2829 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2830 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2831 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2832 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2835 /* Issue SOFTWARE reset command. */
2836 if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2837 != AHCI_SUCCESS) {
2838 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2839 "Try to do a port reset after software "
2840 "reset failed", port);
2841 return (SATA_FAILURE);
2844 /* Set the reset in progress flag */
2845 ahci_portp->ahciport_reset_in_progress = 1;
2847 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2848 ahci_portp->ahciport_mop_in_progress++;
2850 /* Indicate to the framework that a reset has happened */
2851 bzero((void *)&sdevice, sizeof (sata_device_t));
2852 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2853 sdevice.satadev_addr.pmport = pmport;
2854 if (AHCI_ADDR_IS_PMULT(addrp))
2855 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
2856 else
2857 sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
2858 sdevice.satadev_state = SATA_DSTATE_RESET |
2859 SATA_DSTATE_PWR_ACTIVE;
2860 mutex_exit(&ahci_portp->ahciport_mutex);
2861 sata_hba_event_notify(
2862 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2863 &sdevice,
2864 SATA_EVNT_DEVICE_RESET);
2865 mutex_enter(&ahci_portp->ahciport_mutex);
2867 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2868 "port %d:%d sending event up: SATA_EVNT_DEVICE_RESET",
2869 port, pmport);
2871 /* Next try to mop the pending commands */
2872 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2873 finished_tags = ahci_portp->ahciport_pending_tags &
2874 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2875 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2876 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2877 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2878 reset_tags &= ~finished_tags;
2880 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
2881 "reset_tags = %x, finished_tags = %x, slot_status = %x",
2882 reset_tags, finished_tags, slot_status);
2885 * NOTE: Because PxCI be only erased by unset PxCMD.ST bit, so even we
2886 * try to reset a single device behind a port multiplier will
2887 * terminate all the commands on that HBA port. We need mop these
2888 * commands as well.
2890 ahci_mop_commands(ahci_ctlp,
2891 ahci_portp,
2892 slot_status,
2893 0, /* failed tags */
2894 0, /* timeout tags */
2895 0, /* aborted tags */
2896 reset_tags); /* reset tags */
2898 return (SATA_SUCCESS);
2902 * Used to do port reset and reject all the pending packets on a port during
2903 * the reset operation.
2905 static int
2906 ahci_reset_port_reject_pkts(ahci_ctl_t *ahci_ctlp,
2907 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2909 uint32_t slot_status = 0;
2910 uint32_t reset_tags = 0;
2911 uint32_t finished_tags = 0;
2912 uint8_t port = addrp->aa_port;
2914 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2916 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2917 "ahci_reset_port_reject_pkts at port: %d", port);
2920 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2921 * commands are being mopped, therefore there is nothing else to do
2923 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2924 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2925 "ahci_reset_port_reject_pkts: port %d is in "
2926 "mopping process, so return directly ", port);
2927 return (SATA_SUCCESS);
2930 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2931 ahci_portp->ahciport_mop_in_progress++;
2933 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2934 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2935 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2936 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2937 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2938 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2939 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2940 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2943 if (ahci_restart_port_wait_till_ready(ahci_ctlp,
2944 ahci_portp, port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
2945 NULL) != AHCI_SUCCESS) {
2947 /* Clear mop flag */
2948 ahci_portp->ahciport_mop_in_progress--;
2949 if (ahci_portp->ahciport_mop_in_progress == 0)
2950 ahci_portp->ahciport_flags &=
2951 ~AHCI_PORT_FLAG_MOPPING;
2952 return (SATA_FAILURE);
2955 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2956 finished_tags = ahci_portp->ahciport_pending_tags &
2957 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2958 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2959 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2960 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2962 reset_tags &= ~finished_tags;
2964 ahci_mop_commands(ahci_ctlp,
2965 ahci_portp,
2966 slot_status,
2967 0, /* failed tags */
2968 0, /* timeout tags */
2969 0, /* aborted tags */
2970 reset_tags); /* reset tags */
2972 return (SATA_SUCCESS);
2976 * Used to do hba reset and reject all the pending packets on all ports
2977 * during the reset operation.
2979 static int
2980 ahci_reset_hba_reject_pkts(ahci_ctl_t *ahci_ctlp)
2982 ahci_port_t *ahci_portp;
2983 uint32_t slot_status[AHCI_MAX_PORTS];
2984 uint32_t reset_tags[AHCI_MAX_PORTS];
2985 uint32_t finished_tags[AHCI_MAX_PORTS];
2986 int port;
2987 int ret = SATA_SUCCESS;
2989 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2990 "ahci_reset_hba_reject_pkts enter", NULL);
2992 bzero(slot_status, sizeof (slot_status));
2993 bzero(reset_tags, sizeof (reset_tags));
2994 bzero(finished_tags, sizeof (finished_tags));
2996 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
2997 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
2998 continue;
3001 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3003 mutex_enter(&ahci_portp->ahciport_mutex);
3004 ahci_portp->ahciport_reset_in_progress = 1;
3005 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3006 slot_status[port] = ddi_get32(
3007 ahci_ctlp->ahcictl_ahci_acc_handle,
3008 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3009 reset_tags[port] = slot_status[port] &
3010 AHCI_SLOT_MASK(ahci_ctlp);
3011 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3012 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3013 port, reset_tags[port],
3014 ahci_portp->ahciport_pending_tags);
3015 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3016 slot_status[port] = ddi_get32(
3017 ahci_ctlp->ahcictl_ahci_acc_handle,
3018 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3019 reset_tags[port] = slot_status[port] &
3020 AHCI_NCQ_SLOT_MASK(ahci_portp);
3021 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3022 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3023 port, reset_tags[port],
3024 ahci_portp->ahciport_pending_tags);
3026 mutex_exit(&ahci_portp->ahciport_mutex);
3029 if (ahci_hba_reset(ahci_ctlp) != AHCI_SUCCESS) {
3030 ret = SATA_FAILURE;
3033 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3034 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3035 continue;
3038 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3040 mutex_enter(&ahci_portp->ahciport_mutex);
3042 * To prevent recursive enter to ahci_mop_commands, we need
3043 * check AHCI_PORT_FLAG_MOPPING flag.
3045 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3046 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3047 "ahci_reset_hba_reject_pkts: port %d is in "
3048 "mopping process, so return directly ", port);
3049 mutex_exit(&ahci_portp->ahciport_mutex);
3050 continue;
3053 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3054 ahci_portp->ahciport_mop_in_progress++;
3056 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
3057 finished_tags[port] =
3058 ahci_portp->ahciport_pending_tags &
3059 ~slot_status[port] & AHCI_SLOT_MASK(ahci_ctlp);
3060 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
3061 finished_tags[port] =
3062 ahci_portp->ahciport_pending_ncq_tags &
3063 ~slot_status[port] & AHCI_NCQ_SLOT_MASK(ahci_portp);
3065 reset_tags[port] &= ~finished_tags[port];
3067 ahci_mop_commands(ahci_ctlp,
3068 ahci_portp,
3069 slot_status[port],
3070 0, /* failed tags */
3071 0, /* timeout tags */
3072 0, /* aborted tags */
3073 reset_tags[port]); /* reset tags */
3074 mutex_exit(&ahci_portp->ahciport_mutex);
3076 out:
3077 return (ret);
3081 * Called by sata framework to reset a port(s) or device.
3083 static int
3084 ahci_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
3086 ahci_ctl_t *ahci_ctlp;
3087 ahci_port_t *ahci_portp;
3088 ahci_addr_t addr;
3089 uint8_t cport = sd->satadev_addr.cport;
3090 uint8_t pmport = sd->satadev_addr.pmport;
3091 uint8_t port;
3092 int ret = SATA_SUCCESS;
3093 int instance = ddi_get_instance(dip);
3095 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3096 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3097 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3099 ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
3101 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3102 "ahci_tran_reset_dport enter: cport %d", cport);
3104 switch (sd->satadev_addr.qual) {
3105 case SATA_ADDR_PMPORT:
3107 * If we want to issue a COMRESET on a pmport, we need to
3108 * reject the outstanding commands on that pmport. According
3109 * to AHCI spec, PxCI register could only be cleared by
3110 * clearing PxCMD.ST, which will halt the controller port - as
3111 * well as other pmports.
3113 * Therefore we directly reset the controller port for
3114 * simplicity. ahci_tran_probe_port() will handle reset stuff
3115 * like initializing the given pmport.
3117 /* FALLTHRU */
3118 case SATA_ADDR_CPORT:
3119 /* Port reset */
3120 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3121 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3122 "port %d reset port", instance, port);
3124 mutex_enter(&ahci_portp->ahciport_mutex);
3125 ret = ahci_reset_port_reject_pkts(ahci_ctlp, ahci_portp, &addr);
3126 mutex_exit(&ahci_portp->ahciport_mutex);
3128 break;
3130 case SATA_ADDR_DPMPORT:
3131 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3132 "port %d:%d reset device", instance, port, pmport);
3133 /* FALLTHRU */
3134 case SATA_ADDR_DCPORT:
3135 /* Device reset */
3136 if (sd->satadev_addr.qual == SATA_ADDR_DCPORT)
3137 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3138 "port %d reset device", instance, port);
3140 mutex_enter(&ahci_portp->ahciport_mutex);
3142 * software reset request must be sent to SATA_PMULT_HOSTPORT
3143 * if target is a port multiplier:
3145 if (sd->satadev_addr.qual == SATA_ADDR_DCPORT &&
3146 ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT)
3147 AHCI_ADDR_SET_PMULT(&addr, port);
3149 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
3150 ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
3151 ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
3153 * In case the targer driver would send the request
3154 * before sata framework can have the opportunity to
3155 * process those event reports.
3157 sd->satadev_state = ahci_portp->ahciport_port_state;
3158 ahci_update_sata_registers(ahci_ctlp, port, sd);
3159 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3160 "ahci_tran_reset_dport returning SATA_FAILURE "
3161 "while port in FAILED/SHUTDOWN/PWROFF state: "
3162 "port: %d", port);
3163 mutex_exit(&ahci_portp->ahciport_mutex);
3164 ret = SATA_FAILURE;
3165 break;
3168 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) ==
3169 SATA_DTYPE_NONE) {
3171 * ahci_intr_phyrdy_change() may have rendered it to
3172 * AHCI_PORT_TYPE_NODEV.
3174 sd->satadev_type = SATA_DTYPE_NONE;
3175 sd->satadev_state = AHCIPORT_GET_STATE(ahci_portp,
3176 &addr);
3177 ahci_update_sata_registers(ahci_ctlp, port, sd);
3178 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3179 "ahci_tran_reset_dport returning SATA_FAILURE "
3180 "while no device attached: port: %d", port);
3181 mutex_exit(&ahci_portp->ahciport_mutex);
3182 ret = SATA_FAILURE;
3183 break;
3186 if (AHCI_ADDR_IS_PORT(&addr)) {
3187 ret = ahci_reset_device_reject_pkts(ahci_ctlp,
3188 ahci_portp, &addr);
3189 } else {
3190 ret = ahci_reset_pmdevice_reject_pkts(ahci_ctlp,
3191 ahci_portp, &addr);
3194 mutex_exit(&ahci_portp->ahciport_mutex);
3195 break;
3197 case SATA_ADDR_CNTRL:
3198 /* Reset the whole controller */
3199 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3200 "reset the whole hba", instance);
3201 ret = ahci_reset_hba_reject_pkts(ahci_ctlp);
3202 break;
3204 default:
3205 ret = SATA_FAILURE;
3208 return (ret);
3212 * Called by sata framework to activate a port as part of hotplug.
3213 * (cfgadm -c connect satax/y)
3214 * Support port multiplier.
3216 static int
3217 ahci_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
3219 ahci_ctl_t *ahci_ctlp;
3220 ahci_port_t *ahci_portp;
3221 ahci_addr_t addr;
3222 uint8_t cport = satadev->satadev_addr.cport;
3223 uint8_t pmport = satadev->satadev_addr.pmport;
3224 uint8_t port;
3225 int instance = ddi_get_instance(dip);
3227 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3228 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3230 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3231 "ahci_tran_hotplug_port_activate enter: cport %d", cport);
3233 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3235 mutex_enter(&ahci_portp->ahciport_mutex);
3236 ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3237 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3239 if (AHCI_ADDR_IS_PORT(&addr)) {
3240 cmn_err(CE_NOTE, "!ahci%d: ahci port %d is activated",
3241 instance, port);
3243 /* Enable the interrupts on the port */
3244 ahci_enable_port_intrs(ahci_ctlp, port);
3247 * Reset the port so that the PHY communication would be
3248 * re-established. But this reset is an internal operation
3249 * and the sata module doesn't need to know about it.
3250 * Moreover, the port with a device attached will be started
3251 * too.
3253 (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
3254 ahci_portp, port,
3255 AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
3256 NULL);
3259 * Need to check the link status and device status of the port
3260 * and consider raising power if the port was in D3 state
3262 ahci_portp->ahciport_port_state |= SATA_PSTATE_PWRON;
3263 ahci_portp->ahciport_port_state &= ~SATA_PSTATE_PWROFF;
3264 ahci_portp->ahciport_port_state &= ~SATA_PSTATE_SHUTDOWN;
3265 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3266 cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is activated",
3267 instance, port, pmport);
3268 /* AHCI_ADDR_PMPORT */
3269 AHCIPORT_PMSTATE(ahci_portp, &addr) |= SATA_PSTATE_PWRON;
3270 AHCIPORT_PMSTATE(ahci_portp, &addr) &=
3271 ~(SATA_PSTATE_PWROFF|SATA_PSTATE_SHUTDOWN);
3274 satadev->satadev_state = ahci_portp->ahciport_port_state;
3276 ahci_update_sata_registers(ahci_ctlp, port, satadev);
3278 mutex_exit(&ahci_portp->ahciport_mutex);
3279 return (SATA_SUCCESS);
3283 * Called by sata framework to deactivate a port as part of hotplug.
3284 * (cfgadm -c disconnect satax/y)
3285 * Support port multiplier.
3287 static int
3288 ahci_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
3290 ahci_ctl_t *ahci_ctlp;
3291 ahci_port_t *ahci_portp;
3292 ahci_addr_t addr;
3293 uint8_t cport = satadev->satadev_addr.cport;
3294 uint8_t pmport = satadev->satadev_addr.pmport;
3295 uint8_t port;
3296 uint32_t port_scontrol;
3297 int instance = ddi_get_instance(dip);
3299 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3300 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3302 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3303 "ahci_tran_hotplug_port_deactivate enter: cport %d", cport);
3305 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3306 mutex_enter(&ahci_portp->ahciport_mutex);
3307 ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3308 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3310 if (AHCI_ADDR_IS_PORT(&addr)) {
3311 cmn_err(CE_NOTE, "!ahci%d: ahci port %d is deactivated",
3312 instance, port);
3314 /* Disable the interrupts on the port */
3315 ahci_disable_port_intrs(ahci_ctlp, port);
3317 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
3319 /* First to abort all the pending commands */
3320 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3322 /* Then stop the port */
3323 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3324 ahci_portp, port);
3327 /* Next put the PHY offline */
3328 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3329 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
3330 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_DISABLE);
3331 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle, (uint32_t *)
3332 AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
3333 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3334 cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is deactivated",
3335 instance, port, pmport);
3337 ahci_disable_port_intrs(ahci_ctlp, port);
3338 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr)
3339 != SATA_DTYPE_NONE)
3340 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3342 /* Re-enable the interrupts for the other pmports */
3343 ahci_enable_port_intrs(ahci_ctlp, port);
3346 /* Update port state */
3347 AHCIPORT_SET_STATE(ahci_portp, &addr, SATA_PSTATE_SHUTDOWN);
3348 satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
3350 ahci_update_sata_registers(ahci_ctlp, port, satadev);
3352 mutex_exit(&ahci_portp->ahciport_mutex);
3353 return (SATA_SUCCESS);
3357 * To be used to mark all the outstanding pkts with SATA_PKT_ABORTED
3358 * when a device is unplugged or a port is deactivated.
3360 static void
3361 ahci_reject_all_abort_pkts(ahci_ctl_t *ahci_ctlp,
3362 ahci_port_t *ahci_portp, uint8_t port)
3364 uint32_t slot_status = 0;
3365 uint32_t abort_tags = 0;
3367 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3369 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
3370 "ahci_reject_all_abort_pkts at port: %d", port);
3372 /* Read/write port multiplier command takes highest priority */
3373 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
3374 slot_status = 0x1;
3375 abort_tags = 0x1;
3376 goto out;
3380 * When AHCI_PORT_FLAG_MOPPING is set, we need to check whether a
3381 * REQUEST SENSE command or READ LOG EXT command is delivered to HBA
3382 * to get the error data, if yes when the device is removed, the
3383 * command needs to be aborted too.
3385 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3386 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
3387 slot_status = 0x1;
3388 abort_tags = 0x1;
3389 goto out;
3390 } else {
3391 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3392 "ahci_reject_all_abort_pkts return directly "
3393 "port %d no needs to reject any outstanding "
3394 "commands", port);
3395 return;
3399 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3400 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3401 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3402 abort_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
3403 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3404 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3405 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3406 abort_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
3409 out:
3410 /* No need to do mop when there is no outstanding commands */
3411 if (slot_status != 0) {
3412 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3413 ahci_portp->ahciport_mop_in_progress++;
3415 ahci_mop_commands(ahci_ctlp,
3416 ahci_portp,
3417 slot_status,
3418 0, /* failed tags */
3419 0, /* timeout tags */
3420 abort_tags, /* aborting tags */
3421 0); /* reset tags */
3425 #if defined(__lock_lint)
3426 static int
3427 ahci_selftest(dev_info_t *dip, sata_device_t *device)
3429 return (SATA_SUCCESS);
3431 #endif
3434 * Initialize fma capabilities and register with IO fault services.
3436 static void
3437 ahci_fm_init(ahci_ctl_t *ahci_ctlp)
3440 * Need to change iblock to priority for new MSI intr
3442 ddi_iblock_cookie_t fm_ibc;
3444 ahci_ctlp->ahcictl_fm_cap = ddi_getprop(DDI_DEV_T_ANY,
3445 ahci_ctlp->ahcictl_dip,
3446 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
3447 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
3448 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
3450 /* Only register with IO Fault Services if we have some capability */
3451 if (ahci_ctlp->ahcictl_fm_cap) {
3452 /* Adjust access and dma attributes for FMA */
3453 accattr.devacc_attr_access = DDI_FLAGERR_ACC;
3454 buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3455 rcvd_fis_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3456 cmd_list_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3457 cmd_table_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3460 * Register capabilities with IO Fault Services.
3461 * ahcictl_fm_cap will be updated to indicate
3462 * capabilities actually supported (not requested.)
3464 ddi_fm_init(ahci_ctlp->ahcictl_dip,
3465 &ahci_ctlp->ahcictl_fm_cap, &fm_ibc);
3467 if (ahci_ctlp->ahcictl_fm_cap == DDI_FM_NOT_CAPABLE) {
3468 cmn_err(CE_WARN, "!ahci%d: fma init failed.",
3469 ddi_get_instance(ahci_ctlp->ahcictl_dip));
3470 return;
3473 * Initialize pci ereport capabilities if ereport
3474 * capable (should always be.)
3476 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3477 DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3478 pci_ereport_setup(ahci_ctlp->ahcictl_dip);
3482 * Register error callback if error callback capable.
3484 if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3485 ddi_fm_handler_register(ahci_ctlp->ahcictl_dip,
3486 ahci_fm_error_cb, (void *) ahci_ctlp);
3489 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3490 "ahci_fm_fini: fma enabled.", NULL);
3495 * Releases fma capabilities and un-registers with IO fault services.
3497 static void
3498 ahci_fm_fini(ahci_ctl_t *ahci_ctlp)
3500 /* Only unregister FMA capabilities if registered */
3501 if (ahci_ctlp->ahcictl_fm_cap) {
3503 * Un-register error callback if error callback capable.
3505 if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3506 ddi_fm_handler_unregister(ahci_ctlp->ahcictl_dip);
3510 * Release any resources allocated by pci_ereport_setup()
3512 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3513 DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3514 pci_ereport_teardown(ahci_ctlp->ahcictl_dip);
3517 /* Unregister from IO Fault Services */
3518 ddi_fm_fini(ahci_ctlp->ahcictl_dip);
3520 /* Adjust access and dma attributes for FMA */
3521 accattr.devacc_attr_access = DDI_DEFAULT_ACC;
3522 buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3523 rcvd_fis_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3524 cmd_list_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3525 cmd_table_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3527 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3528 "ahci_fm_fini: fma disabled.", NULL);
3532 /*ARGSUSED*/
3533 static int
3534 ahci_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
3537 * as the driver can always deal with an error in any dma or
3538 * access handle, we can just return the fme_status value.
3540 pci_ereport_post(dip, err, NULL);
3541 return (err->fme_status);
3545 ahci_check_acc_handle(ddi_acc_handle_t handle)
3547 ddi_fm_error_t de;
3549 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
3550 return (de.fme_status);
3554 ahci_check_dma_handle(ddi_dma_handle_t handle)
3556 ddi_fm_error_t de;
3558 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
3559 return (de.fme_status);
3563 * Generate an ereport
3565 void
3566 ahci_fm_ereport(ahci_ctl_t *ahci_ctlp, char *detail)
3568 uint64_t ena;
3569 char buf[FM_MAX_CLASS];
3571 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
3572 ena = fm_ena_generate(0, FM_ENA_FMT1);
3573 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3574 ddi_fm_ereport_post(ahci_ctlp->ahcictl_dip, buf, ena,
3575 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
3576 FM_EREPORT_VERSION, NULL);
3581 * Check if all handles are correctly allocated.
3583 static int
3584 ahci_check_all_handle(ahci_ctl_t *ahci_ctlp)
3586 int port;
3588 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
3589 return (DDI_FAILURE);
3592 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3593 ahci_port_t *ahci_portp;
3595 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3596 continue;
3598 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3600 mutex_enter(&ahci_portp->ahciport_mutex);
3601 if (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
3602 mutex_exit(&ahci_portp->ahciport_mutex);
3603 return (DDI_FAILURE);
3605 mutex_exit(&ahci_portp->ahciport_mutex);
3608 return (DDI_SUCCESS);
3612 * Check the access handles for the controller. Note that
3613 * ahcictl_pci_conf_handle is only used in attach process.
3615 static int
3616 ahci_check_ctl_handle(ahci_ctl_t *ahci_ctlp)
3618 if ((ahci_check_acc_handle(ahci_ctlp->
3619 ahcictl_pci_conf_handle) != DDI_FM_OK) ||
3620 (ahci_check_acc_handle(ahci_ctlp->
3621 ahcictl_ahci_acc_handle) != DDI_FM_OK)) {
3622 return (DDI_FAILURE);
3624 return (DDI_SUCCESS);
3628 * Check the DMA handles and the access handles of a controller port.
3630 static int
3631 ahci_check_port_handle(ahci_ctl_t *ahci_ctlp, int port)
3633 ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
3634 int slot;
3636 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3638 if ((ahci_check_dma_handle(ahci_portp->
3639 ahciport_rcvd_fis_dma_handle) != DDI_FM_OK) ||
3640 (ahci_check_dma_handle(ahci_portp->
3641 ahciport_cmd_list_dma_handle) != DDI_FM_OK) ||
3642 (ahci_check_acc_handle(ahci_portp->
3643 ahciport_rcvd_fis_acc_handle) != DDI_FM_OK) ||
3644 (ahci_check_acc_handle(ahci_portp->
3645 ahciport_cmd_list_acc_handle) != DDI_FM_OK)) {
3646 return (DDI_FAILURE);
3648 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
3649 if (ahci_check_slot_handle(ahci_portp, slot)
3650 != DDI_SUCCESS) {
3651 return (DDI_FAILURE);
3654 return (DDI_SUCCESS);
3658 * Check the DMA handles and the access handles of a cmd table slot.
3660 static int
3661 ahci_check_slot_handle(ahci_port_t *ahci_portp, int slot)
3663 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3665 if ((ahci_check_acc_handle(ahci_portp->
3666 ahciport_cmd_tables_acc_handle[slot]) != DDI_FM_OK) ||
3667 (ahci_check_dma_handle(ahci_portp->
3668 ahciport_cmd_tables_dma_handle[slot]) != DDI_FM_OK)) {
3669 return (DDI_FAILURE);
3671 return (DDI_SUCCESS);
3675 * Allocate the ports structure, only called by ahci_attach
3677 static int
3678 ahci_alloc_ports_state(ahci_ctl_t *ahci_ctlp)
3680 int port, cport = 0;
3682 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3683 "ahci_alloc_ports_state enter", NULL);
3685 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3687 /* Allocate structures only for the implemented ports */
3688 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3689 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3690 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3691 "hba port %d not implemented", port);
3692 continue;
3695 ahci_ctlp->ahcictl_cport_to_port[cport] = (uint8_t)port;
3696 ahci_ctlp->ahcictl_port_to_cport[port] =
3697 (uint8_t)cport++;
3699 if (ahci_alloc_port_state(ahci_ctlp, port) != AHCI_SUCCESS) {
3700 goto err_out;
3704 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3705 return (AHCI_SUCCESS);
3707 err_out:
3708 for (port--; port >= 0; port--) {
3709 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3710 ahci_dealloc_port_state(ahci_ctlp, port);
3714 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3715 return (AHCI_FAILURE);
3719 * Reverse of ahci_alloc_ports_state(), only called by ahci_detach
3721 static void
3722 ahci_dealloc_ports_state(ahci_ctl_t *ahci_ctlp)
3724 int port;
3726 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3727 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3728 /* if this port is implemented by the HBA */
3729 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3730 ahci_dealloc_port_state(ahci_ctlp, port);
3732 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3736 * Drain the taskq.
3738 static void
3739 ahci_drain_ports_taskq(ahci_ctl_t *ahci_ctlp)
3741 ahci_port_t *ahci_portp;
3742 int port;
3744 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3745 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3746 continue;
3749 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3751 mutex_enter(&ahci_portp->ahciport_mutex);
3752 ddi_taskq_wait(ahci_portp->ahciport_event_taskq);
3753 mutex_exit(&ahci_portp->ahciport_mutex);
3758 * Initialize the controller and all ports. And then try to start the ports
3759 * if there are devices attached.
3761 * This routine can be called from three seperate cases: DDI_ATTACH,
3762 * PM_LEVEL_D0 and DDI_RESUME. The DDI_ATTACH case is different from
3763 * other two cases; device signature probing are attempted only during
3764 * DDI_ATTACH case.
3766 static int
3767 ahci_initialize_controller(ahci_ctl_t *ahci_ctlp)
3769 ahci_port_t *ahci_portp;
3770 ahci_addr_t addr;
3771 int port;
3773 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3774 "ahci_initialize_controller enter", NULL);
3776 /* Disable the whole controller interrupts */
3777 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3778 ahci_disable_all_intrs(ahci_ctlp);
3779 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3781 /* Initialize the implemented ports and structures */
3782 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3783 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3784 continue;
3787 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3788 mutex_enter(&ahci_portp->ahciport_mutex);
3791 * Ensure that the controller is not in the running state
3792 * by checking every implemented port's PxCMD register
3794 AHCI_ADDR_SET_PORT(&addr, (uint8_t)port);
3796 if (ahci_initialize_port(ahci_ctlp, ahci_portp, &addr)
3797 != AHCI_SUCCESS) {
3798 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3799 "ahci_initialize_controller: failed to "
3800 "initialize port %d", port);
3802 * Set the port state to SATA_PSTATE_FAILED if
3803 * failed to initialize it.
3805 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
3808 mutex_exit(&ahci_portp->ahciport_mutex);
3811 /* Enable the whole controller interrupts */
3812 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3813 ahci_enable_all_intrs(ahci_ctlp);
3814 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3816 return (AHCI_SUCCESS);
3820 * Reverse of ahci_initialize_controller()
3822 * We only need to stop the ports and disable the interrupt.
3824 static void
3825 ahci_uninitialize_controller(ahci_ctl_t *ahci_ctlp)
3827 ahci_port_t *ahci_portp;
3828 int port;
3830 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3831 "ahci_uninitialize_controller enter", NULL);
3833 /* disable all the interrupts. */
3834 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3835 ahci_disable_all_intrs(ahci_ctlp);
3836 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3838 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3839 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3840 continue;
3843 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3845 /* Stop the port by clearing PxCMD.ST */
3846 mutex_enter(&ahci_portp->ahciport_mutex);
3849 * Here we must disable the port interrupt because
3850 * ahci_disable_all_intrs only clear GHC.IE, and IS
3851 * register will be still set if PxIE is enabled.
3852 * When ahci shares one IRQ with other drivers, the
3853 * intr handler may claim the intr mistakenly.
3855 ahci_disable_port_intrs(ahci_ctlp, port);
3856 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3857 ahci_portp, port);
3858 mutex_exit(&ahci_portp->ahciport_mutex);
3863 * ahci_alloc_pmult()
3864 * 1. Setting HBA port registers which are necessary for a port multiplier.
3865 * (Set PxCMD.PMA while PxCMD.ST is '0')
3866 * 2. Allocate ahci_pmult_info structure.
3868 * NOTE: Must stop port before the function is called.
3870 static void
3871 ahci_alloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3873 uint32_t port_cmd_status;
3874 uint8_t port = ahci_portp->ahciport_port_num;
3876 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3878 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3879 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3881 /* The port must have been stopped before. */
3882 ASSERT(!(port_cmd_status & AHCI_CMD_STATUS_ST));
3884 if (!(port_cmd_status & AHCI_CMD_STATUS_PMA)) {
3885 /* set PMA bit */
3886 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3887 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3888 port_cmd_status|AHCI_CMD_STATUS_PMA);
3890 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3891 "ahci_alloc_pmult: "
3892 "PxCMD.PMA bit set at port %d.", port);
3895 /* Allocate port multiplier information structure */
3896 if (ahci_portp->ahciport_pmult_info == NULL) {
3897 ahci_portp->ahciport_pmult_info = (ahci_pmult_info_t *)
3898 kmem_zalloc(sizeof (ahci_pmult_info_t), KM_SLEEP);
3901 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
3905 * ahci_dealloc_pmult()
3906 * 1. Clearing related registers when a port multiplier is detached.
3907 * (Clear PxCMD.PMA while PxCMD.ST is '0')
3908 * 2. Deallocate ahci_pmult_info structure.
3910 * NOTE: Must stop port before the function is called.
3912 static void
3913 ahci_dealloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3915 uint32_t port_cmd_status;
3916 uint8_t port = ahci_portp->ahciport_port_num;
3918 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3920 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3921 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3923 if (port_cmd_status & AHCI_CMD_STATUS_PMA) {
3924 /* Clear PMA bit */
3925 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3926 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3927 (port_cmd_status & (~AHCI_CMD_STATUS_PMA)));
3929 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3930 "ahci_dealloc_pmult: "
3931 "PxCMD.PMA bit cleared at port %d.", port);
3934 /* Release port multiplier information structure */
3935 if (ahci_portp->ahciport_pmult_info != NULL) {
3936 kmem_free(ahci_portp->ahciport_pmult_info,
3937 sizeof (ahci_pmult_info_t));
3938 ahci_portp->ahciport_pmult_info = NULL;
3943 * Staggered Spin-up.
3945 static void
3946 ahci_staggered_spin_up(ahci_ctl_t *ahci_ctlp, uint8_t port)
3948 uint32_t cap_status;
3949 uint32_t port_cmd_status;
3951 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
3953 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3954 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
3956 /* Check for staggered spin-up support */
3957 if (!(cap_status & AHCI_HBA_CAP_SSS))
3958 return;
3960 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3961 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3963 /* If PxCMD.SUD == 1, no staggered spin-up is needed */
3964 if (port_cmd_status & AHCI_CMD_STATUS_SUD)
3965 return;
3967 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "Spin-up at port %d", port);
3969 /* Set PxCMD.SUD */
3970 port_cmd_status |= AHCI_CMD_STATUS_SUD;
3971 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3972 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3973 port_cmd_status);
3977 * The routine is to initialize a port. First put the port in NotRunning
3978 * state, then enable port interrupt and clear Serror register. And under
3979 * AHCI_ATTACH case, find device signature and then try to start the port.
3981 * Called by
3982 * 1. ahci_initialize_controller
3983 * 2. ahci_intr_phyrdy_change (hotplug)
3985 static int
3986 ahci_initialize_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
3987 ahci_addr_t *addrp)
3989 uint32_t port_sstatus, port_task_file, port_cmd_status;
3990 uint8_t port = addrp->aa_port;
3991 boolean_t resuming = B_TRUE; /* processing DDI_RESUME */
3992 int ret;
3994 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3996 /* AHCI_ADDR_PORT: We've no idea of the attached device here. */
3997 ASSERT(AHCI_ADDR_IS_PORT(addrp));
4000 * At the time being, only probe ports/devices and get the types of
4001 * attached devices during DDI_ATTACH. In fact, the device can be
4002 * changed during power state changes, but at the time being, we
4003 * don't support the situation.
4005 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4006 resuming = B_FALSE;
4007 } else {
4008 /* check for DDI_RESUME case */
4009 mutex_exit(&ahci_portp->ahciport_mutex);
4010 mutex_enter(&ahci_ctlp->ahcictl_mutex);
4011 if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH)
4012 resuming = B_FALSE;
4013 mutex_exit(&ahci_ctlp->ahcictl_mutex);
4014 mutex_enter(&ahci_portp->ahciport_mutex);
4017 if (resuming) {
4019 * During the resume, we need to set the PxCLB, PxCLBU, PxFB
4020 * and PxFBU registers in case these registers were cleared
4021 * during the suspend.
4023 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4024 "ahci_initialize_port: port %d "
4025 "set PxCLB, PxCLBU, PxFB and PxFBU "
4026 "during resume", port);
4028 if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
4029 AHCI_SUCCESS)
4030 return (AHCI_FAILURE);
4033 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4034 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
4036 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4037 "ahci_initialize_port: port %d ", port);
4040 * Check whether the port is in NotRunning state, if not,
4041 * put the port in NotRunning state
4043 if (port_cmd_status &
4044 (AHCI_CMD_STATUS_ST |
4045 AHCI_CMD_STATUS_CR |
4046 AHCI_CMD_STATUS_FRE |
4047 AHCI_CMD_STATUS_FR)) {
4048 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
4049 ahci_portp, port);
4052 /* Make sure the drive is spun-up */
4053 ahci_staggered_spin_up(ahci_ctlp, port);
4055 /* Disable interrupt */
4056 ahci_disable_port_intrs(ahci_ctlp, port);
4058 /* Device is unknown at first */
4059 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4061 /* Disable the interface power management */
4062 ahci_disable_interface_pm(ahci_ctlp, port);
4064 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4065 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
4066 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4067 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
4069 /* Check physcial link status */
4070 if (SSTATUS_GET_IPM(port_sstatus) == SSTATUS_IPM_NODEV_NOPHYCOM ||
4071 SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_NOPHYCOM ||
4073 /* Check interface status */
4074 port_task_file & AHCI_TFD_STS_BSY ||
4075 port_task_file & AHCI_TFD_STS_DRQ ||
4077 /* Check whether port reset must be executed */
4078 ahci_ctlp->ahcictl_cap & AHCI_CAP_INIT_PORT_RESET ||
4080 /* Always reset port on RESUME */
4081 resuming != B_FALSE) {
4083 /* Something went wrong, we need do some reset things */
4084 ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
4086 /* Does port reset succeed on HBA port? */
4087 if (ret != AHCI_SUCCESS) {
4088 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4089 "ahci_initialize_port:"
4090 "port reset failed at port %d", port);
4091 return (AHCI_FAILURE);
4094 /* Is port failed? */
4095 if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4096 SATA_PSTATE_FAILED) {
4097 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4098 "ahci_initialize_port: port %d state 0x%x",
4099 port, ahci_portp->ahciport_port_state);
4100 return (AHCI_FAILURE);
4104 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4105 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "port %d is ready now.", port);
4108 * Try to get the device signature if the port is not empty.
4110 if (!resuming && AHCIPORT_DEV_TYPE(ahci_portp, addrp) !=
4111 SATA_DTYPE_NONE)
4112 ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4114 /* Return directly if no device connected */
4115 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_NONE) {
4116 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4117 "No device connected to port %d", port);
4118 goto out;
4121 /* If this is a port multiplier, we need do some initialization */
4122 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
4123 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4124 "Port multiplier found at port %d", port);
4125 ahci_alloc_pmult(ahci_ctlp, ahci_portp);
4128 /* Try to start the port */
4129 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
4130 != AHCI_SUCCESS) {
4131 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4132 "failed to start port %d", port);
4133 return (AHCI_FAILURE);
4135 out:
4136 /* Enable port interrupts */
4137 ahci_enable_port_intrs(ahci_ctlp, port);
4139 return (AHCI_SUCCESS);
4143 * Handle hardware defect, and check the capabilities. For example,
4144 * power management capabilty and MSI capability.
4146 static int
4147 ahci_config_space_init(ahci_ctl_t *ahci_ctlp)
4149 ushort_t caps_ptr, cap_count, cap;
4150 #if AHCI_DEBUG
4151 ushort_t pmcap, pmcsr;
4152 ushort_t msimc;
4153 #endif
4154 uint8_t revision;
4156 ahci_ctlp->ahcictl_venid =
4157 pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4158 PCI_CONF_VENID);
4160 ahci_ctlp->ahcictl_devid =
4161 pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4162 PCI_CONF_DEVID);
4165 * Modify dma_attr_align of ahcictl_buffer_dma_attr. For VT8251, those
4166 * controllers with 0x00 revision id work on 4-byte aligned buffer,
4167 * which is a bug and was fixed after 0x00 revision id controllers.
4169 * Moreover, VT8251 cannot use multiple command slots in the command
4170 * list for non-queued commands because the previous register content
4171 * of PxCI can be re-written in the register write, so a flag will be
4172 * set to record this defect - AHCI_CAP_NO_MCMDLIST_NONQUEUE.
4174 * For VT8251, software reset also has the same defect as the below
4175 * AMD/ATI chipset. That is, software reset will get failed if 0xf
4176 * is filled in pmport field. Therefore, another software reset need
4177 * to be done with 0 filled in pmport field.
4179 if (ahci_ctlp->ahcictl_venid == VIA_VENID) {
4180 revision = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4181 PCI_CONF_REVID);
4182 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4183 "revision id = 0x%x", revision);
4184 if (revision == 0x00) {
4185 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_align = 0x4;
4186 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4187 "change ddi_attr_align to 0x4", NULL);
4190 ahci_ctlp->ahcictl_cap |= AHCI_CAP_NO_MCMDLIST_NONQUEUE;
4191 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4192 "VT8251 cannot use multiple command lists for "
4193 "non-queued commands", NULL);
4195 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4199 * AMD/ATI SB600 (0x1002,0x4380) AHCI chipset doesn't support 64-bit
4200 * DMA addressing for communication memory descriptors though S64A bit
4201 * of CAP register declares it supports. Even though 64-bit DMA for
4202 * data buffer works on ASUS M2A-VM with newer BIOS, three other
4203 * motherboards are known not, so both AHCI_CAP_BUF_32BIT_DMA and
4204 * AHCI_CAP_COMMU_32BIT_DMA are set for this controller.
4206 * Due to certain hardware issue, the chipset must do port reset during
4207 * initialization, otherwise, when retrieving device signature,
4208 * software reset will get time out. So AHCI_CAP_INIT_PORT_RESET flag
4209 * need to set.
4211 * For this chipset software reset will get failure if the pmport of
4212 * Register FIS was set with SATA_PMULT_HOSTPORT (0xf) and no port
4213 * multiplier is connected to the port. In order to fix the issue,
4214 * AHCI_CAP_SRST_NO_HOSTPORT flag need to be set, and once software
4215 * reset got failure, the driver will try to do another software reset
4216 * with pmport 0.
4218 if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4219 ahci_ctlp->ahcictl_devid == 0x4380) {
4220 ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
4221 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4222 ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4223 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4225 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4226 "ATI SB600 cannot do 64-bit DMA for both data buffer and "
4227 "communication memory descriptors though CAP indicates "
4228 "support, so force it to use 32-bit DMA", NULL);
4229 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4230 "ATI SB600 need to do a port reset during initialization",
4231 NULL);
4232 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4233 "ATI SB600 will get software reset failure if pmport "
4234 "is set 0xf and no port multiplier is attached", NULL);
4238 * AMD/ATI SB700/710/750/800 and SP5100 AHCI chipset share the same
4239 * vendor ID and device ID (0x1002,0x4391).
4241 * SB700/750 AHCI chipset on some boards doesn't support 64-bit
4242 * DMA addressing for communication memory descriptors though S64A bit
4243 * of CAP register declares the support. However, it does support
4244 * 64-bit DMA for data buffer. So only AHCI_CAP_COMMU_32BIT_DMA is
4245 * set for this controller.
4247 * SB710 has the same initialization issue as SB600, so it also need
4248 * a port reset. That is AHCI_CAP_INIT_PORT_RESET need to set for it.
4250 * SB700 also has the same issue about software reset, and thus
4251 * AHCI_CAP_SRST_NO_HOSTPORT flag also is needed.
4253 if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4254 ahci_ctlp->ahcictl_devid == 0x4391) {
4255 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4256 ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4257 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4259 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4260 "ATI SB700/750 cannot do 64-bit DMA for communication "
4261 "memory descriptors though CAP indicates support, "
4262 "so force it to use 32-bit DMA", NULL);
4263 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4264 "ATI SB710 need to do a port reset during initialization",
4265 NULL);
4266 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4267 "ATI SB700 will get software reset failure if pmport "
4268 "is set 0xf and no port multiplier is attached", NULL);
4272 * Check if capabilities list is supported and if so,
4273 * get initial capabilities pointer and clear bits 0,1.
4275 if (pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4276 PCI_CONF_STAT) & PCI_STAT_CAP) {
4277 caps_ptr = P2ALIGN(pci_config_get8(
4278 ahci_ctlp->ahcictl_pci_conf_handle,
4279 PCI_CONF_CAP_PTR), 4);
4280 } else {
4281 caps_ptr = PCI_CAP_NEXT_PTR_NULL;
4285 * Walk capabilities if supported.
4287 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
4290 * Check that we haven't exceeded the maximum number of
4291 * capabilities and that the pointer is in a valid range.
4293 if (++cap_count > PCI_CAP_MAX_PTR) {
4294 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4295 "too many device capabilities", NULL);
4296 return (AHCI_FAILURE);
4298 if (caps_ptr < PCI_CAP_PTR_OFF) {
4299 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4300 "capabilities pointer 0x%x out of range",
4301 caps_ptr);
4302 return (AHCI_FAILURE);
4306 * Get next capability and check that it is valid.
4307 * For now, we only support power management.
4309 cap = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4310 caps_ptr);
4311 switch (cap) {
4312 case PCI_CAP_ID_PM:
4314 /* power management supported */
4315 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PM;
4317 /* Save PMCSR offset */
4318 ahci_ctlp->ahcictl_pmcsr_offset = caps_ptr + PCI_PMCSR;
4320 #if AHCI_DEBUG
4321 pmcap = pci_config_get16(
4322 ahci_ctlp->ahcictl_pci_conf_handle,
4323 caps_ptr + PCI_PMCAP);
4324 pmcsr = pci_config_get16(
4325 ahci_ctlp->ahcictl_pci_conf_handle,
4326 ahci_ctlp->ahcictl_pmcsr_offset);
4327 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4328 "Power Management capability found PCI_PMCAP "
4329 "= 0x%x PCI_PMCSR = 0x%x", pmcap, pmcsr);
4330 if ((pmcap & 0x3) == 0x3)
4331 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4332 "PCI Power Management Interface "
4333 "spec 1.2 compliant", NULL);
4334 #endif
4335 break;
4337 case PCI_CAP_ID_MSI:
4338 #if AHCI_DEBUG
4339 msimc = pci_config_get16(
4340 ahci_ctlp->ahcictl_pci_conf_handle,
4341 caps_ptr + PCI_MSI_CTRL);
4342 AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4343 "Message Signaled Interrupt capability found "
4344 "MSICAP_MC.MMC = 0x%x", (msimc & 0xe) >> 1);
4345 #endif
4346 AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4347 "MSI capability found", NULL);
4348 break;
4350 case PCI_CAP_ID_PCIX:
4351 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4352 "PCI-X capability found", NULL);
4353 break;
4355 case PCI_CAP_ID_PCI_E:
4356 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4357 "PCI Express capability found", NULL);
4358 break;
4360 case PCI_CAP_ID_MSI_X:
4361 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4362 "MSI-X capability found", NULL);
4363 break;
4365 case PCI_CAP_ID_SATA:
4366 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4367 "SATA capability found", NULL);
4368 break;
4370 case PCI_CAP_ID_VS:
4371 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4372 "Vendor Specific capability found", NULL);
4373 break;
4375 default:
4376 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4377 "unrecognized capability 0x%x", cap);
4378 break;
4382 * Get next capabilities pointer and clear bits 0,1.
4384 caps_ptr = P2ALIGN(pci_config_get8(
4385 ahci_ctlp->ahcictl_pci_conf_handle,
4386 (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
4389 return (AHCI_SUCCESS);
4393 * Read/Write a register at port multiplier by SATA READ PORTMULT / SATA WRITE
4394 * PORTMULT command. SYNC & POLLING mode is used.
4396 static int
4397 ahci_rdwr_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4398 uint8_t regn, uint32_t *pregv, uint8_t type)
4400 ahci_port_t *ahci_portp;
4401 ahci_addr_t pmult_addr;
4402 sata_pkt_t *spkt;
4403 sata_cmd_t *scmd;
4404 sata_device_t sata_device;
4405 uint8_t port = addrp->aa_port;
4406 uint8_t pmport = addrp->aa_pmport;
4407 uint8_t cport;
4408 uint32_t intr_mask;
4409 int rval;
4410 char portstr[10];
4412 SET_PORTSTR(portstr, addrp);
4413 cport = ahci_ctlp->ahcictl_port_to_cport[port];
4414 ahci_portp = ahci_ctlp->ahcictl_ports[port];
4416 ASSERT(AHCI_ADDR_IS_PMPORT(addrp) || AHCI_ADDR_IS_PMULT(addrp));
4417 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4419 /* Check the existence of the port multiplier */
4420 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT)
4421 return (AHCI_FAILURE);
4423 /* Request a READ/WRITE PORTMULT sata packet. */
4424 bzero(&sata_device, sizeof (sata_device_t));
4425 sata_device.satadev_addr.cport = cport;
4426 sata_device.satadev_addr.pmport = pmport;
4427 sata_device.satadev_addr.qual = SATA_ADDR_PMULT;
4428 sata_device.satadev_rev = SATA_DEVICE_REV;
4431 * Make sure no command is outstanding here. All R/W PMULT requests
4432 * come from
4434 * 1. ahci_attach()
4435 * The port should be empty.
4437 * 2. ahci_tran_probe_port()
4438 * Any request from SATA framework (via ahci_tran_start) should be
4439 * rejected if R/W PMULT command is outstanding.
4441 * If we are doing mopping, do not check those flags because no
4442 * command will be actually outstanding.
4444 * If the port has been occupied by any other commands, the probe
4445 * function will return a SATA_RETRY. SATA framework will retry
4446 * later.
4448 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
4449 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4450 "R/W PMULT failed: R/W PMULT in progress at port %d.",
4451 port, ahci_portp->ahciport_flags);
4452 return (AHCI_FAILURE);
4455 if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) && (
4456 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
4457 NCQ_CMD_IN_PROGRESS(ahci_portp) ||
4458 NON_NCQ_CMD_IN_PROGRESS(ahci_portp))) {
4459 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4460 "R/W PMULT failed: port %d is occupied (flags 0x%x).",
4461 port, ahci_portp->ahciport_flags);
4462 return (AHCI_FAILURE);
4466 * The port multiplier is gone. This may happen when
4467 * 1. Cutting off the power of an enclosure. The device lose the power
4468 * before port multiplier.
4469 * 2. Disconnecting the port multiplier during hot-plugging a sub-drive.
4471 * The issued command should be aborted and the following command
4472 * should not be continued.
4474 if (!(ahci_portp->ahciport_port_state & SATA_STATE_READY)) {
4475 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4476 "READ/WRITE PMULT failed: "
4477 "port-mult is removed from port %d", port);
4478 return (AHCI_FAILURE);
4481 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDWR_PMULT;
4483 spkt = sata_get_rdwr_pmult_pkt(ahci_ctlp->ahcictl_dip,
4484 &sata_device, regn, *pregv, type);
4487 * READ/WRITE PORTMULT command is intended to sent to the control port
4488 * of the port multiplier.
4490 AHCI_ADDR_SET_PMULT(&pmult_addr, addrp->aa_port);
4492 ahci_portp->ahciport_rdwr_pmult_pkt = spkt;
4494 /* No interrupt here. Store the interrupt enable mask. */
4495 intr_mask = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4496 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
4497 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4498 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
4500 rval = ahci_do_sync_start(ahci_ctlp, ahci_portp, &pmult_addr, spkt);
4502 if (rval == AHCI_SUCCESS &&
4503 spkt->satapkt_reason == SATA_PKT_COMPLETED) {
4504 if (type == SATA_RDWR_PMULT_PKT_TYPE_READ) {
4505 scmd = &spkt->satapkt_cmd;
4506 *pregv = scmd->satacmd_lba_high_lsb << 24 |
4507 scmd->satacmd_lba_mid_lsb << 16 |
4508 scmd->satacmd_lba_low_lsb << 8 |
4509 scmd->satacmd_sec_count_lsb;
4511 } else {
4512 /* Failed or not completed. */
4513 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4514 "ahci_rdwr_pmult: cannot [%s] %s[%d] at port %s",
4515 type == SATA_RDWR_PMULT_PKT_TYPE_READ?"Read":"Write",
4516 AHCI_ADDR_IS_PMULT(addrp)?"gscr":"pscr", regn, portstr);
4517 rval = AHCI_FAILURE;
4519 out:
4520 /* Restore the interrupt mask */
4521 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4522 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), intr_mask);
4524 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDWR_PMULT;
4525 ahci_portp->ahciport_rdwr_pmult_pkt = NULL;
4526 sata_free_rdwr_pmult_pkt(spkt);
4527 return (rval);
4530 static int
4531 ahci_read_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4532 uint8_t regn, uint32_t *pregv)
4534 return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, pregv,
4535 SATA_RDWR_PMULT_PKT_TYPE_READ);
4538 static int
4539 ahci_write_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4540 uint8_t regn, uint32_t regv)
4542 return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, &regv,
4543 SATA_RDWR_PMULT_PKT_TYPE_WRITE);
4546 #define READ_PMULT(addrp, r, pv, out) \
4547 if (ahci_read_pmult(ahci_ctlp, addrp, r, pv) != AHCI_SUCCESS) \
4548 goto out;
4550 #define WRITE_PMULT(addrp, r, v, out) \
4551 if (ahci_write_pmult(ahci_ctlp, addrp, r, v) != AHCI_SUCCESS) \
4552 goto out;
4555 * Update sata registers on port multiplier, including GSCR/PSCR registers.
4556 * ahci_update_pmult_gscr()
4557 * ahci_update_pmult_pscr()
4559 static int
4560 ahci_update_pmult_gscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4561 sata_pmult_gscr_t *sg)
4563 ASSERT(MUTEX_HELD(
4564 &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4566 READ_PMULT(addrp, SATA_PMULT_GSCR0, &sg->gscr0, err);
4567 READ_PMULT(addrp, SATA_PMULT_GSCR1, &sg->gscr1, err);
4568 READ_PMULT(addrp, SATA_PMULT_GSCR2, &sg->gscr2, err);
4569 READ_PMULT(addrp, SATA_PMULT_GSCR64, &sg->gscr64, err);
4571 return (AHCI_SUCCESS);
4573 err: /* R/W PMULT error */
4574 return (AHCI_FAILURE);
4577 static int
4578 ahci_update_pmult_pscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4579 sata_device_t *sd)
4581 ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4582 ASSERT(MUTEX_HELD(
4583 &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4585 READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &sd->satadev_scr.sstatus, err);
4586 READ_PMULT(addrp, SATA_PMULT_REG_SERR, &sd->satadev_scr.serror, err);
4587 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &sd->satadev_scr.scontrol, err);
4588 READ_PMULT(addrp, SATA_PMULT_REG_SACT, &sd->satadev_scr.sactive, err);
4590 return (AHCI_SUCCESS);
4592 err: /* R/W PMULT error */
4593 return (AHCI_FAILURE);
4597 * ahci_initialize_pmult()
4599 * Initialize a port multiplier, including
4600 * 1. Enable FEATURES register at port multiplier. (SATA Chp.16)
4601 * 2. Redefine MASK register. (SATA Chap 16.?)
4603 static int
4604 ahci_initialize_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4605 ahci_addr_t *addrp, sata_device_t *sd)
4607 sata_pmult_gscr_t sg;
4608 uint32_t gscr64;
4609 uint8_t port = addrp->aa_port;
4611 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4613 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4614 "[Initialize] Port-multiplier at port %d.", port);
4617 * Enable features of port multiplier. Currently only
4618 * Asynchronous Notification is enabled.
4620 /* Check gscr64 for supported features. */
4621 READ_PMULT(addrp, SATA_PMULT_GSCR64, &gscr64, err);
4623 if (gscr64 & SATA_PMULT_CAP_SNOTIF) {
4624 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4625 "port %d: Port Multiplier supports "
4626 "Asynchronous Notification.", port);
4628 /* Write to gscr96 to enabled features */
4629 WRITE_PMULT(addrp, SATA_PMULT_GSCR96,
4630 SATA_PMULT_CAP_SNOTIF, err);
4632 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4633 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4634 AHCI_SNOTIF_CLEAR_ALL);
4635 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4636 "port %d: PMult PxSNTF cleared.", port);
4641 * Now we need to update gscr33 register to enable hot-plug interrupt
4642 * for sub devices behind port multiplier.
4644 WRITE_PMULT(addrp, SATA_PMULT_GSCR33, (0x1ffff), err);
4645 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4646 "port %d: gscr33 mask set to %x.", port, (0x1ffff));
4649 * Fetch the number of device ports of the port multiplier
4651 if (ahci_update_pmult_gscr(ahci_ctlp, addrp, &sg) != AHCI_SUCCESS)
4652 return (AHCI_FAILURE);
4654 /* Register the port multiplier to SATA Framework. */
4655 mutex_exit(&ahci_portp->ahciport_mutex);
4656 sata_register_pmult(ahci_ctlp->ahcictl_dip, sd, &sg);
4657 mutex_enter(&ahci_portp->ahciport_mutex);
4659 ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports =
4660 sd->satadev_add_info & SATA_PMULT_PORTNUM_MASK;
4662 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4663 "port %d: pmult sub-port number updated to %x.", port,
4664 ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports);
4666 /* Till now port-mult is successfully initialized */
4667 ahci_portp->ahciport_port_state |= SATA_DSTATE_PMULT_INIT;
4668 return (AHCI_SUCCESS);
4670 err: /* R/W PMULT error */
4671 return (AHCI_FAILURE);
4675 * Initialize a port multiplier port. According to spec, firstly we need
4676 * issue a COMRESET, then a software reset to get its signature.
4678 * NOTE: This function should only be called in ahci_probe_pmport()
4680 static int
4681 ahci_initialize_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4682 ahci_addr_t *addrp)
4684 uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
4685 uint8_t port = addrp->aa_port;
4686 uint8_t pmport = addrp->aa_pmport;
4687 int ret = AHCI_FAILURE;
4689 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4690 ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4692 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4693 "ahci_initialize_pmport: port %d:%d", port, pmport);
4695 /* Check HBA port state */
4696 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
4697 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4698 "ahci_initialize_pmport:"
4699 "port %d:%d Port Multiplier is failed.",
4700 port, pmport);
4701 return (AHCI_FAILURE);
4704 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4705 return (AHCI_FAILURE);
4707 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
4709 /* Checking for outstanding commands */
4710 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4711 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4712 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
4713 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4714 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4715 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4716 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
4717 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4720 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
4721 ahci_portp->ahciport_mop_in_progress++;
4723 /* Clear status */
4724 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_UNKNOWN);
4726 /* Firstly assume an unknown device */
4727 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4729 ahci_disable_port_intrs(ahci_ctlp, port);
4731 /* port reset is necessary for port multiplier port */
4732 if (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp) != AHCI_SUCCESS) {
4733 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4734 "ahci_initialize_pmport:"
4735 "port reset failed at port %d:%d",
4736 port, pmport);
4737 goto out;
4740 /* Is port failed? */
4741 if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4742 SATA_PSTATE_FAILED) {
4743 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4744 "ahci_initialize_pmport: port %d:%d failed. "
4745 "state = 0x%x", port, pmport,
4746 ahci_portp->ahciport_port_state);
4747 goto out;
4750 /* Is there any device attached? */
4751 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, addrp)
4752 == SATA_DTYPE_NONE) {
4753 /* Do not waste time on an empty port */
4754 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
4755 "ahci_initialize_pmport: No device is found "
4756 "at port %d:%d", port, pmport);
4757 ret = AHCI_SUCCESS;
4758 goto out;
4761 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4762 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4763 "port %d:%d is ready now.", port, pmport);
4766 * Till now we can assure a device attached to that HBA port and work
4767 * correctly. Now try to get the device signature. This is an optional
4768 * step. If failed, unknown device is assumed, then SATA module will
4769 * continue to use IDENTIFY DEVICE to get the information of the
4770 * device.
4772 ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4774 ret = AHCI_SUCCESS;
4776 out:
4777 /* Next try to mop the pending commands */
4778 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
4779 finished_tags = ahci_portp->ahciport_pending_tags &
4780 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4781 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
4782 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
4783 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4784 reset_tags &= ~finished_tags;
4786 ahci_mop_commands(ahci_ctlp,
4787 ahci_portp,
4788 slot_status,
4789 0, /* failed tags */
4790 0, /* timeout tags */
4791 0, /* aborted tags */
4792 reset_tags); /* reset tags */
4794 /* Clear PxSNTF register if supported. */
4795 if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
4796 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4797 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4798 AHCI_SNOTIF_CLEAR_ALL);
4801 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
4802 ahci_enable_port_intrs(ahci_ctlp, port);
4803 return (ret);
4807 * ahci_probe_pmult()
4809 * This function will be called to probe a port multiplier, which will
4810 * handle hotplug events on port multiplier ports.
4812 * NOTE: Only called from ahci_tran_probe_port()
4814 static int
4815 ahci_probe_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4816 ahci_addr_t *addrp)
4818 sata_device_t sdevice;
4819 ahci_addr_t pmport_addr;
4820 uint32_t gscr32, port_hotplug_tags;
4821 uint32_t pmport_sstatus;
4822 int dev_exists_now = 0, dev_existed_previously = 0;
4823 uint8_t port = addrp->aa_port;
4824 int npmport;
4826 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4828 /* The bits in GSCR32 refers to the pmport that has a hot-plug event. */
4829 READ_PMULT(addrp, SATA_PMULT_GSCR32, &gscr32, err);
4830 port_hotplug_tags = gscr32 & AHCI_PMPORT_MASK(ahci_portp);
4832 do {
4833 npmport = ddi_ffs(port_hotplug_tags) - 1;
4834 if (npmport == -1)
4835 /* no pending hot plug events. */
4836 return (AHCI_SUCCESS);
4838 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4839 "hot-plug event at port %d:%d", port, npmport);
4841 AHCI_ADDR_SET_PMPORT(&pmport_addr, port, (uint8_t)npmport);
4843 /* Check previous device at that port */
4844 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &pmport_addr)
4845 != SATA_DTYPE_NONE)
4846 dev_existed_previously = 1;
4848 /* PxSStatus tells the presence of device. */
4849 READ_PMULT(&pmport_addr, SATA_PMULT_REG_SSTS,
4850 &pmport_sstatus, err);
4852 if (SSTATUS_GET_DET(pmport_sstatus) ==
4853 SSTATUS_DET_DEVPRE_PHYCOM)
4854 dev_exists_now = 1;
4857 * Clear PxSERR is critical. The transition from 0 to 1 will
4858 * emit a FIS which generates an asynchronous notification
4859 * event at controller. If we fail to clear the PxSERR, the
4860 * Async Notif events will no longer be activated on this
4861 * pmport.
4863 WRITE_PMULT(&pmport_addr, SATA_PMULT_REG_SERR,
4864 AHCI_SERROR_CLEAR_ALL, err);
4866 bzero((void *)&sdevice, sizeof (sata_device_t));
4867 sdevice.satadev_addr.cport = ahci_ctlp->
4868 ahcictl_port_to_cport[port];
4869 sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4870 sdevice.satadev_addr.pmport = (uint8_t)npmport;
4871 sdevice.satadev_state = SATA_PSTATE_PWRON;
4873 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4874 "[Existence] %d -> %d", dev_existed_previously,
4875 dev_exists_now);
4877 if (dev_exists_now) {
4878 if (dev_existed_previously) {
4879 /* Link (may) not change: Exist -> Exist * */
4880 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
4881 "ahci_probe_pmult: port %d:%d "
4882 "device link lost/established",
4883 port, npmport);
4885 mutex_exit(&ahci_portp->ahciport_mutex);
4886 sata_hba_event_notify(
4887 ahci_ctlp->ahcictl_sata_hba_tran->
4888 sata_tran_hba_dip,
4889 &sdevice,
4890 SATA_EVNT_LINK_LOST|
4891 SATA_EVNT_LINK_ESTABLISHED);
4892 mutex_enter(&ahci_portp->ahciport_mutex);
4893 } else {
4894 /* Link change: None -> Exist */
4895 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4896 "ahci_probe_pmult: port %d:%d "
4897 "device link established", port, npmport);
4899 /* Clear port state */
4900 AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4901 SATA_STATE_UNKNOWN);
4902 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4903 "ahci_probe_pmult: port %d "
4904 "ahciport_port_state [Cleared].", port);
4906 mutex_exit(&ahci_portp->ahciport_mutex);
4907 sata_hba_event_notify(
4908 ahci_ctlp->ahcictl_sata_hba_tran->
4909 sata_tran_hba_dip,
4910 &sdevice,
4911 SATA_EVNT_LINK_ESTABLISHED);
4912 mutex_enter(&ahci_portp->ahciport_mutex);
4914 } else { /* No device exists now */
4915 if (dev_existed_previously) {
4917 /* Link change: Exist -> None */
4918 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4919 "ahci_probe_pmult: port %d:%d "
4920 "device link lost", port, npmport);
4922 /* An existing device is lost. */
4923 AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4924 SATA_STATE_UNKNOWN);
4925 AHCIPORT_SET_DEV_TYPE(ahci_portp, &pmport_addr,
4926 SATA_DTYPE_NONE);
4928 mutex_exit(&ahci_portp->ahciport_mutex);
4929 sata_hba_event_notify(
4930 ahci_ctlp->ahcictl_sata_hba_tran->
4931 sata_tran_hba_dip,
4932 &sdevice,
4933 SATA_EVNT_LINK_LOST);
4934 mutex_enter(&ahci_portp->ahciport_mutex);
4938 CLEAR_BIT(port_hotplug_tags, npmport);
4939 } while (port_hotplug_tags != 0);
4941 return (AHCI_SUCCESS);
4943 err: /* R/W PMULT error */
4944 return (AHCI_FAILURE);
4948 * Probe and initialize a port multiplier port.
4949 * A port multiplier port could only be initilaizer here.
4951 static int
4952 ahci_probe_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4953 ahci_addr_t *addrp, sata_device_t *sd)
4955 uint32_t port_state;
4956 uint8_t port = addrp->aa_port;
4957 ahci_addr_t addr_pmult;
4959 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4962 * Check the parent - port multiplier first.
4966 * Parent port multiplier might have been removed. This event will be
4967 * ignored and failure.
4969 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
4970 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
4971 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4972 "ahci_tran_probe_port: "
4973 "parent device removed, ignore event.", NULL);
4975 return (AHCI_FAILURE);
4978 /* The port is ready? */
4979 port_state = ahci_portp->ahciport_port_state;
4980 if (!(port_state & SATA_STATE_READY)) {
4981 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4982 "ahci_tran_probe_port: "
4983 "parent port-mult is NOT ready.", NULL);
4985 if (ahci_restart_port_wait_till_ready(ahci_ctlp,
4986 ahci_portp, port, AHCI_PORT_RESET, NULL) !=
4987 AHCI_SUCCESS) {
4988 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4989 "ahci_tran_probe_port: "
4990 "restart port-mult failed.", NULL);
4991 return (AHCI_FAILURE);
4996 * If port-mult is restarted due to some reason, we need
4997 * re-initialized the PMult.
4999 if (!(port_state & SATA_DSTATE_PMULT_INIT)) {
5000 /* Initialize registers on a port multiplier */
5001 AHCI_ADDR_SET_PMULT(&addr_pmult, addrp->aa_port);
5002 if (ahci_initialize_pmult(ahci_ctlp, ahci_portp,
5003 &addr_pmult, sd) != AHCI_SUCCESS)
5004 return (AHCI_FAILURE);
5008 * Then we check the port-mult port
5010 /* Is this pmport initialized? */
5011 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5012 if (!(port_state & SATA_STATE_READY)) {
5014 /* ahci_initialize_pmport() will set READY state */
5015 if (ahci_initialize_pmport(ahci_ctlp,
5016 ahci_portp, addrp) != AHCI_SUCCESS)
5017 return (AHCI_FAILURE);
5020 return (AHCI_SUCCESS);
5024 * AHCI device reset ...; a single device on one of the ports is reset,
5025 * but the HBA and physical communication remain intact. This is the
5026 * least intrusive.
5028 * When issuing a software reset sequence, there should not be other
5029 * commands in the command list, so we will first clear and then re-set
5030 * PxCMD.ST to clear PxCI. And before issuing the software reset,
5031 * the port must be idle and PxTFD.STS.BSY and PxTFD.STS.DRQ must be
5032 * cleared unless command list override (PxCMD.CLO) is supported.
5034 static int
5035 ahci_software_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5036 ahci_addr_t *addrp)
5038 ahci_fis_h2d_register_t *h2d_register_fisp;
5039 ahci_cmd_table_t *cmd_table;
5040 ahci_cmd_header_t *cmd_header;
5041 uint32_t port_cmd_status, port_cmd_issue, port_task_file;
5042 int slot, loop_count;
5043 uint8_t port = addrp->aa_port;
5044 uint8_t pmport = addrp->aa_pmport;
5045 int rval = AHCI_FAILURE;
5047 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5049 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5050 "port %d:%d device software resetting (FIS)", port, pmport);
5052 /* First clear PxCMD.ST (AHCI v1.2 10.4.1) */
5053 if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
5054 port) != AHCI_SUCCESS) {
5055 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5056 "ahci_software_reset: cannot stop HBA port %d.", port);
5057 goto out;
5060 /* Check PxTFD.STS.BSY and PxTFD.STS.DRQ */
5061 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5062 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5064 if (port_task_file & AHCI_TFD_STS_BSY ||
5065 port_task_file & AHCI_TFD_STS_DRQ) {
5066 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_SCLO)) {
5067 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5068 "PxTFD.STS.BSY/DRQ is set (PxTFD=0x%x), "
5069 "cannot issue a software reset.", port_task_file);
5070 goto out;
5074 * If HBA Support CLO, as Command List Override (CAP.SCLO is
5075 * set), PxCMD.CLO bit should be set before set PxCMD.ST, in
5076 * order to clear PxTFD.STS.BSY and PxTFD.STS.DRQ.
5078 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5079 "PxTFD.STS.BSY/DRQ is set, try SCLO.", NULL)
5081 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5082 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5083 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5084 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5085 port_cmd_status|AHCI_CMD_STATUS_CLO);
5087 /* Waiting till PxCMD.SCLO bit is cleared */
5088 loop_count = 0;
5089 do {
5090 /* Wait for 10 millisec */
5091 drv_usecwait(AHCI_10MS_USECS);
5093 /* We are effectively timing out after 1 sec. */
5094 if (loop_count++ > 100) {
5095 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5096 "SCLO time out. port %d is busy.", port);
5097 goto out;
5100 port_cmd_status =
5101 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5102 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5103 } while (port_cmd_status & AHCI_CMD_STATUS_CLO);
5105 /* Re-check */
5106 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5107 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5108 if (port_task_file & AHCI_TFD_STS_BSY ||
5109 port_task_file & AHCI_TFD_STS_DRQ) {
5110 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5111 "SCLO cannot clear PxTFD.STS.BSY/DRQ (PxTFD=0x%x)",
5112 port_task_file);
5113 goto out;
5117 /* Then start port */
5118 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
5119 != AHCI_SUCCESS) {
5120 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5121 "ahci_software_reset: cannot start AHCI port %d.", port);
5122 goto out;
5126 * When ahci_port.ahciport_mop_in_progress is set, A non-zero
5127 * ahci_port.ahciport_pending_ncq_tags may fail
5128 * ahci_claim_free_slot(). Actually according to spec, by clearing
5129 * PxCMD.ST there is no command outstanding while executing software
5130 * reseting. Hence we directly use slot 0 instead of
5131 * ahci_claim_free_slot().
5133 slot = 0;
5135 /* Now send the first H2D Register FIS with SRST set to 1 */
5136 cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5137 bzero((void *)cmd_table, ahci_cmd_table_size);
5139 h2d_register_fisp =
5140 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5142 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5143 SET_FIS_PMP(h2d_register_fisp, pmport);
5144 SET_FIS_DEVCTL(h2d_register_fisp, SATA_DEVCTL_SRST);
5146 /* Set Command Header in Command List */
5147 cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5148 BZERO_DESCR_INFO(cmd_header);
5149 BZERO_PRD_BYTE_COUNT(cmd_header);
5150 SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5151 SET_PORT_MULTI_PORT(cmd_header, pmport);
5153 SET_CLEAR_BUSY_UPON_R_OK(cmd_header, 1);
5154 SET_RESET(cmd_header, 1);
5155 SET_WRITE(cmd_header, 1);
5157 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5159 ahci_cmd_table_size,
5160 DDI_DMA_SYNC_FORDEV);
5162 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5163 slot * sizeof (ahci_cmd_header_t),
5164 sizeof (ahci_cmd_header_t),
5165 DDI_DMA_SYNC_FORDEV);
5167 /* Indicate to the HBA that a command is active. */
5168 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5169 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5170 (0x1 << slot));
5172 loop_count = 0;
5174 /* Loop till the first command is finished */
5175 do {
5176 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5177 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5179 /* We are effectively timing out after 1 sec. */
5180 if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5181 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5182 "the first SRST FIS is timed out, "
5183 "loop_count = %d", loop_count);
5184 goto out;
5186 /* Wait for 10 millisec */
5187 drv_usecwait(AHCI_10MS_USECS);
5188 } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5190 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5191 "ahci_software_reset: 1st loop count: %d, "
5192 "port_cmd_issue = 0x%x, slot = 0x%x",
5193 loop_count, port_cmd_issue, slot);
5195 /* According to ATA spec, we need wait at least 5 microsecs here. */
5196 drv_usecwait(AHCI_1MS_USECS);
5198 /* Now send the second H2D Register FIS with SRST cleard to zero */
5199 cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5200 bzero((void *)cmd_table, ahci_cmd_table_size);
5202 h2d_register_fisp =
5203 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5205 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5206 SET_FIS_PMP(h2d_register_fisp, pmport);
5208 /* Set Command Header in Command List */
5209 cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5210 BZERO_DESCR_INFO(cmd_header);
5211 BZERO_PRD_BYTE_COUNT(cmd_header);
5212 SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5213 SET_PORT_MULTI_PORT(cmd_header, pmport);
5215 SET_WRITE(cmd_header, 1);
5217 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5219 ahci_cmd_table_size,
5220 DDI_DMA_SYNC_FORDEV);
5222 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5223 slot * sizeof (ahci_cmd_header_t),
5224 sizeof (ahci_cmd_header_t),
5225 DDI_DMA_SYNC_FORDEV);
5227 /* Indicate to the HBA that a command is active. */
5228 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5229 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5230 (0x1 << slot));
5232 loop_count = 0;
5234 /* Loop till the second command is finished */
5235 do {
5236 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5237 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5239 /* We are effectively timing out after 1 sec. */
5240 if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5241 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5242 "the second SRST FIS is timed out, "
5243 "loop_count = %d", loop_count);
5244 goto out;
5247 /* Wait for 10 millisec */
5248 drv_usecwait(AHCI_10MS_USECS);
5249 } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5251 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5252 "ahci_software_reset: 2nd loop count: %d, "
5253 "port_cmd_issue = 0x%x, slot = 0x%x",
5254 loop_count, port_cmd_issue, slot);
5256 if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
5257 (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
5258 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
5259 DDI_SERVICE_UNAFFECTED);
5260 goto out;
5263 rval = AHCI_SUCCESS;
5264 out:
5265 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5266 "ahci_software_reset: %s at port %d:%d",
5267 rval == AHCI_SUCCESS ? "succeed" : "failed",
5268 port, pmport);
5270 return (rval);
5274 * AHCI port reset ...; the physical communication between the HBA and device
5275 * on a port are disabled. This is more intrusive.
5277 * When an HBA or port reset occurs, Phy communication is going to
5278 * be re-established with the device through a COMRESET followed by the
5279 * normal out-of-band communication sequence defined in Serial ATA. At
5280 * the end of reset, the device, if working properly, will send a D2H
5281 * Register FIS, which contains the device signature. When the HBA receives
5282 * this FIS, it updates PxTFD.STS and PxTFD.ERR register fields, and updates
5283 * the PxSIG register with the signature.
5285 * NOTE: It is expected both PxCMD.ST and PxCMD.CR are cleared before the
5286 * function is called. If not, it is assumed the interface is in hung
5287 * condition.
5289 static int
5290 ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5291 ahci_addr_t *addrp)
5293 ahci_addr_t pmult_addr;
5294 uint32_t port_cmd_status;
5295 uint32_t port_scontrol, port_sstatus;
5296 uint32_t port_task_file;
5297 uint32_t port_state;
5298 uint8_t port = addrp->aa_port;
5300 int loop_count;
5301 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5303 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5305 /* Target is a port multiplier port? */
5306 if (AHCI_ADDR_IS_PMPORT(addrp))
5307 return (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp));
5309 /* Otherwise it must be an HBA port. */
5310 ASSERT(AHCI_ADDR_IS_PORT(addrp));
5312 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5313 "Port %d port resetting...", port);
5314 ahci_portp->ahciport_port_state = 0;
5316 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5317 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5320 * According to the spec, SUD bit should be set here,
5321 * but JMicron JMB363 doesn't follow it, so print
5322 * a debug message.
5324 if (!(port_cmd_status & AHCI_CMD_STATUS_SUD))
5325 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5326 "ahci_port_reset: port %d SUD bit not set", port);
5328 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5329 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5330 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5332 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5333 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5334 port_scontrol);
5336 /* Enable PxCMD.FRE to read device */
5337 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5338 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5339 port_cmd_status|AHCI_CMD_STATUS_FRE);
5342 * The port enters P:StartComm state, and the HBA tells the link layer
5343 * to start communication, which involves sending COMRESET to the
5344 * device. And the HBA resets PxTFD.STS to 7Fh.
5346 * Give time for COMRESET to percolate, according to the AHCI
5347 * spec, software shall wait at least 1 millisecond before
5348 * clearing PxSCTL.DET
5350 drv_usecwait(AHCI_1MS_USECS * 2);
5352 /* Fetch the SCONTROL again and rewrite the DET part with 0 */
5353 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5354 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5355 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5356 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5357 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5358 port_scontrol);
5361 * When a COMINIT is received from the device, then the port enters
5362 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5363 * PxSSTS.DET to 1h to indicate a device is detected but communication
5364 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5365 * a COMINIT has been received.
5368 * The DET field is valid only if IPM field indicates
5369 * that the interface is in active state.
5371 loop_count = 0;
5372 for (;;) {
5373 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5374 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
5376 if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5378 * If the interface is not active, the DET field
5379 * is considered not accurate. So we want to
5380 * continue looping.
5382 SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5385 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM)
5386 break;
5388 if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5390 * We are effectively timing out after 0.1 sec.
5392 break;
5395 /* Wait for 10 millisec */
5396 drv_usecwait(AHCI_10MS_USECS);
5399 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5400 "ahci_port_reset: 1st loop count: %d, "
5401 "port_sstatus = 0x%x port %d",
5402 loop_count, port_sstatus, port);
5404 if (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM) {
5406 * Either the port is not active or there
5407 * is no device present.
5409 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5410 return (AHCI_SUCCESS);
5413 /* Clear port serror register for the port */
5414 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5415 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5416 AHCI_SERROR_CLEAR_ALL);
5419 * Devices should return a FIS contains its signature to HBA after
5420 * COMINIT signal. Check whether a D2H Register FIS is received by
5421 * polling PxTFD.STS.
5423 loop_count = 0;
5424 for (;;) {
5425 port_task_file =
5426 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5427 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5429 if ((port_task_file & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ |
5430 AHCI_TFD_STS_ERR)) == 0)
5431 break;
5433 if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5435 * We are effectively timing out after 11 sec.
5437 cmn_err(CE_WARN, "!ahci%d: ahci_port_reset port %d "
5438 "the device hardware has been initialized and "
5439 "the power-up diagnostics failed",
5440 instance, port);
5442 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_port_reset: "
5443 "port %d: some or all of BSY, DRQ and ERR in "
5444 "PxTFD.STS are not clear. We need another "
5445 "software reset.", port);
5447 /* Clear port serror register for the port */
5448 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5449 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5450 AHCI_SERROR_CLEAR_ALL);
5452 AHCI_ADDR_SET_PMULT(&pmult_addr, port);
5454 /* Try another software reset. */
5455 if (ahci_software_reset(ahci_ctlp, ahci_portp,
5456 &pmult_addr) != AHCI_SUCCESS) {
5457 AHCIPORT_SET_STATE(ahci_portp, addrp,
5458 SATA_PSTATE_FAILED);
5459 return (AHCI_FAILURE);
5461 break;
5464 /* Wait for 10 millisec */
5465 drv_usecwait(AHCI_10MS_USECS);
5468 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5469 "ahci_port_reset: 2nd loop count: %d, "
5470 "port_task_file = 0x%x port %d",
5471 loop_count, port_task_file, port);
5473 /* Clear port serror register for the port */
5474 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5475 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5476 AHCI_SERROR_CLEAR_ALL);
5478 /* Set port as ready */
5479 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5480 AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5482 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5483 "ahci_port_reset: succeed at port %d.", port);
5484 return (AHCI_SUCCESS);
5488 * COMRESET on a port multiplier port.
5490 * NOTE: Only called in ahci_port_reset()
5492 static int
5493 ahci_pmport_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5494 ahci_addr_t *addrp)
5496 uint32_t port_scontrol, port_sstatus, port_serror;
5497 uint32_t port_cmd_status, port_intr_status;
5498 uint32_t port_state;
5499 uint8_t port = addrp->aa_port;
5500 uint8_t pmport = addrp->aa_pmport;
5501 int loop_count;
5502 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5504 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5505 "port %d:%d: pmport resetting", port, pmport);
5507 /* Initialize pmport state */
5508 AHCIPORT_SET_STATE(ahci_portp, addrp, 0);
5510 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5511 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5512 WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5514 /* PxCMD.FRE should be set before. */
5515 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5516 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5517 ASSERT(port_cmd_status & AHCI_CMD_STATUS_FRE);
5518 if (!(port_cmd_status & AHCI_CMD_STATUS_FRE))
5519 return (AHCI_FAILURE);
5522 * Give time for COMRESET to percolate, according to the AHCI
5523 * spec, software shall wait at least 1 millisecond before
5524 * clearing PxSCTL.DET
5526 drv_usecwait(AHCI_1MS_USECS*2);
5529 * Fetch the SCONTROL again and rewrite the DET part with 0
5530 * This will generate an Asychronous Notification events.
5532 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5533 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5534 WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5537 * The port enters P:StartComm state, and HBA tells link layer to
5538 * start communication, which involves sending COMRESET to device.
5539 * And the HBA resets PxTFD.STS to 7Fh.
5541 * When a COMINIT is received from the device, then the port enters
5542 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5543 * PxSSTS.DET to 1h to indicate a device is detected but communication
5544 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5545 * a COMINIT has been received.
5548 * The DET field is valid only if IPM field indicates
5549 * that the interface is in active state.
5551 loop_count = 0;
5552 do {
5553 READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &port_sstatus, err);
5555 if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5557 * If the interface is not active, the DET field
5558 * is considered not accurate. So we want to
5559 * continue looping.
5561 SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5564 if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5566 * We are effectively timing out after 0.1 sec.
5568 break;
5571 /* Wait for 10 millisec */
5572 drv_usecwait(AHCI_10MS_USECS);
5574 } while (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM);
5576 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5577 "ahci_pmport_reset: 1st loop count: %d, "
5578 "port_sstatus = 0x%x port %d:%d",
5579 loop_count, port_sstatus, port, pmport);
5581 if ((SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) ||
5582 (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM)) {
5584 * Either the port is not active or there
5585 * is no device present.
5587 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5588 "ahci_pmport_reset: "
5589 "no device attached to port %d:%d",
5590 port, pmport);
5591 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5592 return (AHCI_SUCCESS);
5595 /* Now we can make sure there is a device connected to the port */
5596 /* COMINIT signal is supposed to be received (PxSERR.DIAG.X = '1') */
5597 READ_PMULT(addrp, SATA_PMULT_REG_SERR, &port_serror, err);
5599 if (!(port_serror & (1 << 26))) {
5600 cmn_err(CE_WARN, "!ahci%d: ahci_pmport_reset: "
5601 "COMINIT signal from the device not received port %d:%d",
5602 instance, port, pmport);
5604 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_PSTATE_FAILED);
5605 return (AHCI_FAILURE);
5609 * After clear PxSERR register, we will receive a D2H FIS.
5610 * Normally this FIS will cause a IPMS error according to AHCI spec
5611 * v1.2 because there is no command outstanding for it. So we need
5612 * to ignore this error.
5614 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_IGNORE_IPMS;
5615 WRITE_PMULT(addrp, SATA_PMULT_REG_SERR, AHCI_SERROR_CLEAR_ALL, err);
5617 /* Now we need to check the D2H FIS by checking IPMS error. */
5618 loop_count = 0;
5619 do {
5620 port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5621 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
5623 if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5625 * No D2H FIS received. This is possible according
5626 * to SATA 2.6 spec.
5628 cmn_err(CE_WARN, "ahci_port_reset: port %d:%d "
5629 "PxIS.IPMS is not set, we need another "
5630 "software reset.", port, pmport);
5632 break;
5635 /* Wait for 10 millisec */
5636 mutex_exit(&ahci_portp->ahciport_mutex);
5637 delay(AHCI_10MS_TICKS);
5638 mutex_enter(&ahci_portp->ahciport_mutex);
5640 } while (!(port_intr_status & AHCI_INTR_STATUS_IPMS));
5642 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5643 "ahci_pmport_reset: 2st loop count: %d, "
5644 "port_sstatus = 0x%x port %d:%d",
5645 loop_count, port_sstatus, port, pmport);
5647 /* Clear IPMS */
5648 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5649 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
5650 AHCI_INTR_STATUS_IPMS);
5651 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5653 /* This pmport is now ready for ahci_tran_start() */
5654 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5655 AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5657 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5658 "ahci_pmport_reset: succeed at port %d:%d", port, pmport);
5659 return (AHCI_SUCCESS);
5661 err: /* R/W PMULT error */
5662 /* IPMS flags might be set before. */
5663 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5664 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5665 "ahci_pmport_reset: failed at port %d:%d", port, pmport);
5667 return (AHCI_FAILURE);
5671 * AHCI HBA reset ...; the entire HBA is reset, and all ports are disabled.
5672 * This is the most intrusive.
5674 * When an HBA reset occurs, Phy communication will be re-established with
5675 * the device through a COMRESET followed by the normal out-of-band
5676 * communication sequence defined in Serial ATA. At the end of reset, the
5677 * device, if working properly, will send a D2H Register FIS, which contains
5678 * the device signature. When the HBA receives this FIS, it updates PxTFD.STS
5679 * and PxTFD.ERR register fields, and updates the PxSIG register with the
5680 * signature.
5682 * Remember to set GHC.AE to 1 before calling ahci_hba_reset.
5684 static int
5685 ahci_hba_reset(ahci_ctl_t *ahci_ctlp)
5687 ahci_port_t *ahci_portp;
5688 uint32_t ghc_control;
5689 uint8_t port;
5690 int loop_count;
5691 int rval = AHCI_SUCCESS;
5693 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "HBA resetting",
5694 NULL);
5696 mutex_enter(&ahci_ctlp->ahcictl_mutex);
5698 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5699 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5701 /* Setting GHC.HR to 1, remember GHC.AE is already set to 1 before */
5702 ghc_control |= AHCI_HBA_GHC_HR;
5703 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5704 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5707 * Wait until HBA Reset complete or timeout
5709 loop_count = 0;
5710 do {
5711 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5712 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5714 if (loop_count++ > AHCI_POLLRATE_HBA_RESET) {
5715 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5716 "ahci hba reset is timing out, "
5717 "ghc_control = 0x%x", ghc_control);
5718 /* We are effectively timing out after 1 sec. */
5719 break;
5722 /* Wait for 10 millisec */
5723 drv_usecwait(AHCI_10MS_USECS);
5724 } while (ghc_control & AHCI_HBA_GHC_HR);
5726 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5727 "ahci_hba_reset: 1st loop count: %d, "
5728 "ghc_control = 0x%x", loop_count, ghc_control);
5730 if (ghc_control & AHCI_HBA_GHC_HR) {
5731 /* The hba is not reset for some reasons */
5732 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5733 "hba reset failed: HBA in a hung or locked state", NULL);
5734 mutex_exit(&ahci_ctlp->ahcictl_mutex);
5735 return (AHCI_FAILURE);
5739 * HBA reset will clear (AHCI Spec v1.2 10.4.3) GHC.IE / GHC.AE
5741 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5742 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5743 ghc_control |= (AHCI_HBA_GHC_AE | AHCI_HBA_GHC_IE);
5744 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5745 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5747 mutex_exit(&ahci_ctlp->ahcictl_mutex);
5749 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
5750 /* Only check implemented ports */
5751 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
5752 continue;
5755 ahci_portp = ahci_ctlp->ahcictl_ports[port];
5756 mutex_enter(&ahci_portp->ahciport_mutex);
5758 /* Make sure the drive is spun-up */
5759 ahci_staggered_spin_up(ahci_ctlp, port);
5761 if (ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
5762 port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP, NULL) !=
5763 AHCI_SUCCESS) {
5764 rval = AHCI_FAILURE;
5765 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5766 "ahci_hba_reset: port %d failed", port);
5768 * Set the port state to SATA_PSTATE_FAILED if
5769 * failed to initialize it.
5771 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5774 mutex_exit(&ahci_portp->ahciport_mutex);
5777 return (rval);
5781 * This routine is only called from AHCI_ATTACH or phyrdy change
5782 * case. It first calls software reset, then stop the port and try to
5783 * read PxSIG register to find the type of device attached to the port.
5785 * The caller should make sure a valid device exists on specified port and
5786 * physical communication has been established so that the signature could
5787 * be retrieved by software reset.
5789 * NOTE: The port interrupts should be disabled before the function is called.
5791 static void
5792 ahci_find_dev_signature(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5793 ahci_addr_t *addrp)
5795 ahci_addr_t dev_addr;
5796 uint32_t signature;
5797 uint8_t port = addrp->aa_port;
5798 uint8_t pmport = addrp->aa_pmport;
5799 int rval;
5801 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5802 ASSERT(AHCI_ADDR_IS_VALID(addrp));
5805 * If the HBA doesn't support port multiplier, then the driver
5806 * doesn't need to bother to check port multiplier device.
5808 * The second port of ICH7 on ASUS P5W DH deluxe motherboard is
5809 * connected to Silicon Image 4723, to which the two sata drives
5810 * attached can be set with RAID1, RAID0 or Spanning mode.
5812 * We found software reset will get failure if port multiplier address
5813 * 0xf is used by software reset, so just ignore the check since
5814 * ICH7 doesn't support port multiplier device at all.
5816 if (AHCI_ADDR_IS_PORT(addrp) &&
5817 (ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_CBSS)) {
5818 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5819 "ahci_find_dev_signature enter: port %d", port);
5822 * NOTE: when the ahci address is a HBA port, we do not know
5823 * it is a device or a port multiplier that attached. we need
5824 * try a software reset at port multiplier address (0xf
5825 * pmport)
5827 AHCI_ADDR_SET_PMULT(&dev_addr, addrp->aa_port);
5828 } else {
5829 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5830 "ahci_find_dev_signature enter: port %d:%d",
5831 port, pmport);
5832 dev_addr = *addrp;
5835 /* Assume it is unknown. */
5836 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5838 /* Issue a software reset to get the signature */
5839 rval = ahci_software_reset(ahci_ctlp, ahci_portp, &dev_addr);
5840 if (rval != AHCI_SUCCESS) {
5843 * Try to do software reset again with pmport set with 0 if
5844 * the controller is set with AHCI_CAP_SRST_NO_HOSTPORT and
5845 * the original pmport is set with SATA_PMULT_HOSTPORT (0xf)
5847 if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_SRST_NO_HOSTPORT) &&
5848 (dev_addr.aa_pmport == SATA_PMULT_HOSTPORT)) {
5849 dev_addr.aa_pmport = 0;
5850 rval = ahci_software_reset(ahci_ctlp, ahci_portp,
5851 &dev_addr);
5854 if (rval != AHCI_SUCCESS) {
5855 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5856 "ahci_find_dev_signature: software reset failed "
5857 "at port %d:%d, cannot get signature.",
5858 port, pmport);
5860 AHCIPORT_SET_STATE(ahci_portp, addrp,
5861 SATA_PSTATE_FAILED);
5862 return;
5867 * ahci_software_reset has started the port, so we need manually stop
5868 * the port again.
5870 if (AHCI_ADDR_IS_PORT(addrp)) {
5871 if (ahci_put_port_into_notrunning_state(ahci_ctlp,
5872 ahci_portp, port) != AHCI_SUCCESS) {
5873 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5874 "ahci_find_dev_signature: cannot stop port %d.",
5875 port);
5876 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5877 return;
5881 /* Now we can make sure that a valid signature is received. */
5882 signature = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5883 (uint32_t *)AHCI_PORT_PxSIG(ahci_ctlp, port));
5885 if (AHCI_ADDR_IS_PMPORT(addrp)) {
5886 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
5887 "ahci_find_dev_signature: signature = 0x%x at port %d:%d",
5888 signature, port, pmport);
5889 } else {
5890 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5891 "ahci_find_dev_signature: signature = 0x%x at port %d",
5892 signature, port);
5895 /* NOTE: Only support ATAPI device at controller port. */
5896 if (signature == AHCI_SIGNATURE_ATAPI && !AHCI_ADDR_IS_PORT(addrp))
5897 signature = SATA_DTYPE_UNKNOWN;
5899 switch (signature) {
5901 case AHCI_SIGNATURE_DISK:
5902 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATADISK);
5903 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5904 "Disk is found at port: %d", port);
5905 break;
5907 case AHCI_SIGNATURE_ATAPI:
5908 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATAPI);
5909 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5910 "ATAPI device is found at port: %d", port);
5911 break;
5913 case AHCI_SIGNATURE_PORT_MULTIPLIER:
5914 /* Port Multiplier cannot recursively attached. */
5915 ASSERT(AHCI_ADDR_IS_PORT(addrp));
5916 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_PMULT);
5917 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5918 "Port Multiplier is found at port: %d", port);
5919 break;
5921 default:
5922 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5923 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5924 "Unknown device is found at port: %d", port);
5929 * According to the spec, to reliably detect hot plug removals, software
5930 * must disable interface power management. Software should perform the
5931 * following initialization on a port after a device is attached:
5932 * Set PxSCTL.IPM to 3h to disable interface state transitions
5933 * Set PxCMD.ALPE to '0' to disable aggressive power management
5934 * Disable device initiated interface power management by SET FEATURE
5936 * We can ignore the last item because by default the feature is disabled
5938 static void
5939 ahci_disable_interface_pm(ahci_ctl_t *ahci_ctlp, uint8_t port)
5941 uint32_t port_scontrol, port_cmd_status;
5943 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5944 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5945 SCONTROL_SET_IPM(port_scontrol, SCONTROL_IPM_DISABLE_BOTH);
5946 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5947 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
5949 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5950 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5951 port_cmd_status &= ~AHCI_CMD_STATUS_ALPE;
5952 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5953 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
5957 * Start the port - set PxCMD.ST to 1, if PxCMD.FRE is not set
5958 * to 1, then set it firstly.
5960 * Each port contains two major DMA engines. One DMA engine walks through
5961 * the command list, and is controlled by PxCMD.ST. The second DMA engine
5962 * copies received FISes into system memory, and is controlled by PxCMD.FRE.
5964 * Software shall not set PxCMD.ST to '1' until it verifies that PxCMD.CR
5965 * is '0' and has set PxCMD.FRE is '1'. And software shall not clear
5966 * PxCMD.FRE while PxCMD.ST or PxCMD.CR is set '1'.
5968 * Software shall not set PxCMD.ST to '1' unless a functional device is
5969 * present on the port(as determined by PxTFD.STS.BSY = '0',
5970 * PxTFD.STS.DRQ = '0', and PxSSTS.DET = 3h).
5972 static int
5973 ahci_start_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
5975 uint32_t port_cmd_status;
5977 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5979 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_start_port: %d enter", port);
5981 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
5982 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5983 "the state for port %d is 0x%x",
5984 port, ahci_portp->ahciport_port_state);
5985 return (AHCI_FAILURE);
5988 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
5989 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5990 "no device is attached at port %d", port);
5991 return (AHCI_FAILURE);
5994 /* First to set PxCMD.FRE before setting PxCMD.ST. */
5995 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5996 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5998 if (!(port_cmd_status & AHCI_CMD_STATUS_FRE)) {
5999 port_cmd_status |= AHCI_CMD_STATUS_FRE;
6000 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6001 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6002 port_cmd_status);
6005 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6006 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6008 port_cmd_status |= AHCI_CMD_STATUS_ST;
6010 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6011 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6012 port_cmd_status);
6014 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_STARTED;
6016 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port: "
6017 "PxCMD.ST set to '1' at port %d", port);
6019 return (AHCI_SUCCESS);
6023 * Setup PxCLB, PxCLBU, PxFB, and PxFBU for particular port. First, we need
6024 * to make sure PxCMD.ST, PxCMD.CR, PxCMD.FRE, and PxCMD.FR are all cleared.
6025 * Then set PxCLB, PxCLBU, PxFB, and PxFBU.
6027 static int
6028 ahci_setup_port_base_addresses(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6030 uint8_t port = ahci_portp->ahciport_port_num;
6031 uint32_t port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6032 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6034 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6036 /* Step 1: Make sure both PxCMD.ST and PxCMD.CR are cleared. */
6037 if (port_cmd_status & (AHCI_CMD_STATUS_ST | AHCI_CMD_STATUS_CR)) {
6038 if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
6039 port) != AHCI_SUCCESS)
6040 return (AHCI_FAILURE);
6042 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6043 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6046 /* Step 2: Make sure both PxCMD.FRE and PxCMD.FR are cleared. */
6047 if (port_cmd_status & (AHCI_CMD_STATUS_FRE | AHCI_CMD_STATUS_FR)) {
6048 int loop_count = 0;
6050 /* Clear PxCMD.FRE */
6051 port_cmd_status &= ~AHCI_CMD_STATUS_FRE;
6052 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6053 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
6054 port_cmd_status);
6056 /* Wait until PxCMD.FR is cleared */
6057 for (;;) {
6058 port_cmd_status =
6059 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6060 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
6062 if (!(port_cmd_status & AHCI_CMD_STATUS_FR))
6063 break;
6065 if (loop_count++ >= AHCI_POLLRATE_PORT_IDLE_FR) {
6066 AHCIDBG(AHCIDBG_INIT | AHCIDBG_ERRS, ahci_ctlp,
6067 "ahci_setup_port_base_addresses: cannot "
6068 "clear PxCMD.FR for port %d.", port);
6071 * We are effectively timing out after 0.5 sec.
6072 * This value is specified in AHCI spec.
6074 return (AHCI_FAILURE);
6077 /* Wait for 1 millisec */
6078 drv_usecwait(AHCI_1MS_USECS);
6082 /* Step 3: Config Port Command List Base Address */
6083 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6084 (uint32_t *)AHCI_PORT_PxCLB(ahci_ctlp, port),
6085 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6087 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6088 (uint32_t *)AHCI_PORT_PxCLBU(ahci_ctlp, port),
6089 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_notused);
6091 /* Step 4: Config Port Received FIS Base Address */
6092 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6093 (uint32_t *)AHCI_PORT_PxFB(ahci_ctlp, port),
6094 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6096 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6097 (uint32_t *)AHCI_PORT_PxFBU(ahci_ctlp, port),
6098 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_notused);
6100 return (AHCI_SUCCESS);
6104 * Allocate the ahci_port_t including Received FIS and Command List.
6105 * The argument - port is the physical port number, and not logical
6106 * port number seen by the SATA framework.
6108 static int
6109 ahci_alloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6111 dev_info_t *dip = ahci_ctlp->ahcictl_dip;
6112 ahci_port_t *ahci_portp;
6113 char taskq_name[64] = "event_handle_taskq";
6115 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6117 ahci_portp =
6118 (ahci_port_t *)kmem_zalloc(sizeof (ahci_port_t), KM_SLEEP);
6120 ahci_ctlp->ahcictl_ports[port] = ahci_portp;
6121 ahci_portp->ahciport_port_num = port;
6123 /* Initialize the port condition variable */
6124 cv_init(&ahci_portp->ahciport_cv, NULL, CV_DRIVER, NULL);
6126 /* Initialize the port mutex */
6127 mutex_init(&ahci_portp->ahciport_mutex, NULL, MUTEX_DRIVER,
6128 (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
6130 mutex_enter(&ahci_portp->ahciport_mutex);
6133 * Allocate memory for received FIS structure and
6134 * command list for this port
6136 if (ahci_alloc_rcvd_fis(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6137 goto err_case1;
6140 if (ahci_alloc_cmd_list(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6141 goto err_case2;
6144 /* Setup PxCMD.CLB, PxCMD.CLBU, PxCMD.FB, and PxCMD.FBU */
6145 if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
6146 AHCI_SUCCESS) {
6147 goto err_case3;
6150 (void) snprintf(taskq_name + strlen(taskq_name),
6151 sizeof (taskq_name) - strlen(taskq_name),
6152 "_port%d", port);
6154 /* Create the taskq for the port */
6155 if ((ahci_portp->ahciport_event_taskq = ddi_taskq_create(dip,
6156 taskq_name, 2, TASKQ_DEFAULTPRI, 0)) == NULL) {
6157 cmn_err(CE_WARN, "!ahci%d: ddi_taskq_create failed for event "
6158 "handle", ddi_get_instance(ahci_ctlp->ahcictl_dip));
6159 goto err_case3;
6162 /* Allocate the argument for the taskq */
6163 ahci_portp->ahciport_event_args =
6164 kmem_zalloc(sizeof (ahci_event_arg_t), KM_SLEEP);
6166 ahci_portp->ahciport_event_args->ahciea_addrp =
6167 kmem_zalloc(sizeof (ahci_addr_t), KM_SLEEP);
6169 if (ahci_portp->ahciport_event_args == NULL)
6170 goto err_case4;
6172 /* Initialize the done queue */
6173 ahci_portp->ahciport_doneq = NULL;
6174 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
6175 ahci_portp->ahciport_doneq_len = 0;
6177 mutex_exit(&ahci_portp->ahciport_mutex);
6179 return (AHCI_SUCCESS);
6181 err_case4:
6182 ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6184 err_case3:
6185 ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6187 err_case2:
6188 ahci_dealloc_rcvd_fis(ahci_portp);
6190 err_case1:
6191 mutex_exit(&ahci_portp->ahciport_mutex);
6192 mutex_destroy(&ahci_portp->ahciport_mutex);
6193 cv_destroy(&ahci_portp->ahciport_cv);
6195 kmem_free(ahci_portp, sizeof (ahci_port_t));
6197 return (AHCI_FAILURE);
6201 * Reverse of ahci_alloc_port_state().
6203 static void
6204 ahci_dealloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6206 ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
6208 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6209 ASSERT(ahci_portp != NULL);
6211 mutex_enter(&ahci_portp->ahciport_mutex);
6212 kmem_free(ahci_portp->ahciport_event_args->ahciea_addrp,
6213 sizeof (ahci_addr_t));
6214 ahci_portp->ahciport_event_args->ahciea_addrp = NULL;
6215 kmem_free(ahci_portp->ahciport_event_args, sizeof (ahci_event_arg_t));
6216 ahci_portp->ahciport_event_args = NULL;
6217 ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6218 ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6219 ahci_dealloc_rcvd_fis(ahci_portp);
6220 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
6221 mutex_exit(&ahci_portp->ahciport_mutex);
6223 mutex_destroy(&ahci_portp->ahciport_mutex);
6224 cv_destroy(&ahci_portp->ahciport_cv);
6226 kmem_free(ahci_portp, sizeof (ahci_port_t));
6228 ahci_ctlp->ahcictl_ports[port] = NULL;
6232 * Allocates memory for the Received FIS Structure
6234 static int
6235 ahci_alloc_rcvd_fis(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6237 size_t rcvd_fis_size;
6238 size_t ret_len;
6239 uint_t cookie_count;
6241 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6243 rcvd_fis_size = sizeof (ahci_rcvd_fis_t);
6245 /* allocate rcvd FIS dma handle. */
6246 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6247 &ahci_ctlp->ahcictl_rcvd_fis_dma_attr,
6248 DDI_DMA_SLEEP,
6249 NULL,
6250 &ahci_portp->ahciport_rcvd_fis_dma_handle) !=
6251 DDI_SUCCESS) {
6252 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6253 "rcvd FIS dma handle alloc failed", NULL);
6255 return (AHCI_FAILURE);
6258 if (ddi_dma_mem_alloc(ahci_portp->ahciport_rcvd_fis_dma_handle,
6259 rcvd_fis_size,
6260 &accattr,
6261 DDI_DMA_CONSISTENT,
6262 DDI_DMA_SLEEP,
6263 NULL,
6264 (caddr_t *)&ahci_portp->ahciport_rcvd_fis,
6265 &ret_len,
6266 &ahci_portp->ahciport_rcvd_fis_acc_handle) != 0) {
6268 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6269 "rcvd FIS dma mem alloc fail", NULL);
6270 /* error.. free the dma handle. */
6271 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6272 return (AHCI_FAILURE);
6275 if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle,
6276 NULL,
6277 (caddr_t)ahci_portp->ahciport_rcvd_fis,
6278 rcvd_fis_size,
6279 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6280 DDI_DMA_SLEEP,
6281 NULL,
6282 &ahci_portp->ahciport_rcvd_fis_dma_cookie,
6283 &cookie_count) != DDI_DMA_MAPPED) {
6285 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6286 "rcvd FIS dma handle bind fail", NULL);
6287 /* error.. free the dma handle & free the memory. */
6288 ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6289 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6290 return (AHCI_FAILURE);
6293 bzero((void *)ahci_portp->ahciport_rcvd_fis, rcvd_fis_size);
6295 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6296 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_laddress);
6297 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6298 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6300 return (AHCI_SUCCESS);
6304 * Deallocates the Received FIS Structure
6306 static void
6307 ahci_dealloc_rcvd_fis(ahci_port_t *ahci_portp)
6309 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6311 /* Unbind the cmd list dma handle first. */
6312 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle);
6314 /* Then free the underlying memory. */
6315 ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6317 /* Now free the handle itself. */
6318 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6322 * Allocates memory for the Command List, which contains up to 32 entries.
6323 * Each entry contains a command header, which is a 32-byte structure that
6324 * includes the pointer to the command table.
6326 static int
6327 ahci_alloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6329 size_t cmd_list_size;
6330 size_t ret_len;
6331 uint_t cookie_count;
6333 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6335 cmd_list_size =
6336 ahci_ctlp->ahcictl_num_cmd_slots * sizeof (ahci_cmd_header_t);
6338 /* allocate cmd list dma handle. */
6339 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6340 &ahci_ctlp->ahcictl_cmd_list_dma_attr,
6341 DDI_DMA_SLEEP,
6342 NULL,
6343 &ahci_portp->ahciport_cmd_list_dma_handle) != DDI_SUCCESS) {
6345 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6346 "cmd list dma handle alloc failed", NULL);
6347 return (AHCI_FAILURE);
6350 if (ddi_dma_mem_alloc(ahci_portp->ahciport_cmd_list_dma_handle,
6351 cmd_list_size,
6352 &accattr,
6353 DDI_DMA_CONSISTENT,
6354 DDI_DMA_SLEEP,
6355 NULL,
6356 (caddr_t *)&ahci_portp->ahciport_cmd_list,
6357 &ret_len,
6358 &ahci_portp->ahciport_cmd_list_acc_handle) != 0) {
6360 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6361 "cmd list dma mem alloc fail", NULL);
6362 /* error.. free the dma handle. */
6363 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6364 return (AHCI_FAILURE);
6367 if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_cmd_list_dma_handle,
6368 NULL,
6369 (caddr_t)ahci_portp->ahciport_cmd_list,
6370 cmd_list_size,
6371 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6372 DDI_DMA_SLEEP,
6373 NULL,
6374 &ahci_portp->ahciport_cmd_list_dma_cookie,
6375 &cookie_count) != DDI_DMA_MAPPED) {
6377 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6378 "cmd list dma handle bind fail", NULL);
6379 /* error.. free the dma handle & free the memory. */
6380 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6381 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6382 return (AHCI_FAILURE);
6385 bzero((void *)ahci_portp->ahciport_cmd_list, cmd_list_size);
6387 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6388 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_laddress);
6390 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6391 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6393 if (ahci_alloc_cmd_tables(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6394 goto err_out;
6397 return (AHCI_SUCCESS);
6399 err_out:
6400 /* Unbind the cmd list dma handle first. */
6401 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6403 /* Then free the underlying memory. */
6404 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6406 /* Now free the handle itself. */
6407 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6409 return (AHCI_FAILURE);
6413 * Deallocates the Command List
6415 static void
6416 ahci_dealloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6418 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6420 /* First dealloc command table */
6421 ahci_dealloc_cmd_tables(ahci_ctlp, ahci_portp);
6423 /* Unbind the cmd list dma handle first. */
6424 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6426 /* Then free the underlying memory. */
6427 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6429 /* Now free the handle itself. */
6430 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6434 * Allocates memory for all Command Tables, which contains Command FIS,
6435 * ATAPI Command and Physical Region Descriptor Table.
6437 static int
6438 ahci_alloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6440 size_t ret_len;
6441 ddi_dma_cookie_t cmd_table_dma_cookie;
6442 uint_t cookie_count;
6443 int slot;
6445 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6447 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
6448 "ahci_alloc_cmd_tables: port %d enter",
6449 ahci_portp->ahciport_port_num);
6451 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6452 /* Allocate cmd table dma handle. */
6453 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6454 &ahci_ctlp->ahcictl_cmd_table_dma_attr,
6455 DDI_DMA_SLEEP,
6456 NULL,
6457 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]) !=
6458 DDI_SUCCESS) {
6460 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6461 "cmd table dma handle alloc failed", NULL);
6463 goto err_out;
6466 if (ddi_dma_mem_alloc(
6467 ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6468 ahci_cmd_table_size,
6469 &accattr,
6470 DDI_DMA_CONSISTENT,
6471 DDI_DMA_SLEEP,
6472 NULL,
6473 (caddr_t *)&ahci_portp->ahciport_cmd_tables[slot],
6474 &ret_len,
6475 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]) !=
6476 0) {
6478 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6479 "cmd table dma mem alloc fail", NULL);
6481 /* error.. free the dma handle. */
6482 ddi_dma_free_handle(
6483 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6484 goto err_out;
6487 if (ddi_dma_addr_bind_handle(
6488 ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6489 NULL,
6490 (caddr_t)ahci_portp->ahciport_cmd_tables[slot],
6491 ahci_cmd_table_size,
6492 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6493 DDI_DMA_SLEEP,
6494 NULL,
6495 &cmd_table_dma_cookie,
6496 &cookie_count) != DDI_DMA_MAPPED) {
6498 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6499 "cmd table dma handle bind fail", NULL);
6500 /* error.. free the dma handle & free the memory. */
6501 ddi_dma_mem_free(
6502 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6503 ddi_dma_free_handle(
6504 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6505 goto err_out;
6508 bzero((void *)ahci_portp->ahciport_cmd_tables[slot],
6509 ahci_cmd_table_size);
6511 /* Config Port Command Table Base Address */
6512 SET_COMMAND_TABLE_BASE_ADDR(
6513 (&ahci_portp->ahciport_cmd_list[slot]),
6514 cmd_table_dma_cookie.dmac_laddress & 0xffffffffull);
6516 #ifndef __lock_lint
6517 SET_COMMAND_TABLE_BASE_ADDR_UPPER(
6518 (&ahci_portp->ahciport_cmd_list[slot]),
6519 cmd_table_dma_cookie.dmac_laddress >> 32);
6520 #endif
6523 return (AHCI_SUCCESS);
6524 err_out:
6526 for (slot--; slot >= 0; slot--) {
6527 /* Unbind the cmd table dma handle first */
6528 (void) ddi_dma_unbind_handle(
6529 ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6531 /* Then free the underlying memory */
6532 ddi_dma_mem_free(
6533 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6535 /* Now free the handle itself */
6536 ddi_dma_free_handle(
6537 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6540 return (AHCI_FAILURE);
6544 * Deallocates memory for all Command Tables.
6546 static void
6547 ahci_dealloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6549 int slot;
6551 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6553 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
6554 "ahci_dealloc_cmd_tables: %d enter",
6555 ahci_portp->ahciport_port_num);
6557 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6558 /* Unbind the cmd table dma handle first. */
6559 (void) ddi_dma_unbind_handle(
6560 ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6562 /* Then free the underlying memory. */
6563 ddi_dma_mem_free(
6564 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6566 /* Now free the handle itself. */
6567 ddi_dma_free_handle(
6568 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6573 * Update SATA registers at controller ports
6575 static void
6576 ahci_update_sata_registers(ahci_ctl_t *ahci_ctlp, uint8_t port,
6577 sata_device_t *sd)
6579 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
6581 sd->satadev_scr.sstatus =
6582 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6583 (uint32_t *)(AHCI_PORT_PxSSTS(ahci_ctlp, port)));
6584 sd->satadev_scr.serror =
6585 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6586 (uint32_t *)(AHCI_PORT_PxSERR(ahci_ctlp, port)));
6587 sd->satadev_scr.scontrol =
6588 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6589 (uint32_t *)(AHCI_PORT_PxSCTL(ahci_ctlp, port)));
6590 sd->satadev_scr.sactive =
6591 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6592 (uint32_t *)(AHCI_PORT_PxSACT(ahci_ctlp, port)));
6596 * For poll mode, ahci_port_intr will be called to emulate the interrupt
6598 static void
6599 ahci_port_intr(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
6601 uint32_t port_intr_status;
6602 uint32_t port_intr_enable;
6604 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
6605 "ahci_port_intr enter: port %d", port);
6607 mutex_enter(&ahci_portp->ahciport_mutex);
6608 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_POLLING) {
6609 /* For SATA_OPMODE_POLLING commands */
6610 port_intr_enable =
6611 (AHCI_INTR_STATUS_DHRS |
6612 AHCI_INTR_STATUS_PSS |
6613 AHCI_INTR_STATUS_SDBS |
6614 AHCI_INTR_STATUS_UFS |
6615 AHCI_INTR_STATUS_PCS |
6616 AHCI_INTR_STATUS_PRCS |
6617 AHCI_INTR_STATUS_OFS |
6618 AHCI_INTR_STATUS_INFS |
6619 AHCI_INTR_STATUS_IFS |
6620 AHCI_INTR_STATUS_HBDS |
6621 AHCI_INTR_STATUS_HBFS |
6622 AHCI_INTR_STATUS_TFES);
6623 } else {
6625 * port_intr_enable indicates that the corresponding interrrupt
6626 * reporting is enabled.
6628 port_intr_enable = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6629 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
6632 /* IPMS error in port reset should be ignored according AHCI spec. */
6633 if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_IGNORE_IPMS))
6634 port_intr_enable |= AHCI_INTR_STATUS_IPMS;
6635 mutex_exit(&ahci_portp->ahciport_mutex);
6638 * port_intr_stats indicates that the corresponding interrupt
6639 * condition is active.
6641 port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6642 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
6644 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6645 "ahci_port_intr: port %d, port_intr_status = 0x%x, "
6646 "port_intr_enable = 0x%x",
6647 port, port_intr_status, port_intr_enable);
6649 port_intr_status &= port_intr_enable;
6652 * Pending interrupt events are indicated by the PxIS register.
6653 * Make sure we don't miss any event.
6655 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
6656 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6657 DDI_SERVICE_UNAFFECTED);
6658 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6659 DDI_FME_VERSION);
6660 return;
6663 /* First clear the port interrupts status */
6664 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6665 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
6666 port_intr_status);
6668 /* Check the completed non-queued commands */
6669 if (port_intr_status & (AHCI_INTR_STATUS_DHRS |
6670 AHCI_INTR_STATUS_PSS)) {
6671 (void) ahci_intr_cmd_cmplt(ahci_ctlp,
6672 ahci_portp, port);
6675 /* Check the completed queued commands */
6676 if (port_intr_status & AHCI_INTR_STATUS_SDBS) {
6677 (void) ahci_intr_set_device_bits(ahci_ctlp,
6678 ahci_portp, port);
6681 /* Check the port connect change status interrupt bit */
6682 if (port_intr_status & AHCI_INTR_STATUS_PCS) {
6683 (void) ahci_intr_port_connect_change(ahci_ctlp,
6684 ahci_portp, port);
6687 /* Check the device mechanical presence status interrupt bit */
6688 if (port_intr_status & AHCI_INTR_STATUS_DMPS) {
6689 (void) ahci_intr_device_mechanical_presence_status(
6690 ahci_ctlp, ahci_portp, port);
6693 /* Check the PhyRdy change status interrupt bit */
6694 if (port_intr_status & AHCI_INTR_STATUS_PRCS) {
6695 (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp,
6696 port);
6700 * Check the non-fatal error interrupt bits, there are four
6701 * kinds of non-fatal errors at the time being:
6703 * PxIS.UFS - Unknown FIS Error
6704 * PxIS.OFS - Overflow Error
6705 * PxIS.INFS - Interface Non-Fatal Error
6706 * PxIS.IPMS - Incorrect Port Multiplier Status Error
6708 * For these non-fatal errors, the HBA can continue to operate,
6709 * so the driver just log the error messages.
6711 if (port_intr_status & (AHCI_INTR_STATUS_UFS |
6712 AHCI_INTR_STATUS_OFS |
6713 AHCI_INTR_STATUS_IPMS |
6714 AHCI_INTR_STATUS_INFS)) {
6715 (void) ahci_intr_non_fatal_error(ahci_ctlp, ahci_portp,
6716 port, port_intr_status);
6720 * Check the fatal error interrupt bits, there are four kinds
6721 * of fatal errors for AHCI controllers:
6723 * PxIS.HBFS - Host Bus Fatal Error
6724 * PxIS.HBDS - Host Bus Data Error
6725 * PxIS.IFS - Interface Fatal Error
6726 * PxIS.TFES - Task File Error
6728 * The fatal error means the HBA can not recover from it by
6729 * itself, and it will try to abort the transfer, and the software
6730 * must intervene to restart the port.
6732 if (port_intr_status & (AHCI_INTR_STATUS_IFS |
6733 AHCI_INTR_STATUS_HBDS |
6734 AHCI_INTR_STATUS_HBFS |
6735 AHCI_INTR_STATUS_TFES))
6736 (void) ahci_intr_fatal_error(ahci_ctlp, ahci_portp,
6737 port, port_intr_status);
6739 /* Check the cold port detect interrupt bit */
6740 if (port_intr_status & AHCI_INTR_STATUS_CPDS) {
6741 (void) ahci_intr_cold_port_detect(ahci_ctlp, ahci_portp, port);
6744 /* Second clear the corresponding bit in IS.IPS */
6745 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6746 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (0x1 << port));
6748 /* Try to recover at the end of the interrupt handler. */
6749 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6750 DDI_FM_OK) {
6751 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6752 DDI_SERVICE_UNAFFECTED);
6753 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6754 DDI_FME_VERSION);
6759 * Interrupt service handler
6761 static uint_t
6762 ahci_intr(caddr_t arg1, caddr_t arg2)
6764 #ifndef __lock_lint
6765 _NOTE(ARGUNUSED(arg2))
6766 #endif
6767 /* LINTED */
6768 ahci_ctl_t *ahci_ctlp = (ahci_ctl_t *)arg1;
6769 ahci_port_t *ahci_portp;
6770 int32_t global_intr_status;
6771 uint8_t port;
6774 * global_intr_status indicates that the corresponding port has
6775 * an interrupt pending.
6777 global_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6778 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp));
6780 if (!(global_intr_status & ahci_ctlp->ahcictl_ports_implemented)) {
6781 /* The interrupt is not ours */
6782 return (DDI_INTR_UNCLAIMED);
6786 * Check the handle after reading global_intr_status - we don't want
6787 * to miss any port with pending interrupts.
6789 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6790 DDI_FM_OK) {
6791 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6792 DDI_SERVICE_UNAFFECTED);
6793 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6794 DDI_FME_VERSION);
6795 return (DDI_INTR_UNCLAIMED);
6798 /* Loop for all the ports */
6799 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
6800 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
6801 continue;
6803 if (!((0x1 << port) & global_intr_status)) {
6804 continue;
6807 ahci_portp = ahci_ctlp->ahcictl_ports[port];
6809 /* Call ahci_port_intr */
6810 ahci_port_intr(ahci_ctlp, ahci_portp, port);
6813 return (DDI_INTR_CLAIMED);
6817 * For non-queued commands, when the corresponding bit in the PxCI register
6818 * is cleared, it means the command is completed successfully. And according
6819 * to the HBA state machine, there are three conditions which possibly will
6820 * try to clear the PxCI register bit.
6821 * 1. Receive one D2H Register FIS which is with 'I' bit set
6822 * 2. Update PIO Setup FIS
6823 * 3. Transmit a command and receive R_OK if CTBA.C is set (software reset)
6825 * Process completed non-queued commands when the interrupt status bit -
6826 * AHCI_INTR_STATUS_DHRS or AHCI_INTR_STATUS_PSS is set.
6828 * AHCI_INTR_STATUS_DHRS means a D2H Register FIS has been received
6829 * with the 'I' bit set. And the following commands will send thus
6830 * FIS with 'I' bit set upon the successful completion:
6831 * 1. Non-data commands
6832 * 2. DMA data-in command
6833 * 3. DMA data-out command
6834 * 4. PIO data-out command
6835 * 5. PACKET non-data commands
6836 * 6. PACKET PIO data-in command
6837 * 7. PACKET PIO data-out command
6838 * 8. PACKET DMA data-in command
6839 * 9. PACKET DMA data-out command
6841 * AHCI_INTR_STATUS_PSS means a PIO Setup FIS has been received
6842 * with the 'I' bit set. And the following commands will send this
6843 * FIS upon the successful completion:
6844 * 1. PIO data-in command
6846 static int
6847 ahci_intr_cmd_cmplt(ahci_ctl_t *ahci_ctlp,
6848 ahci_port_t *ahci_portp, uint8_t port)
6850 uint32_t port_cmd_issue = 0;
6851 uint32_t finished_tags;
6852 int finished_slot;
6853 sata_pkt_t *satapkt;
6854 ahci_fis_d2h_register_t *rcvd_fisp;
6855 #if AHCI_DEBUG
6856 ahci_cmd_header_t *cmd_header;
6857 uint32_t cmd_dmacount;
6858 #endif
6860 mutex_enter(&ahci_portp->ahciport_mutex);
6862 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6863 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6864 !NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
6866 * Spurious interrupt. Nothing to be done.
6868 mutex_exit(&ahci_portp->ahciport_mutex);
6869 return (AHCI_SUCCESS);
6872 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6873 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
6875 /* If the PxCI corrupts, don't complete the commmands. */
6876 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
6877 != DDI_FM_OK) {
6878 mutex_exit(&ahci_portp->ahciport_mutex);
6879 return (AHCI_FAILURE);
6882 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
6883 /* Slot 0 is always used during error recovery */
6884 finished_tags = 0x1 & ~port_cmd_issue;
6885 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
6886 "ahci_intr_cmd_cmplt: port %d the sata pkt for error "
6887 "retrieval is finished, and finished_tags = 0x%x",
6888 port, finished_tags);
6889 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
6890 finished_tags = 0x1 & ~port_cmd_issue;
6891 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
6892 "ahci_intr_cmd_cmplt: port %d the sata pkt for r/w "
6893 "port multiplier is finished, and finished_tags = 0x%x",
6894 port, finished_tags);
6896 } else {
6898 finished_tags = ahci_portp->ahciport_pending_tags &
6899 ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
6902 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6903 "ahci_intr_cmd_cmplt: pending_tags = 0x%x, "
6904 "port_cmd_issue = 0x%x finished_tags = 0x%x",
6905 ahci_portp->ahciport_pending_tags, port_cmd_issue,
6906 finished_tags);
6908 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6909 (finished_tags == 0x1)) {
6910 satapkt = ahci_portp->ahciport_err_retri_pkt;
6911 ASSERT(satapkt != NULL);
6913 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6914 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6915 "with SATA_PKT_COMPLETED", (void *)satapkt);
6917 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6918 goto out;
6921 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6922 (finished_tags == 0x1)) {
6923 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
6924 ASSERT(satapkt != NULL);
6926 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6927 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6928 "with SATA_PKT_COMPLETED", (void *)satapkt);
6930 /* READ PORTMULT need copy out FIS content. */
6931 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
6932 rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
6933 ahcirf_d2h_register_fis);
6934 satapkt->satapkt_cmd.satacmd_status_reg =
6935 GET_RFIS_STATUS(rcvd_fisp);
6936 ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
6939 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6940 goto out;
6943 while (finished_tags) {
6944 finished_slot = ddi_ffs(finished_tags) - 1;
6945 if (finished_slot == -1) {
6946 goto out;
6949 satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
6950 ASSERT(satapkt != NULL);
6951 #if AHCI_DEBUG
6953 * For non-native queued commands, the PRD byte count field
6954 * shall contain an accurate count of the number of bytes
6955 * transferred for the command before the PxCI bit is cleared
6956 * to '0' for the command.
6958 * The purpose of this field is to let software know how many
6959 * bytes transferred for a given operation in order to
6960 * determine if underflow occurred. When issuing native command
6961 * queuing commands, this field should not be used and is not
6962 * required to be valid since in this case underflow is always
6963 * illegal.
6965 * For data reads, the HBA will update its PRD byte count with
6966 * the total number of bytes received from the last FIS, and
6967 * may be able to continue normally. For data writes, the
6968 * device will detect an error, and HBA most likely will get
6969 * a fatal error.
6971 * Therefore, here just put code to debug part. And please
6972 * refer to the comment above ahci_intr_fatal_error for the
6973 * definition of underflow error.
6975 cmd_dmacount =
6976 ahci_portp->ahciport_prd_bytecounts[finished_slot];
6977 if (cmd_dmacount) {
6978 cmd_header =
6979 &ahci_portp->ahciport_cmd_list[finished_slot];
6980 AHCIDBG(AHCIDBG_INTR|AHCIDBG_PRDT, ahci_ctlp,
6981 "ahci_intr_cmd_cmplt: port %d, "
6982 "PRD Byte Count = 0x%x, "
6983 "ahciport_prd_bytecounts = 0x%x", port,
6984 cmd_header->ahcich_prd_byte_count,
6985 cmd_dmacount);
6987 if (cmd_header->ahcich_prd_byte_count != cmd_dmacount) {
6988 AHCIDBG(AHCIDBG_UNDERFLOW, ahci_ctlp,
6989 "ahci_intr_cmd_cmplt: port %d, "
6990 "an underflow occurred", port);
6993 #endif
6996 * For SATAC_SMART command with SATA_SMART_RETURN_STATUS
6997 * feature, sata_special_regs flag will be set, and the
6998 * driver should copy the status and the other corresponding
6999 * register values in the D2H Register FIS received (It's
7000 * working on Non-data protocol) from the device back to
7001 * the sata_cmd.
7003 * For every AHCI port, there is only one Received FIS
7004 * structure, which contains the FISes received from the
7005 * device, So we're trying to copy the content of D2H
7006 * Register FIS in the Received FIS structure back to
7007 * the sata_cmd.
7009 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
7010 rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
7011 ahcirf_d2h_register_fis);
7012 satapkt->satapkt_cmd.satacmd_status_reg =
7013 GET_RFIS_STATUS(rcvd_fisp);
7014 ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
7017 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7018 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
7019 "with SATA_PKT_COMPLETED", (void *)satapkt);
7021 CLEAR_BIT(ahci_portp->ahciport_pending_tags, finished_slot);
7022 CLEAR_BIT(finished_tags, finished_slot);
7023 ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7025 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7027 out:
7028 AHCIDBG(AHCIDBG_PKTCOMP, ahci_ctlp,
7029 "ahci_intr_cmd_cmplt: pending_tags = 0x%x",
7030 ahci_portp->ahciport_pending_tags);
7032 ahci_flush_doneq(ahci_portp);
7034 mutex_exit(&ahci_portp->ahciport_mutex);
7036 return (AHCI_SUCCESS);
7040 * AHCI_INTR_STATUS_SDBS means a Set Device Bits FIS has been received
7041 * with the 'I' bit set and has been copied into system memory. It will
7042 * be sent under the following situations:
7044 * 1. NCQ command is completed
7046 * The completion of NCQ commands (READ/WRITE FPDMA QUEUED) is performed
7047 * via the Set Device Bits FIS. When such event is generated, the software
7048 * needs to read PxSACT register and compares the current value to the
7049 * list of commands previously issue by software. ahciport_pending_ncq_tags
7050 * keeps the tags of previously issued commands.
7052 * 2. Asynchronous Notification
7054 * Asynchronous Notification is a feature in SATA spec 2.6.
7056 * 1) ATAPI device will send a signal to the host when media is inserted or
7057 * removed and avoids polling the device for media changes. The signal
7058 * sent to the host is a Set Device Bits FIS with the 'I' and 'N' bits
7059 * set to '1'. At the moment, it's not supported yet.
7061 * 2) Port multiplier will send a signal to the host when a hot plug event
7062 * has occured on a port multiplier port. It is used when command based
7063 * switching is employed. This is handled by ahci_intr_pmult_sntf_events()
7065 static int
7066 ahci_intr_set_device_bits(ahci_ctl_t *ahci_ctlp,
7067 ahci_port_t *ahci_portp, uint8_t port)
7069 ahci_addr_t addr;
7071 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7072 "ahci_intr_set_device_bits enter: port %d", port);
7074 /* Initialize HBA port address */
7075 AHCI_ADDR_SET_PORT(&addr, port);
7077 /* NCQ plug handler */
7078 (void) ahci_intr_ncq_events(ahci_ctlp, ahci_portp, &addr);
7080 /* Check port multiplier's asynchronous notification events */
7081 if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
7082 (void) ahci_intr_pmult_sntf_events(ahci_ctlp,
7083 ahci_portp, port);
7086 /* ATAPI events is not supported yet */
7088 return (AHCI_SUCCESS);
7091 * NCQ interrupt handler. Called upon a NCQ command is completed.
7092 * Only be called from ahci_intr_set_device_bits().
7094 static int
7095 ahci_intr_ncq_events(ahci_ctl_t *ahci_ctlp,
7096 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
7098 uint32_t port_sactive;
7099 uint32_t port_cmd_issue;
7100 uint32_t issued_tags;
7101 int issued_slot;
7102 uint32_t finished_tags;
7103 int finished_slot;
7104 uint8_t port = addrp->aa_port;
7105 sata_pkt_t *satapkt;
7107 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7108 "ahci_intr_set_device_bits enter: port %d", port);
7110 mutex_enter(&ahci_portp->ahciport_mutex);
7111 if (!NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7112 mutex_exit(&ahci_portp->ahciport_mutex);
7113 return (AHCI_SUCCESS);
7117 * First the handler got which commands are finished by checking
7118 * PxSACT register
7120 port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7121 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7123 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
7124 ~port_sactive & AHCI_NCQ_SLOT_MASK(ahci_portp);
7126 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7127 "ahci_intr_set_device_bits: port %d pending_ncq_tags = 0x%x "
7128 "port_sactive = 0x%x", port,
7129 ahci_portp->ahciport_pending_ncq_tags, port_sactive);
7131 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7132 "ahci_intr_set_device_bits: finished_tags = 0x%x", finished_tags);
7135 * For NCQ commands, the software can determine which command has
7136 * already been transmitted to the device by checking PxCI register.
7138 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7139 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7141 issued_tags = ahci_portp->ahciport_pending_tags &
7142 ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
7144 /* If the PxSACT/PxCI corrupts, don't complete the NCQ commmands. */
7145 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
7146 != DDI_FM_OK) {
7147 mutex_exit(&ahci_portp->ahciport_mutex);
7148 return (AHCI_FAILURE);
7151 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7152 "ahci_intr_set_device_bits: port %d pending_tags = 0x%x "
7153 "port_cmd_issue = 0x%x", port,
7154 ahci_portp->ahciport_pending_tags, port_cmd_issue);
7156 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7157 "ahci_intr_set_device_bits: issued_tags = 0x%x", issued_tags);
7160 * Clear ahciport_pending_tags bit when the corresponding command
7161 * is already sent down to the device.
7163 while (issued_tags) {
7164 issued_slot = ddi_ffs(issued_tags) - 1;
7165 if (issued_slot == -1) {
7166 goto next;
7168 CLEAR_BIT(ahci_portp->ahciport_pending_tags, issued_slot);
7169 CLEAR_BIT(issued_tags, issued_slot);
7172 next:
7173 while (finished_tags) {
7174 finished_slot = ddi_ffs(finished_tags) - 1;
7175 if (finished_slot == -1) {
7176 goto out;
7179 /* The command is certainly transmitted to the device */
7180 ASSERT(!(ahci_portp->ahciport_pending_tags &
7181 (0x1 << finished_slot)));
7183 satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
7184 ASSERT(satapkt != NULL);
7186 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7187 "ahci_intr_set_device_bits: sending up pkt 0x%p "
7188 "with SATA_PKT_COMPLETED", (void *)satapkt);
7190 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags, finished_slot);
7191 CLEAR_BIT(finished_tags, finished_slot);
7192 ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7194 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7196 out:
7197 AHCIDBG(AHCIDBG_PKTCOMP|AHCIDBG_NCQ, ahci_ctlp,
7198 "ahci_intr_set_device_bits: port %d "
7199 "pending_ncq_tags = 0x%x pending_tags = 0x%x",
7200 port, ahci_portp->ahciport_pending_ncq_tags,
7201 ahci_portp->ahciport_pending_tags);
7203 ahci_flush_doneq(ahci_portp);
7205 mutex_exit(&ahci_portp->ahciport_mutex);
7207 return (AHCI_SUCCESS);
7211 * Port multiplier asynchronous notification event handler. Called upon a
7212 * device is hot plugged/pulled.
7214 * The async-notification event will only be recorded by ahcipmi_snotif_tags
7215 * here and will be handled by ahci_probe_pmult().
7217 * NOTE: called only from ahci_port_intr().
7219 static int
7220 ahci_intr_pmult_sntf_events(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7221 uint8_t port)
7223 sata_device_t sdevice;
7225 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7226 "ahci_intr_pmult_sntf_events enter: port %d ", port);
7228 /* no hot-plug while attaching process */
7229 mutex_enter(&ahci_ctlp->ahcictl_mutex);
7230 if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH) {
7231 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7232 return (AHCI_SUCCESS);
7234 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7236 mutex_enter(&ahci_portp->ahciport_mutex);
7237 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
7238 mutex_exit(&ahci_portp->ahciport_mutex);
7239 return (AHCI_SUCCESS);
7242 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
7244 ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags =
7245 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7246 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port));
7247 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7248 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
7249 AHCI_SNOTIF_CLEAR_ALL);
7251 if (ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags == 0) {
7252 mutex_exit(&ahci_portp->ahciport_mutex);
7253 return (AHCI_SUCCESS);
7256 /* Port Multiplier sub-device hot-plug handler */
7257 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
7258 mutex_exit(&ahci_portp->ahciport_mutex);
7259 return (AHCI_SUCCESS);
7262 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_PMULT_SNTF) {
7263 /* Not allowed to re-enter. */
7264 mutex_exit(&ahci_portp->ahciport_mutex);
7265 return (AHCI_SUCCESS);
7268 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_PMULT_SNTF;
7271 * NOTE:
7272 * Even if Asynchronous Notification is supported (and enabled) by
7273 * both controller and the port multiplier, the content of PxSNTF
7274 * register is always set to 0x8000 by async notification event. We
7275 * need to check GSCR[32] on the port multiplier to find out the
7276 * owner of this event.
7277 * This is not accord with SATA spec 2.6 and needs further
7278 * clarification.
7280 /* hot-plug will not reported while reseting. */
7281 if (ahci_portp->ahciport_reset_in_progress == 1) {
7282 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7283 "port %d snotif event ignored", port);
7284 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7285 mutex_exit(&ahci_portp->ahciport_mutex);
7286 return (AHCI_SUCCESS);
7289 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7290 "PxSNTF is set to 0x%x by port multiplier",
7291 ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags);
7294 * Now we need do some necessary operation and inform SATA framework
7295 * that link/device events has happened.
7297 bzero((void *)&sdevice, sizeof (sata_device_t));
7298 sdevice.satadev_addr.cport = ahci_ctlp->
7299 ahcictl_port_to_cport[port];
7300 sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
7301 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
7302 sdevice.satadev_state = SATA_PSTATE_PWRON;
7304 /* Just reject packets, do not stop that port. */
7305 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7307 mutex_exit(&ahci_portp->ahciport_mutex);
7308 sata_hba_event_notify(
7309 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7310 &sdevice,
7311 SATA_EVNT_PMULT_LINK_CHANGED);
7312 mutex_enter(&ahci_portp->ahciport_mutex);
7314 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7315 mutex_exit(&ahci_portp->ahciport_mutex);
7317 return (AHCI_SUCCESS);
7321 * 1=Change in Current Connect Status. 0=No change in Current Connect Status.
7322 * This bit reflects the state of PxSERR.DIAG.X. This bit is only cleared
7323 * when PxSERR.DIAG.X is cleared. When PxSERR.DIAG.X is set to one, it
7324 * indicates a COMINIT signal was received.
7326 * Hot plug insertion is detected by reception of a COMINIT signal from the
7327 * device. On reception of unsolicited COMINIT, the HBA shall generate a
7328 * COMRESET. If the COMINIT is in responce to a COMRESET, then the HBA shall
7329 * begin the normal communication negotiation sequence as outlined in the
7330 * Serial ATA 1.0a specification. When a COMRESET is sent to the device the
7331 * PxSSTS.DET field shall be cleared to 0h. When a COMINIT is received, the
7332 * PxSSTS.DET field shall be set to 1h. When the communication negotiation
7333 * sequence is complete and PhyRdy is true the PxSSTS.DET field shall be set
7334 * to 3h. Therefore, at the moment the ahci driver is going to check PhyRdy
7335 * to handle hot plug insertion. In this interrupt handler, just do nothing
7336 * but print some log message and clear the bit.
7338 static int
7339 ahci_intr_port_connect_change(ahci_ctl_t *ahci_ctlp,
7340 ahci_port_t *ahci_portp, uint8_t port)
7342 #if AHCI_DEBUG
7343 uint32_t port_serror;
7344 #endif
7346 mutex_enter(&ahci_portp->ahciport_mutex);
7348 #if AHCI_DEBUG
7349 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7350 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7352 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7353 "ahci_intr_port_connect_change: port %d, "
7354 "port_serror = 0x%x", port, port_serror);
7355 #endif
7357 /* Clear PxSERR.DIAG.X to clear the interrupt bit */
7358 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7359 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7360 SERROR_EXCHANGED_ERR);
7362 mutex_exit(&ahci_portp->ahciport_mutex);
7364 return (AHCI_SUCCESS);
7368 * Hot Plug Operation for platforms that support Mechanical Presence
7369 * Switches.
7371 * When set, it indicates that a mechanical presence switch attached to this
7372 * port has been opened or closed, which may lead to a change in the connection
7373 * state of the device. This bit is only valid if both CAP.SMPS and PxCMD.MPSP
7374 * are set to '1'.
7376 * At the moment, this interrupt is not needed and disabled and we just log
7377 * the debug message.
7379 static int
7380 ahci_intr_device_mechanical_presence_status(ahci_ctl_t *ahci_ctlp,
7381 ahci_port_t *ahci_portp, uint8_t port)
7383 uint32_t cap_status, port_cmd_status;
7385 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7386 "ahci_intr_device_mechanical_presence_status enter, "
7387 "port %d", port);
7389 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7390 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
7392 mutex_enter(&ahci_portp->ahciport_mutex);
7393 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7394 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7396 if (!(cap_status & AHCI_HBA_CAP_SMPS) ||
7397 !(port_cmd_status & AHCI_CMD_STATUS_MPSP)) {
7398 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7399 "CAP.SMPS or PxCMD.MPSP is not set, so just ignore "
7400 "the interrupt: cap_status = 0x%x, "
7401 "port_cmd_status = 0x%x", cap_status, port_cmd_status);
7402 mutex_exit(&ahci_portp->ahciport_mutex);
7404 return (AHCI_SUCCESS);
7407 #if AHCI_DEBUG
7408 if (port_cmd_status & AHCI_CMD_STATUS_MPSS) {
7409 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7410 "The mechanical presence switch is open: "
7411 "port %d, port_cmd_status = 0x%x",
7412 port, port_cmd_status);
7413 } else {
7414 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7415 "The mechanical presence switch is close: "
7416 "port %d, port_cmd_status = 0x%x",
7417 port, port_cmd_status);
7419 #endif
7421 mutex_exit(&ahci_portp->ahciport_mutex);
7423 return (AHCI_SUCCESS);
7427 * Native Hot Plug Support.
7429 * When set, it indicates that the internal PHYRDY signal changed state.
7430 * This bit reflects the state of PxSERR.DIAG.N.
7432 * There are three kinds of conditions to generate this interrupt event:
7433 * 1. a device is inserted
7434 * 2. a device is disconnected
7435 * 3. when the link enters/exits a Partial or Slumber interface power
7436 * management state
7438 * If inteface power management is enabled for a port, the PxSERR.DIAG.N
7439 * bit may be set due to the link entering the Partial or Slumber power
7440 * management state, rather than due to a hot plug insertion or removal
7441 * event. So far, the interface power management is disabled, so the
7442 * driver can reliably get removal detection notification via the
7443 * PxSERR.DIAG.N bit.
7445 static int
7446 ahci_intr_phyrdy_change(ahci_ctl_t *ahci_ctlp,
7447 ahci_port_t *ahci_portp, uint8_t port)
7449 uint32_t port_sstatus = 0; /* No dev present & PHY not established. */
7450 sata_device_t sdevice;
7451 int dev_exists_now = 0;
7452 int dev_existed_previously = 0;
7453 ahci_addr_t port_addr;
7455 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7456 "ahci_intr_phyrdy_change enter, port %d", port);
7458 /* Clear PxSERR.DIAG.N to clear the interrupt bit */
7459 mutex_enter(&ahci_portp->ahciport_mutex);
7460 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7461 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7462 SERROR_PHY_RDY_CHG);
7463 mutex_exit(&ahci_portp->ahciport_mutex);
7465 mutex_enter(&ahci_ctlp->ahcictl_mutex);
7466 if ((ahci_ctlp->ahcictl_sata_hba_tran == NULL) ||
7467 (ahci_portp == NULL)) {
7468 /* The whole controller setup is not yet done. */
7469 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7470 return (AHCI_SUCCESS);
7472 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7474 mutex_enter(&ahci_portp->ahciport_mutex);
7476 /* SStatus tells the presence of device. */
7477 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7478 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
7480 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
7481 dev_exists_now = 1;
7484 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
7485 dev_existed_previously = 1;
7488 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_NODEV) {
7489 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_NODEV;
7490 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7491 "ahci_intr_phyrdy_change: port %d "
7492 "AHCI_PORT_FLAG_NODEV is cleared", port);
7493 if (dev_exists_now == 0)
7494 dev_existed_previously = 1;
7497 bzero((void *)&sdevice, sizeof (sata_device_t));
7498 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
7499 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
7500 sdevice.satadev_addr.pmport = 0;
7501 sdevice.satadev_state = SATA_PSTATE_PWRON;
7502 ahci_portp->ahciport_port_state = SATA_PSTATE_PWRON;
7504 AHCI_ADDR_SET_PORT(&port_addr, port);
7506 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
7507 if (dev_exists_now) {
7508 if (dev_existed_previously) { /* 1 -> 1 */
7509 /* Things are fine now. The loss was temporary. */
7510 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7511 "ahci_intr_phyrdy_change port %d "
7512 "device link lost/established", port);
7514 mutex_exit(&ahci_portp->ahciport_mutex);
7515 sata_hba_event_notify(
7516 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7517 &sdevice,
7518 SATA_EVNT_LINK_LOST|SATA_EVNT_LINK_ESTABLISHED);
7519 mutex_enter(&ahci_portp->ahciport_mutex);
7521 } else { /* 0 -> 1 */
7522 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7523 "ahci_intr_phyrdy_change: port %d "
7524 "device link established", port);
7527 * A new device has been detected. The new device
7528 * might be a port multiplier instead of a drive, so
7529 * we cannot update the signature directly.
7531 (void) ahci_initialize_port(ahci_ctlp,
7532 ahci_portp, &port_addr);
7534 /* Try to start the port */
7535 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
7536 != AHCI_SUCCESS) {
7537 sdevice.satadev_state |= SATA_PSTATE_FAILED;
7538 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7539 "ahci_intr_phyrdy_change: port %d failed "
7540 "at start port", port);
7543 /* Clear the max queue depth for inserted device */
7544 ahci_portp->ahciport_max_ncq_tags = 0;
7546 mutex_exit(&ahci_portp->ahciport_mutex);
7547 sata_hba_event_notify(
7548 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7549 &sdevice,
7550 SATA_EVNT_LINK_ESTABLISHED);
7551 mutex_enter(&ahci_portp->ahciport_mutex);
7554 } else { /* No device exists now */
7556 if (dev_existed_previously) { /* 1 -> 0 */
7557 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7558 "ahci_intr_phyrdy_change: port %d "
7559 "device link lost", port);
7561 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7562 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
7563 ahci_portp, port);
7565 if (ahci_portp->ahciport_device_type ==
7566 SATA_DTYPE_PMULT) {
7567 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
7570 /* An existing device is lost. */
7571 ahci_portp->ahciport_device_type = SATA_DTYPE_NONE;
7572 ahci_portp->ahciport_port_state = SATA_STATE_UNKNOWN;
7574 mutex_exit(&ahci_portp->ahciport_mutex);
7575 sata_hba_event_notify(
7576 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7577 &sdevice,
7578 SATA_EVNT_LINK_LOST);
7579 mutex_enter(&ahci_portp->ahciport_mutex);
7582 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
7584 mutex_exit(&ahci_portp->ahciport_mutex);
7586 return (AHCI_SUCCESS);
7590 * PxIS.UFS - Unknown FIS Error
7592 * This interrupt event means an unknown FIS was received and has been
7593 * copied into system memory. An unknown FIS is not considered an illegal
7594 * FIS, unless the length received is more than 64 bytes. If an unknown
7595 * FIS arrives with length <= 64 bytes, it is posted and the HBA continues
7596 * normal operation. If the unknown FIS is more than 64 bytes, then it
7597 * won't be posted to memory and PxSERR.ERR.P will be set, which is then
7598 * a fatal error.
7600 * PxIS.IPMS - Incorrect Port Multiplier Status
7602 * IPMS Indicates that the HBA received a FIS from a device that did not
7603 * have a command outstanding. The IPMS bit may be set during enumeration
7604 * of devices on a Port Multiplier due to the normal Port Multiplier
7605 * enumeration process. It is recommended that IPMS only be used after
7606 * enumeration is complete on the Port Multiplier (copied from spec).
7608 * PxIS.OFS - Overflow Error
7610 * Command list overflow is defined as software building a command table
7611 * that has fewer total bytes than the transaction given to the device.
7612 * On device writes, the HBA will run out of data, and on reads, there
7613 * will be no room to put the data.
7615 * For an overflow on data read, either PIO or DMA, the HBA will set
7616 * PxIS.OFS, and the HBA will do a best effort to continue, and it's a
7617 * non-fatal error when the HBA can continues. Sometimes, it will cause
7618 * a fatal error and need the software to do something.
7620 * For an overflow on data write, setting PxIS.OFS is optional for both
7621 * DMA and PIO, and it's a fatal error, and a COMRESET is required by
7622 * software to clean up from this serious error.
7624 * PxIS.INFS - Interface Non-Fatal Error
7626 * This interrupt event indicates that the HBA encountered an error on
7627 * the Serial ATA interface but was able to continue operation. The kind
7628 * of error usually occurred during a non-Data FIS, and under this condition
7629 * the FIS will be re-transmitted by HBA automatically.
7631 * When the FMA is implemented, there should be a stat structure to
7632 * record how many every kind of error happens.
7634 static int
7635 ahci_intr_non_fatal_error(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7636 uint8_t port, uint32_t intr_status)
7638 uint32_t port_serror;
7639 #if AHCI_DEBUG
7640 uint32_t port_cmd_status;
7641 uint32_t port_cmd_issue;
7642 uint32_t port_sactive;
7643 int current_slot;
7644 uint32_t current_tags;
7645 sata_pkt_t *satapkt;
7646 ahci_cmd_header_t *cmd_header;
7647 uint32_t cmd_dmacount;
7648 #endif
7650 mutex_enter(&ahci_portp->ahciport_mutex);
7652 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7653 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7655 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY|AHCIDBG_ERRS, ahci_ctlp,
7656 "ahci_intr_non_fatal_error: port %d, "
7657 "PxSERR = 0x%x, PxIS = 0x%x ", port, port_serror, intr_status);
7659 ahci_log_serror_message(ahci_ctlp, port, port_serror, 1);
7661 if (intr_status & AHCI_INTR_STATUS_UFS) {
7662 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7663 "ahci port %d has unknown FIS error", port);
7665 /* Clear the interrupt bit by clearing PxSERR.DIAG.F */
7666 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7667 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7668 SERROR_FIS_TYPE);
7671 #if AHCI_DEBUG
7672 if (intr_status & AHCI_INTR_STATUS_IPMS) {
7673 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci port %d "
7674 "has Incorrect Port Multiplier Status error", port);
7677 if (intr_status & AHCI_INTR_STATUS_OFS) {
7678 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7679 "ahci port %d has overflow error", port);
7682 if (intr_status & AHCI_INTR_STATUS_INFS) {
7683 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7684 "ahci port %d has interface non fatal error", port);
7688 * Record the error occurred command's slot.
7690 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
7691 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7692 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7693 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7695 current_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7696 AHCI_CMD_STATUS_CCS_SHIFT;
7698 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7699 satapkt = ahci_portp->ahciport_err_retri_pkt;
7700 ASSERT(satapkt != NULL);
7701 ASSERT(current_slot == 0);
7702 } else {
7703 satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7706 if (satapkt != NULL) {
7707 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7708 "ahci_intr_non_fatal_error: pending_tags = 0x%x "
7709 "cmd 0x%x", ahci_portp->ahciport_pending_tags,
7710 satapkt->satapkt_cmd.satacmd_cmd_reg);
7712 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7713 "ahci_intr_non_fatal_error: port %d, "
7714 "satapkt 0x%p is being processed when error occurs",
7715 port, (void *)satapkt);
7718 * PRD Byte Count field of command header is not
7719 * required to reflect the total number of bytes
7720 * transferred when an overflow occurs, so here
7721 * just log the value.
7723 cmd_dmacount =
7724 ahci_portp->ahciport_prd_bytecounts[current_slot];
7725 if (cmd_dmacount) {
7726 cmd_header = &ahci_portp->
7727 ahciport_cmd_list[current_slot];
7728 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7729 "ahci_intr_non_fatal_error: port %d, "
7730 "PRD Byte Count = 0x%x, "
7731 "ahciport_prd_bytecounts = 0x%x", port,
7732 cmd_header->ahcich_prd_byte_count,
7733 cmd_dmacount);
7736 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7738 * For queued command, list those command which have already
7739 * been transmitted to the device and still not completed.
7741 port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7742 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7744 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7745 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7747 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS, ahci_ctlp,
7748 "ahci_intr_non_fatal_error: pending_ncq_tags = 0x%x "
7749 "port_sactive = 0x%x port_cmd_issue = 0x%x",
7750 ahci_portp->ahciport_pending_ncq_tags,
7751 port_sactive, port_cmd_issue);
7753 current_tags = ahci_portp->ahciport_pending_ncq_tags &
7754 port_sactive & ~port_cmd_issue &
7755 AHCI_NCQ_SLOT_MASK(ahci_portp);
7757 while (current_tags) {
7758 current_slot = ddi_ffs(current_tags) - 1;
7759 if (current_slot == -1) {
7760 goto out;
7763 satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7764 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS,
7765 ahci_ctlp, "ahci_intr_non_fatal_error: "
7766 "port %d, satapkt 0x%p is outstanding when "
7767 "error occurs", port, (void *)satapkt);
7769 CLEAR_BIT(current_tags, current_slot);
7772 out:
7773 #endif
7774 mutex_exit(&ahci_portp->ahciport_mutex);
7776 return (AHCI_SUCCESS);
7780 * According to the AHCI spec, the error types include system memory
7781 * errors, interface errors, port multiplier errors, device errors,
7782 * command list overflow, command list underflow, native command
7783 * queuing tag errors and pio data transfer errors.
7785 * System memory errors such as target abort, master abort, and parity
7786 * may cause the host to stop, and they are serious errors and needed
7787 * to be recovered with software intervention. When system software
7788 * has given a pointer to the HBA that doesn't exist in physical memory,
7789 * a master/target abort error occurs, and PxIS.HBFS will be set. A
7790 * data error such as CRC or parity occurs, the HBA aborts the transfer
7791 * (if necessary) and PxIS.HBDS will be set.
7793 * Interface errors are errors that occur due to electrical issues on
7794 * the interface, or protocol miscommunication between the device and
7795 * HBA, and the respective PxSERR register bit will be set. And PxIS.IFS
7796 * (fatal) or PxIS.INFS (non-fatal) will be set. The conditions that
7797 * causes PxIS.IFS/PxIS.INFS to be set are
7798 * 1. in PxSERR.ERR, P bit is set to '1'
7799 * 2. in PxSERR.DIAG, C or H bit is set to '1'
7800 * 3. PhyRdy drop unexpectly, N bit is set to '1'
7801 * If the error occurred during a non-data FIS, the FIS must be
7802 * retransmitted, and the error is non-fatal and PxIS.INFS is set. If
7803 * the error occurred during a data FIS, the transfer will stop, so
7804 * the error is fatal and PxIS.IFS is set.
7806 * When a FIS arrives that updates the taskfile, the HBA checks to see
7807 * if PxTFD.STS.ERR is set. If yes, PxIS.TFES will be set and the HBA
7808 * stops processing any more commands.
7810 * Command list overflow is defined as software building a command table
7811 * that has fewer total bytes than the transaction given to the device.
7812 * On device writes, the HBA will run out of data, and on reads, there
7813 * will be no room to put the data. For an overflow on data read, either
7814 * PIO or DMA, the HBA will set PxIS.OFS, and it's a non-fatal error.
7815 * For an overflow on data write, setting PxIS.OFS is optional for both
7816 * DMA and PIO, and a COMRESET is required by software to clean up from
7817 * this serious error.
7819 * Command list underflow is defined as software building a command
7820 * table that has more total bytes than the transaction given to the
7821 * device. For data writes, both PIO and DMA, the device will detect
7822 * an error and end the transfer. And these errors are most likely going
7823 * to be fatal errors that will cause the port to be restarted. For
7824 * data reads, the HBA updates its PRD byte count, and may be
7825 * able to continue normally, but is not required to. And The HBA is
7826 * not required to detect underflow conditions for native command
7827 * queuing command.
7829 * The HBA does not actively check incoming DMA Setup FISes to ensure
7830 * that the PxSACT register bit for that slot is set. Existing error
7831 * mechanisms, such as host bus failure, or bad protocol, are used to
7832 * recover from this case.
7834 * In accordance with Serial ATA 1.0a, DATA FISes prior to the final
7835 * DATA FIS must be an integral number of Dwords. If the HBA receives
7836 * a request which is not an integral number of Dwords, the HBA
7837 * set PxSERR.ERR.P to '1', set PxIS.IFS to '1' and stop running until
7838 * software restarts the port. And the HBA ensures that the size
7839 * of the DATA FIS received during a PIO command matches the size in
7840 * the Transfer Cound field of the preceding PIO Setup FIS, if not, the
7841 * HBA sets PxSERR.ERR.P to '1', set PxIS.IFS to '1', and then
7842 * stop running until software restarts the port.
7845 * the fatal errors include PxIS.IFS, PxIS.HBDS, PxIS.HBFS and PxIS.TFES.
7847 * PxIS.IFS indicates that the hba encountered an error on the serial ata
7848 * interface which caused the transfer to stop.
7850 * PxIS.HBDS indicates that the hba encountered a data error
7851 * (uncorrectable ecc/parity) when reading from or writing to system memory.
7853 * PxIS.HBFS indicates that the hba encountered a host bus error that it
7854 * cannot recover from, such as a bad software pointer.
7856 * PxIS.TFES is set whenever the status register is updated by the device
7857 * and the error bit (bit 0) is set.
7859 static int
7860 ahci_intr_fatal_error(ahci_ctl_t *ahci_ctlp,
7861 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
7863 uint32_t port_cmd_status;
7864 uint32_t port_serror;
7865 uint32_t task_file_status;
7866 int failed_slot;
7867 sata_pkt_t *spkt = NULL;
7868 uint8_t err_byte;
7869 ahci_event_arg_t *args;
7870 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
7871 uint32_t failed_tags = 0;
7872 int task_fail_flag = 0, task_abort_flag = 0;
7873 uint32_t slot_status;
7875 mutex_enter(&ahci_portp->ahciport_mutex);
7878 * ahci_intr_phyrdy_change() may have rendered it to
7879 * SATA_DTYPE_NONE.
7881 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
7882 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7883 "ahci_intr_fatal_error: port %d no device attached, "
7884 "and just return without doing anything", port);
7885 goto out0;
7888 if (intr_status & AHCI_INTR_STATUS_TFES) {
7889 task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7890 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
7891 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7892 "ahci_intr_fatal_error: port %d "
7893 "task_file_status = 0x%x", port, task_file_status);
7894 task_fail_flag = 1;
7896 err_byte = (task_file_status & AHCI_TFD_ERR_MASK)
7897 >> AHCI_TFD_ERR_SHIFT;
7898 if (err_byte == SATA_ERROR_ABORT)
7899 task_abort_flag = 1;
7903 * Here we just log the fatal error info in interrupt context.
7904 * Misc recovery processing will be handled in task queue.
7906 if (task_fail_flag == 1) {
7907 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7909 * Read PxCMD.CCS to determine the slot that the HBA
7910 * was processing when the error occurred.
7912 port_cmd_status = ddi_get32(
7913 ahci_ctlp->ahcictl_ahci_acc_handle,
7914 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7915 failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7916 AHCI_CMD_STATUS_CCS_SHIFT;
7917 failed_tags = 0x1 << failed_slot;
7919 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
7920 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7921 "ahci_intr_fatal_error: spkt 0x%p is being "
7922 "processed when fatal error occurred for port %d",
7923 spkt, port);
7926 * Won't emit the error message if it is an IDENTIFY
7927 * DEVICE command sent to an ATAPI device.
7929 if ((spkt != NULL) &&
7930 (spkt->satapkt_cmd.satacmd_cmd_reg ==
7931 SATAC_ID_DEVICE) &&
7932 (task_abort_flag == 1))
7933 goto out1;
7936 * Won't emit the error message if it is an ATAPI PACKET
7937 * command
7939 if ((spkt != NULL) &&
7940 (spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_PACKET))
7941 goto out1;
7943 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7944 slot_status = ddi_get32(
7945 ahci_ctlp->ahcictl_ahci_acc_handle,
7946 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7947 failed_tags = slot_status &
7948 AHCI_NCQ_SLOT_MASK(ahci_portp);
7952 /* print the fatal error type */
7953 ahci_log_fatal_error_message(ahci_ctlp, port, intr_status);
7954 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_ERRPRINT;
7956 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7957 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7959 /* print PxSERR related error message */
7960 ahci_log_serror_message(ahci_ctlp, port, port_serror, 0);
7962 /* print task file register value */
7963 if (task_fail_flag == 1) {
7964 cmn_err(CE_WARN, "!ahci%d: ahci port %d task_file_status "
7965 "= 0x%x", instance, port, task_file_status);
7966 if (task_abort_flag == 1) {
7967 cmn_err(CE_WARN, "!ahci%d: the below command (s) on "
7968 "port %d are aborted", instance, port);
7969 ahci_dump_commands(ahci_ctlp, port, failed_tags);
7973 out1:
7974 /* Prepare the argument for the taskq */
7975 args = ahci_portp->ahciport_event_args;
7976 args->ahciea_ctlp = (void *)ahci_ctlp;
7977 args->ahciea_portp = (void *)ahci_portp;
7978 args->ahciea_event = intr_status;
7979 AHCI_ADDR_SET_PORT((ahci_addr_t *)args->ahciea_addrp, port);
7981 /* Start the taskq to handle error recovery */
7982 if ((ddi_taskq_dispatch(ahci_portp->ahciport_event_taskq,
7983 ahci_events_handler,
7984 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
7985 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
7986 cmn_err(CE_WARN, "!ahci%d: start taskq for error recovery "
7987 "port %d failed", instance, port);
7989 out0:
7990 mutex_exit(&ahci_portp->ahciport_mutex);
7992 return (AHCI_SUCCESS);
7996 * Hot Plug Operation for platforms that support Cold Presence Detect.
7998 * When set, a device status has changed as detected by the cold presence
7999 * detect logic. This bit can either be set due to a non-connected port
8000 * receiving a device, or a connected port having its device removed.
8001 * This bit is only valid if the port supports cold presence detect as
8002 * indicated by PxCMD.CPD set to '1'.
8004 * At the moment, this interrupt is not needed and disabled and we just
8005 * log the debug message.
8007 static int
8008 ahci_intr_cold_port_detect(ahci_ctl_t *ahci_ctlp,
8009 ahci_port_t *ahci_portp, uint8_t port)
8011 uint32_t port_cmd_status;
8012 sata_device_t sdevice;
8014 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8015 "ahci_intr_cold_port_detect enter, port %d", port);
8017 mutex_enter(&ahci_portp->ahciport_mutex);
8019 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8020 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8021 if (!(port_cmd_status & AHCI_CMD_STATUS_CPD)) {
8022 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8023 "port %d does not support cold presence detect, so "
8024 "we just ignore this interrupt", port);
8025 mutex_exit(&ahci_portp->ahciport_mutex);
8026 return (AHCI_SUCCESS);
8029 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8030 "port %d device status has changed", port);
8032 bzero((void *)&sdevice, sizeof (sata_device_t));
8033 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
8034 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
8035 sdevice.satadev_addr.pmport = 0;
8036 sdevice.satadev_state = SATA_PSTATE_PWRON;
8038 if (port_cmd_status & AHCI_CMD_STATUS_CPS) {
8039 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8040 "port %d: a device is hot plugged", port);
8041 mutex_exit(&ahci_portp->ahciport_mutex);
8042 sata_hba_event_notify(
8043 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8044 &sdevice,
8045 SATA_EVNT_DEVICE_ATTACHED);
8046 mutex_enter(&ahci_portp->ahciport_mutex);
8048 } else {
8049 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8050 "port %d: a device is hot unplugged", port);
8051 mutex_exit(&ahci_portp->ahciport_mutex);
8052 sata_hba_event_notify(
8053 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8054 &sdevice,
8055 SATA_EVNT_DEVICE_DETACHED);
8056 mutex_enter(&ahci_portp->ahciport_mutex);
8059 mutex_exit(&ahci_portp->ahciport_mutex);
8061 return (AHCI_SUCCESS);
8065 * Enable the interrupts for a particular port.
8067 static void
8068 ahci_enable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8070 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8072 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8073 "ahci_enable_port_intrs enter, port %d", port);
8076 * Clear port interrupt status before enabling interrupt
8078 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8079 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
8080 AHCI_PORT_INTR_MASK);
8083 * Clear the pending bit from IS.IPS
8085 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8086 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (1 << port));
8089 * Enable the following interrupts:
8090 * Device to Host Register FIS Interrupt (DHRS)
8091 * PIO Setup FIS Interrupt (PSS)
8092 * Set Device Bits Interrupt (SDBS)
8093 * Unknown FIS Interrupt (UFS)
8094 * Port Connect Change Status (PCS)
8095 * PhyRdy Change Status (PRCS)
8096 * Overflow Status (OFS)
8097 * Interface Non-fatal Error Status (INFS)
8098 * Interface Fatal Error Status (IFS)
8099 * Host Bus Data Error Status (HBDS)
8100 * Host Bus Fatal Error Status (HBFS)
8101 * Task File Error Status (TFES)
8103 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8104 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port),
8105 (AHCI_INTR_STATUS_DHRS |
8106 AHCI_INTR_STATUS_PSS |
8107 AHCI_INTR_STATUS_SDBS |
8108 AHCI_INTR_STATUS_UFS |
8109 AHCI_INTR_STATUS_DPS |
8110 AHCI_INTR_STATUS_PCS |
8111 AHCI_INTR_STATUS_PRCS |
8112 AHCI_INTR_STATUS_OFS |
8113 AHCI_INTR_STATUS_INFS |
8114 AHCI_INTR_STATUS_IFS |
8115 AHCI_INTR_STATUS_HBDS |
8116 AHCI_INTR_STATUS_HBFS |
8117 AHCI_INTR_STATUS_TFES));
8121 * Enable interrupts for all the ports.
8123 static void
8124 ahci_enable_all_intrs(ahci_ctl_t *ahci_ctlp)
8126 uint32_t ghc_control;
8128 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8130 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_enable_all_intrs enter", NULL);
8132 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8133 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8135 ghc_control |= AHCI_HBA_GHC_IE;
8137 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8138 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8142 * Disable interrupts for a particular port.
8144 static void
8145 ahci_disable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8147 ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8148 MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8150 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8151 "ahci_disable_port_intrs enter, port %d", port);
8153 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8154 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
8158 * Disable interrupts for the whole HBA.
8160 * The global bit is cleared, then all interrupt sources from all
8161 * ports are disabled.
8163 static void
8164 ahci_disable_all_intrs(ahci_ctl_t *ahci_ctlp)
8166 uint32_t ghc_control;
8168 ASSERT(ahci_ctlp->ahcictl_flags & (AHCI_ATTACH | AHCI_QUIESCE) ||
8169 MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8171 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_disable_all_intrs enter",
8172 NULL);
8174 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8175 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8177 ghc_control &= ~AHCI_HBA_GHC_IE;
8179 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8180 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8184 * Handle FIXED or MSI interrupts.
8187 * According to AHCI spec, the HBA may support several interrupt modes:
8188 * * pin based interrupts (FIXED)
8189 * * single MSI message interrupts
8190 * * multiple MSI based message interrupts
8192 * For pin based interrupts, the software interrupt handler need to check IS
8193 * register to find out which port has pending interrupts. And then check
8194 * PxIS register to find out which interrupt events happened on that port.
8196 * For single MSI message interrupts, MSICAP.MC.MSIE is set with '1', and
8197 * MSICAP.MC.MME is set with '0'. This mode is similar to pin based interrupts
8198 * in that software interrupt handler need to check IS register to determine
8199 * which port triggered the interrupts since it uses a single message for all
8200 * port interrupts.
8202 * HBA may optionally support multiple MSI message for better performance. In
8203 * this mode, each port may have its own interrupt message, and thus generation
8204 * of interrupts is no longer controlled through the IS register. MSICAP.MC.MMC
8205 * represents a power-of-2 wrapper on the number of implemented ports, and
8206 * the mapping of ports to interrupts is done in a 1-1 relationship, up to the
8207 * maximum number of assigned interrupts. When the number of MSI messages
8208 * allocated is less than the number requested, then hardware may have two
8209 * implementation behaviors:
8210 * * assign each ports its own interrupt and then force all additional
8211 * ports to share the last interrupt message, and this condition is
8212 * indicated by clearing GHC.MRSM to '0'
8213 * * revert to single MSI mode, indicated by setting GHC.MRSM to '1'
8214 * When multiple-message MSI is enabled, hardware will still set IS register
8215 * as single message case. And this IS register may be used by software when
8216 * fewer than the requested number of messages is granted in order to determine
8217 * which port had the interrupt.
8219 * Note: The current ahci driver only supports the first two interrupt modes:
8220 * pin based interrupts and single MSI message interrupts, and the reason
8221 * is indicated in below code.
8223 static int
8224 ahci_add_intrs(ahci_ctl_t *ahci_ctlp, int intr_type)
8226 dev_info_t *dip = ahci_ctlp->ahcictl_dip;
8227 int count, avail, actual;
8228 int i, rc;
8230 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
8231 "ahci_add_intrs enter interrupt type 0x%x", intr_type);
8233 /* get number of interrupts. */
8234 rc = ddi_intr_get_nintrs(dip, intr_type, &count);
8235 if ((rc != DDI_SUCCESS) || (count == 0)) {
8236 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8237 "ddi_intr_get_nintrs() failed, "
8238 "rc %d count %d\n", rc, count);
8239 return (DDI_FAILURE);
8242 /* get number of available interrupts. */
8243 rc = ddi_intr_get_navail(dip, intr_type, &avail);
8244 if ((rc != DDI_SUCCESS) || (avail == 0)) {
8245 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8246 "ddi_intr_get_navail() failed, "
8247 "rc %d avail %d\n", rc, avail);
8248 return (DDI_FAILURE);
8251 #if AHCI_DEBUG
8252 if (avail < count) {
8253 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8254 "ddi_intr_get_nintrs returned %d, navail() returned %d",
8255 count, avail);
8257 #endif
8260 * Note: So far Solaris restricts the maximum number of messages for
8261 * x86 to 2, that is avail is 2, so here we set the count with 1 to
8262 * force the driver to use single MSI message interrupt. In future if
8263 * Solaris remove the restriction, then we need to delete the below
8264 * code and try to use multiple interrupt routine to gain better
8265 * performance.
8267 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
8268 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8269 "force to use one interrupt routine though the "
8270 "HBA supports %d interrupt", count);
8271 count = 1;
8274 /* Allocate an array of interrupt handles. */
8275 ahci_ctlp->ahcictl_intr_size = count * sizeof (ddi_intr_handle_t);
8276 ahci_ctlp->ahcictl_intr_htable =
8277 kmem_alloc(ahci_ctlp->ahcictl_intr_size, KM_SLEEP);
8279 /* call ddi_intr_alloc(). */
8280 rc = ddi_intr_alloc(dip, ahci_ctlp->ahcictl_intr_htable,
8281 intr_type, 0, count, &actual, DDI_INTR_ALLOC_NORMAL);
8283 if ((rc != DDI_SUCCESS) || (actual == 0)) {
8284 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8285 "ddi_intr_alloc() failed, rc %d count %d actual %d "
8286 "avail %d\n", rc, count, actual, avail);
8287 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8288 ahci_ctlp->ahcictl_intr_size);
8289 return (DDI_FAILURE);
8292 /* use interrupt count returned */
8293 #if AHCI_DEBUG
8294 if (actual < count) {
8295 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8296 "Requested: %d, Received: %d", count, actual);
8298 #endif
8300 ahci_ctlp->ahcictl_intr_cnt = actual;
8303 * Get priority for first, assume remaining are all the same.
8305 if (ddi_intr_get_pri(ahci_ctlp->ahcictl_intr_htable[0],
8306 &ahci_ctlp->ahcictl_intr_pri) != DDI_SUCCESS) {
8307 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8308 "ddi_intr_get_pri() failed", NULL);
8310 /* Free already allocated intr. */
8311 for (i = 0; i < actual; i++) {
8312 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8315 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8316 ahci_ctlp->ahcictl_intr_size);
8317 return (DDI_FAILURE);
8320 /* Test for high level interrupt. */
8321 if (ahci_ctlp->ahcictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
8322 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8323 "ahci_add_intrs: Hi level intr not supported", NULL);
8325 /* Free already allocated intr. */
8326 for (i = 0; i < actual; i++) {
8327 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8330 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8331 sizeof (ddi_intr_handle_t));
8333 return (DDI_FAILURE);
8336 /* Call ddi_intr_add_handler(). */
8337 for (i = 0; i < actual; i++) {
8338 if (ddi_intr_add_handler(ahci_ctlp->ahcictl_intr_htable[i],
8339 ahci_intr, (caddr_t)ahci_ctlp, NULL) != DDI_SUCCESS) {
8340 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8341 "ddi_intr_add_handler() failed", NULL);
8343 /* Free already allocated intr. */
8344 for (i = 0; i < actual; i++) {
8345 (void) ddi_intr_free(
8346 ahci_ctlp->ahcictl_intr_htable[i]);
8349 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8350 ahci_ctlp->ahcictl_intr_size);
8351 return (DDI_FAILURE);
8355 if (ddi_intr_get_cap(ahci_ctlp->ahcictl_intr_htable[0],
8356 &ahci_ctlp->ahcictl_intr_cap) != DDI_SUCCESS) {
8357 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8358 "ddi_intr_get_cap() failed", NULL);
8360 /* Free already allocated intr. */
8361 for (i = 0; i < actual; i++) {
8362 (void) ddi_intr_free(
8363 ahci_ctlp->ahcictl_intr_htable[i]);
8366 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8367 ahci_ctlp->ahcictl_intr_size);
8368 return (DDI_FAILURE);
8371 if (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
8372 /* Call ddi_intr_block_enable() for MSI. */
8373 (void) ddi_intr_block_enable(ahci_ctlp->ahcictl_intr_htable,
8374 ahci_ctlp->ahcictl_intr_cnt);
8375 } else {
8376 /* Call ddi_intr_enable() for FIXED or MSI non block enable. */
8377 for (i = 0; i < ahci_ctlp->ahcictl_intr_cnt; i++) {
8378 (void) ddi_intr_enable(
8379 ahci_ctlp->ahcictl_intr_htable[i]);
8383 return (DDI_SUCCESS);
8387 * Removes the registered interrupts irrespective of whether they
8388 * were legacy or MSI.
8390 * NOTE: The controller interrupts must be disabled before calling
8391 * this routine.
8393 static void
8394 ahci_rem_intrs(ahci_ctl_t *ahci_ctlp)
8396 int x;
8398 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_rem_intrs entered", NULL);
8400 /* Disable all interrupts. */
8401 if ((ahci_ctlp->ahcictl_intr_type == DDI_INTR_TYPE_MSI) &&
8402 (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
8403 /* Call ddi_intr_block_disable(). */
8404 (void) ddi_intr_block_disable(ahci_ctlp->ahcictl_intr_htable,
8405 ahci_ctlp->ahcictl_intr_cnt);
8406 } else {
8407 for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8408 (void) ddi_intr_disable(
8409 ahci_ctlp->ahcictl_intr_htable[x]);
8413 /* Call ddi_intr_remove_handler(). */
8414 for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8415 (void) ddi_intr_remove_handler(
8416 ahci_ctlp->ahcictl_intr_htable[x]);
8417 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[x]);
8420 kmem_free(ahci_ctlp->ahcictl_intr_htable, ahci_ctlp->ahcictl_intr_size);
8424 * This routine tries to put port into P:NotRunning state by clearing
8425 * PxCMD.ST. HBA will clear PxCI to 0h, PxSACT to 0h, PxCMD.CCS to 0h
8426 * and PxCMD.CR to '0'.
8428 static int
8429 ahci_put_port_into_notrunning_state(ahci_ctl_t *ahci_ctlp,
8430 ahci_port_t *ahci_portp, uint8_t port)
8432 uint32_t port_cmd_status;
8433 int loop_count;
8435 ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8436 MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8438 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8439 "ahci_put_port_into_notrunning_state enter: port %d", port);
8441 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8442 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8444 port_cmd_status &= ~AHCI_CMD_STATUS_ST;
8445 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8446 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
8448 /* Wait until PxCMD.CR is cleared */
8449 loop_count = 0;
8450 do {
8451 port_cmd_status =
8452 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8453 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8455 if (loop_count++ > AHCI_POLLRATE_PORT_IDLE) {
8456 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
8457 "clearing port %d CMD.CR timeout, "
8458 "port_cmd_status = 0x%x", port,
8459 port_cmd_status);
8461 * We are effectively timing out after 0.5 sec.
8462 * This value is specified in AHCI spec.
8464 break;
8467 /* Wait for 10 millisec */
8468 drv_usecwait(AHCI_10MS_USECS);
8469 } while (port_cmd_status & AHCI_CMD_STATUS_CR);
8471 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_STARTED;
8473 if (port_cmd_status & AHCI_CMD_STATUS_CR) {
8474 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8475 "ahci_put_port_into_notrunning_state: failed to clear "
8476 "PxCMD.CR to '0' after loop count: %d, and "
8477 "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8478 return (AHCI_FAILURE);
8479 } else {
8480 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8481 "ahci_put_port_into_notrunning_state: succeeded to clear "
8482 "PxCMD.CR to '0' after loop count: %d, and "
8483 "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8484 return (AHCI_SUCCESS);
8489 * First clear PxCMD.ST, and then check PxTFD. If both PxTFD.STS.BSY
8490 * and PxTFD.STS.DRQ cleared to '0', it means the device is in a
8491 * stable state, then set PxCMD.ST to '1' to start the port directly.
8492 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue a
8493 * COMRESET to the device to put it in an idle state.
8495 * The fifth argument returns whether the port reset is involved during
8496 * the process.
8498 * The routine will be called under following scenarios:
8499 * + To reset the HBA
8500 * + To abort the packet(s)
8501 * + To reset the port
8502 * + To activate the port
8503 * + Fatal error recovery
8504 * + To abort the timeout packet(s)
8506 * NOTES!!! During this procedure, PxSERR register will be cleared, and
8507 * according to the spec, the clearance of three bits will also clear
8508 * three interrupt status bits.
8509 * 1. PxSERR.DIAG.F will clear PxIS.UFS
8510 * 2. PxSERR.DIAG.X will clear PxIS.PCS
8511 * 3. PxSERR.DIAG.N will clear PxIS.PRCS
8513 * Among these three interrupt events, the driver needs to take care of
8514 * PxIS.PRCS, which is the hot plug event. When the driver found out
8515 * a device was unplugged, it will call the interrupt handler.
8517 static int
8518 ahci_restart_port_wait_till_ready(ahci_ctl_t *ahci_ctlp,
8519 ahci_port_t *ahci_portp, uint8_t port, int flag, int *reset_flag)
8521 uint32_t port_sstatus;
8522 uint32_t task_file_status;
8523 sata_device_t sdevice;
8524 int rval;
8525 ahci_addr_t addr_port;
8526 ahci_pmult_info_t *pminfo = NULL;
8527 int dev_exists_begin = 0;
8528 int dev_exists_end = 0;
8529 uint32_t previous_dev_type = ahci_portp->ahciport_device_type;
8530 int npmport = 0;
8531 uint8_t cport = ahci_ctlp->ahcictl_port_to_cport[port];
8533 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8535 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8536 "ahci_restart_port_wait_till_ready: port %d enter", port);
8538 AHCI_ADDR_SET_PORT(&addr_port, port);
8540 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE)
8541 dev_exists_begin = 1;
8543 /* First clear PxCMD.ST */
8544 rval = ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
8545 port);
8546 if (rval != AHCI_SUCCESS)
8548 * If PxCMD.CR does not clear within a reasonable time, it
8549 * may assume the interface is in a hung condition and may
8550 * continue with issuing the port reset.
8552 goto reset;
8554 /* Then clear PxSERR */
8555 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8556 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
8557 AHCI_SERROR_CLEAR_ALL);
8559 /* Then get PxTFD */
8560 task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8561 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
8564 * Check whether the device is in a stable status, if yes,
8565 * then start the port directly. However for ahci_tran_reset_dport,
8566 * we may have to perform a port reset.
8568 if (!(task_file_status & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ)) &&
8569 !(flag & AHCI_PORT_RESET))
8570 goto out;
8572 reset:
8574 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue
8575 * a COMRESET to the device
8577 ahci_disable_port_intrs(ahci_ctlp, port);
8578 rval = ahci_port_reset(ahci_ctlp, ahci_portp, &addr_port);
8579 ahci_enable_port_intrs(ahci_ctlp, port);
8581 #ifdef AHCI_DEBUG
8582 if (rval != AHCI_SUCCESS)
8583 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8584 "ahci_restart_port_wait_till_ready: port %d failed",
8585 port);
8586 #endif
8588 if (reset_flag != NULL)
8589 *reset_flag = 1;
8591 /* Indicate to the framework that a reset has happened. */
8592 if ((ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) &&
8593 (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) &&
8594 !(flag & AHCI_RESET_NO_EVENTS_UP)) {
8595 /* Set the reset in progress flag */
8596 ahci_portp->ahciport_reset_in_progress = 1;
8598 bzero((void *)&sdevice, sizeof (sata_device_t));
8599 sdevice.satadev_addr.cport =
8600 ahci_ctlp->ahcictl_port_to_cport[port];
8601 sdevice.satadev_addr.pmport = 0;
8602 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8604 sdevice.satadev_state = SATA_DSTATE_RESET |
8605 SATA_DSTATE_PWR_ACTIVE;
8606 if (ahci_ctlp->ahcictl_sata_hba_tran) {
8607 mutex_exit(&ahci_portp->ahciport_mutex);
8608 sata_hba_event_notify(
8609 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8610 &sdevice,
8611 SATA_EVNT_DEVICE_RESET);
8612 mutex_enter(&ahci_portp->ahciport_mutex);
8615 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8616 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8617 } else {
8618 ahci_portp->ahciport_reset_in_progress = 0;
8621 out:
8622 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8624 /* SStatus tells the presence of device. */
8625 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8626 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
8628 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
8629 dev_exists_end = 1;
8632 if (dev_exists_begin == 0 && dev_exists_end == 0) /* 0 -> 0 */
8633 return (rval);
8635 /* Check whether a hot plug event happened */
8636 if (dev_exists_begin == 1 && dev_exists_end == 0) { /* 1 -> 0 */
8637 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8638 "ahci_restart_port_wait_till_ready: port %d "
8639 "device is removed", port);
8640 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_NODEV;
8641 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8642 "ahci_restart_port_wait_till_ready: port %d "
8643 "AHCI_PORT_FLAG_NODEV flag is set", port);
8644 mutex_exit(&ahci_portp->ahciport_mutex);
8645 (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp, port);
8646 mutex_enter(&ahci_portp->ahciport_mutex);
8648 return (rval);
8652 /* 0/1 -> 1 : device may change */
8654 * May be called by ahci_fatal_error_recovery_handler, so
8655 * don't issue software if the previous device is ATAPI.
8657 if (ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
8658 return (rval);
8661 * The COMRESET will make port multiplier enter legacy mode.
8662 * Issue a software reset to make it work again.
8664 ahci_disable_port_intrs(ahci_ctlp, port);
8665 ahci_find_dev_signature(ahci_ctlp, ahci_portp, &addr_port);
8666 ahci_enable_port_intrs(ahci_ctlp, port);
8669 * Following codes are specific for the port multiplier
8671 if (previous_dev_type != SATA_DTYPE_PMULT &&
8672 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8673 /* in case previous_dev_type is corrupt */
8674 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8675 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8676 return (rval);
8679 /* Device change: PMult -> Non-PMult */
8680 if (previous_dev_type == SATA_DTYPE_PMULT &&
8681 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8683 * This might happen because
8684 * 1. Software reset failed. Port multiplier is not correctly
8685 * enumerated.
8686 * 2. Another non-port-multiplier device is attached. Perhaps
8687 * the port multiplier was replaced by another device by
8688 * whatever reason, but AHCI driver missed hot-plug event.
8690 * Now that the port has been initialized, we just need to
8691 * update the port structure according new device, then report
8692 * and wait SATA framework to probe new device.
8695 /* Force to release pmult resource */
8696 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8697 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8699 bzero((void *)&sdevice, sizeof (sata_device_t));
8700 sdevice.satadev_addr.cport =
8701 ahci_ctlp->ahcictl_port_to_cport[port];
8702 sdevice.satadev_addr.pmport = 0;
8703 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8705 sdevice.satadev_state = SATA_DSTATE_RESET |
8706 SATA_DSTATE_PWR_ACTIVE;
8708 mutex_exit(&ahci_portp->ahciport_mutex);
8709 sata_hba_event_notify(
8710 ahci_ctlp->ahcictl_dip,
8711 &sdevice,
8712 SATA_EVNT_DEVICE_RESET);
8713 mutex_enter(&ahci_portp->ahciport_mutex);
8715 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8716 "Port multiplier is [Gone] at port %d ", port);
8717 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8718 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8720 return (AHCI_SUCCESS);
8723 /* Device change: Non-PMult -> PMult */
8724 if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
8726 /* NOTE: The PxCMD.PMA may be cleared by HBA reset. */
8727 ahci_alloc_pmult(ahci_ctlp, ahci_portp);
8729 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8731 pminfo = ahci_portp->ahciport_pmult_info;
8732 ASSERT(pminfo != NULL);
8734 /* Device (may) change: PMult -> PMult */
8736 * First initialize port multiplier. Set state to READY and wait for
8737 * probe entry point to initialize it
8739 ahci_portp->ahciport_port_state = SATA_STATE_READY;
8742 * It's a little complicated while target is a port multiplier. we
8743 * need to COMRESET all pmports behind that PMult otherwise those
8744 * sub-links between the PMult and the sub-devices will be in an
8745 * inactive state (indicated by PSCR0/PxSSTS) and the following access
8746 * to those sub-devices will be rejected by Link-Fatal-Error.
8749 * The PxSNTF will be set soon after the pmult is plugged. While the
8750 * pmult itself is attaching, sata_hba_event_notfiy will fail. so we
8751 * simply mark every sub-port as 'unknown', then ahci_probe_pmport
8752 * will initialized it.
8754 for (npmport = 0; npmport < pminfo->ahcipmi_num_dev_ports; npmport++)
8755 pminfo->ahcipmi_port_state[npmport] = SATA_STATE_UNKNOWN;
8757 /* Report reset event. */
8758 ahci_portp->ahciport_reset_in_progress = 1;
8760 bzero((void *)&sdevice, sizeof (sata_device_t));
8761 sdevice.satadev_addr.cport = cport;
8762 sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
8763 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
8764 sdevice.satadev_state = SATA_DSTATE_RESET | SATA_DSTATE_PWR_ACTIVE;
8765 sata_hba_event_notify(ahci_ctlp->ahcictl_dip, &sdevice,
8766 SATA_EVNT_DEVICE_RESET);
8768 return (rval);
8772 * This routine may be called under four scenarios:
8773 * a) do the recovery from fatal error
8774 * b) or we need to timeout some commands
8775 * c) or we need to abort some commands
8776 * d) or we need reset device/port/controller
8778 * In all these scenarios, we need to send any pending unfinished
8779 * commands up to sata framework.
8781 static void
8782 ahci_mop_commands(ahci_ctl_t *ahci_ctlp,
8783 ahci_port_t *ahci_portp,
8784 uint32_t slot_status,
8785 uint32_t failed_tags,
8786 uint32_t timeout_tags,
8787 uint32_t aborted_tags,
8788 uint32_t reset_tags)
8790 uint32_t finished_tags = 0;
8791 uint32_t unfinished_tags = 0;
8792 int tmp_slot;
8793 sata_pkt_t *satapkt;
8794 int ncq_cmd_in_progress = 0;
8795 int err_retri_cmd_in_progress = 0;
8796 int rdwr_pmult_cmd_in_progress = 0;
8798 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8800 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8801 "ahci_mop_commands entered: port: %d slot_status: 0x%x",
8802 ahci_portp->ahciport_port_num, slot_status);
8804 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8805 "ahci_mop_commands: failed_tags: 0x%x, "
8806 "timeout_tags: 0x%x aborted_tags: 0x%x, "
8807 "reset_tags: 0x%x", failed_tags,
8808 timeout_tags, aborted_tags, reset_tags);
8810 #ifdef AHCI_DEBUG
8811 if (ahci_debug_flags & AHCIDBG_ERRS) {
8812 int i;
8813 char msg_buf[200] = {0, };
8814 for (i = 0x1f; i >= 0; i--) {
8815 if (ahci_portp->ahciport_slot_pkts[i] != NULL)
8816 msg_buf[i] = 'X';
8817 else
8818 msg_buf[i] = '.';
8820 msg_buf[0x20] = '\0';
8821 cmn_err(CE_NOTE, "port[%d] slots: %s",
8822 ahci_portp->ahciport_port_num, msg_buf);
8823 cmn_err(CE_NOTE, "[ERR-RT] %p [RW-PM] %p ",
8824 (void *)ahci_portp->ahciport_err_retri_pkt,
8825 (void *)ahci_portp->ahciport_rdwr_pmult_pkt);
8827 #endif
8829 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8830 finished_tags = ahci_portp->ahciport_pending_tags &
8831 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
8833 unfinished_tags = slot_status &
8834 AHCI_SLOT_MASK(ahci_ctlp) &
8835 ~failed_tags &
8836 ~aborted_tags &
8837 ~reset_tags &
8838 ~timeout_tags;
8839 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8840 ncq_cmd_in_progress = 1;
8841 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
8842 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
8844 unfinished_tags = slot_status &
8845 AHCI_NCQ_SLOT_MASK(ahci_portp) &
8846 ~failed_tags &
8847 ~aborted_tags &
8848 ~reset_tags &
8849 ~timeout_tags;
8850 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
8853 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT is
8854 * set, it means REQUEST SENSE or READ LOG EXT command doesn't
8855 * complete successfully due to one of the following three
8856 * conditions:
8858 * 1. Fatal error - failed_tags includes its slot
8859 * 2. Timed out - timeout_tags includes its slot
8860 * 3. Aborted when hot unplug - aborted_tags includes its
8861 * slot
8863 * Please note that the command is always sent down in Slot 0
8865 err_retri_cmd_in_progress = 1;
8866 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_NCQ, ahci_ctlp,
8867 "ahci_mop_commands is called for port %d while "
8868 "REQUEST SENSE or READ LOG EXT for error retrieval "
8869 "is being executed slot_status = 0x%x",
8870 ahci_portp->ahciport_port_num, slot_status);
8871 ASSERT(ahci_portp->ahciport_mop_in_progress > 1);
8872 ASSERT(slot_status == 0x1);
8873 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
8874 rdwr_pmult_cmd_in_progress = 1;
8875 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
8876 "ahci_mop_commands is called for port %d while "
8877 "READ/WRITE PORTMULT command is being executed",
8878 ahci_portp->ahciport_port_num);
8880 ASSERT(slot_status == 0x1);
8883 #ifdef AHCI_DEBUG
8884 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8885 "ahci_mop_commands: finished_tags: 0x%x, "
8886 "unfinished_tags 0x%x", finished_tags, unfinished_tags);
8887 #endif
8889 /* Send up finished packets with SATA_PKT_COMPLETED */
8890 while (finished_tags) {
8891 tmp_slot = ddi_ffs(finished_tags) - 1;
8892 if (tmp_slot == -1) {
8893 break;
8896 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8897 ASSERT(satapkt != NULL);
8899 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_mop_commands: "
8900 "sending up pkt 0x%p with SATA_PKT_COMPLETED",
8901 (void *)satapkt);
8904 * Cannot fetch the return register content since the port
8905 * was restarted, so the corresponding tag will be set to
8906 * aborted tags.
8908 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
8909 CLEAR_BIT(finished_tags, tmp_slot);
8910 aborted_tags |= tmp_slot;
8911 continue;
8914 if (ncq_cmd_in_progress)
8915 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8916 tmp_slot);
8917 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8918 CLEAR_BIT(finished_tags, tmp_slot);
8919 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8921 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
8924 /* Send up failed packets with SATA_PKT_DEV_ERROR. */
8925 while (failed_tags) {
8926 if (err_retri_cmd_in_progress) {
8927 satapkt = ahci_portp->ahciport_err_retri_pkt;
8928 ASSERT(satapkt != NULL);
8929 ASSERT(failed_tags == 0x1);
8931 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8932 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8933 (void *)satapkt);
8934 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8935 break;
8937 if (rdwr_pmult_cmd_in_progress) {
8938 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8939 ASSERT(satapkt != NULL);
8940 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8941 "ahci_mop_commands: sending up "
8942 "rdwr pmult pkt 0x%p with SATA_PKT_DEV_ERROR",
8943 (void *)satapkt);
8944 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8945 break;
8948 tmp_slot = ddi_ffs(failed_tags) - 1;
8949 if (tmp_slot == -1) {
8950 break;
8953 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8954 ASSERT(satapkt != NULL);
8956 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8957 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8958 (void *)satapkt);
8960 if (ncq_cmd_in_progress)
8961 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8962 tmp_slot);
8963 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8964 CLEAR_BIT(failed_tags, tmp_slot);
8965 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8967 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8970 /* Send up timeout packets with SATA_PKT_TIMEOUT. */
8971 while (timeout_tags) {
8972 if (err_retri_cmd_in_progress) {
8973 satapkt = ahci_portp->ahciport_err_retri_pkt;
8974 ASSERT(satapkt != NULL);
8975 ASSERT(timeout_tags == 0x1);
8977 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8978 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
8979 (void *)satapkt);
8980 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8981 break;
8983 if (rdwr_pmult_cmd_in_progress) {
8984 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8985 ASSERT(satapkt != NULL);
8986 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8987 "ahci_mop_commands: sending up "
8988 "rdwr pmult pkt 0x%p with SATA_PKT_TIMEOUT",
8989 (void *)satapkt);
8990 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8991 break;
8994 tmp_slot = ddi_ffs(timeout_tags) - 1;
8995 if (tmp_slot == -1) {
8996 break;
8999 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9000 ASSERT(satapkt != NULL);
9002 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9003 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
9004 (void *)satapkt);
9006 if (ncq_cmd_in_progress)
9007 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9008 tmp_slot);
9009 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9010 CLEAR_BIT(timeout_tags, tmp_slot);
9011 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9013 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
9016 /* Send up aborted packets with SATA_PKT_ABORTED */
9017 while (aborted_tags) {
9018 if (err_retri_cmd_in_progress) {
9019 satapkt = ahci_portp->ahciport_err_retri_pkt;
9020 ASSERT(satapkt != NULL);
9021 ASSERT(aborted_tags == 0x1);
9023 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9024 "sending up pkt 0x%p with SATA_PKT_ABORTED",
9025 (void *)satapkt);
9026 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9027 break;
9029 if (rdwr_pmult_cmd_in_progress) {
9030 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9031 ASSERT(satapkt != NULL);
9032 ASSERT(aborted_tags == 0x1);
9033 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9034 "ahci_mop_commands: sending up "
9035 "rdwr pmult pkt 0x%p with SATA_PKT_ABORTED",
9036 (void *)satapkt);
9037 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9038 break;
9041 tmp_slot = ddi_ffs(aborted_tags) - 1;
9042 if (tmp_slot == -1) {
9043 break;
9046 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9047 ASSERT(satapkt != NULL);
9049 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9050 "sending up pkt 0x%p with SATA_PKT_ABORTED",
9051 (void *)satapkt);
9053 if (ncq_cmd_in_progress)
9054 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9055 tmp_slot);
9056 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9057 CLEAR_BIT(aborted_tags, tmp_slot);
9058 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9060 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
9063 /* Send up reset packets with SATA_PKT_RESET. */
9064 while (reset_tags) {
9065 if (rdwr_pmult_cmd_in_progress) {
9066 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9067 ASSERT(satapkt != NULL);
9068 ASSERT(aborted_tags == 0x1);
9069 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9070 "ahci_mop_commands: sending up "
9071 "rdwr pmult pkt 0x%p with SATA_PKT_RESET",
9072 (void *)satapkt);
9073 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9074 break;
9077 tmp_slot = ddi_ffs(reset_tags) - 1;
9078 if (tmp_slot == -1) {
9079 break;
9082 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9083 ASSERT(satapkt != NULL);
9085 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9086 "sending up pkt 0x%p with SATA_PKT_RESET",
9087 (void *)satapkt);
9089 if (ncq_cmd_in_progress)
9090 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9091 tmp_slot);
9092 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9093 CLEAR_BIT(reset_tags, tmp_slot);
9094 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9096 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9099 /* Send up unfinished packets with SATA_PKT_RESET */
9100 while (unfinished_tags) {
9101 tmp_slot = ddi_ffs(unfinished_tags) - 1;
9102 if (tmp_slot == -1) {
9103 break;
9106 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9107 ASSERT(satapkt != NULL);
9109 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9110 "sending up pkt 0x%p with SATA_PKT_RESET",
9111 (void *)satapkt);
9113 if (ncq_cmd_in_progress)
9114 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9115 tmp_slot);
9116 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9117 CLEAR_BIT(unfinished_tags, tmp_slot);
9118 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9120 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9123 ahci_portp->ahciport_mop_in_progress--;
9124 ASSERT(ahci_portp->ahciport_mop_in_progress >= 0);
9126 if (ahci_portp->ahciport_mop_in_progress == 0)
9127 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_MOPPING;
9129 ahci_flush_doneq(ahci_portp);
9133 * This routine is going to first request a READ LOG EXT sata pkt from sata
9134 * module, and then deliver it to the HBA to get the ncq failure context.
9135 * The return value is the exactly failed tags.
9137 static uint32_t
9138 ahci_get_rdlogext_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9139 uint8_t port)
9141 sata_device_t sdevice;
9142 sata_pkt_t *rdlog_spkt, *spkt;
9143 ddi_dma_handle_t buf_dma_handle;
9144 ahci_addr_t addr;
9145 int loop_count;
9146 int rval;
9147 int failed_slot;
9148 uint32_t failed_tags = 0;
9149 struct sata_ncq_error_recovery_page *ncq_err_page;
9151 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_NCQ, ahci_ctlp,
9152 "ahci_get_rdlogext_data enter: port %d", port);
9154 /* Prepare the sdevice data */
9155 bzero((void *)&sdevice, sizeof (sata_device_t));
9156 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9158 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9159 sdevice.satadev_addr.pmport = 0;
9161 /* Translate sata_device.satadev_addr -> ahci_addr */
9162 ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9165 * Call the sata hba interface to get a rdlog spkt
9167 loop_count = 0;
9168 loop:
9169 rdlog_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9170 &sdevice, SATA_ERR_RETR_PKT_TYPE_NCQ);
9171 if (rdlog_spkt == NULL) {
9172 if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9173 /* Sleep for a while */
9174 drv_usecwait(AHCI_10MS_USECS);
9175 goto loop;
9177 /* Timed out after 1s */
9178 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9179 "failed to get rdlog spkt for port %d", port);
9180 return (failed_tags);
9183 ASSERT(rdlog_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9186 * This flag is used to handle the specific error recovery when the
9187 * READ LOG EXT command gets a failure (fatal error or time-out).
9189 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDLOGEXT;
9192 * This start is not supposed to fail because after port is restarted,
9193 * the whole command list is empty.
9195 ahci_portp->ahciport_err_retri_pkt = rdlog_spkt;
9196 (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rdlog_spkt);
9197 ahci_portp->ahciport_err_retri_pkt = NULL;
9199 /* Remove the flag after READ LOG EXT command is completed */
9200 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDLOGEXT;
9202 if (rdlog_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9203 /* Update the request log data */
9204 buf_dma_handle = *(ddi_dma_handle_t *)
9205 (rdlog_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9206 rval = ddi_dma_sync(buf_dma_handle, 0, 0,
9207 DDI_DMA_SYNC_FORKERNEL);
9208 if (rval == DDI_SUCCESS) {
9209 ncq_err_page =
9210 (struct sata_ncq_error_recovery_page *)rdlog_spkt->
9211 satapkt_cmd.satacmd_bp->b_un.b_addr;
9213 /* Get the failed tag */
9214 failed_slot = ncq_err_page->ncq_tag;
9215 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9216 "ahci_get_rdlogext_data: port %d "
9217 "failed slot %d", port, failed_slot);
9218 if (failed_slot & NQ) {
9219 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9220 "the failed slot is not a valid tag", NULL);
9221 goto out;
9224 failed_slot &= NCQ_TAG_MASK;
9225 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9226 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9227 "ahci_get_rdlogext_data: failed spkt 0x%p",
9228 (void *)spkt);
9229 if (spkt == NULL) {
9230 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9231 "the failed slot spkt is NULL", NULL);
9232 goto out;
9235 failed_tags = 0x1 << failed_slot;
9237 /* Fill out the error context */
9238 ahci_copy_ncq_err_page(&spkt->satapkt_cmd,
9239 ncq_err_page);
9240 ahci_update_sata_registers(ahci_ctlp, port,
9241 &spkt->satapkt_device);
9244 out:
9245 sata_free_error_retrieval_pkt(rdlog_spkt);
9247 return (failed_tags);
9251 * This routine is going to first request a REQUEST SENSE sata pkt from sata
9252 * module, and then deliver it to the HBA to get the sense data and copy
9253 * the sense data back to the orignal failed sata pkt, and free the REQUEST
9254 * SENSE sata pkt later.
9256 static void
9257 ahci_get_rqsense_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9258 uint8_t port, sata_pkt_t *spkt)
9260 sata_device_t sdevice;
9261 sata_pkt_t *rs_spkt;
9262 sata_cmd_t *sata_cmd;
9263 ddi_dma_handle_t buf_dma_handle;
9264 ahci_addr_t addr;
9265 int loop_count;
9266 #if AHCI_DEBUG
9267 struct scsi_extended_sense *rqsense;
9268 #endif
9270 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9271 "ahci_get_rqsense_data enter: port %d", port);
9273 /* Prepare the sdevice data */
9274 bzero((void *)&sdevice, sizeof (sata_device_t));
9275 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9277 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9278 sdevice.satadev_addr.pmport = 0;
9280 /* Translate sata_device.satadev_addr -> ahci_addr */
9281 ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9283 sata_cmd = &spkt->satapkt_cmd;
9286 * Call the sata hba interface to get a rs spkt
9288 loop_count = 0;
9289 loop:
9290 rs_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9291 &sdevice, SATA_ERR_RETR_PKT_TYPE_ATAPI);
9292 if (rs_spkt == NULL) {
9293 if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9294 /* Sleep for a while */
9295 drv_usecwait(AHCI_10MS_USECS);
9296 goto loop;
9299 /* Timed out after 1s */
9300 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9301 "failed to get rs spkt for port %d", port);
9302 return;
9305 ASSERT(rs_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9308 * This flag is used to handle the specific error recovery when the
9309 * REQUEST SENSE command gets a faiure (fatal error or time-out).
9311 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RQSENSE;
9314 * This start is not supposed to fail because after port is restarted,
9315 * the whole command list is empty.
9317 ahci_portp->ahciport_err_retri_pkt = rs_spkt;
9318 (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rs_spkt);
9319 ahci_portp->ahciport_err_retri_pkt = NULL;
9321 /* Remove the flag after REQUEST SENSE command is completed */
9322 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RQSENSE;
9324 if (rs_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9325 /* Update the request sense data */
9326 buf_dma_handle = *(ddi_dma_handle_t *)
9327 (rs_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9328 (void) ddi_dma_sync(buf_dma_handle, 0, 0,
9329 DDI_DMA_SYNC_FORKERNEL);
9330 /* Copy the request sense data */
9331 bcopy(rs_spkt->
9332 satapkt_cmd.satacmd_bp->b_un.b_addr,
9333 &sata_cmd->satacmd_rqsense,
9334 SATA_ATAPI_MIN_RQSENSE_LEN);
9335 #if AHCI_DEBUG
9336 rqsense = (struct scsi_extended_sense *)
9337 sata_cmd->satacmd_rqsense;
9339 /* Dump the sense data */
9340 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp, "\n", NULL);
9341 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9342 "Sense data for satapkt %p ATAPI cmd 0x%x",
9343 spkt, sata_cmd->satacmd_acdb[0]);
9344 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9345 " es_code 0x%x es_class 0x%x "
9346 "es_key 0x%x es_add_code 0x%x "
9347 "es_qual_code 0x%x",
9348 rqsense->es_code, rqsense->es_class,
9349 rqsense->es_key, rqsense->es_add_code,
9350 rqsense->es_qual_code);
9351 #endif
9354 sata_free_error_retrieval_pkt(rs_spkt);
9358 * Fatal errors will cause the HBA to enter the ERR: Fatal state. To recover,
9359 * the port must be restarted. When the HBA detects thus error, it may try
9360 * to abort a transfer. And if the transfer was aborted, the device is
9361 * expected to send a D2H Register FIS with PxTFD.STS.ERR set to '1' and both
9362 * PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0'. Then system software knows
9363 * that the device is in a stable status and transfers may be restarted without
9364 * issuing a COMRESET to the device. If PxTFD.STS.BSY or PxTFD.STS.DRQ is set,
9365 * then the software will send the COMRESET to do the port reset.
9367 * Software should perform the appropriate error recovery actions based on
9368 * whether non-queued commands were being issued or natived command queuing
9369 * commands were being issued.
9371 * And software will complete the command that had the error with error mark
9372 * to higher level software.
9374 * Fatal errors include the following:
9375 * PxIS.IFS - Interface Fatal Error Status
9376 * PxIS.HBDS - Host Bus Data Error Status
9377 * PxIS.HBFS - Host Bus Fatal Error Status
9378 * PxIS.TFES - Task File Error Status
9380 static void
9381 ahci_fatal_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9382 ahci_port_t *ahci_portp, ahci_addr_t *addrp, uint32_t intr_status)
9384 uint32_t port_cmd_status;
9385 uint32_t slot_status = 0;
9386 uint32_t failed_tags = 0;
9387 int failed_slot;
9388 int reset_flag = 0, flag = 0;
9389 ahci_fis_d2h_register_t *ahci_rcvd_fisp;
9390 sata_cmd_t *sata_cmd = NULL;
9391 sata_pkt_t *spkt = NULL;
9392 #if AHCI_DEBUG
9393 ahci_cmd_header_t *cmd_header;
9394 #endif
9395 uint8_t port = addrp->aa_port;
9396 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9397 int rval;
9399 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9401 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9402 "ahci_fatal_error_recovery_handler enter: port %d", port);
9404 /* Port multiplier error */
9405 if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
9406 /* FBS code is neither completed nor tested. */
9407 ahci_pmult_error_recovery_handler(ahci_ctlp, ahci_portp,
9408 port, intr_status);
9410 /* Force a port reset */
9411 flag = AHCI_PORT_RESET;
9414 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9415 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9417 /* Read PxCI to see which commands are still outstanding */
9418 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9419 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9422 * Read PxCMD.CCS to determine the slot that the HBA
9423 * was processing when the error occurred.
9425 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9426 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9427 failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9428 AHCI_CMD_STATUS_CCS_SHIFT;
9430 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9431 spkt = ahci_portp->ahciport_err_retri_pkt;
9432 ASSERT(spkt != NULL);
9433 } else {
9434 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9435 if (spkt == NULL) {
9436 /* May happen when interface errors occur? */
9437 goto next;
9441 #if AHCI_DEBUG
9443 * Debugging purpose...
9445 if (ahci_portp->ahciport_prd_bytecounts[failed_slot]) {
9446 cmd_header =
9447 &ahci_portp->ahciport_cmd_list[failed_slot];
9448 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9449 "ahci_fatal_error_recovery_handler: port %d, "
9450 "PRD Byte Count = 0x%x, "
9451 "ahciport_prd_bytecounts = 0x%x", port,
9452 cmd_header->ahcich_prd_byte_count,
9453 ahci_portp->ahciport_prd_bytecounts[failed_slot]);
9455 #endif
9457 sata_cmd = &spkt->satapkt_cmd;
9459 /* Fill out the status and error registers for PxIS.TFES */
9460 if (intr_status & AHCI_INTR_STATUS_TFES) {
9461 ahci_rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
9462 ahcirf_d2h_register_fis);
9464 /* Copy the error context back to the sata_cmd */
9465 ahci_copy_err_cnxt(sata_cmd, ahci_rcvd_fisp);
9468 /* The failed command must be one of the outstanding commands */
9469 failed_tags = 0x1 << failed_slot;
9470 ASSERT(failed_tags & slot_status);
9472 /* Update the sata registers, especially PxSERR register */
9473 ahci_update_sata_registers(ahci_ctlp, port,
9474 &spkt->satapkt_device);
9476 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9477 /* Read PxSACT to see which commands are still outstanding */
9478 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9479 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9481 next:
9483 #if AHCI_DEBUG
9485 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9486 * set, it means a fatal error happened after REQUEST SENSE command
9487 * or READ LOG EXT command is delivered to the HBA during the error
9488 * recovery process. At this time, the only outstanding command is
9489 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9491 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9492 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9493 "ahci_fatal_error_recovery_handler: port %d REQUEST SENSE "
9494 "command or READ LOG EXT command for error data retrieval "
9495 "failed", port);
9496 ASSERT(slot_status == 0x1);
9497 ASSERT(failed_slot == 0);
9498 ASSERT(spkt->satapkt_cmd.satacmd_acdb[0] ==
9499 SCMD_REQUEST_SENSE ||
9500 spkt->satapkt_cmd.satacmd_cmd_reg ==
9501 SATAC_READ_LOG_EXT);
9503 #endif
9505 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9506 ahci_portp->ahciport_mop_in_progress++;
9508 rval = ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9509 port, flag, &reset_flag);
9511 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9512 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9513 if (rval == AHCI_SUCCESS)
9514 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9515 "succeed", instance, port);
9516 else
9517 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9518 "failed", instance, port);
9522 * Won't retrieve error information:
9523 * 1. Port reset was involved to recover
9524 * 2. Device is gone
9525 * 3. IDENTIFY DEVICE command sent to ATAPI device
9526 * 4. REQUEST SENSE or READ LOG EXT command during error recovery
9528 if (reset_flag ||
9529 ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
9530 spkt && spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_ID_DEVICE ||
9531 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9532 goto out;
9535 * Deliver READ LOG EXT to gather information about the error when
9536 * a COMRESET has not been performed as part of the error recovery
9537 * during NCQ command processing.
9539 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9540 failed_tags = ahci_get_rdlogext_data(ahci_ctlp,
9541 ahci_portp, port);
9542 goto out;
9546 * Deliver REQUEST SENSE for ATAPI command to gather information about
9547 * the error when a COMRESET has not been performed as part of the
9548 * error recovery.
9550 if (spkt && ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
9551 ahci_get_rqsense_data(ahci_ctlp, ahci_portp, port, spkt);
9552 out:
9553 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9554 "ahci_fatal_error_recovery_handler: port %d fatal error "
9555 "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9556 "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9557 port, slot_status, ahci_portp->ahciport_pending_tags,
9558 ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9560 ahci_mop_commands(ahci_ctlp,
9561 ahci_portp,
9562 slot_status,
9563 failed_tags, /* failed tags */
9564 0, /* timeout tags */
9565 0, /* aborted tags */
9566 0); /* reset tags */
9570 * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9571 * 1. device specific.PxFBS.SDE=1
9572 * 2. Non Device specific.
9573 * Nothing will be done when Command-based switching is employed.
9575 * Currently code is neither completed nor tested.
9577 static void
9578 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9579 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9581 #ifndef __lock_lint
9582 _NOTE(ARGUNUSED(intr_status))
9583 #endif
9584 uint32_t port_fbs_ctrl;
9585 int loop_count = 0;
9586 ahci_addr_t addr;
9588 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9590 /* Nothing will be done under Command-based switching. */
9591 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9592 return;
9594 port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9595 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9597 if (!(port_fbs_ctrl & AHCI_FBS_EN))
9598 /* FBS is not enabled. */
9599 return;
9601 /* Problem's getting complicated now. */
9603 * If FIS-based switching is used, we need to check
9604 * the PxFBS to see the error type.
9606 port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9607 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9609 /* Refer to spec(v1.2) 9.3.6.1 */
9610 if (port_fbs_ctrl & AHCI_FBS_SDE) {
9611 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9612 "A Device Sepcific Error: port %d", port);
9614 * Controller has paused commands for all other
9615 * sub-devices until PxFBS.DEC is set.
9617 ahci_reject_all_abort_pkts(ahci_ctlp,
9618 ahci_portp, 0);
9620 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
9621 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port),
9622 port_fbs_ctrl | AHCI_FBS_DEC);
9625 * Wait controller clear PxFBS.DEC,
9626 * then we can continue.
9628 loop_count = 0;
9629 do {
9630 port_fbs_ctrl = ddi_get32(ahci_ctlp->
9631 ahcictl_ahci_acc_handle, (uint32_t *)
9632 AHCI_PORT_PxFBS(ahci_ctlp, port));
9634 if (loop_count++ > 1000)
9636 * Esclate the error. Follow
9637 * non-device specific error
9638 * procedure.
9640 return;
9642 drv_usecwait(AHCI_100US_USECS);
9643 } while (port_fbs_ctrl & AHCI_FBS_DEC);
9646 * Issue a software reset to ensure drive is in
9647 * a known state.
9649 (void) ahci_software_reset(ahci_ctlp,
9650 ahci_portp, &addr);
9652 } else {
9654 /* Process Non-Device Specific Error. */
9655 /* This will be handled later on. */
9656 cmn_err(CE_NOTE, "!FBS is not supported now.");
9660 * Handle events - fatal error recovery
9662 static void
9663 ahci_events_handler(void *args)
9665 ahci_event_arg_t *ahci_event_arg;
9666 ahci_ctl_t *ahci_ctlp;
9667 ahci_port_t *ahci_portp;
9668 ahci_addr_t *addrp;
9669 uint32_t event;
9670 int instance;
9672 ahci_event_arg = (ahci_event_arg_t *)args;
9674 ahci_ctlp = ahci_event_arg->ahciea_ctlp;
9675 ahci_portp = ahci_event_arg->ahciea_portp;
9676 addrp = ahci_event_arg->ahciea_addrp;
9677 event = ahci_event_arg->ahciea_event;
9678 instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9680 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9681 "ahci_events_handler enter: port %d intr_status = 0x%x",
9682 ahci_portp->ahciport_port_num, event);
9684 mutex_enter(&ahci_portp->ahciport_mutex);
9687 * ahci_intr_phyrdy_change() may have rendered it to
9688 * SATA_DTYPE_NONE.
9690 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9691 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
9692 "ahci_events_handler: port %d no device attached, "
9693 "and just return without doing anything",
9694 ahci_portp->ahciport_port_num);
9696 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9697 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9698 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9699 "succeed", instance, ahci_portp->ahciport_port_num);
9702 goto out;
9705 if (event & (AHCI_INTR_STATUS_IFS |
9706 AHCI_INTR_STATUS_HBDS |
9707 AHCI_INTR_STATUS_HBFS |
9708 AHCI_INTR_STATUS_TFES))
9709 ahci_fatal_error_recovery_handler(ahci_ctlp, ahci_portp,
9710 addrp, event);
9712 out:
9713 mutex_exit(&ahci_portp->ahciport_mutex);
9717 * ahci_watchdog_handler() and ahci_do_sync_start will call us if they
9718 * detect there are some commands which are timed out.
9720 static void
9721 ahci_timeout_pkts(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9722 uint8_t port, uint32_t tmp_timeout_tags)
9724 uint32_t slot_status = 0;
9725 uint32_t finished_tags = 0;
9726 uint32_t timeout_tags = 0;
9728 AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_ENTRY, ahci_ctlp,
9729 "ahci_timeout_pkts enter: port %d", port);
9731 mutex_enter(&ahci_portp->ahciport_mutex);
9733 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9734 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) ||
9735 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9736 /* Read PxCI to see which commands are still outstanding */
9737 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9738 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9739 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9740 /* Read PxSACT to see which commands are still outstanding */
9741 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9742 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9745 #if AHCI_DEBUG
9747 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9748 * set, it means a fatal error happened after REQUEST SENSE command
9749 * or READ LOG EXT command is delivered to the HBA during the error
9750 * recovery process. At this time, the only outstanding command is
9751 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9753 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9754 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9755 "ahci_timeout_pkts called while REQUEST SENSE "
9756 "command or READ LOG EXT command for error recovery "
9757 "timed out timeout_tags = 0x%x, slot_status = 0x%x, "
9758 "pending_tags = 0x%x, pending_ncq_tags = 0x%x",
9759 tmp_timeout_tags, slot_status,
9760 ahci_portp->ahciport_pending_tags,
9761 ahci_portp->ahciport_pending_ncq_tags);
9762 ASSERT(slot_status == 0x1);
9763 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9764 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9765 "ahci_timeout_pkts called while executing R/W PMULT "
9766 "command timeout_tags = 0x%x, slot_status = 0x%x",
9767 tmp_timeout_tags, slot_status);
9768 ASSERT(slot_status == 0x1);
9770 #endif
9772 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9773 ahci_portp->ahciport_mop_in_progress++;
9775 (void) ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9776 port, AHCI_PORT_RESET, NULL);
9779 * Re-identify timeout tags because some previously checked commands
9780 * could already complete.
9782 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9783 finished_tags = ahci_portp->ahciport_pending_tags &
9784 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
9785 timeout_tags = tmp_timeout_tags & ~finished_tags;
9787 AHCIDBG(AHCIDBG_TIMEOUT, ahci_ctlp,
9788 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9789 "timeout_tags = 0x%x, port_cmd_issue = 0x%x, "
9790 "pending_tags = 0x%x ",
9791 port, finished_tags, timeout_tags,
9792 slot_status, ahci_portp->ahciport_pending_tags);
9793 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9794 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
9795 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
9796 timeout_tags = tmp_timeout_tags & ~finished_tags;
9798 AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_NCQ, ahci_ctlp,
9799 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9800 "timeout_tags = 0x%x, port_sactive = 0x%x, "
9801 "pending_ncq_tags = 0x%x ",
9802 port, finished_tags, timeout_tags,
9803 slot_status, ahci_portp->ahciport_pending_ncq_tags);
9804 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9805 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9806 timeout_tags = tmp_timeout_tags;
9809 ahci_mop_commands(ahci_ctlp,
9810 ahci_portp,
9811 slot_status,
9812 0, /* failed tags */
9813 timeout_tags, /* timeout tags */
9814 0, /* aborted tags */
9815 0); /* reset tags */
9817 mutex_exit(&ahci_portp->ahciport_mutex);
9821 * Watchdog handler kicks in every 5 seconds to timeout any commands pending
9822 * for long time.
9824 static void
9825 ahci_watchdog_handler(ahci_ctl_t *ahci_ctlp)
9827 ahci_port_t *ahci_portp;
9828 sata_pkt_t *spkt;
9829 uint32_t pending_tags;
9830 uint32_t timeout_tags;
9831 uint32_t port_cmd_status;
9832 uint32_t port_sactive;
9833 uint8_t port;
9834 int tmp_slot;
9835 int current_slot;
9836 uint32_t current_tags;
9837 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9839 mutex_enter(&ahci_ctlp->ahcictl_mutex);
9841 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9842 "ahci_watchdog_handler entered", NULL);
9844 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
9845 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
9846 continue;
9849 ahci_portp = ahci_ctlp->ahcictl_ports[port];
9851 mutex_enter(&ahci_portp->ahciport_mutex);
9852 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9853 mutex_exit(&ahci_portp->ahciport_mutex);
9854 continue;
9857 /* Skip the check for those ports in error recovery */
9858 if ((ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) &&
9859 !(ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))) {
9860 mutex_exit(&ahci_portp->ahciport_mutex);
9861 continue;
9864 pending_tags = 0;
9865 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9866 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9868 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9869 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9870 current_slot = 0;
9871 pending_tags = 0x1;
9872 } else if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9873 current_slot =
9874 (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9875 AHCI_CMD_STATUS_CCS_SHIFT;
9876 pending_tags = ahci_portp->ahciport_pending_tags;
9877 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9878 port_sactive = ddi_get32(
9879 ahci_ctlp->ahcictl_ahci_acc_handle,
9880 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9881 current_tags = port_sactive &
9882 ~port_cmd_status &
9883 AHCI_NCQ_SLOT_MASK(ahci_portp);
9884 pending_tags = ahci_portp->ahciport_pending_ncq_tags;
9887 timeout_tags = 0;
9888 while (pending_tags) {
9889 tmp_slot = ddi_ffs(pending_tags) - 1;
9890 if (tmp_slot == -1) {
9891 break;
9894 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9895 spkt = ahci_portp->ahciport_err_retri_pkt;
9896 else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
9897 spkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9898 else
9899 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9901 if ((spkt != NULL) && spkt->satapkt_time &&
9902 !(spkt->satapkt_op_mode & SATA_OPMODE_POLLING)) {
9904 * If a packet has survived for more than it's
9905 * max life cycles, it is a candidate for time
9906 * out.
9908 ahci_portp->ahciport_slot_timeout[tmp_slot] -=
9909 ahci_watchdog_timeout;
9911 if (ahci_portp->ahciport_slot_timeout[tmp_slot]
9912 > 0)
9913 goto next;
9915 #if AHCI_DEBUG
9916 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9917 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9918 ahci_ctlp, "watchdog: the current "
9919 "tags is 0x%x", current_tags);
9920 } else {
9921 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9922 ahci_ctlp, "watchdog: the current "
9923 "slot is %d", current_slot);
9925 #endif
9928 * We need to check whether the HBA has
9929 * begun to execute the command, if not,
9930 * then re-set the timer of the command.
9932 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9933 (tmp_slot != current_slot) ||
9934 NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9935 ((0x1 << tmp_slot) & current_tags)) {
9936 ahci_portp->ahciport_slot_timeout \
9937 [tmp_slot] = spkt->satapkt_time;
9938 } else {
9939 timeout_tags |= (0x1 << tmp_slot);
9940 cmn_err(CE_WARN, "!ahci%d: watchdog "
9941 "port %d satapkt 0x%p timed out\n",
9942 instance, port, (void *)spkt);
9945 next:
9946 CLEAR_BIT(pending_tags, tmp_slot);
9949 if (timeout_tags) {
9950 mutex_exit(&ahci_portp->ahciport_mutex);
9951 mutex_exit(&ahci_ctlp->ahcictl_mutex);
9952 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
9953 port, timeout_tags);
9954 mutex_enter(&ahci_ctlp->ahcictl_mutex);
9955 mutex_enter(&ahci_portp->ahciport_mutex);
9958 mutex_exit(&ahci_portp->ahciport_mutex);
9961 /* Re-install the watchdog timeout handler */
9962 if (ahci_ctlp->ahcictl_timeout_id != 0) {
9963 ahci_ctlp->ahcictl_timeout_id =
9964 timeout((void (*)(void *))ahci_watchdog_handler,
9965 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
9968 mutex_exit(&ahci_ctlp->ahcictl_mutex);
9972 * Fill the error context into sata_cmd for non-queued command error.
9974 static void
9975 ahci_copy_err_cnxt(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
9977 scmd->satacmd_status_reg = GET_RFIS_STATUS(rfisp);
9978 scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
9979 scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
9980 scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
9981 scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
9982 scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
9983 scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
9985 if (scmd->satacmd_addr_type == ATA_ADDR_LBA48) {
9986 scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
9987 scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
9988 scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
9989 scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
9994 * Fill the ncq error page into sata_cmd for queued command error.
9996 static void
9997 ahci_copy_ncq_err_page(sata_cmd_t *scmd,
9998 struct sata_ncq_error_recovery_page *ncq_err_page)
10000 scmd->satacmd_sec_count_msb = ncq_err_page->ncq_sector_count_ext;
10001 scmd->satacmd_sec_count_lsb = ncq_err_page->ncq_sector_count;
10002 scmd->satacmd_lba_low_msb = ncq_err_page->ncq_sector_number_ext;
10003 scmd->satacmd_lba_low_lsb = ncq_err_page->ncq_sector_number;
10004 scmd->satacmd_lba_mid_msb = ncq_err_page->ncq_cyl_low_ext;
10005 scmd->satacmd_lba_mid_lsb = ncq_err_page->ncq_cyl_low;
10006 scmd->satacmd_lba_high_msb = ncq_err_page->ncq_cyl_high_ext;
10007 scmd->satacmd_lba_high_lsb = ncq_err_page->ncq_cyl_high;
10008 scmd->satacmd_device_reg = ncq_err_page->ncq_dev_head;
10009 scmd->satacmd_status_reg = ncq_err_page->ncq_status;
10010 scmd->satacmd_error_reg = ncq_err_page->ncq_error;
10014 * Put the respective register value to sata_cmd_t for satacmd_flags.
10016 static void
10017 ahci_copy_out_regs(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
10019 if (scmd->satacmd_flags.sata_copy_out_sec_count_msb)
10020 scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
10021 if (scmd->satacmd_flags.sata_copy_out_lba_low_msb)
10022 scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
10023 if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb)
10024 scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
10025 if (scmd->satacmd_flags.sata_copy_out_lba_high_msb)
10026 scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
10027 if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb)
10028 scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
10029 if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb)
10030 scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
10031 if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb)
10032 scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
10033 if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb)
10034 scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
10035 if (scmd->satacmd_flags.sata_copy_out_device_reg)
10036 scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
10037 if (scmd->satacmd_flags.sata_copy_out_error_reg)
10038 scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
10041 static void
10042 ahci_log_fatal_error_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10043 uint32_t intr_status)
10045 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
10047 if (intr_status & AHCI_INTR_STATUS_IFS)
10048 cmn_err(CE_WARN, "!ahci%d: ahci port %d has interface fatal "
10049 "error", instance, port);
10051 if (intr_status & AHCI_INTR_STATUS_HBDS)
10052 cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus data error",
10053 instance, port);
10055 if (intr_status & AHCI_INTR_STATUS_HBFS)
10056 cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus fatal error",
10057 instance, port);
10059 if (intr_status & AHCI_INTR_STATUS_TFES)
10060 cmn_err(CE_WARN, "!ahci%d: ahci port %d has task file error",
10061 instance, port);
10063 cmn_err(CE_WARN, "!ahci%d: ahci port %d is trying to do error "
10064 "recovery", instance, port);
10067 static void
10068 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
10069 uint32_t slot_tags)
10071 ahci_port_t *ahci_portp;
10072 int tmp_slot;
10073 sata_pkt_t *spkt;
10074 sata_cmd_t cmd;
10076 ahci_portp = ahci_ctlp->ahcictl_ports[port];
10077 ASSERT(ahci_portp != NULL);
10079 while (slot_tags) {
10080 tmp_slot = ddi_ffs(slot_tags) - 1;
10081 if (tmp_slot == -1) {
10082 break;
10085 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
10086 if (spkt != NULL) {
10087 cmd = spkt->satapkt_cmd;
10089 cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
10090 "features_reg = 0x%x sec_count_msb = 0x%x "
10091 "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
10092 "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
10093 "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
10094 "lba_high_lsb = 0x%x device_reg = 0x%x "
10095 "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10096 cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10097 cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10098 cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10099 cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10100 cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10101 cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10102 *((uint32_t *)&(cmd.satacmd_flags)));
10105 CLEAR_BIT(slot_tags, tmp_slot);
10110 * Dump the serror message to the log.
10112 static void
10113 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10114 uint32_t port_serror, int debug_only)
10116 static char err_buf[512];
10117 static char err_msg_header[16];
10118 char *err_msg = err_buf;
10120 *err_buf = '\0';
10121 *err_msg_header = '\0';
10123 if (port_serror & SERROR_DATA_ERR_FIXED) {
10124 err_msg = strcat(err_msg,
10125 "\tRecovered Data Integrity Error (I)\n");
10128 if (port_serror & SERROR_COMM_ERR_FIXED) {
10129 err_msg = strcat(err_msg,
10130 "\tRecovered Communication Error (M)\n");
10133 if (port_serror & SERROR_DATA_ERR) {
10134 err_msg = strcat(err_msg,
10135 "\tTransient Data Integrity Error (T)\n");
10138 if (port_serror & SERROR_PERSISTENT_ERR) {
10139 err_msg = strcat(err_msg,
10140 "\tPersistent Communication or Data Integrity Error (C)\n");
10143 if (port_serror & SERROR_PROTOCOL_ERR) {
10144 err_msg = strcat(err_msg, "\tProtocol Error (P)\n");
10147 if (port_serror & SERROR_INT_ERR) {
10148 err_msg = strcat(err_msg, "\tInternal Error (E)\n");
10151 if (port_serror & SERROR_PHY_RDY_CHG) {
10152 err_msg = strcat(err_msg, "\tPhyRdy Change (N)\n");
10155 if (port_serror & SERROR_PHY_INT_ERR) {
10156 err_msg = strcat(err_msg, "\tPhy Internal Error (I)\n");
10159 if (port_serror & SERROR_COMM_WAKE) {
10160 err_msg = strcat(err_msg, "\tComm Wake (W)\n");
10163 if (port_serror & SERROR_10B_TO_8B_ERR) {
10164 err_msg = strcat(err_msg, "\t10B to 8B Decode Error (B)\n");
10167 if (port_serror & SERROR_DISPARITY_ERR) {
10168 err_msg = strcat(err_msg, "\tDisparity Error (D)\n");
10171 if (port_serror & SERROR_CRC_ERR) {
10172 err_msg = strcat(err_msg, "\tCRC Error (C)\n");
10175 if (port_serror & SERROR_HANDSHAKE_ERR) {
10176 err_msg = strcat(err_msg, "\tHandshake Error (H)\n");
10179 if (port_serror & SERROR_LINK_SEQ_ERR) {
10180 err_msg = strcat(err_msg, "\tLink Sequence Error (S)\n");
10183 if (port_serror & SERROR_TRANS_ERR) {
10184 err_msg = strcat(err_msg,
10185 "\tTransport state transition error (T)\n");
10188 if (port_serror & SERROR_FIS_TYPE) {
10189 err_msg = strcat(err_msg, "\tUnknown FIS Type (F)\n");
10192 if (port_serror & SERROR_EXCHANGED_ERR) {
10193 err_msg = strcat(err_msg, "\tExchanged (X)\n");
10196 if (*err_msg == '\0')
10197 return;
10199 if (debug_only) {
10200 (void) sprintf(err_msg_header, "port %d", port);
10201 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg_header, NULL);
10202 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg, NULL);
10203 } else if (ahci_ctlp) {
10204 cmn_err(CE_WARN, "!ahci%d: %s %s",
10205 ddi_get_instance(ahci_ctlp->ahcictl_dip),
10206 err_msg_header, err_msg);
10208 /* sata trace debug */
10209 sata_trace_debug(ahci_ctlp->ahcictl_dip,
10210 "ahci%d: %s %s", ddi_get_instance(ahci_ctlp->ahcictl_dip),
10211 err_msg_header, err_msg);
10212 } else {
10213 cmn_err(CE_WARN, "!ahci: %s %s", err_msg_header, err_msg);
10215 /* sata trace debug */
10216 sata_trace_debug(NULL, "ahci: %s %s", err_msg_header, err_msg);
10221 * Translate the sata_address_t type into the ahci_addr_t type.
10222 * sata_device.satadev_addr structure is used as source.
10224 static void
10225 ahci_get_ahci_addr(ahci_ctl_t *ahci_ctlp, sata_device_t *sd,
10226 ahci_addr_t *ahci_addrp)
10228 sata_address_t *sata_addrp = &sd->satadev_addr;
10229 ahci_addrp->aa_port =
10230 ahci_ctlp->ahcictl_cport_to_port[sata_addrp->cport];
10231 ahci_addrp->aa_pmport = sata_addrp->pmport;
10233 switch (sata_addrp->qual) {
10234 case SATA_ADDR_DCPORT:
10235 case SATA_ADDR_CPORT:
10236 ahci_addrp->aa_qual = AHCI_ADDR_PORT;
10237 break;
10238 case SATA_ADDR_PMULT:
10239 case SATA_ADDR_PMULT_SPEC:
10240 ahci_addrp->aa_qual = AHCI_ADDR_PMULT;
10241 break;
10242 case SATA_ADDR_DPMPORT:
10243 case SATA_ADDR_PMPORT:
10244 ahci_addrp->aa_qual = AHCI_ADDR_PMPORT;
10245 break;
10246 case SATA_ADDR_NULL:
10247 default:
10248 /* something went wrong */
10249 ahci_addrp->aa_qual = AHCI_ADDR_NULL;
10250 break;
10255 * This routine is to calculate the total number of ports implemented
10256 * by the HBA.
10258 static int
10259 ahci_get_num_implemented_ports(uint32_t ports_implemented)
10261 uint8_t i;
10262 int num = 0;
10264 for (i = 0; i < AHCI_MAX_PORTS; i++) {
10265 if (((uint32_t)0x1 << i) & ports_implemented)
10266 num++;
10269 return (num);
10272 #if AHCI_DEBUG
10273 static void
10274 ahci_log(ahci_ctl_t *ahci_ctlp, uint_t level, char *fmt, ...)
10276 static char name[16];
10277 va_list ap;
10279 mutex_enter(&ahci_log_mutex);
10281 va_start(ap, fmt);
10282 if (ahci_ctlp) {
10283 (void) sprintf(name, "ahci%d: ",
10284 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10285 } else {
10286 (void) sprintf(name, "ahci: ");
10289 (void) vsprintf(ahci_log_buf, fmt, ap);
10290 va_end(ap);
10292 cmn_err(level, "%s%s", name, ahci_log_buf);
10294 mutex_exit(&ahci_log_mutex);
10296 #endif
10299 * quiesce(9E) entry point.
10301 * This function is called when the system is single-threaded at high
10302 * PIL with preemption disabled. Therefore, this function must not be
10303 * blocked. Because no taskqs are running, there is no need for us to
10304 * take any action for enclosure services which are running in the
10305 * taskq context, especially as no interrupts are generated by it nor
10306 * are any messages expected to come in.
10308 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10309 * DDI_FAILURE indicates an error condition and should almost never happen.
10311 static int
10312 ahci_quiesce(dev_info_t *dip)
10314 ahci_ctl_t *ahci_ctlp;
10315 ahci_port_t *ahci_portp;
10316 int instance, port;
10318 instance = ddi_get_instance(dip);
10319 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10321 if (ahci_ctlp == NULL)
10322 return (DDI_FAILURE);
10324 #if AHCI_DEBUG
10325 ahci_debug_flags = 0;
10326 #endif
10328 ahci_ctlp->ahcictl_flags |= AHCI_QUIESCE;
10330 /* disable all the interrupts. */
10331 ahci_disable_all_intrs(ahci_ctlp);
10333 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
10334 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
10335 continue;
10338 ahci_portp = ahci_ctlp->ahcictl_ports[port];
10341 * Stop the port by clearing PxCMD.ST
10343 * Here we must disable the port interrupt because
10344 * ahci_disable_all_intrs only clear GHC.IE, and IS
10345 * register will be still set if PxIE is enabled.
10346 * When ahci shares one IRQ with other drivers, the
10347 * intr handler may claim the intr mistakenly.
10349 ahci_disable_port_intrs(ahci_ctlp, port);
10350 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
10351 ahci_portp, port);
10354 ahci_ctlp->ahcictl_flags &= ~AHCI_QUIESCE;
10356 return (DDI_SUCCESS);
10360 * The function will add a sata packet to the done queue.
10362 static void
10363 ahci_add_doneq(ahci_port_t *ahci_portp, sata_pkt_t *satapkt, int reason)
10365 ASSERT(satapkt != NULL);
10366 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10368 /* set the reason for all packets */
10369 satapkt->satapkt_reason = reason;
10370 satapkt->satapkt_hba_driver_private = NULL;
10372 if (! (satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10373 satapkt->satapkt_comp) {
10375 * only add to queue when mode is not synch and there is
10376 * completion callback
10378 *ahci_portp->ahciport_doneqtail = satapkt;
10379 ahci_portp->ahciport_doneqtail =
10380 (sata_pkt_t **)&(satapkt->satapkt_hba_driver_private);
10381 ahci_portp->ahciport_doneq_len++;
10383 } else if ((satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10384 ! (satapkt->satapkt_op_mode & SATA_OPMODE_POLLING))
10386 * for sync/non-poll mode, just call cv_broadcast
10388 cv_broadcast(&ahci_portp->ahciport_cv);
10392 * The function will call completion callback of sata packet on the
10393 * completed queue
10395 static void
10396 ahci_flush_doneq(ahci_port_t *ahci_portp)
10398 sata_pkt_t *satapkt, *next;
10400 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10402 if (ahci_portp->ahciport_doneq) {
10403 satapkt = ahci_portp->ahciport_doneq;
10405 ahci_portp->ahciport_doneq = NULL;
10406 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10407 ahci_portp->ahciport_doneq_len = 0;
10409 mutex_exit(&ahci_portp->ahciport_mutex);
10411 while (satapkt != NULL) {
10412 next = satapkt->satapkt_hba_driver_private;
10413 satapkt->satapkt_hba_driver_private = NULL;
10415 /* Call the callback */
10416 (*satapkt->satapkt_comp)(satapkt);
10418 satapkt = next;
10421 mutex_enter(&ahci_portp->ahciport_mutex);
10426 * Sets the state for the specified port on the controller to desired state.
10427 * This must be run in the context of the enclosure taskq which ensures that
10428 * only one event is outstanding at any time.
10430 static boolean_t
10431 ahci_em_set_led(ahci_ctl_t *ahci_ctlp, uint8_t port, ahci_em_led_state_t desire)
10433 ahci_em_led_msg_t msg;
10434 ahci_em_msg_hdr_t hdr;
10435 uint32_t msgval, hdrval;
10436 uint_t i, max_delay = ahci_em_tx_delay_count;
10438 msg.alm_hba = port;
10439 msg.alm_pminfo = 0;
10440 msg.alm_value = 0;
10442 if (desire & AHCI_EM_LED_IDENT_ENABLE) {
10443 msg.alm_value |= AHCI_LED_ON << AHCI_LED_IDENT_OFF;
10446 if (desire & AHCI_EM_LED_FAULT_ENABLE) {
10447 msg.alm_value |= AHCI_LED_ON << AHCI_LED_FAULT_OFF;
10450 if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0 &&
10451 (desire & AHCI_EM_LED_ACTIVITY_DISABLE) == 0) {
10452 msg.alm_value |= AHCI_LED_ON << AHCI_LED_ACTIVITY_OFF;
10455 hdr.aemh_rsvd = 0;
10456 hdr.aemh_mlen = sizeof (ahci_em_led_msg_t);
10457 hdr.aemh_dlen = 0;
10458 hdr.aemh_mtype = AHCI_EM_MSG_TYPE_LED;
10460 bcopy(&msg, &msgval, sizeof (msgval));
10461 bcopy(&hdr, &hdrval, sizeof (hdrval));
10464 * First, make sure we can transmit. We should not have been placed in a
10465 * situation where an outstanding transmission is going on.
10467 for (i = 0; i < max_delay; i++) {
10468 uint32_t val;
10470 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10471 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10472 if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10473 break;
10475 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10478 if (i == max_delay)
10479 return (B_FALSE);
10481 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10482 (uint32_t *)ahci_ctlp->ahcictl_em_tx_off, hdrval);
10483 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10484 (uint32_t *)(ahci_ctlp->ahcictl_em_tx_off + 4), msgval);
10485 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10486 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_TM);
10488 for (i = 0; i < max_delay; i++) {
10489 uint32_t val;
10491 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10492 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10493 if ((val & AHCI_HBA_EM_CTL_CTL_TM) == 0)
10494 break;
10496 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10499 if (i == max_delay)
10500 return (B_FALSE);
10502 return (B_TRUE);
10505 typedef struct ahci_em_led_task_arg {
10506 ahci_ctl_t *aelta_ctl;
10507 uint8_t aelta_port;
10508 uint_t aelta_op;
10509 ahci_em_led_state_t aelta_state;
10510 uint_t aelta_ret;
10511 kcondvar_t aelta_cv;
10512 uint_t aelta_ref;
10513 } ahci_em_led_task_arg_t;
10515 static void
10516 ahci_em_led_task_free(ahci_em_led_task_arg_t *task)
10518 ASSERT3U(task->aelta_ref, ==, 0);
10519 cv_destroy(&task->aelta_cv);
10520 kmem_free(task, sizeof (*task));
10523 static void
10524 ahci_em_led_task(void *arg)
10526 boolean_t ret, cleanup = B_FALSE;
10527 ahci_em_led_task_arg_t *led = arg;
10528 ahci_em_led_state_t state;
10530 mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10531 if (led->aelta_ctl->ahcictl_em_flags != AHCI_EM_USABLE) {
10532 led->aelta_ret = EIO;
10533 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10534 return;
10537 state = led->aelta_ctl->ahcictl_em_state[led->aelta_port];
10538 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10540 switch (led->aelta_op) {
10541 case AHCI_EM_IOC_SET_OP_ADD:
10542 state |= led->aelta_state;
10543 break;
10544 case AHCI_EM_IOC_SET_OP_REM:
10545 state &= ~led->aelta_state;
10546 break;
10547 case AHCI_EM_IOC_SET_OP_SET:
10548 state = led->aelta_state;
10549 break;
10550 default:
10551 led->aelta_ret = ENOTSUP;
10552 return;
10555 ret = ahci_em_set_led(led->aelta_ctl, led->aelta_port, state);
10557 mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10558 if (ret) {
10559 led->aelta_ctl->ahcictl_em_state[led->aelta_port] =
10560 led->aelta_state;
10561 led->aelta_ret = 0;
10562 } else {
10563 led->aelta_ret = EIO;
10564 led->aelta_ctl->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10566 led->aelta_ref--;
10567 if (led->aelta_ref > 0) {
10568 cv_signal(&led->aelta_cv);
10569 } else {
10570 cleanup = B_TRUE;
10572 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10574 if (cleanup) {
10575 ahci_em_led_task_free(led);
10579 static void
10580 ahci_em_reset(void *arg)
10582 uint_t i, max_delay = ahci_em_reset_delay_count;
10583 ahci_ctl_t *ahci_ctlp = arg;
10586 * We've been asked to reset the device. The caller should have set the
10587 * resetting flag. Make sure that we don't have a request to quiesce.
10589 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10590 ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_RESETTING);
10591 if (ahci_ctlp->ahcictl_em_flags & AHCI_EM_QUIESCE) {
10592 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10593 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10594 return;
10596 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10598 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
10599 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp), AHCI_HBA_EM_CTL_CTL_RST);
10600 for (i = 0; i < max_delay; i++) {
10601 uint32_t val;
10603 val = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
10604 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp));
10605 if ((val & AHCI_HBA_EM_CTL_CTL_RST) == 0)
10606 break;
10608 delay(drv_usectohz(ahci_em_reset_delay_ms * 1000));
10611 if (i == max_delay) {
10612 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10613 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10614 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10615 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10616 cmn_err(CE_WARN, "!ahci%d: enclosure timed out resetting",
10617 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10618 return;
10621 for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10623 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i))
10624 continue;
10627 * Try to flush all the LEDs as part of reset. If it fails,
10628 * drive on.
10630 if (!ahci_em_set_led(ahci_ctlp, i,
10631 ahci_ctlp->ahcictl_em_state[i])) {
10632 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10633 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10634 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10635 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10636 cmn_err(CE_WARN, "!ahci%d: enclosure timed out "
10637 "setting port %u",
10638 ddi_get_instance(ahci_ctlp->ahcictl_dip), i);
10639 return;
10643 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10644 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_RESETTING;
10645 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_READY;
10646 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10649 static boolean_t
10650 ahci_em_init(ahci_ctl_t *ahci_ctlp)
10652 char name[128];
10655 * First make sure we actually have enclosure services and if so, that
10656 * we have the hardware support that we care about for this.
10658 if (ahci_ctlp->ahcictl_em_loc == 0 ||
10659 (ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_SUPP_LED) == 0)
10660 return (B_TRUE);
10663 * Next, make sure that the buffer is large enough for us. We need two
10664 * dwords or 8 bytes. The location register is stored in dwords.
10666 if ((ahci_ctlp->ahcictl_em_loc & AHCI_HBA_EM_LOC_SZ_MASK) <
10667 AHCI_EM_BUFFER_MIN) {
10668 return (B_TRUE);
10671 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_PRESENT;
10673 ahci_ctlp->ahcictl_em_tx_off = ((ahci_ctlp->ahcictl_em_loc &
10674 AHCI_HBA_EM_LOC_OFST_MASK) >> AHCI_HBA_EM_LOC_OFST_SHIFT) * 4;
10675 ahci_ctlp->ahcictl_em_tx_off += ahci_ctlp->ahcictl_ahci_addr;
10677 bzero(ahci_ctlp->ahcictl_em_state,
10678 sizeof (ahci_ctlp->ahcictl_em_state));
10680 (void) snprintf(name, sizeof (name), "ahcti_em_taskq%d",
10681 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10682 if ((ahci_ctlp->ahcictl_em_taskq =
10683 ddi_taskq_create(ahci_ctlp->ahcictl_dip, name, 1,
10684 TASKQ_DEFAULTPRI, 0)) == NULL) {
10685 cmn_err(CE_WARN, "!ahci%d: ddi_tasq_create failed for em "
10686 "services", ddi_get_instance(ahci_ctlp->ahcictl_dip));
10687 return (B_FALSE);
10690 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10691 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10692 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10693 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10694 ahci_ctlp, DDI_SLEEP);
10696 return (B_TRUE);
10699 static int
10700 ahci_em_ioctl_get(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10702 int i;
10703 ahci_ioc_em_get_t get;
10705 bzero(&get, sizeof (get));
10706 get.aiemg_nports = ahci_ctlp->ahcictl_ports_implemented;
10707 if ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) == 0) {
10708 get.aiemg_flags |= AHCI_EM_FLAG_CONTROL_ACTIVITY;
10711 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10712 for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10713 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i)) {
10714 continue;
10716 get.aiemg_status[i] = ahci_ctlp->ahcictl_em_state[i];
10718 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10720 if (ddi_copyout(&get, (void *)arg, sizeof (get), 0) != 0)
10721 return (EFAULT);
10723 return (0);
10726 static int
10727 ahci_em_ioctl_set(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10729 int ret;
10730 ahci_ioc_em_set_t set;
10731 ahci_em_led_task_arg_t *task;
10732 boolean_t signal, cleanup;
10734 if (ddi_copyin((void *)arg, &set, sizeof (set), 0) != 0)
10735 return (EFAULT);
10737 if (set.aiems_port > ahci_ctlp->ahcictl_num_ports)
10738 return (EINVAL);
10740 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, set.aiems_port)) {
10741 return (EINVAL);
10744 if ((set.aiems_leds & ~(AHCI_EM_LED_IDENT_ENABLE |
10745 AHCI_EM_LED_FAULT_ENABLE |
10746 AHCI_EM_LED_ACTIVITY_DISABLE)) != 0) {
10747 return (EINVAL);
10750 switch (set.aiems_op) {
10751 case AHCI_EM_IOC_SET_OP_ADD:
10752 case AHCI_EM_IOC_SET_OP_REM:
10753 case AHCI_EM_IOC_SET_OP_SET:
10754 break;
10755 default:
10756 return (EINVAL);
10759 if ((set.aiems_leds & AHCI_EM_LED_ACTIVITY_DISABLE) != 0 &&
10760 ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) != 0)) {
10761 return (ENOTSUP);
10764 task = kmem_alloc(sizeof (*task), KM_NOSLEEP | KM_NORMALPRI);
10765 if (task == NULL) {
10766 return (ENOMEM);
10769 task->aelta_ctl = ahci_ctlp;
10770 task->aelta_port = (uint8_t)set.aiems_port;
10771 task->aelta_op = set.aiems_op;
10772 task->aelta_state = set.aiems_leds;
10774 cv_init(&task->aelta_cv, NULL, CV_DRIVER, NULL);
10777 * Initialize the reference count to two. One for us and one for the
10778 * taskq. This will be used in case we get canceled.
10780 task->aelta_ref = 2;
10783 * Once dispatched, the task state is protected by our global mutex.
10785 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq,
10786 ahci_em_led_task, task, DDI_SLEEP);
10788 signal = B_FALSE;
10789 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10790 while (task->aelta_ref > 1) {
10791 if (cv_wait_sig(&task->aelta_cv, &ahci_ctlp->ahcictl_mutex) ==
10792 0) {
10793 signal = B_TRUE;
10794 break;
10799 * Remove our reference count. If we were woken up because of a signal
10800 * then the taskq may still be dispatched. In which case we shouldn't
10801 * free this memory until it is done. In that case, the taskq will take
10802 * care of it.
10804 task->aelta_ref--;
10805 cleanup = (task->aelta_ref == 0);
10806 if (signal) {
10807 ret = EINTR;
10808 } else {
10809 ret = task->aelta_ret;
10811 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10813 if (cleanup) {
10814 ahci_em_led_task_free(task);
10817 return (ret);
10820 static int
10821 ahci_em_ioctl(dev_info_t *dip, int cmd, intptr_t arg)
10823 int inst;
10824 ahci_ctl_t *ahci_ctlp;
10826 inst = ddi_get_instance(dip);
10827 if ((ahci_ctlp = ddi_get_soft_state(ahci_statep, inst)) == NULL) {
10828 return (ENXIO);
10831 switch (cmd) {
10832 case AHCI_EM_IOC_GET:
10833 return (ahci_em_ioctl_get(ahci_ctlp, arg));
10834 case AHCI_EM_IOC_SET:
10835 return (ahci_em_ioctl_set(ahci_ctlp, arg));
10836 default:
10837 return (ENOTTY);
10842 static void
10843 ahci_em_quiesce(ahci_ctl_t *ahci_ctlp)
10845 ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT);
10847 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10848 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_QUIESCE;
10849 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10851 ddi_taskq_wait(ahci_ctlp->ahcictl_em_taskq);
10854 static void
10855 ahci_em_suspend(ahci_ctl_t *ahci_ctlp)
10857 ahci_em_quiesce(ahci_ctlp);
10859 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10860 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_READY;
10861 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10864 static void
10865 ahci_em_resume(ahci_ctl_t *ahci_ctlp)
10867 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10868 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10869 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10871 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10872 ahci_ctlp, DDI_SLEEP);
10875 static void
10876 ahci_em_fini(ahci_ctl_t *ahci_ctlp)
10878 if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10879 return;
10882 ahci_em_quiesce(ahci_ctlp);
10883 ddi_taskq_destroy(ahci_ctlp->ahcictl_em_taskq);
10884 ahci_ctlp->ahcictl_em_taskq = NULL;