Merge commit 'cb41b9c565d4eec9e1f06e24d429696f59f2f07d'
[unleashed.git] / usr / src / uts / common / io / sata / adapters / ahci / ahci.c
blobf59fcb974ef7d1eaef2fe10c05933ece85e1af9b
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.
28 * AHCI (Advanced Host Controller Interface) SATA HBA Driver
30 * Power Management Support
31 * ------------------------
33 * At the moment, the ahci driver only implements suspend/resume to
34 * support Suspend to RAM on X86 feature. Device power management isn't
35 * implemented, link power management is disabled, and hot plug isn't
36 * allowed during the period from suspend to resume.
38 * For s/r support, the ahci driver only need to implement DDI_SUSPEND
39 * and DDI_RESUME entries, and don't need to take care of new requests
40 * sent down after suspend because the target driver (sd) has already
41 * handled these conditions, and blocked these requests. For the detailed
42 * information, please check with sdopen, sdclose and sdioctl routines.
46 #include <sys/note.h>
47 #include <sys/scsi/scsi.h>
48 #include <sys/pci.h>
49 #include <sys/disp.h>
50 #include <sys/sata/sata_hba.h>
51 #include <sys/sata/adapters/ahci/ahcireg.h>
52 #include <sys/sata/adapters/ahci/ahcivar.h>
55 * FMA header files
57 #include <sys/ddifm.h>
58 #include <sys/fm/protocol.h>
59 #include <sys/fm/util.h>
60 #include <sys/fm/io/ddi.h>
63 * This is the string displayed by modinfo, etc.
65 static char ahci_ident[] = "ahci driver";
68 * Function prototypes for driver entry points
70 static int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
71 static int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
72 static int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
73 static int ahci_quiesce(dev_info_t *);
76 * Function prototypes for SATA Framework interfaces
78 static int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
79 static int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
81 static int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
82 static int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);
83 static int ahci_tran_abort(dev_info_t *, sata_pkt_t *, int);
84 static int ahci_tran_reset_dport(dev_info_t *, sata_device_t *);
85 static int ahci_tran_hotplug_port_activate(dev_info_t *, sata_device_t *);
86 static int ahci_tran_hotplug_port_deactivate(dev_info_t *, sata_device_t *);
87 #if defined(__lock_lint)
88 static int ahci_selftest(dev_info_t *, sata_device_t *);
89 #endif
92 * FMA Prototypes
94 static void ahci_fm_init(ahci_ctl_t *);
95 static void ahci_fm_fini(ahci_ctl_t *);
96 static int ahci_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void*);
97 int ahci_check_acc_handle(ddi_acc_handle_t);
98 int ahci_check_dma_handle(ddi_dma_handle_t);
99 void ahci_fm_ereport(ahci_ctl_t *, char *);
100 static int ahci_check_all_handle(ahci_ctl_t *);
101 static int ahci_check_ctl_handle(ahci_ctl_t *);
102 static int ahci_check_port_handle(ahci_ctl_t *, int);
103 static int ahci_check_slot_handle(ahci_port_t *, int);
106 * Local function prototypes
108 static int ahci_setup_port_base_addresses(ahci_ctl_t *, ahci_port_t *);
109 static int ahci_alloc_ports_state(ahci_ctl_t *);
110 static void ahci_dealloc_ports_state(ahci_ctl_t *);
111 static int ahci_alloc_port_state(ahci_ctl_t *, uint8_t);
112 static void ahci_dealloc_port_state(ahci_ctl_t *, uint8_t);
113 static int ahci_alloc_rcvd_fis(ahci_ctl_t *, ahci_port_t *);
114 static void ahci_dealloc_rcvd_fis(ahci_port_t *);
115 static int ahci_alloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
116 static void ahci_dealloc_cmd_list(ahci_ctl_t *, ahci_port_t *);
117 static int ahci_alloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
118 static void ahci_dealloc_cmd_tables(ahci_ctl_t *, ahci_port_t *);
119 static void ahci_alloc_pmult(ahci_ctl_t *, ahci_port_t *);
120 static void ahci_dealloc_pmult(ahci_ctl_t *, ahci_port_t *);
122 static int ahci_initialize_controller(ahci_ctl_t *);
123 static void ahci_uninitialize_controller(ahci_ctl_t *);
124 static int ahci_initialize_port(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
125 static int ahci_config_space_init(ahci_ctl_t *);
126 static void ahci_staggered_spin_up(ahci_ctl_t *, uint8_t);
128 static void ahci_drain_ports_taskq(ahci_ctl_t *);
129 static int ahci_rdwr_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *,
130 uint8_t);
131 static int ahci_read_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t *);
132 static int ahci_write_pmult(ahci_ctl_t *, ahci_addr_t *, uint8_t, uint32_t);
133 static int ahci_update_pmult_pscr(ahci_ctl_t *, ahci_addr_t *,
134 sata_device_t *);
135 static int ahci_update_pmult_gscr(ahci_ctl_t *, ahci_addr_t *,
136 sata_pmult_gscr_t *);
137 static int ahci_initialize_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
138 sata_device_t *);
139 static int ahci_initialize_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
140 static int ahci_probe_pmult(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
141 static int ahci_probe_pmport(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *,
142 sata_device_t *);
144 static void ahci_disable_interface_pm(ahci_ctl_t *, uint8_t);
145 static int ahci_start_port(ahci_ctl_t *, ahci_port_t *, uint8_t);
146 static void ahci_find_dev_signature(ahci_ctl_t *, ahci_port_t *,
147 ahci_addr_t *);
148 static void ahci_update_sata_registers(ahci_ctl_t *, uint8_t, sata_device_t *);
149 static int ahci_deliver_satapkt(ahci_ctl_t *, ahci_port_t *,
150 ahci_addr_t *, sata_pkt_t *);
151 static int ahci_do_sync_start(ahci_ctl_t *, ahci_port_t *,
152 ahci_addr_t *, sata_pkt_t *);
153 static int ahci_claim_free_slot(ahci_ctl_t *, ahci_port_t *,
154 ahci_addr_t *, int);
155 static void ahci_copy_err_cnxt(sata_cmd_t *, ahci_fis_d2h_register_t *);
156 static void ahci_copy_ncq_err_page(sata_cmd_t *,
157 struct sata_ncq_error_recovery_page *);
158 static void ahci_copy_out_regs(sata_cmd_t *, ahci_fis_d2h_register_t *);
159 static void ahci_add_doneq(ahci_port_t *, sata_pkt_t *, int);
160 static void ahci_flush_doneq(ahci_port_t *);
162 static int ahci_software_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
163 static int ahci_hba_reset(ahci_ctl_t *);
164 static int ahci_port_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
165 static int ahci_pmport_reset(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
166 static void ahci_reject_all_abort_pkts(ahci_ctl_t *, ahci_port_t *, uint8_t);
167 static int ahci_reset_device_reject_pkts(ahci_ctl_t *, ahci_port_t *,
168 ahci_addr_t *);
169 static int ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *, ahci_port_t *,
170 ahci_addr_t *);
171 static int ahci_reset_port_reject_pkts(ahci_ctl_t *, ahci_port_t *,
172 ahci_addr_t *);
173 static int ahci_reset_hba_reject_pkts(ahci_ctl_t *);
174 static int ahci_put_port_into_notrunning_state(ahci_ctl_t *, ahci_port_t *,
175 uint8_t);
176 static int ahci_restart_port_wait_till_ready(ahci_ctl_t *, ahci_port_t *,
177 uint8_t, int, int *);
178 static void ahci_mop_commands(ahci_ctl_t *, ahci_port_t *, uint32_t,
179 uint32_t, uint32_t, uint32_t, uint32_t);
180 static uint32_t ahci_get_rdlogext_data(ahci_ctl_t *, ahci_port_t *, uint8_t);
181 static void ahci_get_rqsense_data(ahci_ctl_t *, ahci_port_t *,
182 uint8_t, sata_pkt_t *);
183 static void ahci_fatal_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
184 ahci_addr_t *, uint32_t);
185 static void ahci_pmult_error_recovery_handler(ahci_ctl_t *, ahci_port_t *,
186 uint8_t, uint32_t);
187 static void ahci_timeout_pkts(ahci_ctl_t *, ahci_port_t *,
188 uint8_t, uint32_t);
189 static void ahci_events_handler(void *);
190 static void ahci_watchdog_handler(ahci_ctl_t *);
192 static uint_t ahci_intr(caddr_t, caddr_t);
193 static void ahci_port_intr(ahci_ctl_t *, ahci_port_t *, uint8_t);
194 static int ahci_add_intrs(ahci_ctl_t *, int);
195 static void ahci_rem_intrs(ahci_ctl_t *);
196 static void ahci_enable_all_intrs(ahci_ctl_t *);
197 static void ahci_disable_all_intrs(ahci_ctl_t *);
198 static void ahci_enable_port_intrs(ahci_ctl_t *, uint8_t);
199 static void ahci_disable_port_intrs(ahci_ctl_t *, uint8_t);
201 static int ahci_intr_cmd_cmplt(ahci_ctl_t *, ahci_port_t *, uint8_t);
202 static int ahci_intr_set_device_bits(ahci_ctl_t *, ahci_port_t *, uint8_t);
203 static int ahci_intr_ncq_events(ahci_ctl_t *, ahci_port_t *, ahci_addr_t *);
204 static int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
205 static int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
206 static int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
207 ahci_port_t *, uint8_t);
208 static int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
209 static int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
210 uint8_t, uint32_t);
211 static int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
212 uint8_t, uint32_t);
213 static int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
215 static void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
216 static int ahci_get_num_implemented_ports(uint32_t);
217 static void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
218 static void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
219 static void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
220 #if AHCI_DEBUG
221 static void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
222 #endif
226 * DMA attributes for the data buffer
228 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
229 * does not support 64-bit addressing
231 static ddi_dma_attr_t buffer_dma_attr = {
232 DMA_ATTR_V0, /* dma_attr_version */
233 0x0ull, /* dma_attr_addr_lo: lowest bus address */
234 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
235 0x3fffffull, /* dma_attr_count_max i.e. for one cookie */
236 0x2ull, /* dma_attr_align: word aligned */
237 1, /* dma_attr_burstsizes */
238 1, /* dma_attr_minxfer */
239 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
240 0xffffffffull, /* dma_attr_seg */
241 AHCI_PRDT_NUMBER, /* dma_attr_sgllen */
242 512, /* dma_attr_granular */
243 0, /* dma_attr_flags */
247 * DMA attributes for the rcvd FIS
249 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
250 * does not support 64-bit addressing
252 static ddi_dma_attr_t rcvd_fis_dma_attr = {
253 DMA_ATTR_V0, /* dma_attr_version */
254 0x0ull, /* dma_attr_addr_lo: lowest bus address */
255 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
256 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
257 0x100ull, /* dma_attr_align: 256-byte aligned */
258 1, /* dma_attr_burstsizes */
259 1, /* dma_attr_minxfer */
260 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
261 0xffffffffull, /* dma_attr_seg */
262 1, /* dma_attr_sgllen */
263 1, /* dma_attr_granular */
264 0, /* dma_attr_flags */
268 * DMA attributes for the command list
270 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
271 * does not support 64-bit addressing
273 static ddi_dma_attr_t cmd_list_dma_attr = {
274 DMA_ATTR_V0, /* dma_attr_version */
275 0x0ull, /* dma_attr_addr_lo: lowest bus address */
276 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
277 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
278 0x400ull, /* dma_attr_align: 1K-byte aligned */
279 1, /* dma_attr_burstsizes */
280 1, /* dma_attr_minxfer */
281 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
282 0xffffffffull, /* dma_attr_seg */
283 1, /* dma_attr_sgllen */
284 1, /* dma_attr_granular */
285 0, /* dma_attr_flags */
289 * DMA attributes for cmd tables
291 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
292 * does not support 64-bit addressing
294 static ddi_dma_attr_t cmd_table_dma_attr = {
295 DMA_ATTR_V0, /* dma_attr_version */
296 0x0ull, /* dma_attr_addr_lo: lowest bus address */
297 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
298 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
299 0x80ull, /* dma_attr_align: 128-byte aligned */
300 1, /* dma_attr_burstsizes */
301 1, /* dma_attr_minxfer */
302 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
303 0xffffffffull, /* dma_attr_seg */
304 1, /* dma_attr_sgllen */
305 1, /* dma_attr_granular */
306 0, /* dma_attr_flags */
310 /* Device access attributes */
311 static ddi_device_acc_attr_t accattr = {
312 DDI_DEVICE_ATTR_V1,
313 DDI_STRUCTURE_LE_ACC,
314 DDI_STRICTORDER_ACC,
315 DDI_DEFAULT_ACC
319 static struct dev_ops ahcictl_dev_ops = {
320 DEVO_REV, /* devo_rev */
321 0, /* refcnt */
322 ahci_getinfo, /* info */
323 nulldev, /* identify */
324 nulldev, /* probe */
325 ahci_attach, /* attach */
326 ahci_detach, /* detach */
327 nodev, /* no reset */
328 NULL, /* driver operations */
329 NULL, /* bus operations */
330 NULL, /* power */
331 ahci_quiesce, /* quiesce */
334 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
335 SATA_TRAN_HOTPLUG_OPS_REV_1,
336 ahci_tran_hotplug_port_activate,
337 ahci_tran_hotplug_port_deactivate
340 extern struct mod_ops mod_driverops;
342 static struct modldrv modldrv = {
343 &mod_driverops, /* driverops */
344 ahci_ident, /* short description */
345 &ahcictl_dev_ops, /* driver ops */
348 static struct modlinkage modlinkage = {
349 MODREV_1,
350 &modldrv,
351 NULL
354 /* The following variables are watchdog handler related */
355 static clock_t ahci_watchdog_timeout = 5; /* 5 seconds */
356 static clock_t ahci_watchdog_tick;
359 * This static variable indicates the size of command table,
360 * and it's changeable with prdt number, which ahci_dma_prdt_number
361 * indicates.
363 static size_t ahci_cmd_table_size;
366 * The below global variables are tunable via /etc/system
368 * ahci_dma_prdt_number
369 * ahci_msi_enabled
370 * ahci_buf_64bit_dma
371 * ahci_commu_64bit_dma
374 /* The number of Physical Region Descriptor Table(PRDT) in Command Table */
375 int ahci_dma_prdt_number = AHCI_PRDT_NUMBER;
377 /* AHCI MSI is tunable */
378 boolean_t ahci_msi_enabled = B_TRUE;
381 * 64-bit dma addressing for data buffer is tunable
383 * The variable controls only the below value:
384 * DBAU (upper 32-bits physical address of data block)
386 boolean_t ahci_buf_64bit_dma = B_TRUE;
389 * 64-bit dma addressing for communication system descriptors is tunable
391 * The variable controls the below three values:
393 * PxCLBU (upper 32-bits for the command list base physical address)
394 * PxFBU (upper 32-bits for the received FIS base physical address)
395 * CTBAU (upper 32-bits of command table base)
397 boolean_t ahci_commu_64bit_dma = B_TRUE;
400 * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
401 * chipset. If the users want to have a try with 64-bit dma, please change
402 * the below variable value to enable it.
404 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
407 * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
408 * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
409 * please change the below value to enable it.
411 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
415 * End of global tunable variable definition
418 #if AHCI_DEBUG
419 uint32_t ahci_debug_flags = 0;
420 #else
421 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
422 #endif
425 #if AHCI_DEBUG
426 /* The following is needed for ahci_log() */
427 static kmutex_t ahci_log_mutex;
428 static char ahci_log_buf[512];
429 #endif
431 /* Opaque state pointer initialized by ddi_soft_state_init() */
432 static void *ahci_statep = NULL;
435 * ahci module initialization.
438 _init(void)
440 int ret;
442 ret = ddi_soft_state_init(&ahci_statep, sizeof (ahci_ctl_t), 0);
443 if (ret != 0) {
444 goto err_out;
447 #if AHCI_DEBUG
448 mutex_init(&ahci_log_mutex, NULL, MUTEX_DRIVER, NULL);
449 #endif
451 if ((ret = sata_hba_init(&modlinkage)) != 0) {
452 #if AHCI_DEBUG
453 mutex_destroy(&ahci_log_mutex);
454 #endif
455 ddi_soft_state_fini(&ahci_statep);
456 goto err_out;
459 /* watchdog tick */
460 ahci_watchdog_tick = drv_usectohz(
461 (clock_t)ahci_watchdog_timeout * 1000000);
463 ret = mod_install(&modlinkage);
464 if (ret != 0) {
465 sata_hba_fini(&modlinkage);
466 #if AHCI_DEBUG
467 mutex_destroy(&ahci_log_mutex);
468 #endif
469 ddi_soft_state_fini(&ahci_statep);
470 goto err_out;
473 return (ret);
475 err_out:
476 cmn_err(CE_WARN, "!ahci: Module init failed");
477 return (ret);
481 * ahci module uninitialize.
484 _fini(void)
486 int ret;
488 ret = mod_remove(&modlinkage);
489 if (ret != 0) {
490 return (ret);
493 /* Remove the resources allocated in _init(). */
494 sata_hba_fini(&modlinkage);
495 #if AHCI_DEBUG
496 mutex_destroy(&ahci_log_mutex);
497 #endif
498 ddi_soft_state_fini(&ahci_statep);
500 return (ret);
504 * _info entry point
507 _info(struct modinfo *modinfop)
509 return (mod_info(&modlinkage, modinfop));
513 * The attach entry point for dev_ops.
515 static int
516 ahci_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
518 ahci_ctl_t *ahci_ctlp = NULL;
519 int instance = ddi_get_instance(dip);
520 int status;
521 int attach_state;
522 uint32_t cap_status, ahci_version;
523 uint32_t ghc_control;
524 int intr_types;
525 int i;
526 pci_regspec_t *regs;
527 int regs_length;
528 int rnumber;
529 #if AHCI_DEBUG
530 int speed;
531 #endif
533 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "ahci_attach enter",
534 NULL);
536 switch (cmd) {
537 case DDI_ATTACH:
538 break;
540 case DDI_RESUME:
543 * During DDI_RESUME, the hardware state of the device
544 * (power may have been removed from the device) must be
545 * restored, allow pending requests to continue, and
546 * service new requests.
548 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
549 mutex_enter(&ahci_ctlp->ahcictl_mutex);
552 * GHC.AE must be set to 1 before any other AHCI register
553 * is accessed
555 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
556 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
557 ghc_control |= AHCI_HBA_GHC_AE;
558 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
559 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
561 /* Restart watch thread */
562 if (ahci_ctlp->ahcictl_timeout_id == 0)
563 ahci_ctlp->ahcictl_timeout_id = timeout(
564 (void (*)(void *))ahci_watchdog_handler,
565 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
567 mutex_exit(&ahci_ctlp->ahcictl_mutex);
570 * Re-initialize the controller and enable the interrupts and
571 * restart all the ports.
573 * Note that so far we don't support hot-plug during
574 * suspend/resume.
576 if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
577 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
578 "Failed to initialize the controller "
579 "during DDI_RESUME", NULL);
580 return (DDI_FAILURE);
583 mutex_enter(&ahci_ctlp->ahcictl_mutex);
584 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
585 mutex_exit(&ahci_ctlp->ahcictl_mutex);
587 return (DDI_SUCCESS);
589 default:
590 return (DDI_FAILURE);
593 attach_state = AHCI_ATTACH_STATE_NONE;
595 /* Allocate soft state */
596 status = ddi_soft_state_zalloc(ahci_statep, instance);
597 if (status != DDI_SUCCESS) {
598 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
599 instance);
600 goto err_out;
603 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
604 ahci_ctlp->ahcictl_flags |= AHCI_ATTACH;
605 ahci_ctlp->ahcictl_dip = dip;
607 /* Initialize the cport/port mapping */
608 for (i = 0; i < AHCI_MAX_PORTS; i++) {
609 ahci_ctlp->ahcictl_port_to_cport[i] = 0xff;
610 ahci_ctlp->ahcictl_cport_to_port[i] = 0xff;
613 attach_state |= AHCI_ATTACH_STATE_STATEP_ALLOC;
615 /* Initialize FMA properties */
616 ahci_fm_init(ahci_ctlp);
618 attach_state |= AHCI_ATTACH_STATE_FMA;
621 * Now map the AHCI base address; which includes global
622 * registers and port control registers
624 * According to the spec, the AHCI Base Address is BAR5,
625 * but BAR0-BAR4 are optional, so we need to check which
626 * rnumber is used for BAR5.
630 * search through DDI "reg" property for the AHCI register set
632 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
633 DDI_PROP_DONTPASS, "reg", (int **)&regs,
634 (uint_t *)&regs_length) != DDI_PROP_SUCCESS) {
635 cmn_err(CE_WARN, "!ahci%d: Cannot lookup reg property",
636 instance);
637 goto err_out;
640 /* AHCI Base Address is located at 0x24 offset */
641 for (rnumber = 0; rnumber < regs_length; ++rnumber) {
642 if ((regs[rnumber].pci_phys_hi & PCI_REG_REG_M)
643 == AHCI_PCI_RNUM)
644 break;
647 ddi_prop_free(regs);
649 if (rnumber == regs_length) {
650 cmn_err(CE_WARN, "!ahci%d: Cannot find AHCI register set",
651 instance);
652 goto err_out;
655 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "rnumber = %d", rnumber);
657 status = ddi_regs_map_setup(dip,
658 rnumber,
659 (caddr_t *)&ahci_ctlp->ahcictl_ahci_addr,
662 &accattr,
663 &ahci_ctlp->ahcictl_ahci_acc_handle);
664 if (status != DDI_SUCCESS) {
665 cmn_err(CE_WARN, "!ahci%d: Cannot map register space",
666 instance);
667 goto err_out;
670 attach_state |= AHCI_ATTACH_STATE_REG_MAP;
673 * GHC.AE must be set to 1 before any other AHCI register
674 * is accessed
676 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
677 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
678 ghc_control |= AHCI_HBA_GHC_AE;
679 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
680 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
682 /* Get the AHCI version information */
683 ahci_version = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
684 (uint32_t *)AHCI_GLOBAL_VS(ahci_ctlp));
686 cmn_err(CE_NOTE, "!ahci%d: hba AHCI version = %x.%x", instance,
687 (ahci_version & 0xffff0000) >> 16,
688 ((ahci_version & 0x0000ff00) >> 4 |
689 (ahci_version & 0x000000ff)));
691 /* We don't support controllers whose versions are lower than 1.0 */
692 if (!(ahci_version & 0xffff0000)) {
693 cmn_err(CE_WARN, "ahci%d: Don't support AHCI HBA with lower "
694 "than version 1.0", instance);
695 goto err_out;
698 /* Get the HBA capabilities information */
699 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
700 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
702 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
703 cap_status);
705 /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
706 if (ahci_version >= 0x00010200) {
707 uint32_t cap2_status;
709 /* Get the HBA capabilities extended information */
710 cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
711 (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
713 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
714 "hba capabilities extended = 0x%x", cap2_status);
717 #if AHCI_DEBUG
718 /* Get the interface speed supported by the HBA */
719 speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
720 if (speed == 0x01) {
721 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
722 "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
723 } else if (speed == 0x10) {
724 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
725 "hba interface speed support: Gen 2 (3 Gbps)", NULL);
726 } else if (speed == 0x11) {
727 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
728 "hba interface speed support: Gen 3 (6 Gbps)", NULL);
730 #endif
732 /* Get the number of command slots supported by the HBA */
733 ahci_ctlp->ahcictl_num_cmd_slots =
734 ((cap_status & AHCI_HBA_CAP_NCS) >>
735 AHCI_HBA_CAP_NCS_SHIFT) + 1;
737 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of cmd slots: %d",
738 ahci_ctlp->ahcictl_num_cmd_slots);
740 /* Get the bit map which indicates ports implemented by the HBA */
741 ahci_ctlp->ahcictl_ports_implemented =
742 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
743 (uint32_t *)AHCI_GLOBAL_PI(ahci_ctlp));
745 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba implementation of ports: 0x%x",
746 ahci_ctlp->ahcictl_ports_implemented);
748 /* Max port number implemented */
749 ahci_ctlp->ahcictl_num_ports =
750 ddi_fls(ahci_ctlp->ahcictl_ports_implemented);
752 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba number of ports: %d",
753 (cap_status & AHCI_HBA_CAP_NP) + 1);
755 /* Get the number of implemented ports by the HBA */
756 ahci_ctlp->ahcictl_num_implemented_ports =
757 ahci_get_num_implemented_ports(
758 ahci_ctlp->ahcictl_ports_implemented);
760 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
761 "hba number of implemented ports: %d",
762 ahci_ctlp->ahcictl_num_implemented_ports);
764 /* Check whether HBA supports 64bit DMA addressing */
765 if (!(cap_status & AHCI_HBA_CAP_S64A)) {
766 ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
767 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
768 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
769 "hba does not support 64-bit addressing", NULL);
772 /* Checking for the support of Port Multiplier */
773 if (cap_status & AHCI_HBA_CAP_SPM) {
774 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_CBSS;
775 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
776 "hba supports port multiplier (CBSS)", NULL);
778 /* Support FIS-based switching ? */
779 if (cap_status & AHCI_HBA_CAP_FBSS) {
780 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PMULT_FBSS;
781 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
782 "hba supports FIS-based switching (FBSS)", NULL);
786 /* Checking for Support Command List Override */
787 if (cap_status & AHCI_HBA_CAP_SCLO) {
788 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SCLO;
789 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
790 "hba supports command list override.", NULL);
793 /* Checking for Asynchronous Notification */
794 if (cap_status & AHCI_HBA_CAP_SSNTF) {
795 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SNTF;
796 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
797 "hba supports asynchronous notification.", NULL);
800 if (pci_config_setup(dip, &ahci_ctlp->ahcictl_pci_conf_handle)
801 != DDI_SUCCESS) {
802 cmn_err(CE_WARN, "!ahci%d: Cannot set up pci configure space",
803 instance);
804 goto err_out;
807 attach_state |= AHCI_ATTACH_STATE_PCICFG_SETUP;
810 * Check the pci configuration space, and set caps. We also
811 * handle the hardware defect in this function.
813 * For example, force ATI SB600 to use 32-bit dma addressing
814 * since it doesn't support 64-bit dma though its CAP register
815 * declares it support.
817 if (ahci_config_space_init(ahci_ctlp) == AHCI_FAILURE) {
818 cmn_err(CE_WARN, "!ahci%d: ahci_config_space_init failed",
819 instance);
820 goto err_out;
824 * Disable the whole controller interrupts before adding
825 * interrupt handlers(s).
827 ahci_disable_all_intrs(ahci_ctlp);
829 /* Get supported interrupt types */
830 if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
831 cmn_err(CE_WARN, "!ahci%d: ddi_intr_get_supported_types failed",
832 instance);
833 goto err_out;
836 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
837 "ddi_intr_get_supported_types() returned: 0x%x",
838 intr_types);
840 if (ahci_msi_enabled && (intr_types & DDI_INTR_TYPE_MSI)) {
842 * Try MSI first, but fall back to FIXED if failed
844 if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_MSI) ==
845 DDI_SUCCESS) {
846 ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_MSI;
847 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
848 "Using MSI interrupt type", NULL);
849 goto intr_done;
852 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
853 "MSI registration failed, "
854 "trying FIXED interrupts", NULL);
857 if (intr_types & DDI_INTR_TYPE_FIXED) {
858 if (ahci_add_intrs(ahci_ctlp, DDI_INTR_TYPE_FIXED) ==
859 DDI_SUCCESS) {
860 ahci_ctlp->ahcictl_intr_type = DDI_INTR_TYPE_FIXED;
861 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
862 "Using FIXED interrupt type", NULL);
863 goto intr_done;
866 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
867 "FIXED interrupt registration failed", NULL);
870 cmn_err(CE_WARN, "!ahci%d: Interrupt registration failed", instance);
872 goto err_out;
874 intr_done:
876 attach_state |= AHCI_ATTACH_STATE_INTR_ADDED;
878 /* Initialize the controller mutex */
879 mutex_init(&ahci_ctlp->ahcictl_mutex, NULL, MUTEX_DRIVER,
880 (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
882 attach_state |= AHCI_ATTACH_STATE_MUTEX_INIT;
884 if (ahci_dma_prdt_number < AHCI_MIN_PRDT_NUMBER) {
885 ahci_dma_prdt_number = AHCI_MIN_PRDT_NUMBER;
886 } else if (ahci_dma_prdt_number > AHCI_MAX_PRDT_NUMBER) {
887 ahci_dma_prdt_number = AHCI_MAX_PRDT_NUMBER;
890 ahci_cmd_table_size = (sizeof (ahci_cmd_table_t) +
891 (ahci_dma_prdt_number - AHCI_PRDT_NUMBER) *
892 sizeof (ahci_prdt_item_t));
894 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
895 "ahci_attach: ahci_dma_prdt_number set by user is 0x%x,"
896 " ahci_cmd_table_size is 0x%x",
897 ahci_dma_prdt_number, ahci_cmd_table_size);
899 if (ahci_dma_prdt_number != AHCI_PRDT_NUMBER)
900 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_sgllen =
901 ahci_dma_prdt_number;
903 ahci_ctlp->ahcictl_buffer_dma_attr = buffer_dma_attr;
904 ahci_ctlp->ahcictl_rcvd_fis_dma_attr = rcvd_fis_dma_attr;
905 ahci_ctlp->ahcictl_cmd_list_dma_attr = cmd_list_dma_attr;
906 ahci_ctlp->ahcictl_cmd_table_dma_attr = cmd_table_dma_attr;
909 * enable 64bit dma for data buffer for SB600 if
910 * sb600_buf_64bit_dma_disable is B_FALSE
912 if ((ahci_buf_64bit_dma == B_FALSE) ||
913 ((ahci_ctlp->ahcictl_cap & AHCI_CAP_BUF_32BIT_DMA) &&
914 !(sb600_buf_64bit_dma_disable == B_FALSE &&
915 ahci_ctlp->ahcictl_venid == 0x1002 &&
916 ahci_ctlp->ahcictl_devid == 0x4380))) {
917 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_addr_hi =
918 0xffffffffull;
922 * enable 64bit dma for command buffer for SB600/700/710/800
923 * if sbxxx_commu_64bit_dma_disable is B_FALSE
925 if ((ahci_commu_64bit_dma == B_FALSE) ||
926 ((ahci_ctlp->ahcictl_cap & AHCI_CAP_COMMU_32BIT_DMA) &&
927 !(sbxxx_commu_64bit_dma_disable == B_FALSE &&
928 ahci_ctlp->ahcictl_venid == 0x1002 &&
929 (ahci_ctlp->ahcictl_devid == 0x4380 ||
930 ahci_ctlp->ahcictl_devid == 0x4391)))) {
931 ahci_ctlp->ahcictl_rcvd_fis_dma_attr.dma_attr_addr_hi =
932 0xffffffffull;
933 ahci_ctlp->ahcictl_cmd_list_dma_attr.dma_attr_addr_hi =
934 0xffffffffull;
935 ahci_ctlp->ahcictl_cmd_table_dma_attr.dma_attr_addr_hi =
936 0xffffffffull;
939 /* Allocate the ports structure */
940 status = ahci_alloc_ports_state(ahci_ctlp);
941 if (status != AHCI_SUCCESS) {
942 cmn_err(CE_WARN, "!ahci%d: Cannot allocate ports structure",
943 instance);
944 goto err_out;
947 attach_state |= AHCI_ATTACH_STATE_PORT_ALLOC;
950 * Initialize the controller and ports.
952 status = ahci_initialize_controller(ahci_ctlp);
953 if (status != AHCI_SUCCESS) {
954 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
955 instance);
956 goto err_out;
959 attach_state |= AHCI_ATTACH_STATE_HW_INIT;
961 /* Start one thread to check packet timeouts */
962 ahci_ctlp->ahcictl_timeout_id = timeout(
963 (void (*)(void *))ahci_watchdog_handler,
964 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
966 attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
968 if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
969 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
970 instance);
971 goto err_out;
974 /* Check all handles at the end of the attach operation. */
975 if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
976 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
977 instance);
978 goto err_out;
981 ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
983 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
985 return (DDI_SUCCESS);
987 err_out:
988 /* FMA message */
989 ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
990 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
992 if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
993 mutex_enter(&ahci_ctlp->ahcictl_mutex);
994 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
995 ahci_ctlp->ahcictl_timeout_id = 0;
996 mutex_exit(&ahci_ctlp->ahcictl_mutex);
999 if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1000 ahci_uninitialize_controller(ahci_ctlp);
1003 if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1004 ahci_dealloc_ports_state(ahci_ctlp);
1007 if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1008 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1011 if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {
1012 ahci_rem_intrs(ahci_ctlp);
1015 if (attach_state & AHCI_ATTACH_STATE_PCICFG_SETUP) {
1016 pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1019 if (attach_state & AHCI_ATTACH_STATE_REG_MAP) {
1020 ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1023 if (attach_state & AHCI_ATTACH_STATE_FMA) {
1024 ahci_fm_fini(ahci_ctlp);
1027 if (attach_state & AHCI_ATTACH_STATE_STATEP_ALLOC) {
1028 ddi_soft_state_free(ahci_statep, instance);
1031 return (DDI_FAILURE);
1035 * The detach entry point for dev_ops.
1037 static int
1038 ahci_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1040 ahci_ctl_t *ahci_ctlp;
1041 int instance;
1042 int ret;
1044 instance = ddi_get_instance(dip);
1045 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1047 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1049 switch (cmd) {
1050 case DDI_DETACH:
1052 /* disable the interrupts for an uninterrupted detach */
1053 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1054 ahci_disable_all_intrs(ahci_ctlp);
1055 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1057 /* unregister from the sata framework. */
1058 ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1059 if (ret != AHCI_SUCCESS) {
1060 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1061 ahci_enable_all_intrs(ahci_ctlp);
1062 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1063 return (DDI_FAILURE);
1066 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1068 /* stop the watchdog handler */
1069 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1070 ahci_ctlp->ahcictl_timeout_id = 0;
1072 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1074 /* uninitialize the controller */
1075 ahci_uninitialize_controller(ahci_ctlp);
1077 /* remove the interrupts */
1078 ahci_rem_intrs(ahci_ctlp);
1080 /* deallocate the ports structures */
1081 ahci_dealloc_ports_state(ahci_ctlp);
1083 /* destroy mutex */
1084 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1086 /* teardown the pci config */
1087 pci_config_teardown(&ahci_ctlp->ahcictl_pci_conf_handle);
1089 /* remove the reg maps. */
1090 ddi_regs_map_free(&ahci_ctlp->ahcictl_ahci_acc_handle);
1092 /* release fma resource */
1093 ahci_fm_fini(ahci_ctlp);
1095 /* free the soft state. */
1096 ddi_soft_state_free(ahci_statep, instance);
1098 return (DDI_SUCCESS);
1100 case DDI_SUSPEND:
1103 * The steps associated with suspension must include putting
1104 * the underlying device into a quiescent state so that it
1105 * will not generate interrupts or modify or access memory.
1107 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1108 if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1109 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1110 return (DDI_SUCCESS);
1113 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1115 /* stop the watchdog handler */
1116 if (ahci_ctlp->ahcictl_timeout_id) {
1117 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1118 ahci_ctlp->ahcictl_timeout_id = 0;
1121 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1124 * drain the taskq
1126 ahci_drain_ports_taskq(ahci_ctlp);
1129 * Disable the interrupts and stop all the ports.
1131 ahci_uninitialize_controller(ahci_ctlp);
1133 return (DDI_SUCCESS);
1135 default:
1136 return (DDI_FAILURE);
1141 * The info entry point for dev_ops.
1144 static int
1145 ahci_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
1147 _NOTE(ARGUNUSED(dip))
1149 ahci_ctl_t *ahci_ctlp;
1150 int instance;
1151 dev_t dev;
1153 dev = (dev_t)arg;
1154 instance = getminor(dev);
1156 switch (infocmd) {
1157 case DDI_INFO_DEVT2DEVINFO:
1158 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
1159 if (ahci_ctlp != NULL) {
1160 *result = ahci_ctlp->ahcictl_dip;
1161 return (DDI_SUCCESS);
1162 } else {
1163 *result = NULL;
1164 return (DDI_FAILURE);
1166 case DDI_INFO_DEVT2INSTANCE:
1167 *(int *)result = instance;
1168 break;
1169 default:
1170 break;
1173 return (DDI_SUCCESS);
1177 * Registers the ahci with sata framework.
1179 static int
1180 ahci_register_sata_hba_tran(ahci_ctl_t *ahci_ctlp, uint32_t cap_status)
1182 struct sata_hba_tran *sata_hba_tran;
1184 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
1185 "ahci_register_sata_hba_tran enter", NULL);
1187 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1189 /* Allocate memory for the sata_hba_tran */
1190 sata_hba_tran = kmem_zalloc(sizeof (sata_hba_tran_t), KM_SLEEP);
1192 sata_hba_tran->sata_tran_hba_rev = SATA_TRAN_HBA_REV;
1193 sata_hba_tran->sata_tran_hba_dip = ahci_ctlp->ahcictl_dip;
1194 sata_hba_tran->sata_tran_hba_dma_attr =
1195 &ahci_ctlp->ahcictl_buffer_dma_attr;
1197 /* Report the number of implemented ports */
1198 sata_hba_tran->sata_tran_hba_num_cports =
1199 ahci_ctlp->ahcictl_num_implemented_ports;
1201 /* Support ATAPI device */
1202 sata_hba_tran->sata_tran_hba_features_support = SATA_CTLF_ATAPI;
1204 /* Get the data transfer capability for PIO command by the HBA */
1205 if (cap_status & AHCI_HBA_CAP_PMD) {
1206 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PIO_MDRQ;
1207 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports multiple "
1208 "DRQ block data transfer for PIO command protocol", NULL);
1212 * According to the AHCI spec, the ATA/ATAPI-7 queued feature set
1213 * is not supported by AHCI (including the READ QUEUED (EXT), WRITE
1214 * QUEUED (EXT), and SERVICE commands). Queued operations are
1215 * supported in AHCI using the READ FPDMA QUEUED and WRITE FPDMA
1216 * QUEUED commands when the HBA and device support native command
1217 * queuing(NCQ).
1219 * SATA_CTLF_NCQ will be set to sata_tran_hba_features_support if the
1220 * CAP register of the HBA indicates NCQ is supported.
1222 * SATA_CTLF_NCQ cannot be set if AHCI_CAP_NO_MCMDLIST_NONQUEUE is
1223 * set because the previous register content of PxCI can be re-written
1224 * in the register write.
1226 if ((cap_status & AHCI_HBA_CAP_SNCQ) &&
1227 !(ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE)) {
1228 sata_hba_tran->sata_tran_hba_features_support |= SATA_CTLF_NCQ;
1229 ahci_ctlp->ahcictl_cap |= AHCI_CAP_NCQ;
1230 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "HBA supports Native "
1231 "Command Queuing", NULL);
1234 /* Support port multiplier? */
1235 if (cap_status & AHCI_HBA_CAP_SPM) {
1236 sata_hba_tran->sata_tran_hba_features_support |=
1237 SATA_CTLF_PORT_MULTIPLIER;
1239 /* Support FIS-based switching for port multiplier? */
1240 if (cap_status & AHCI_HBA_CAP_FBSS) {
1241 sata_hba_tran->sata_tran_hba_features_support |=
1242 SATA_CTLF_PMULT_FBS;
1246 /* Report the number of command slots */
1247 sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1249 sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1250 sata_hba_tran->sata_tran_start = ahci_tran_start;
1251 sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1252 sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1253 sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1254 #ifdef __lock_lint
1255 sata_hba_tran->sata_tran_selftest = ahci_selftest;
1256 #endif
1258 * When SATA framework adds support for pwrmgt the
1259 * pwrmgt_ops needs to be updated
1261 sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1262 sata_hba_tran->sata_tran_ioctl = NULL;
1264 ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1266 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1268 /* Attach it to SATA framework */
1269 if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1270 != DDI_SUCCESS) {
1271 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1272 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1273 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1274 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1275 return (AHCI_FAILURE);
1278 return (AHCI_SUCCESS);
1282 * Unregisters the ahci with sata framework.
1284 static int
1285 ahci_unregister_sata_hba_tran(ahci_ctl_t *ahci_ctlp)
1287 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1288 "ahci_unregister_sata_hba_tran enter", NULL);
1290 /* Detach from the SATA framework. */
1291 if (sata_hba_detach(ahci_ctlp->ahcictl_dip, DDI_DETACH) !=
1292 DDI_SUCCESS) {
1293 return (AHCI_FAILURE);
1296 /* Deallocate sata_hba_tran. */
1297 kmem_free((void *)ahci_ctlp->ahcictl_sata_hba_tran,
1298 sizeof (sata_hba_tran_t));
1300 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1301 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1302 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1304 return (AHCI_SUCCESS);
1307 #define SET_PORTSTR(str, addrp) \
1308 if (AHCI_ADDR_IS_PORT(addrp)) \
1309 (void) sprintf((str), "%d", (addrp)->aa_port); \
1310 else if (AHCI_ADDR_IS_PMULT(addrp)) \
1311 (void) sprintf((str), "%d (pmult)", (addrp)->aa_port); \
1312 else \
1313 (void) sprintf((str), "%d:%d", (addrp)->aa_port, \
1314 (addrp)->aa_pmport);
1317 * ahci_tran_probe_port is called by SATA framework. It returns port state,
1318 * port status registers and an attached device type via sata_device
1319 * structure.
1321 * We return the cached information from a previous hardware probe. The
1322 * actual hardware probing itself was done either from within
1323 * ahci_initialize_controller() during the driver attach or from a phy
1324 * ready change interrupt handler.
1326 static int
1327 ahci_tran_probe_port(dev_info_t *dip, sata_device_t *sd)
1329 ahci_ctl_t *ahci_ctlp;
1330 ahci_port_t *ahci_portp;
1331 ahci_addr_t addr, pmult_addr;
1332 uint8_t cport = sd->satadev_addr.cport;
1333 char portstr[10];
1334 uint8_t device_type;
1335 uint32_t port_state;
1336 uint8_t port;
1337 int rval = SATA_SUCCESS, rval_init;
1339 ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1340 port = ahci_ctlp->ahcictl_cport_to_port[cport];
1342 ahci_portp = ahci_ctlp->ahcictl_ports[port];
1344 mutex_enter(&ahci_portp->ahciport_mutex);
1346 ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
1347 ASSERT(AHCI_ADDR_IS_VALID(&addr));
1348 SET_PORTSTR(portstr, &addr);
1350 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1351 "ahci_tran_probe_port enter: port %s", portstr);
1353 if ((AHCI_ADDR_IS_PMULT(&addr) || AHCI_ADDR_IS_PMPORT(&addr)) &&
1354 (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1355 ahci_portp->ahciport_pmult_info == NULL)) {
1356 /* port mutliplier is removed. */
1357 AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1358 "ahci_tran_probe_port: "
1359 "pmult is removed from port %s", portstr);
1360 mutex_exit(&ahci_portp->ahciport_mutex);
1361 return (SATA_FAILURE);
1365 * The sata_device may refer to
1366 * 1. A controller port.
1367 * A controller port should be ready here.
1368 * 2. A port multiplier.
1369 * SATA_ADDR_PMULT_SPEC - if it is not initialized yet, initialize
1370 * it and register the port multiplier to the framework.
1371 * SATA_ADDR_PMULT - check the status of all its device ports.
1372 * 3. A port multiplier port.
1373 * If it has not been initialized, initialized it.
1375 * A port multiplier or a port multiplier port may require some
1376 * initialization because we cannot do these time-consuming jobs in an
1377 * interrupt context.
1379 if (sd->satadev_addr.qual & SATA_ADDR_PMULT_SPEC) {
1380 AHCI_ADDR_SET_PMULT(&pmult_addr, port);
1381 /* Initialize registers on a port multiplier */
1382 rval_init = ahci_initialize_pmult(ahci_ctlp,
1383 ahci_portp, &pmult_addr, sd);
1384 if (rval_init != AHCI_SUCCESS) {
1385 AHCIDBG(AHCIDBG_PMULT, ahci_ctlp,
1386 "ahci_tran_probe_port: "
1387 "pmult initialization failed.", NULL);
1388 mutex_exit(&ahci_portp->ahciport_mutex);
1389 return (SATA_FAILURE);
1391 } else if (sd->satadev_addr.qual & SATA_ADDR_PMULT) {
1392 /* Check pmports hotplug events */
1393 (void) ahci_probe_pmult(ahci_ctlp, ahci_portp, &addr);
1394 } else if (sd->satadev_addr.qual & (SATA_ADDR_PMPORT |
1395 SATA_ADDR_DPMPORT)) {
1396 if (ahci_probe_pmport(ahci_ctlp, ahci_portp,
1397 &addr, sd) != AHCI_SUCCESS) {
1398 rval = SATA_FAILURE;
1399 goto out;
1403 /* Update port state and device type */
1404 port_state = AHCIPORT_GET_STATE(ahci_portp, &addr);
1406 switch (port_state) {
1408 case SATA_PSTATE_FAILED:
1409 sd->satadev_state = SATA_PSTATE_FAILED;
1410 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1411 "ahci_tran_probe_port: port %s PORT FAILED", portstr);
1412 goto out;
1414 case SATA_PSTATE_SHUTDOWN:
1415 sd->satadev_state = SATA_PSTATE_SHUTDOWN;
1416 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1417 "ahci_tran_probe_port: port %s PORT SHUTDOWN", portstr);
1418 goto out;
1420 case SATA_PSTATE_PWROFF:
1421 sd->satadev_state = SATA_PSTATE_PWROFF;
1422 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1423 "ahci_tran_probe_port: port %s PORT PWROFF", portstr);
1424 goto out;
1426 case SATA_PSTATE_PWRON:
1427 sd->satadev_state = SATA_PSTATE_PWRON;
1428 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1429 "ahci_tran_probe_port: port %s PORT PWRON", portstr);
1430 break;
1432 default:
1433 sd->satadev_state = port_state;
1434 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1435 "ahci_tran_probe_port: port %s PORT NORMAL %x",
1436 portstr, port_state);
1437 break;
1440 device_type = AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1442 switch (device_type) {
1444 case SATA_DTYPE_ATADISK:
1445 sd->satadev_type = SATA_DTYPE_ATADISK;
1446 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1447 "ahci_tran_probe_port: port %s DISK found", portstr);
1448 break;
1450 case SATA_DTYPE_ATAPI:
1452 * HBA driver only knows it's an ATAPI device, and don't know
1453 * it's CD/DVD, tape or ATAPI disk because the ATAPI device
1454 * type need to be determined by checking IDENTIFY PACKET
1455 * DEVICE data
1457 sd->satadev_type = SATA_DTYPE_ATAPI;
1458 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1459 "ahci_tran_probe_port: port %s ATAPI found", portstr);
1460 break;
1462 case SATA_DTYPE_PMULT:
1463 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr));
1464 sd->satadev_type = SATA_DTYPE_PMULT;
1466 /* Update the number of pmports. */
1467 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
1468 sd->satadev_add_info = ahci_portp->
1469 ahciport_pmult_info->ahcipmi_num_dev_ports;
1471 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1472 "ahci_tran_probe_port: port %s Port Multiplier found",
1473 portstr);
1474 break;
1476 case SATA_DTYPE_UNKNOWN:
1477 sd->satadev_type = SATA_DTYPE_UNKNOWN;
1478 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1479 "ahci_tran_probe_port: port %s Unknown device found",
1480 portstr);
1481 break;
1483 default:
1484 /* we don't support any other device types */
1485 sd->satadev_type = SATA_DTYPE_NONE;
1486 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1487 "ahci_tran_probe_port: port %s No device found", portstr);
1488 break;
1491 out:
1492 /* Register update only fails while probing a pmult/pmport */
1493 if (AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMULT(&addr)) {
1494 ahci_update_sata_registers(ahci_ctlp, port, sd);
1495 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
1496 if (port_state & SATA_STATE_READY)
1497 if (ahci_update_pmult_pscr(ahci_ctlp,
1498 &addr, sd) != AHCI_SUCCESS)
1499 rval = SATA_FAILURE;
1502 /* Check handles for the sata registers access */
1503 if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
1504 (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
1505 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1506 DDI_SERVICE_UNAFFECTED);
1507 rval = SATA_FAILURE;
1510 mutex_exit(&ahci_portp->ahciport_mutex);
1511 return (rval);
1515 * There are four operation modes in sata framework:
1516 * SATA_OPMODE_INTERRUPTS
1517 * SATA_OPMODE_POLLING
1518 * SATA_OPMODE_ASYNCH
1519 * SATA_OPMODE_SYNCH
1521 * Their combined meanings as following:
1523 * SATA_OPMODE_SYNCH
1524 * The command has to be completed before sata_tran_start functions returns.
1525 * Either interrupts or polling could be used - it's up to the driver.
1526 * Mode used currently for internal, sata-module initiated operations.
1528 * SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS
1529 * It is the same as the one above.
1531 * SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING
1532 * The command has to be completed before sata_tran_start function returns.
1533 * No interrupt used, polling only. This should be the mode used for scsi
1534 * packets with FLAG_NOINTR.
1536 * SATA_OPMODE_ASYNCH | SATA_OPMODE_INTERRUPTS
1537 * The command may be queued (callback function specified). Interrupts could
1538 * be used. It's normal operation mode.
1541 * Called by sata framework to transport a sata packet down stream.
1543 static int
1544 ahci_tran_start(dev_info_t *dip, sata_pkt_t *spkt)
1546 ahci_ctl_t *ahci_ctlp;
1547 ahci_port_t *ahci_portp;
1548 ahci_addr_t addr;
1549 uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
1550 uint8_t port;
1551 char portstr[10];
1553 ahci_ctlp = ddi_get_soft_state(ahci_statep, ddi_get_instance(dip));
1554 port = ahci_ctlp->ahcictl_cport_to_port[cport];
1556 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
1557 "ahci_tran_start enter: cport %d satapkt 0x%p",
1558 cport, (void *)spkt);
1560 ahci_portp = ahci_ctlp->ahcictl_ports[port];
1562 mutex_enter(&ahci_portp->ahciport_mutex);
1563 ahci_get_ahci_addr(ahci_ctlp, &spkt->satapkt_device, &addr);
1564 SET_PORTSTR(portstr, &addr);
1566 /* Sanity check */
1567 if (AHCI_ADDR_IS_PMPORT(&addr)) {
1568 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT ||
1569 ahci_portp->ahciport_pmult_info == NULL) {
1571 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1572 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1573 spkt->satapkt_device.satadev_state = SATA_STATE_UNKNOWN;
1574 ahci_update_sata_registers(ahci_ctlp, port,
1575 &spkt->satapkt_device);
1576 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1577 "ahci_tran_start returning PORT_ERROR while "
1578 "pmult removed: port: %s", portstr);
1579 mutex_exit(&ahci_portp->ahciport_mutex);
1580 return (SATA_TRAN_PORT_ERROR);
1583 if (!(AHCIPORT_GET_STATE(ahci_portp, &addr) &
1584 SATA_STATE_READY)) {
1585 if (!ddi_in_panic() ||
1586 ahci_initialize_pmport(ahci_ctlp,
1587 ahci_portp, &addr) != AHCI_SUCCESS) {
1588 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1589 spkt->satapkt_device.satadev_type =
1590 AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1591 spkt->satapkt_device.satadev_state =
1592 AHCIPORT_GET_STATE(ahci_portp, &addr);
1593 ahci_update_sata_registers(ahci_ctlp, port,
1594 &spkt->satapkt_device);
1595 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1596 "ahci_tran_start returning PORT_ERROR "
1597 "while sub-link is not initialized "
1598 "at port: %s", portstr);
1599 mutex_exit(&ahci_portp->ahciport_mutex);
1600 return (SATA_TRAN_PORT_ERROR);
1605 if (AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_FAILED ||
1606 AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_SHUTDOWN||
1607 AHCIPORT_GET_STATE(ahci_portp, &addr) & SATA_PSTATE_PWROFF) {
1609 * In case the target driver would send the packet before
1610 * sata framework can have the opportunity to process those
1611 * event reports.
1613 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1614 spkt->satapkt_device.satadev_state =
1615 ahci_portp->ahciport_port_state;
1616 ahci_update_sata_registers(ahci_ctlp, port,
1617 &spkt->satapkt_device);
1618 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1619 "ahci_tran_start returning PORT_ERROR while "
1620 "port in FAILED/SHUTDOWN/PWROFF state: "
1621 "port: %s", portstr);
1622 mutex_exit(&ahci_portp->ahciport_mutex);
1623 return (SATA_TRAN_PORT_ERROR);
1626 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) == SATA_DTYPE_NONE) {
1628 * ahci_intr_phyrdy_change() may have rendered it to
1629 * SATA_DTYPE_NONE.
1631 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
1632 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
1633 spkt->satapkt_device.satadev_state =
1634 ahci_portp->ahciport_port_state;
1635 ahci_update_sata_registers(ahci_ctlp, port,
1636 &spkt->satapkt_device);
1637 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1638 "ahci_tran_start returning PORT_ERROR while "
1639 "no device attached: port: %s", portstr);
1640 mutex_exit(&ahci_portp->ahciport_mutex);
1641 return (SATA_TRAN_PORT_ERROR);
1644 /* R/W PMULT command will occupy the whole HBA port */
1645 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
1646 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1647 "ahci_tran_start returning BUSY while "
1648 "executing READ/WRITE PORT-MULT command: "
1649 "port: %s", portstr);
1650 spkt->satapkt_reason = SATA_PKT_BUSY;
1651 mutex_exit(&ahci_portp->ahciport_mutex);
1652 return (SATA_TRAN_BUSY);
1655 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
1656 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1657 "ahci_tran_start returning BUSY while "
1658 "hot-plug in progress: port: %s", portstr);
1659 spkt->satapkt_reason = SATA_PKT_BUSY;
1660 mutex_exit(&ahci_portp->ahciport_mutex);
1661 return (SATA_TRAN_BUSY);
1665 * SATA HBA driver should remember that a device was reset and it
1666 * is supposed to reject any packets which do not specify either
1667 * SATA_IGNORE_DEV_RESET_STATE or SATA_CLEAR_DEV_RESET_STATE.
1669 * This is to prevent a race condition when a device was arbitrarily
1670 * reset by the HBA driver (and lost it's setting) and a target
1671 * driver sending some commands to a device before the sata framework
1672 * has a chance to restore the device setting (such as cache enable/
1673 * disable or other resettable stuff).
1676 * It is unnecessary to use specific flags to indicate
1677 * reset_in_progress for a pmport. While mopping, all command will be
1678 * mopped so that the entire HBA port is being dealt as a single
1679 * object.
1681 if (spkt->satapkt_cmd.satacmd_flags.sata_clear_dev_reset) {
1682 ahci_portp->ahciport_reset_in_progress = 0;
1683 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1684 "ahci_tran_start [CLEAR] the "
1685 "reset_in_progress for port: %d", port);
1688 if (ahci_portp->ahciport_reset_in_progress &&
1689 ! spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset &&
1690 ! ddi_in_panic()) {
1691 spkt->satapkt_reason = SATA_PKT_BUSY;
1692 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1693 "ahci_tran_start returning BUSY while "
1694 "reset in progress: port: %d", port);
1695 mutex_exit(&ahci_portp->ahciport_mutex);
1696 return (SATA_TRAN_BUSY);
1699 #ifdef AHCI_DEBUG
1700 if (spkt->satapkt_cmd.satacmd_flags.sata_ignore_dev_reset) {
1701 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1702 "ahci_tran_start: packet 0x%p [PASSTHRU] at port %d",
1703 spkt, port);
1705 #endif
1707 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
1708 spkt->satapkt_reason = SATA_PKT_BUSY;
1709 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1710 "ahci_tran_start returning BUSY while "
1711 "mopping in progress: port: %d", port);
1712 mutex_exit(&ahci_portp->ahciport_mutex);
1713 return (SATA_TRAN_BUSY);
1716 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
1717 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
1718 DDI_SERVICE_UNAFFECTED);
1719 mutex_exit(&ahci_portp->ahciport_mutex);
1720 return (SATA_TRAN_BUSY);
1723 if (spkt->satapkt_op_mode &
1724 (SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING)) {
1726 * If a SYNC command to be executed in interrupt context,
1727 * bounce it back to sata module.
1729 if (!(spkt->satapkt_op_mode & SATA_OPMODE_POLLING) &&
1730 servicing_interrupt()) {
1731 spkt->satapkt_reason = SATA_PKT_BUSY;
1732 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1733 "ahci_tran_start returning BUSY while "
1734 "sending SYNC mode under interrupt context: "
1735 "port : %d", port);
1736 mutex_exit(&ahci_portp->ahciport_mutex);
1737 return (SATA_TRAN_BUSY);
1740 /* We need to do the sync start now */
1741 if (ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr,
1742 spkt) == AHCI_FAILURE) {
1743 goto fail_out;
1745 } else {
1746 /* Async start, using interrupt */
1747 if (ahci_deliver_satapkt(ahci_ctlp, ahci_portp, &addr, spkt)
1748 == AHCI_FAILURE) {
1749 spkt->satapkt_reason = SATA_PKT_QUEUE_FULL;
1750 goto fail_out;
1754 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_tran_start "
1755 "sata tran accepted: port %s", portstr);
1757 mutex_exit(&ahci_portp->ahciport_mutex);
1758 return (SATA_TRAN_ACCEPTED);
1760 fail_out:
1762 * Failed to deliver packet to the controller.
1763 * Check if it's caused by invalid handles.
1765 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS ||
1766 ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
1767 spkt->satapkt_device.satadev_type =
1768 AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr);
1769 spkt->satapkt_device.satadev_state =
1770 AHCIPORT_GET_STATE(ahci_portp, &addr);
1771 spkt->satapkt_reason = SATA_PKT_DEV_ERROR;
1772 mutex_exit(&ahci_portp->ahciport_mutex);
1773 return (SATA_TRAN_PORT_ERROR);
1776 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_tran_start "
1777 "return QUEUE_FULL: port %d", port);
1778 mutex_exit(&ahci_portp->ahciport_mutex);
1779 return (SATA_TRAN_QUEUE_FULL);
1783 * SATA_OPMODE_SYNCH flag is set
1785 * If SATA_OPMODE_POLLING flag is set, then we must poll the command
1786 * without interrupt, otherwise we can still use the interrupt.
1788 static int
1789 ahci_do_sync_start(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1790 ahci_addr_t *addrp, sata_pkt_t *spkt)
1792 int pkt_timeout_ticks;
1793 uint32_t timeout_tags;
1794 int rval;
1795 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1796 uint8_t port = addrp->aa_port;
1798 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1800 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1801 "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1803 if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1804 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1805 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1806 addrp, spkt)) == AHCI_FAILURE) {
1807 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1808 return (rval);
1811 pkt_timeout_ticks =
1812 drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1814 while (spkt->satapkt_reason == SATA_PKT_BUSY) {
1815 /* Simulate the interrupt */
1816 mutex_exit(&ahci_portp->ahciport_mutex);
1817 ahci_port_intr(ahci_ctlp, ahci_portp, port);
1818 mutex_enter(&ahci_portp->ahciport_mutex);
1820 if (spkt->satapkt_reason != SATA_PKT_BUSY)
1821 break;
1823 mutex_exit(&ahci_portp->ahciport_mutex);
1824 drv_usecwait(AHCI_1MS_USECS);
1825 mutex_enter(&ahci_portp->ahciport_mutex);
1827 pkt_timeout_ticks -= AHCI_1MS_TICKS;
1828 if (pkt_timeout_ticks < 0) {
1829 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1830 "port %d satapkt 0x%p timed out\n",
1831 instance, port, (void *)spkt);
1832 timeout_tags = (0x1 << rval);
1833 mutex_exit(&ahci_portp->ahciport_mutex);
1834 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1835 port, timeout_tags);
1836 mutex_enter(&ahci_portp->ahciport_mutex);
1840 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1841 return (AHCI_SUCCESS);
1843 } else {
1844 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1845 addrp, spkt)) == AHCI_FAILURE)
1846 return (rval);
1848 #if AHCI_DEBUG
1850 * Note that the driver always uses the slot 0 to deliver
1851 * REQUEST SENSE or READ LOG EXT command
1853 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1854 ASSERT(rval == 0);
1855 #endif
1857 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1858 cv_wait(&ahci_portp->ahciport_cv,
1859 &ahci_portp->ahciport_mutex);
1861 return (AHCI_SUCCESS);
1866 * Searches for and claims a free command slot.
1868 * Returns value:
1870 * AHCI_FAILURE returned only if
1871 * 1. No empty slot left
1872 * 2. Non-queued command requested while queued command(s) is outstanding
1873 * 3. Queued command requested while non-queued command(s) is outstanding
1874 * 4. HBA doesn't support multiple-use of command list while already a
1875 * non-queued command is oustanding
1876 * 5. Queued command requested while some queued command(s) has been
1877 * outstanding on a different port multiplier port. (AHCI spec 1.2,
1878 * 9.1.2)
1880 * claimed slot number returned if succeeded
1882 * NOTE: it will always return slot 0 for following commands to simplify the
1883 * algorithm.
1884 * 1. REQUEST SENSE or READ LOG EXT command during error recovery process
1885 * 2. READ/WRITE PORTMULT command
1887 static int
1888 ahci_claim_free_slot(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
1889 ahci_addr_t *addrp, int command_type)
1891 uint32_t port_cmd_issue;
1892 uint32_t free_slots;
1893 int slot;
1895 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1897 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_claim_free_slot enter "
1898 "ahciport_pending_tags = 0x%x "
1899 "ahciport_pending_ncq_tags = 0x%x",
1900 ahci_portp->ahciport_pending_tags,
1901 ahci_portp->ahciport_pending_ncq_tags);
1904 * According to the AHCI spec, system software is responsible to
1905 * ensure that queued and non-queued commands are not mixed in
1906 * the command list.
1908 if (command_type == AHCI_NON_NCQ_CMD) {
1909 /* Non-NCQ command request */
1910 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
1911 AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
1912 "ahci_claim_free_slot: there is still pending "
1913 "queued command(s) in the command list, "
1914 "so no available slot for the non-queued "
1915 "command", NULL);
1916 return (AHCI_FAILURE);
1918 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
1919 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
1920 "ahci_claim_free_slot: there is still pending "
1921 "read/write port-mult command(s) in command list, "
1922 "so no available slot for the non-queued command",
1923 NULL);
1924 return (AHCI_FAILURE);
1926 if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_NO_MCMDLIST_NONQUEUE) &&
1927 NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
1928 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1929 "ahci_claim_free_slot: HBA cannot support multiple-"
1930 "use of the command list for non-queued commands",
1931 NULL);
1932 return (AHCI_FAILURE);
1934 free_slots = (~ahci_portp->ahciport_pending_tags) &
1935 AHCI_SLOT_MASK(ahci_ctlp);
1936 } else if (command_type == AHCI_NCQ_CMD) {
1937 /* NCQ command request */
1938 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
1939 AHCIDBG(AHCIDBG_INFO|AHCIDBG_NCQ, ahci_ctlp,
1940 "ahci_claim_free_slot: there is still pending "
1941 "non-queued command(s) in the command list, "
1942 "so no available slot for the queued command",
1943 NULL);
1944 return (AHCI_FAILURE);
1948 * NCQ commands cannot be sent to different port multiplier
1949 * ports in Command-Based Switching mode
1952 * NOTE: In Command-Based Switching mode, AHCI controller
1953 * usually reports a 'Handshake Error' when multiple NCQ
1954 * commands are outstanding simultaneously.
1956 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
1957 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
1958 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS) &&
1959 NCQ_CMD_IN_PROGRESS(ahci_portp) &&
1960 AHCIPORT_NCQ_PMPORT(ahci_portp) !=
1961 addrp->aa_pmport) {
1962 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
1963 "ahci_claim_free_slot: there is still "
1964 "pending queued command(s) in the "
1965 "command list for another Port Multiplier "
1966 "port, so no available slot.", NULL);
1967 return (AHCI_FAILURE);
1971 free_slots = (~ahci_portp->ahciport_pending_ncq_tags) &
1972 AHCI_NCQ_SLOT_MASK(ahci_portp);
1973 } else if (command_type == AHCI_ERR_RETRI_CMD) {
1974 /* Error retrieval command request */
1975 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
1976 "ahci_claim_free_slot: slot 0 is allocated for REQUEST "
1977 "SENSE or READ LOG EXT command", NULL);
1978 slot = 0;
1979 goto out;
1980 } else if (command_type == AHCI_RDWR_PMULT_CMD) {
1982 * An extra check on PxCI. Sometimes PxCI bits may not be
1983 * cleared during hot-plug or error recovery process.
1985 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
1986 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, addrp->aa_port));
1988 if (port_cmd_issue != 0) {
1989 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
1990 "ahci_claim_free_slot: there is still pending "
1991 "command(s) in command list (0x%x/0x%x, PxCI %x),"
1992 "so no available slot for R/W PMULT command.",
1993 NON_NCQ_CMD_IN_PROGRESS(ahci_portp),
1994 NCQ_CMD_IN_PROGRESS(ahci_portp),
1995 port_cmd_issue);
1996 return (AHCI_FAILURE);
1999 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2000 "ahci_claim_free_slot: slot 0 is allocated for "
2001 "READ/WRITE PORTMULT command", NULL);
2002 slot = 0;
2003 goto out;
2006 slot = ddi_ffs(free_slots) - 1;
2007 if (slot == -1) {
2008 AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2009 "ahci_claim_free_slot: no empty slots", NULL);
2010 return (AHCI_FAILURE);
2014 * According to the AHCI spec, to allow a simple mechanism for the
2015 * HBA to map command list slots to queue entries, software must
2016 * match the tag number it uses to the slot it is placing the command
2017 * in. For example, if a queued command is placed in slot 5, the tag
2018 * for that command must be 5.
2020 if (command_type == AHCI_NCQ_CMD) {
2021 ahci_portp->ahciport_pending_ncq_tags |= (0x1 << slot);
2022 if (AHCI_ADDR_IS_PMPORT(addrp)) {
2023 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
2024 AHCIPORT_NCQ_PMPORT(ahci_portp) = addrp->aa_pmport;
2028 ahci_portp->ahciport_pending_tags |= (0x1 << slot);
2030 out:
2031 AHCIDBG(AHCIDBG_VERBOSE, ahci_ctlp,
2032 "ahci_claim_free_slot: found slot: 0x%x", slot);
2034 return (slot);
2038 * Builds the Command Table for the sata packet and delivers it to controller.
2040 * Returns:
2041 * slot number if we can obtain a slot successfully
2042 * otherwise, return AHCI_FAILURE
2044 static int
2045 ahci_deliver_satapkt(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
2046 ahci_addr_t *addrp, sata_pkt_t *spkt)
2048 int cmd_slot;
2049 sata_cmd_t *scmd;
2050 ahci_fis_h2d_register_t *h2d_register_fisp;
2051 ahci_cmd_table_t *cmd_table;
2052 ahci_cmd_header_t *cmd_header;
2053 int ncookies;
2054 int i;
2055 int command_type = AHCI_NON_NCQ_CMD;
2056 int ncq_qdepth;
2057 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
2058 uint8_t port, pmport;
2059 #if AHCI_DEBUG
2060 uint32_t *ptr;
2061 uint8_t *ptr2;
2062 #endif
2064 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2066 port = addrp->aa_port;
2067 pmport = addrp->aa_pmport;
2069 spkt->satapkt_reason = SATA_PKT_BUSY;
2071 scmd = &spkt->satapkt_cmd;
2073 /* Check if the command is a NCQ command */
2074 if (scmd->satacmd_cmd_reg == SATAC_READ_FPDMA_QUEUED ||
2075 scmd->satacmd_cmd_reg == SATAC_WRITE_FPDMA_QUEUED) {
2076 command_type = AHCI_NCQ_CMD;
2079 * When NCQ is support, system software must determine the
2080 * maximum tag allowed by the device and the HBA, and it
2081 * must use a value not beyond of the lower bound of the two.
2083 * Sata module is going to calculate the qdepth and send
2084 * down to HBA driver via sata_cmd.
2086 ncq_qdepth = scmd->satacmd_flags.sata_max_queue_depth + 1;
2089 * At the moment, the driver doesn't support the dynamic
2090 * setting of the maximum ncq depth, and the value can be
2091 * set either during the attach or after hot-plug insertion.
2093 if (ahci_portp->ahciport_max_ncq_tags == 0) {
2094 ahci_portp->ahciport_max_ncq_tags = ncq_qdepth;
2095 AHCIDBG(AHCIDBG_NCQ, ahci_ctlp,
2096 "ahci_deliver_satapkt: port %d the max tags for "
2097 "NCQ command is %d", port, ncq_qdepth);
2098 } else {
2099 if (ncq_qdepth != ahci_portp->ahciport_max_ncq_tags) {
2100 cmn_err(CE_WARN, "!ahci%d: ahci_deliver_satapkt"
2101 " port %d the max tag for NCQ command is "
2102 "requested to change from %d to %d, at the"
2103 " moment the driver doesn't support the "
2104 "dynamic change so it's going to "
2105 "still use the previous tag value",
2106 instance, port,
2107 ahci_portp->ahciport_max_ncq_tags,
2108 ncq_qdepth);
2113 /* Check if the command is an error retrieval command */
2114 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
2115 command_type = AHCI_ERR_RETRI_CMD;
2117 /* Check if the command is an read/write pmult command */
2118 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2119 command_type = AHCI_RDWR_PMULT_CMD;
2121 /* Check if there is an empty command slot */
2122 cmd_slot = ahci_claim_free_slot(ahci_ctlp, ahci_portp,
2123 addrp, command_type);
2124 if (cmd_slot == AHCI_FAILURE) {
2125 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "no free command slot", NULL);
2126 return (AHCI_FAILURE);
2129 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INFO, ahci_ctlp,
2130 "ahci_deliver_satapkt enter: cmd_reg: 0x%x, cmd_slot: 0x%x, "
2131 "port: %d, satapkt: 0x%p", scmd->satacmd_cmd_reg,
2132 cmd_slot, port, (void *)spkt);
2134 cmd_table = ahci_portp->ahciport_cmd_tables[cmd_slot];
2135 bzero((void *)cmd_table, ahci_cmd_table_size);
2137 /* For data transfer operations, it is the H2D Register FIS */
2138 h2d_register_fisp =
2139 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
2141 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
2144 * PMP field only make sense when target is a port multiplier or a
2145 * device behind a port multiplier. Otherwise should set it to 0.
2147 if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2148 SET_FIS_PMP(h2d_register_fisp, pmport);
2150 SET_FIS_CDMDEVCTL(h2d_register_fisp, 1);
2151 SET_FIS_COMMAND(h2d_register_fisp, scmd->satacmd_cmd_reg);
2152 SET_FIS_FEATURES(h2d_register_fisp, scmd->satacmd_features_reg);
2153 SET_FIS_SECTOR_COUNT(h2d_register_fisp, scmd->satacmd_sec_count_lsb);
2155 switch (scmd->satacmd_addr_type) {
2157 case 0:
2159 * satacmd_addr_type will be 0 for the commands below:
2160 * ATAPI command
2161 * SATAC_IDLE_IM
2162 * SATAC_STANDBY_IM
2163 * SATAC_DOWNLOAD_MICROCODE
2164 * SATAC_FLUSH_CACHE
2165 * SATAC_SET_FEATURES
2166 * SATAC_SMART
2167 * SATAC_ID_PACKET_DEVICE
2168 * SATAC_ID_DEVICE
2169 * SATAC_READ_PORTMULT
2170 * SATAC_WRITE_PORTMULT
2172 /* FALLTHRU */
2174 case ATA_ADDR_LBA:
2175 /* FALLTHRU */
2177 case ATA_ADDR_LBA28:
2178 /* LBA[7:0] */
2179 SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2181 /* LBA[15:8] */
2182 SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2184 /* LBA[23:16] */
2185 SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2187 /* LBA [27:24] (also called dev_head) */
2188 SET_FIS_DEV_HEAD(h2d_register_fisp, scmd->satacmd_device_reg);
2190 break;
2192 case ATA_ADDR_LBA48:
2193 /* LBA[7:0] */
2194 SET_FIS_SECTOR(h2d_register_fisp, scmd->satacmd_lba_low_lsb);
2196 /* LBA[15:8] */
2197 SET_FIS_CYL_LOW(h2d_register_fisp, scmd->satacmd_lba_mid_lsb);
2199 /* LBA[23:16] */
2200 SET_FIS_CYL_HI(h2d_register_fisp, scmd->satacmd_lba_high_lsb);
2202 /* LBA [31:24] */
2203 SET_FIS_SECTOR_EXP(h2d_register_fisp,
2204 scmd->satacmd_lba_low_msb);
2206 /* LBA [39:32] */
2207 SET_FIS_CYL_LOW_EXP(h2d_register_fisp,
2208 scmd->satacmd_lba_mid_msb);
2210 /* LBA [47:40] */
2211 SET_FIS_CYL_HI_EXP(h2d_register_fisp,
2212 scmd->satacmd_lba_high_msb);
2214 /* Set dev_head */
2215 SET_FIS_DEV_HEAD(h2d_register_fisp,
2216 scmd->satacmd_device_reg);
2218 /* Set the extended sector count and features */
2219 SET_FIS_SECTOR_COUNT_EXP(h2d_register_fisp,
2220 scmd->satacmd_sec_count_msb);
2221 SET_FIS_FEATURES_EXP(h2d_register_fisp,
2222 scmd->satacmd_features_reg_ext);
2223 break;
2227 * For NCQ command (READ/WRITE FPDMA QUEUED), sector count 7:0 is
2228 * filled into features field, and sector count 8:15 is filled into
2229 * features (exp) field. The hba driver doesn't need to anything
2230 * special with regard to this, since sata framework has already
2231 * done so.
2233 * However the driver needs to make sure TAG is filled into sector
2234 * field.
2236 if (command_type == AHCI_NCQ_CMD) {
2237 SET_FIS_SECTOR_COUNT(h2d_register_fisp,
2238 (cmd_slot << SATA_TAG_QUEUING_SHIFT));
2241 ncookies = scmd->satacmd_num_dma_cookies;
2242 AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2243 "ncookies = 0x%x, ahci_dma_prdt_number = 0x%x",
2244 ncookies, ahci_dma_prdt_number);
2246 ASSERT(ncookies <= ahci_dma_prdt_number);
2247 ahci_portp->ahciport_prd_bytecounts[cmd_slot] = 0;
2249 /* *** now fill the scatter gather list ******* */
2250 for (i = 0; i < ncookies; i++) {
2251 cmd_table->ahcict_prdt[i].ahcipi_data_base_addr =
2252 scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[0];
2253 cmd_table->ahcict_prdt[i].ahcipi_data_base_addr_upper =
2254 scmd->satacmd_dma_cookie_list[i]._dmu._dmac_la[1];
2255 cmd_table->ahcict_prdt[i].ahcipi_descr_info =
2256 scmd->satacmd_dma_cookie_list[i].dmac_size - 1;
2257 ahci_portp->ahciport_prd_bytecounts[cmd_slot] +=
2258 scmd->satacmd_dma_cookie_list[i].dmac_size;
2261 AHCIDBG(AHCIDBG_PRDT, ahci_ctlp,
2262 "ahciport_prd_bytecounts 0x%x for cmd_slot 0x%x",
2263 ahci_portp->ahciport_prd_bytecounts[cmd_slot], cmd_slot);
2265 /* The ACMD field is filled in for ATAPI command */
2266 if (scmd->satacmd_cmd_reg == SATAC_PACKET) {
2267 bcopy(scmd->satacmd_acdb, cmd_table->ahcict_atapi_cmd,
2268 SATA_ATAPI_MAX_CDB_LEN);
2271 /* Set Command Header in Command List */
2272 cmd_header = &ahci_portp->ahciport_cmd_list[cmd_slot];
2273 BZERO_DESCR_INFO(cmd_header);
2274 BZERO_PRD_BYTE_COUNT(cmd_header);
2276 /* Set the number of entries in the PRD table */
2277 SET_PRD_TABLE_LENGTH(cmd_header, ncookies);
2279 /* Set the length of the command in the CFIS area */
2280 SET_COMMAND_FIS_LENGTH(cmd_header, AHCI_H2D_REGISTER_FIS_LENGTH);
2283 * PMP field only make sense when target is a port multiplier or a
2284 * device behind a port multiplier. Otherwise should set it to 0.
2286 if (AHCI_ADDR_IS_PMULT(addrp) || AHCI_ADDR_IS_PMPORT(addrp))
2287 SET_PORT_MULTI_PORT(cmd_header, pmport);
2289 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "command data direction is "
2290 "sata_data_direction = 0x%x",
2291 scmd->satacmd_flags.sata_data_direction);
2293 /* Set A bit if it is an ATAPI command */
2294 if (scmd->satacmd_cmd_reg == SATAC_PACKET)
2295 SET_ATAPI(cmd_header, AHCI_CMDHEAD_ATAPI);
2297 /* Set W bit if data is going to the device */
2298 if (scmd->satacmd_flags.sata_data_direction == SATA_DIR_WRITE)
2299 SET_WRITE(cmd_header, AHCI_CMDHEAD_DATA_WRITE);
2302 * Set the prefetchable bit - this bit is only valid if the PRDTL
2303 * field is non-zero or the ATAPI 'A' bit is set in the command
2304 * header. This bit cannot be set when using native command
2305 * queuing commands or when using FIS-based switching with a Port
2306 * multiplier.
2308 if (command_type != AHCI_NCQ_CMD)
2309 SET_PREFETCHABLE(cmd_header, AHCI_CMDHEAD_PREFETCHABLE);
2312 * Now remember the sata packet in ahciport_slot_pkts[].
2313 * Error retrieval command and r/w port multiplier command will
2314 * be stored specifically for each port.
2316 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
2317 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
2318 ahci_portp->ahciport_slot_pkts[cmd_slot] = spkt;
2321 * Keep the timeout value
2323 ahci_portp->ahciport_slot_timeout[cmd_slot] = spkt->satapkt_time;
2326 * If the intial timout is less than 1 tick, then make it longer by
2327 * 1 tick to avoid immediate timeout
2329 if (ahci_portp->ahciport_slot_timeout[cmd_slot] <=
2330 ahci_watchdog_timeout)
2331 ahci_portp->ahciport_slot_timeout[cmd_slot] +=
2332 ahci_watchdog_timeout;
2334 #if AHCI_DEBUG
2335 if (ahci_debug_flags & AHCIDBG_ATACMD &&
2336 scmd->satacmd_cmd_reg != SATAC_PACKET ||
2337 ahci_debug_flags & AHCIDBG_ATAPICMD &&
2338 scmd->satacmd_cmd_reg == SATAC_PACKET) {
2340 /* Dump the command header and table */
2341 ahci_log(ahci_ctlp, CE_WARN, "\n");
2342 ahci_log(ahci_ctlp, CE_WARN, "Command header&table for spkt "
2343 "0x%p cmd_reg 0x%x port %d", spkt,
2344 scmd->satacmd_cmd_reg, port);
2345 ptr = (uint32_t *)cmd_header;
2346 ahci_log(ahci_ctlp, CE_WARN,
2347 " Command Header:%8x %8x %8x %8x",
2348 ptr[0], ptr[1], ptr[2], ptr[3]);
2350 /* Dump the H2D register FIS */
2351 ptr = (uint32_t *)h2d_register_fisp;
2352 ahci_log(ahci_ctlp, CE_WARN,
2353 " Command FIS: %8x %8x %8x %8x",
2354 ptr[0], ptr[1], ptr[2], ptr[3]);
2356 /* Dump the ACMD register FIS */
2357 ptr2 = (uint8_t *)&(cmd_table->ahcict_atapi_cmd);
2358 for (i = 0; i < SATA_ATAPI_MAX_CDB_LEN/8; i++)
2359 if (ahci_debug_flags & AHCIDBG_ATAPICMD)
2360 ahci_log(ahci_ctlp, CE_WARN,
2361 " ATAPI command: %2x %2x %2x %2x "
2362 "%2x %2x %2x %2x",
2363 ptr2[8 * i], ptr2[8 * i + 1],
2364 ptr2[8 * i + 2], ptr2[8 * i + 3],
2365 ptr2[8 * i + 4], ptr2[8 * i + 5],
2366 ptr2[8 * i + 6], ptr2[8 * i + 7]);
2368 /* Dump the PRDT */
2369 for (i = 0; i < ncookies; i++) {
2370 ptr = (uint32_t *)&(cmd_table->ahcict_prdt[i]);
2371 ahci_log(ahci_ctlp, CE_WARN,
2372 " Cookie %d: %8x %8x %8x %8x",
2373 i, ptr[0], ptr[1], ptr[2], ptr[3]);
2376 #endif
2378 (void) ddi_dma_sync(
2379 ahci_portp->ahciport_cmd_tables_dma_handle[cmd_slot],
2381 ahci_cmd_table_size,
2382 DDI_DMA_SYNC_FORDEV);
2384 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
2385 cmd_slot * sizeof (ahci_cmd_header_t),
2386 sizeof (ahci_cmd_header_t),
2387 DDI_DMA_SYNC_FORDEV);
2389 if ((ahci_check_dma_handle(ahci_portp->
2390 ahciport_cmd_tables_dma_handle[cmd_slot]) != DDI_FM_OK) ||
2391 ahci_check_dma_handle(ahci_portp->
2392 ahciport_cmd_list_dma_handle) != DDI_FM_OK) {
2393 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2394 DDI_SERVICE_UNAFFECTED);
2395 return (AHCI_FAILURE);
2398 /* Set the corresponding bit in the PxSACT.DS for queued command */
2399 if (command_type == AHCI_NCQ_CMD) {
2400 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2401 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port),
2402 (0x1 << cmd_slot));
2405 /* Indicate to the HBA that a command is active. */
2406 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
2407 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
2408 (0x1 << cmd_slot));
2410 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_deliver_satapkt "
2411 "exit: port %d", port);
2413 /* Make sure the command is started by the PxSACT/PxCI */
2414 if (ahci_check_acc_handle(ahci_ctlp->
2415 ahcictl_ahci_acc_handle) != DDI_FM_OK) {
2416 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
2417 DDI_SERVICE_UNAFFECTED);
2418 return (AHCI_FAILURE);
2421 return (cmd_slot);
2425 * Called by the sata framework to abort the previously sent packet(s).
2427 * Reset device to abort commands.
2429 static int
2430 ahci_tran_abort(dev_info_t *dip, sata_pkt_t *spkt, int flag)
2432 ahci_ctl_t *ahci_ctlp;
2433 ahci_port_t *ahci_portp;
2434 uint32_t slot_status = 0;
2435 uint32_t aborted_tags = 0;
2436 uint32_t finished_tags = 0;
2437 uint8_t cport = spkt->satapkt_device.satadev_addr.cport;
2438 uint8_t port;
2439 int tmp_slot;
2440 int instance = ddi_get_instance(dip);
2442 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
2443 port = ahci_ctlp->ahcictl_cport_to_port[cport];
2445 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2446 "ahci_tran_abort enter: port %d", port);
2448 ahci_portp = ahci_ctlp->ahcictl_ports[port];
2449 mutex_enter(&ahci_portp->ahciport_mutex);
2452 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2453 * commands are being mopped, therefore there is nothing else to do
2455 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2456 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2457 "ahci_tran_abort: port %d is in "
2458 "mopping process, so just return directly ", port);
2459 mutex_exit(&ahci_portp->ahciport_mutex);
2460 return (SATA_SUCCESS);
2464 * If AHCI_PORT_FLAG_RDWR_PMULT flag is set, it means a R/W PMULT
2465 * command is being executed so no other commands is outstanding,
2466 * nothing to do.
2468 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_RDWR_PMULT) {
2469 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2470 "ahci_tran_abort: port %d is reading/writing "
2471 "port multiplier, so just return directly ", port);
2472 mutex_exit(&ahci_portp->ahciport_mutex);
2473 return (SATA_SUCCESS);
2476 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
2477 ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
2478 ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
2480 * In case the targer driver would send the request before
2481 * sata framework can have the opportunity to process those
2482 * event reports.
2484 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2485 spkt->satapkt_device.satadev_state =
2486 ahci_portp->ahciport_port_state;
2487 ahci_update_sata_registers(ahci_ctlp, port,
2488 &spkt->satapkt_device);
2489 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2490 "ahci_tran_abort returning SATA_FAILURE while "
2491 "port in FAILED/SHUTDOWN/PWROFF state: "
2492 "port: %d", port);
2493 mutex_exit(&ahci_portp->ahciport_mutex);
2494 return (SATA_FAILURE);
2497 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
2499 * ahci_intr_phyrdy_change() may have rendered it to
2500 * AHCI_PORT_TYPE_NODEV.
2502 spkt->satapkt_reason = SATA_PKT_PORT_ERROR;
2503 spkt->satapkt_device.satadev_type = SATA_DTYPE_NONE;
2504 spkt->satapkt_device.satadev_state =
2505 ahci_portp->ahciport_port_state;
2506 ahci_update_sata_registers(ahci_ctlp, port,
2507 &spkt->satapkt_device);
2508 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2509 "ahci_tran_abort returning SATA_FAILURE while "
2510 "no device attached: port: %d", port);
2511 mutex_exit(&ahci_portp->ahciport_mutex);
2512 return (SATA_FAILURE);
2515 if (flag == SATA_ABORT_ALL_PACKETS) {
2516 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2517 aborted_tags = ahci_portp->ahciport_pending_tags;
2518 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2519 aborted_tags = ahci_portp->ahciport_pending_ncq_tags;
2521 cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort all packets",
2522 instance, port);
2523 } else {
2524 aborted_tags = 0xffffffff;
2526 * Aborting one specific packet, first search the
2527 * ahciport_slot_pkts[] list for matching spkt.
2529 for (tmp_slot = 0;
2530 tmp_slot < ahci_ctlp->ahcictl_num_cmd_slots; tmp_slot++) {
2531 if (ahci_portp->ahciport_slot_pkts[tmp_slot] == spkt) {
2532 aborted_tags = (0x1 << tmp_slot);
2533 break;
2537 if (aborted_tags == 0xffffffff) {
2538 /* request packet is not on the pending list */
2539 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
2540 "Cannot find the aborting pkt 0x%p on the "
2541 "pending list", (void *)spkt);
2542 ahci_update_sata_registers(ahci_ctlp, port,
2543 &spkt->satapkt_device);
2544 mutex_exit(&ahci_portp->ahciport_mutex);
2545 return (SATA_FAILURE);
2547 cmn_err(CE_NOTE, "!ahci%d: ahci port %d abort satapkt 0x%p",
2548 instance, port, (void *)spkt);
2551 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2552 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2553 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2554 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2555 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2556 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2558 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2559 ahci_portp->ahciport_mop_in_progress++;
2562 * To abort the packet(s), first we are trying to clear PxCMD.ST
2563 * to stop the port, and if the port can be stopped
2564 * successfully with PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0',
2565 * then we just send back the aborted packet(s) with ABORTED flag
2566 * and then restart the port by setting PxCMD.ST and PxCMD.FRE.
2567 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then we
2568 * perform a COMRESET.
2570 (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
2571 ahci_portp, port, 0, NULL);
2574 * Compute which have finished and which need to be retried.
2576 * The finished tags are ahciport_pending_tags/ahciport_pending_ncq_tags
2577 * minus the slot_status. The aborted_tags has to be deducted by
2578 * finished_tags since we can't possibly abort a tag which had finished
2579 * already.
2581 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2582 finished_tags = ahci_portp->ahciport_pending_tags &
2583 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2584 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2585 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2586 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2588 aborted_tags &= ~finished_tags;
2590 ahci_mop_commands(ahci_ctlp,
2591 ahci_portp,
2592 slot_status,
2593 0, /* failed tags */
2594 0, /* timeout tags */
2595 aborted_tags,
2596 0); /* reset tags */
2598 ahci_update_sata_registers(ahci_ctlp, port, &spkt->satapkt_device);
2599 mutex_exit(&ahci_portp->ahciport_mutex);
2601 return (SATA_SUCCESS);
2605 * Used to do device reset and reject all the pending packets on a device
2606 * during the reset operation.
2608 * NOTE: ONLY called by ahci_tran_reset_dport
2610 static int
2611 ahci_reset_device_reject_pkts(ahci_ctl_t *ahci_ctlp,
2612 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2614 uint32_t slot_status = 0;
2615 uint32_t reset_tags = 0;
2616 uint32_t finished_tags = 0;
2617 uint8_t port = addrp->aa_port;
2618 sata_device_t sdevice;
2619 int ret;
2621 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2623 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2624 "ahci_reset_device_reject_pkts on port: %d", port);
2627 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2628 * commands are being mopped, therefore there is nothing else to do
2630 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2631 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2632 "ahci_reset_device_reject_pkts: port %d is in "
2633 "mopping process, so return directly ", port);
2634 return (SATA_SUCCESS);
2637 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2638 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2639 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2640 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2641 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2642 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2643 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2644 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2647 if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2648 != AHCI_SUCCESS) {
2649 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2650 "Try to do a port reset after software "
2651 "reset failed", port);
2652 ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
2653 if (ret != AHCI_SUCCESS) {
2654 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2655 "ahci_reset_device_reject_pkts: port %d "
2656 "failed", port);
2657 return (SATA_FAILURE);
2660 /* Set the reset in progress flag */
2661 ahci_portp->ahciport_reset_in_progress = 1;
2663 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2664 ahci_portp->ahciport_mop_in_progress++;
2666 /* Indicate to the framework that a reset has happened */
2667 bzero((void *)&sdevice, sizeof (sata_device_t));
2668 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2669 sdevice.satadev_addr.pmport = 0;
2670 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
2671 sdevice.satadev_state = SATA_DSTATE_RESET |
2672 SATA_DSTATE_PWR_ACTIVE;
2673 mutex_exit(&ahci_portp->ahciport_mutex);
2674 sata_hba_event_notify(
2675 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2676 &sdevice,
2677 SATA_EVNT_DEVICE_RESET);
2678 mutex_enter(&ahci_portp->ahciport_mutex);
2680 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2681 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
2683 /* Next try to mop the pending commands */
2684 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2685 finished_tags = ahci_portp->ahciport_pending_tags &
2686 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2687 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2688 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2689 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2691 reset_tags &= ~finished_tags;
2693 ahci_mop_commands(ahci_ctlp,
2694 ahci_portp,
2695 slot_status,
2696 0, /* failed tags */
2697 0, /* timeout tags */
2698 0, /* aborted tags */
2699 reset_tags); /* reset tags */
2701 return (SATA_SUCCESS);
2705 * Used to do device reset and reject all the pending packets on a device
2706 * during the reset operation.
2708 * NOTE: ONLY called by ahci_tran_reset_dport
2710 static int
2711 ahci_reset_pmdevice_reject_pkts(ahci_ctl_t *ahci_ctlp,
2712 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2714 uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
2715 uint8_t port = addrp->aa_port;
2716 uint8_t pmport = addrp->aa_pmport;
2717 sata_device_t sdevice;
2719 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2721 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_PMULT, ahci_ctlp,
2722 "ahci_reset_pmdevice_reject_pkts at port %d:%d", port, pmport);
2724 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2725 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2726 "ahci_reset_pmdevice_reject_pkts: port %d is in "
2727 "mopping process, so return directly ", port);
2728 return (SATA_SUCCESS);
2731 /* Checking for outstanding commands */
2732 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2733 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2734 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2735 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2736 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2737 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2738 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2739 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2742 /* Issue SOFTWARE reset command. */
2743 if (ahci_software_reset(ahci_ctlp, ahci_portp, addrp)
2744 != AHCI_SUCCESS) {
2745 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2746 "Try to do a port reset after software "
2747 "reset failed", port);
2748 return (SATA_FAILURE);
2751 /* Set the reset in progress flag */
2752 ahci_portp->ahciport_reset_in_progress = 1;
2754 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2755 ahci_portp->ahciport_mop_in_progress++;
2757 /* Indicate to the framework that a reset has happened */
2758 bzero((void *)&sdevice, sizeof (sata_device_t));
2759 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
2760 sdevice.satadev_addr.pmport = pmport;
2761 if (AHCI_ADDR_IS_PMULT(addrp))
2762 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
2763 else
2764 sdevice.satadev_addr.qual = SATA_ADDR_DPMPORT;
2765 sdevice.satadev_state = SATA_DSTATE_RESET |
2766 SATA_DSTATE_PWR_ACTIVE;
2767 mutex_exit(&ahci_portp->ahciport_mutex);
2768 sata_hba_event_notify(
2769 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
2770 &sdevice,
2771 SATA_EVNT_DEVICE_RESET);
2772 mutex_enter(&ahci_portp->ahciport_mutex);
2774 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
2775 "port %d:%d sending event up: SATA_EVNT_DEVICE_RESET",
2776 port, pmport);
2778 /* Next try to mop the pending commands */
2779 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2780 finished_tags = ahci_portp->ahciport_pending_tags &
2781 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2782 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2783 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2784 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2785 reset_tags &= ~finished_tags;
2787 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
2788 "reset_tags = %x, finished_tags = %x, slot_status = %x",
2789 reset_tags, finished_tags, slot_status);
2792 * NOTE: Because PxCI be only erased by unset PxCMD.ST bit, so even we
2793 * try to reset a single device behind a port multiplier will
2794 * terminate all the commands on that HBA port. We need mop these
2795 * commands as well.
2797 ahci_mop_commands(ahci_ctlp,
2798 ahci_portp,
2799 slot_status,
2800 0, /* failed tags */
2801 0, /* timeout tags */
2802 0, /* aborted tags */
2803 reset_tags); /* reset tags */
2805 return (SATA_SUCCESS);
2809 * Used to do port reset and reject all the pending packets on a port during
2810 * the reset operation.
2812 static int
2813 ahci_reset_port_reject_pkts(ahci_ctl_t *ahci_ctlp,
2814 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
2816 uint32_t slot_status = 0;
2817 uint32_t reset_tags = 0;
2818 uint32_t finished_tags = 0;
2819 uint8_t port = addrp->aa_port;
2821 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
2823 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2824 "ahci_reset_port_reject_pkts at port: %d", port);
2827 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2828 * commands are being mopped, therefore there is nothing else to do
2830 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2831 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2832 "ahci_reset_port_reject_pkts: port %d is in "
2833 "mopping process, so return directly ", port);
2834 return (SATA_SUCCESS);
2837 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2838 ahci_portp->ahciport_mop_in_progress++;
2840 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2841 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2842 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2843 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2844 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2845 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
2846 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2847 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2850 if (ahci_restart_port_wait_till_ready(ahci_ctlp,
2851 ahci_portp, port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
2852 NULL) != AHCI_SUCCESS) {
2854 /* Clear mop flag */
2855 ahci_portp->ahciport_mop_in_progress--;
2856 if (ahci_portp->ahciport_mop_in_progress == 0)
2857 ahci_portp->ahciport_flags &=
2858 ~AHCI_PORT_FLAG_MOPPING;
2859 return (SATA_FAILURE);
2862 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2863 finished_tags = ahci_portp->ahciport_pending_tags &
2864 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
2865 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2866 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
2867 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
2869 reset_tags &= ~finished_tags;
2871 ahci_mop_commands(ahci_ctlp,
2872 ahci_portp,
2873 slot_status,
2874 0, /* failed tags */
2875 0, /* timeout tags */
2876 0, /* aborted tags */
2877 reset_tags); /* reset tags */
2879 return (SATA_SUCCESS);
2883 * Used to do hba reset and reject all the pending packets on all ports
2884 * during the reset operation.
2886 static int
2887 ahci_reset_hba_reject_pkts(ahci_ctl_t *ahci_ctlp)
2889 ahci_port_t *ahci_portp;
2890 uint32_t slot_status[AHCI_MAX_PORTS];
2891 uint32_t reset_tags[AHCI_MAX_PORTS];
2892 uint32_t finished_tags[AHCI_MAX_PORTS];
2893 int port;
2894 int ret = SATA_SUCCESS;
2896 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
2897 "ahci_reset_hba_reject_pkts enter", NULL);
2899 bzero(slot_status, sizeof (slot_status));
2900 bzero(reset_tags, sizeof (reset_tags));
2901 bzero(finished_tags, sizeof (finished_tags));
2903 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
2904 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
2905 continue;
2908 ahci_portp = ahci_ctlp->ahcictl_ports[port];
2910 mutex_enter(&ahci_portp->ahciport_mutex);
2911 ahci_portp->ahciport_reset_in_progress = 1;
2912 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2913 slot_status[port] = ddi_get32(
2914 ahci_ctlp->ahcictl_ahci_acc_handle,
2915 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
2916 reset_tags[port] = slot_status[port] &
2917 AHCI_SLOT_MASK(ahci_ctlp);
2918 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
2919 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
2920 port, reset_tags[port],
2921 ahci_portp->ahciport_pending_tags);
2922 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
2923 slot_status[port] = ddi_get32(
2924 ahci_ctlp->ahcictl_ahci_acc_handle,
2925 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
2926 reset_tags[port] = slot_status[port] &
2927 AHCI_NCQ_SLOT_MASK(ahci_portp);
2928 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
2929 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
2930 port, reset_tags[port],
2931 ahci_portp->ahciport_pending_tags);
2933 mutex_exit(&ahci_portp->ahciport_mutex);
2936 if (ahci_hba_reset(ahci_ctlp) != AHCI_SUCCESS) {
2937 ret = SATA_FAILURE;
2940 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
2941 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
2942 continue;
2945 ahci_portp = ahci_ctlp->ahcictl_ports[port];
2947 mutex_enter(&ahci_portp->ahciport_mutex);
2949 * To prevent recursive enter to ahci_mop_commands, we need
2950 * check AHCI_PORT_FLAG_MOPPING flag.
2952 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
2953 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
2954 "ahci_reset_hba_reject_pkts: port %d is in "
2955 "mopping process, so return directly ", port);
2956 mutex_exit(&ahci_portp->ahciport_mutex);
2957 continue;
2960 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
2961 ahci_portp->ahciport_mop_in_progress++;
2963 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
2964 finished_tags[port] =
2965 ahci_portp->ahciport_pending_tags &
2966 ~slot_status[port] & AHCI_SLOT_MASK(ahci_ctlp);
2967 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
2968 finished_tags[port] =
2969 ahci_portp->ahciport_pending_ncq_tags &
2970 ~slot_status[port] & AHCI_NCQ_SLOT_MASK(ahci_portp);
2972 reset_tags[port] &= ~finished_tags[port];
2974 ahci_mop_commands(ahci_ctlp,
2975 ahci_portp,
2976 slot_status[port],
2977 0, /* failed tags */
2978 0, /* timeout tags */
2979 0, /* aborted tags */
2980 reset_tags[port]); /* reset tags */
2981 mutex_exit(&ahci_portp->ahciport_mutex);
2983 out:
2984 return (ret);
2988 * Called by sata framework to reset a port(s) or device.
2990 static int
2991 ahci_tran_reset_dport(dev_info_t *dip, sata_device_t *sd)
2993 ahci_ctl_t *ahci_ctlp;
2994 ahci_port_t *ahci_portp;
2995 ahci_addr_t addr;
2996 uint8_t cport = sd->satadev_addr.cport;
2997 uint8_t pmport = sd->satadev_addr.pmport;
2998 uint8_t port;
2999 int ret = SATA_SUCCESS;
3000 int instance = ddi_get_instance(dip);
3002 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3003 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3004 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3006 ahci_get_ahci_addr(ahci_ctlp, sd, &addr);
3008 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3009 "ahci_tran_reset_dport enter: cport %d", cport);
3011 switch (sd->satadev_addr.qual) {
3012 case SATA_ADDR_PMPORT:
3014 * If we want to issue a COMRESET on a pmport, we need to
3015 * reject the outstanding commands on that pmport. According
3016 * to AHCI spec, PxCI register could only be cleared by
3017 * clearing PxCMD.ST, which will halt the controller port - as
3018 * well as other pmports.
3020 * Therefore we directly reset the controller port for
3021 * simplicity. ahci_tran_probe_port() will handle reset stuff
3022 * like initializing the given pmport.
3024 /* FALLTHRU */
3025 case SATA_ADDR_CPORT:
3026 /* Port reset */
3027 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3028 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3029 "port %d reset port", instance, port);
3031 mutex_enter(&ahci_portp->ahciport_mutex);
3032 ret = ahci_reset_port_reject_pkts(ahci_ctlp, ahci_portp, &addr);
3033 mutex_exit(&ahci_portp->ahciport_mutex);
3035 break;
3037 case SATA_ADDR_DPMPORT:
3038 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3039 "port %d:%d reset device", instance, port, pmport);
3040 /* FALLTHRU */
3041 case SATA_ADDR_DCPORT:
3042 /* Device reset */
3043 if (sd->satadev_addr.qual == SATA_ADDR_DCPORT)
3044 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3045 "port %d reset device", instance, port);
3047 mutex_enter(&ahci_portp->ahciport_mutex);
3049 * software reset request must be sent to SATA_PMULT_HOSTPORT
3050 * if target is a port multiplier:
3052 if (sd->satadev_addr.qual == SATA_ADDR_DCPORT &&
3053 ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT)
3054 AHCI_ADDR_SET_PMULT(&addr, port);
3056 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED |
3057 ahci_portp->ahciport_port_state & SATA_PSTATE_SHUTDOWN |
3058 ahci_portp->ahciport_port_state & SATA_PSTATE_PWROFF) {
3060 * In case the targer driver would send the request
3061 * before sata framework can have the opportunity to
3062 * process those event reports.
3064 sd->satadev_state = ahci_portp->ahciport_port_state;
3065 ahci_update_sata_registers(ahci_ctlp, port, sd);
3066 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3067 "ahci_tran_reset_dport returning SATA_FAILURE "
3068 "while port in FAILED/SHUTDOWN/PWROFF state: "
3069 "port: %d", port);
3070 mutex_exit(&ahci_portp->ahciport_mutex);
3071 ret = SATA_FAILURE;
3072 break;
3075 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr) ==
3076 SATA_DTYPE_NONE) {
3078 * ahci_intr_phyrdy_change() may have rendered it to
3079 * AHCI_PORT_TYPE_NODEV.
3081 sd->satadev_type = SATA_DTYPE_NONE;
3082 sd->satadev_state = AHCIPORT_GET_STATE(ahci_portp,
3083 &addr);
3084 ahci_update_sata_registers(ahci_ctlp, port, sd);
3085 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3086 "ahci_tran_reset_dport returning SATA_FAILURE "
3087 "while no device attached: port: %d", port);
3088 mutex_exit(&ahci_portp->ahciport_mutex);
3089 ret = SATA_FAILURE;
3090 break;
3093 if (AHCI_ADDR_IS_PORT(&addr)) {
3094 ret = ahci_reset_device_reject_pkts(ahci_ctlp,
3095 ahci_portp, &addr);
3096 } else {
3097 ret = ahci_reset_pmdevice_reject_pkts(ahci_ctlp,
3098 ahci_portp, &addr);
3101 mutex_exit(&ahci_portp->ahciport_mutex);
3102 break;
3104 case SATA_ADDR_CNTRL:
3105 /* Reset the whole controller */
3106 cmn_err(CE_NOTE, "!ahci%d: ahci_tran_reset_dport "
3107 "reset the whole hba", instance);
3108 ret = ahci_reset_hba_reject_pkts(ahci_ctlp);
3109 break;
3111 default:
3112 ret = SATA_FAILURE;
3115 return (ret);
3119 * Called by sata framework to activate a port as part of hotplug.
3120 * (cfgadm -c connect satax/y)
3121 * Support port multiplier.
3123 static int
3124 ahci_tran_hotplug_port_activate(dev_info_t *dip, sata_device_t *satadev)
3126 ahci_ctl_t *ahci_ctlp;
3127 ahci_port_t *ahci_portp;
3128 ahci_addr_t addr;
3129 uint8_t cport = satadev->satadev_addr.cport;
3130 uint8_t pmport = satadev->satadev_addr.pmport;
3131 uint8_t port;
3132 int instance = ddi_get_instance(dip);
3134 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3135 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3137 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3138 "ahci_tran_hotplug_port_activate enter: cport %d", cport);
3140 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3142 mutex_enter(&ahci_portp->ahciport_mutex);
3143 ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3144 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3146 if (AHCI_ADDR_IS_PORT(&addr)) {
3147 cmn_err(CE_NOTE, "!ahci%d: ahci port %d is activated",
3148 instance, port);
3150 /* Enable the interrupts on the port */
3151 ahci_enable_port_intrs(ahci_ctlp, port);
3154 * Reset the port so that the PHY communication would be
3155 * re-established. But this reset is an internal operation
3156 * and the sata module doesn't need to know about it.
3157 * Moreover, the port with a device attached will be started
3158 * too.
3160 (void) ahci_restart_port_wait_till_ready(ahci_ctlp,
3161 ahci_portp, port,
3162 AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP,
3163 NULL);
3166 * Need to check the link status and device status of the port
3167 * and consider raising power if the port was in D3 state
3169 ahci_portp->ahciport_port_state |= SATA_PSTATE_PWRON;
3170 ahci_portp->ahciport_port_state &= ~SATA_PSTATE_PWROFF;
3171 ahci_portp->ahciport_port_state &= ~SATA_PSTATE_SHUTDOWN;
3172 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3173 cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is activated",
3174 instance, port, pmport);
3175 /* AHCI_ADDR_PMPORT */
3176 AHCIPORT_PMSTATE(ahci_portp, &addr) |= SATA_PSTATE_PWRON;
3177 AHCIPORT_PMSTATE(ahci_portp, &addr) &=
3178 ~(SATA_PSTATE_PWROFF|SATA_PSTATE_SHUTDOWN);
3181 satadev->satadev_state = ahci_portp->ahciport_port_state;
3183 ahci_update_sata_registers(ahci_ctlp, port, satadev);
3185 mutex_exit(&ahci_portp->ahciport_mutex);
3186 return (SATA_SUCCESS);
3190 * Called by sata framework to deactivate a port as part of hotplug.
3191 * (cfgadm -c disconnect satax/y)
3192 * Support port multiplier.
3194 static int
3195 ahci_tran_hotplug_port_deactivate(dev_info_t *dip, sata_device_t *satadev)
3197 ahci_ctl_t *ahci_ctlp;
3198 ahci_port_t *ahci_portp;
3199 ahci_addr_t addr;
3200 uint8_t cport = satadev->satadev_addr.cport;
3201 uint8_t pmport = satadev->satadev_addr.pmport;
3202 uint8_t port;
3203 uint32_t port_scontrol;
3204 int instance = ddi_get_instance(dip);
3206 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
3207 port = ahci_ctlp->ahcictl_cport_to_port[cport];
3209 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
3210 "ahci_tran_hotplug_port_deactivate enter: cport %d", cport);
3212 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3213 mutex_enter(&ahci_portp->ahciport_mutex);
3214 ahci_get_ahci_addr(ahci_ctlp, satadev, &addr);
3215 ASSERT(AHCI_ADDR_IS_PORT(&addr) || AHCI_ADDR_IS_PMPORT(&addr));
3217 if (AHCI_ADDR_IS_PORT(&addr)) {
3218 cmn_err(CE_NOTE, "!ahci%d: ahci port %d is deactivated",
3219 instance, port);
3221 /* Disable the interrupts on the port */
3222 ahci_disable_port_intrs(ahci_ctlp, port);
3224 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
3226 /* First to abort all the pending commands */
3227 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3229 /* Then stop the port */
3230 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3231 ahci_portp, port);
3234 /* Next put the PHY offline */
3235 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3236 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
3237 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_DISABLE);
3238 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle, (uint32_t *)
3239 AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
3240 } else if (AHCI_ADDR_IS_PMPORT(&addr)) {
3241 cmn_err(CE_NOTE, "!ahci%d: ahci port %d:%d is deactivated",
3242 instance, port, pmport);
3244 ahci_disable_port_intrs(ahci_ctlp, port);
3245 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &addr)
3246 != SATA_DTYPE_NONE)
3247 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
3249 /* Re-enable the interrupts for the other pmports */
3250 ahci_enable_port_intrs(ahci_ctlp, port);
3253 /* Update port state */
3254 AHCIPORT_SET_STATE(ahci_portp, &addr, SATA_PSTATE_SHUTDOWN);
3255 satadev->satadev_state = SATA_PSTATE_SHUTDOWN;
3257 ahci_update_sata_registers(ahci_ctlp, port, satadev);
3259 mutex_exit(&ahci_portp->ahciport_mutex);
3260 return (SATA_SUCCESS);
3264 * To be used to mark all the outstanding pkts with SATA_PKT_ABORTED
3265 * when a device is unplugged or a port is deactivated.
3267 static void
3268 ahci_reject_all_abort_pkts(ahci_ctl_t *ahci_ctlp,
3269 ahci_port_t *ahci_portp, uint8_t port)
3271 uint32_t slot_status = 0;
3272 uint32_t abort_tags = 0;
3274 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3276 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
3277 "ahci_reject_all_abort_pkts at port: %d", port);
3279 /* Read/write port multiplier command takes highest priority */
3280 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
3281 slot_status = 0x1;
3282 abort_tags = 0x1;
3283 goto out;
3287 * When AHCI_PORT_FLAG_MOPPING is set, we need to check whether a
3288 * REQUEST SENSE command or READ LOG EXT command is delivered to HBA
3289 * to get the error data, if yes when the device is removed, the
3290 * command needs to be aborted too.
3292 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) {
3293 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
3294 slot_status = 0x1;
3295 abort_tags = 0x1;
3296 goto out;
3297 } else {
3298 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3299 "ahci_reject_all_abort_pkts return directly "
3300 "port %d no needs to reject any outstanding "
3301 "commands", port);
3302 return;
3306 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3307 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3308 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
3309 abort_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
3310 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
3311 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3312 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
3313 abort_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
3316 out:
3317 /* No need to do mop when there is no outstanding commands */
3318 if (slot_status != 0) {
3319 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
3320 ahci_portp->ahciport_mop_in_progress++;
3322 ahci_mop_commands(ahci_ctlp,
3323 ahci_portp,
3324 slot_status,
3325 0, /* failed tags */
3326 0, /* timeout tags */
3327 abort_tags, /* aborting tags */
3328 0); /* reset tags */
3332 #if defined(__lock_lint)
3333 static int
3334 ahci_selftest(dev_info_t *dip, sata_device_t *device)
3336 return (SATA_SUCCESS);
3338 #endif
3341 * Initialize fma capabilities and register with IO fault services.
3343 static void
3344 ahci_fm_init(ahci_ctl_t *ahci_ctlp)
3347 * Need to change iblock to priority for new MSI intr
3349 ddi_iblock_cookie_t fm_ibc;
3351 ahci_ctlp->ahcictl_fm_cap = ddi_getprop(DDI_DEV_T_ANY,
3352 ahci_ctlp->ahcictl_dip,
3353 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
3354 DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
3355 DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
3357 /* Only register with IO Fault Services if we have some capability */
3358 if (ahci_ctlp->ahcictl_fm_cap) {
3359 /* Adjust access and dma attributes for FMA */
3360 accattr.devacc_attr_access = DDI_FLAGERR_ACC;
3361 buffer_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3362 rcvd_fis_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3363 cmd_list_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3364 cmd_table_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
3367 * Register capabilities with IO Fault Services.
3368 * ahcictl_fm_cap will be updated to indicate
3369 * capabilities actually supported (not requested.)
3371 ddi_fm_init(ahci_ctlp->ahcictl_dip,
3372 &ahci_ctlp->ahcictl_fm_cap, &fm_ibc);
3374 if (ahci_ctlp->ahcictl_fm_cap == DDI_FM_NOT_CAPABLE) {
3375 cmn_err(CE_WARN, "!ahci%d: fma init failed.",
3376 ddi_get_instance(ahci_ctlp->ahcictl_dip));
3377 return;
3380 * Initialize pci ereport capabilities if ereport
3381 * capable (should always be.)
3383 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3384 DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3385 pci_ereport_setup(ahci_ctlp->ahcictl_dip);
3389 * Register error callback if error callback capable.
3391 if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3392 ddi_fm_handler_register(ahci_ctlp->ahcictl_dip,
3393 ahci_fm_error_cb, (void *) ahci_ctlp);
3396 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3397 "ahci_fm_fini: fma enabled.", NULL);
3402 * Releases fma capabilities and un-registers with IO fault services.
3404 static void
3405 ahci_fm_fini(ahci_ctl_t *ahci_ctlp)
3407 /* Only unregister FMA capabilities if registered */
3408 if (ahci_ctlp->ahcictl_fm_cap) {
3410 * Un-register error callback if error callback capable.
3412 if (DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3413 ddi_fm_handler_unregister(ahci_ctlp->ahcictl_dip);
3417 * Release any resources allocated by pci_ereport_setup()
3419 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap) ||
3420 DDI_FM_ERRCB_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3421 pci_ereport_teardown(ahci_ctlp->ahcictl_dip);
3424 /* Unregister from IO Fault Services */
3425 ddi_fm_fini(ahci_ctlp->ahcictl_dip);
3427 /* Adjust access and dma attributes for FMA */
3428 accattr.devacc_attr_access = DDI_DEFAULT_ACC;
3429 buffer_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3430 rcvd_fis_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3431 cmd_list_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3432 cmd_table_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
3434 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3435 "ahci_fm_fini: fma disabled.", NULL);
3439 /*ARGSUSED*/
3440 static int
3441 ahci_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
3444 * as the driver can always deal with an error in any dma or
3445 * access handle, we can just return the fme_status value.
3447 pci_ereport_post(dip, err, NULL);
3448 return (err->fme_status);
3452 ahci_check_acc_handle(ddi_acc_handle_t handle)
3454 ddi_fm_error_t de;
3456 ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
3457 return (de.fme_status);
3461 ahci_check_dma_handle(ddi_dma_handle_t handle)
3463 ddi_fm_error_t de;
3465 ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
3466 return (de.fme_status);
3470 * Generate an ereport
3472 void
3473 ahci_fm_ereport(ahci_ctl_t *ahci_ctlp, char *detail)
3475 uint64_t ena;
3476 char buf[FM_MAX_CLASS];
3478 (void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
3479 ena = fm_ena_generate(0, FM_ENA_FMT1);
3480 if (DDI_FM_EREPORT_CAP(ahci_ctlp->ahcictl_fm_cap)) {
3481 ddi_fm_ereport_post(ahci_ctlp->ahcictl_dip, buf, ena,
3482 DDI_NOSLEEP, FM_VERSION, DATA_TYPE_UINT8,
3483 FM_EREPORT_VERSION, NULL);
3488 * Check if all handles are correctly allocated.
3490 static int
3491 ahci_check_all_handle(ahci_ctl_t *ahci_ctlp)
3493 int port;
3495 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
3496 return (DDI_FAILURE);
3499 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3500 ahci_port_t *ahci_portp;
3502 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3503 continue;
3505 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3507 mutex_enter(&ahci_portp->ahciport_mutex);
3508 if (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS) {
3509 mutex_exit(&ahci_portp->ahciport_mutex);
3510 return (DDI_FAILURE);
3512 mutex_exit(&ahci_portp->ahciport_mutex);
3515 return (DDI_SUCCESS);
3519 * Check the access handles for the controller. Note that
3520 * ahcictl_pci_conf_handle is only used in attach process.
3522 static int
3523 ahci_check_ctl_handle(ahci_ctl_t *ahci_ctlp)
3525 if ((ahci_check_acc_handle(ahci_ctlp->
3526 ahcictl_pci_conf_handle) != DDI_FM_OK) ||
3527 (ahci_check_acc_handle(ahci_ctlp->
3528 ahcictl_ahci_acc_handle) != DDI_FM_OK)) {
3529 return (DDI_FAILURE);
3531 return (DDI_SUCCESS);
3535 * Check the DMA handles and the access handles of a controller port.
3537 static int
3538 ahci_check_port_handle(ahci_ctl_t *ahci_ctlp, int port)
3540 ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
3541 int slot;
3543 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3545 if ((ahci_check_dma_handle(ahci_portp->
3546 ahciport_rcvd_fis_dma_handle) != DDI_FM_OK) ||
3547 (ahci_check_dma_handle(ahci_portp->
3548 ahciport_cmd_list_dma_handle) != DDI_FM_OK) ||
3549 (ahci_check_acc_handle(ahci_portp->
3550 ahciport_rcvd_fis_acc_handle) != DDI_FM_OK) ||
3551 (ahci_check_acc_handle(ahci_portp->
3552 ahciport_cmd_list_acc_handle) != DDI_FM_OK)) {
3553 return (DDI_FAILURE);
3555 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
3556 if (ahci_check_slot_handle(ahci_portp, slot)
3557 != DDI_SUCCESS) {
3558 return (DDI_FAILURE);
3561 return (DDI_SUCCESS);
3565 * Check the DMA handles and the access handles of a cmd table slot.
3567 static int
3568 ahci_check_slot_handle(ahci_port_t *ahci_portp, int slot)
3570 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3572 if ((ahci_check_acc_handle(ahci_portp->
3573 ahciport_cmd_tables_acc_handle[slot]) != DDI_FM_OK) ||
3574 (ahci_check_dma_handle(ahci_portp->
3575 ahciport_cmd_tables_dma_handle[slot]) != DDI_FM_OK)) {
3576 return (DDI_FAILURE);
3578 return (DDI_SUCCESS);
3582 * Allocate the ports structure, only called by ahci_attach
3584 static int
3585 ahci_alloc_ports_state(ahci_ctl_t *ahci_ctlp)
3587 int port, cport = 0;
3589 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3590 "ahci_alloc_ports_state enter", NULL);
3592 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3594 /* Allocate structures only for the implemented ports */
3595 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3596 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3597 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3598 "hba port %d not implemented", port);
3599 continue;
3602 ahci_ctlp->ahcictl_cport_to_port[cport] = (uint8_t)port;
3603 ahci_ctlp->ahcictl_port_to_cport[port] =
3604 (uint8_t)cport++;
3606 if (ahci_alloc_port_state(ahci_ctlp, port) != AHCI_SUCCESS) {
3607 goto err_out;
3611 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3612 return (AHCI_SUCCESS);
3614 err_out:
3615 for (port--; port >= 0; port--) {
3616 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3617 ahci_dealloc_port_state(ahci_ctlp, port);
3621 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3622 return (AHCI_FAILURE);
3626 * Reverse of ahci_alloc_ports_state(), only called by ahci_detach
3628 static void
3629 ahci_dealloc_ports_state(ahci_ctl_t *ahci_ctlp)
3631 int port;
3633 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3634 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3635 /* if this port is implemented by the HBA */
3636 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp, port))
3637 ahci_dealloc_port_state(ahci_ctlp, port);
3639 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3643 * Drain the taskq.
3645 static void
3646 ahci_drain_ports_taskq(ahci_ctl_t *ahci_ctlp)
3648 ahci_port_t *ahci_portp;
3649 int port;
3651 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3652 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3653 continue;
3656 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3658 mutex_enter(&ahci_portp->ahciport_mutex);
3659 ddi_taskq_wait(ahci_portp->ahciport_event_taskq);
3660 mutex_exit(&ahci_portp->ahciport_mutex);
3665 * Initialize the controller and all ports. And then try to start the ports
3666 * if there are devices attached.
3668 * This routine can be called from three seperate cases: DDI_ATTACH,
3669 * PM_LEVEL_D0 and DDI_RESUME. The DDI_ATTACH case is different from
3670 * other two cases; device signature probing are attempted only during
3671 * DDI_ATTACH case.
3673 static int
3674 ahci_initialize_controller(ahci_ctl_t *ahci_ctlp)
3676 ahci_port_t *ahci_portp;
3677 ahci_addr_t addr;
3678 int port;
3680 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3681 "ahci_initialize_controller enter", NULL);
3683 /* Disable the whole controller interrupts */
3684 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3685 ahci_disable_all_intrs(ahci_ctlp);
3686 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3688 /* Initialize the implemented ports and structures */
3689 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3690 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3691 continue;
3694 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3695 mutex_enter(&ahci_portp->ahciport_mutex);
3698 * Ensure that the controller is not in the running state
3699 * by checking every implemented port's PxCMD register
3701 AHCI_ADDR_SET_PORT(&addr, (uint8_t)port);
3703 if (ahci_initialize_port(ahci_ctlp, ahci_portp, &addr)
3704 != AHCI_SUCCESS) {
3705 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
3706 "ahci_initialize_controller: failed to "
3707 "initialize port %d", port);
3709 * Set the port state to SATA_PSTATE_FAILED if
3710 * failed to initialize it.
3712 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
3715 mutex_exit(&ahci_portp->ahciport_mutex);
3718 /* Enable the whole controller interrupts */
3719 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3720 ahci_enable_all_intrs(ahci_ctlp);
3721 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3723 return (AHCI_SUCCESS);
3727 * Reverse of ahci_initialize_controller()
3729 * We only need to stop the ports and disable the interrupt.
3731 static void
3732 ahci_uninitialize_controller(ahci_ctl_t *ahci_ctlp)
3734 ahci_port_t *ahci_portp;
3735 int port;
3737 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
3738 "ahci_uninitialize_controller enter", NULL);
3740 /* disable all the interrupts. */
3741 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3742 ahci_disable_all_intrs(ahci_ctlp);
3743 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3745 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
3746 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
3747 continue;
3750 ahci_portp = ahci_ctlp->ahcictl_ports[port];
3752 /* Stop the port by clearing PxCMD.ST */
3753 mutex_enter(&ahci_portp->ahciport_mutex);
3756 * Here we must disable the port interrupt because
3757 * ahci_disable_all_intrs only clear GHC.IE, and IS
3758 * register will be still set if PxIE is enabled.
3759 * When ahci shares one IRQ with other drivers, the
3760 * intr handler may claim the intr mistakenly.
3762 ahci_disable_port_intrs(ahci_ctlp, port);
3763 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3764 ahci_portp, port);
3765 mutex_exit(&ahci_portp->ahciport_mutex);
3770 * ahci_alloc_pmult()
3771 * 1. Setting HBA port registers which are necessary for a port multiplier.
3772 * (Set PxCMD.PMA while PxCMD.ST is '0')
3773 * 2. Allocate ahci_pmult_info structure.
3775 * NOTE: Must stop port before the function is called.
3777 static void
3778 ahci_alloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3780 uint32_t port_cmd_status;
3781 uint8_t port = ahci_portp->ahciport_port_num;
3783 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3785 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3786 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3788 /* The port must have been stopped before. */
3789 ASSERT(!(port_cmd_status & AHCI_CMD_STATUS_ST));
3791 if (!(port_cmd_status & AHCI_CMD_STATUS_PMA)) {
3792 /* set PMA bit */
3793 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3794 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3795 port_cmd_status|AHCI_CMD_STATUS_PMA);
3797 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3798 "ahci_alloc_pmult: "
3799 "PxCMD.PMA bit set at port %d.", port);
3802 /* Allocate port multiplier information structure */
3803 if (ahci_portp->ahciport_pmult_info == NULL) {
3804 ahci_portp->ahciport_pmult_info = (ahci_pmult_info_t *)
3805 kmem_zalloc(sizeof (ahci_pmult_info_t), KM_SLEEP);
3808 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
3812 * ahci_dealloc_pmult()
3813 * 1. Clearing related registers when a port multiplier is detached.
3814 * (Clear PxCMD.PMA while PxCMD.ST is '0')
3815 * 2. Deallocate ahci_pmult_info structure.
3817 * NOTE: Must stop port before the function is called.
3819 static void
3820 ahci_dealloc_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
3822 uint32_t port_cmd_status;
3823 uint8_t port = ahci_portp->ahciport_port_num;
3825 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3827 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3828 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3830 if (port_cmd_status & AHCI_CMD_STATUS_PMA) {
3831 /* Clear PMA bit */
3832 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3833 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3834 (port_cmd_status & (~AHCI_CMD_STATUS_PMA)));
3836 AHCIDBG(AHCIDBG_INIT|AHCIDBG_PMULT, ahci_ctlp,
3837 "ahci_dealloc_pmult: "
3838 "PxCMD.PMA bit cleared at port %d.", port);
3841 /* Release port multiplier information structure */
3842 if (ahci_portp->ahciport_pmult_info != NULL) {
3843 kmem_free(ahci_portp->ahciport_pmult_info,
3844 sizeof (ahci_pmult_info_t));
3845 ahci_portp->ahciport_pmult_info = NULL;
3850 * Staggered Spin-up.
3852 static void
3853 ahci_staggered_spin_up(ahci_ctl_t *ahci_ctlp, uint8_t port)
3855 uint32_t cap_status;
3856 uint32_t port_cmd_status;
3858 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
3860 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3861 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
3863 /* Check for staggered spin-up support */
3864 if (!(cap_status & AHCI_HBA_CAP_SSS))
3865 return;
3867 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3868 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3870 /* If PxCMD.SUD == 1, no staggered spin-up is needed */
3871 if (port_cmd_status & AHCI_CMD_STATUS_SUD)
3872 return;
3874 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "Spin-up at port %d", port);
3876 /* Set PxCMD.SUD */
3877 port_cmd_status |= AHCI_CMD_STATUS_SUD;
3878 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
3879 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
3880 port_cmd_status);
3884 * The routine is to initialize a port. First put the port in NotRunning
3885 * state, then enable port interrupt and clear Serror register. And under
3886 * AHCI_ATTACH case, find device signature and then try to start the port.
3888 * Called by
3889 * 1. ahci_initialize_controller
3890 * 2. ahci_intr_phyrdy_change (hotplug)
3892 static int
3893 ahci_initialize_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
3894 ahci_addr_t *addrp)
3896 uint32_t port_sstatus, port_task_file, port_cmd_status;
3897 uint8_t port = addrp->aa_port;
3898 boolean_t resuming = B_TRUE; /* processing DDI_RESUME */
3899 int ret;
3901 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
3903 /* AHCI_ADDR_PORT: We've no idea of the attached device here. */
3904 ASSERT(AHCI_ADDR_IS_PORT(addrp));
3907 * At the time being, only probe ports/devices and get the types of
3908 * attached devices during DDI_ATTACH. In fact, the device can be
3909 * changed during power state changes, but at the time being, we
3910 * don't support the situation.
3912 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
3913 resuming = B_FALSE;
3914 } else {
3915 /* check for DDI_RESUME case */
3916 mutex_exit(&ahci_portp->ahciport_mutex);
3917 mutex_enter(&ahci_ctlp->ahcictl_mutex);
3918 if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH)
3919 resuming = B_FALSE;
3920 mutex_exit(&ahci_ctlp->ahcictl_mutex);
3921 mutex_enter(&ahci_portp->ahciport_mutex);
3924 if (resuming) {
3926 * During the resume, we need to set the PxCLB, PxCLBU, PxFB
3927 * and PxFBU registers in case these registers were cleared
3928 * during the suspend.
3930 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
3931 "ahci_initialize_port: port %d "
3932 "set PxCLB, PxCLBU, PxFB and PxFBU "
3933 "during resume", port);
3935 if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
3936 AHCI_SUCCESS)
3937 return (AHCI_FAILURE);
3940 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3941 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
3943 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
3944 "ahci_initialize_port: port %d ", port);
3947 * Check whether the port is in NotRunning state, if not,
3948 * put the port in NotRunning state
3950 if (port_cmd_status &
3951 (AHCI_CMD_STATUS_ST |
3952 AHCI_CMD_STATUS_CR |
3953 AHCI_CMD_STATUS_FRE |
3954 AHCI_CMD_STATUS_FR)) {
3955 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
3956 ahci_portp, port);
3959 /* Make sure the drive is spun-up */
3960 ahci_staggered_spin_up(ahci_ctlp, port);
3962 /* Disable interrupt */
3963 ahci_disable_port_intrs(ahci_ctlp, port);
3965 /* Device is unknown at first */
3966 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
3968 /* Disable the interface power management */
3969 ahci_disable_interface_pm(ahci_ctlp, port);
3971 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3972 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
3973 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
3974 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
3976 /* Check physcial link status */
3977 if (SSTATUS_GET_IPM(port_sstatus) == SSTATUS_IPM_NODEV_NOPHYCOM ||
3978 SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_NOPHYCOM ||
3980 /* Check interface status */
3981 port_task_file & AHCI_TFD_STS_BSY ||
3982 port_task_file & AHCI_TFD_STS_DRQ ||
3984 /* Check whether port reset must be executed */
3985 ahci_ctlp->ahcictl_cap & AHCI_CAP_INIT_PORT_RESET ||
3987 /* Always reset port on RESUME */
3988 resuming != B_FALSE) {
3990 /* Something went wrong, we need do some reset things */
3991 ret = ahci_port_reset(ahci_ctlp, ahci_portp, addrp);
3993 /* Does port reset succeed on HBA port? */
3994 if (ret != AHCI_SUCCESS) {
3995 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
3996 "ahci_initialize_port:"
3997 "port reset failed at port %d", port);
3998 return (AHCI_FAILURE);
4001 /* Is port failed? */
4002 if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4003 SATA_PSTATE_FAILED) {
4004 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4005 "ahci_initialize_port: port %d state 0x%x",
4006 port, ahci_portp->ahciport_port_state);
4007 return (AHCI_FAILURE);
4011 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4012 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "port %d is ready now.", port);
4015 * Try to get the device signature if the port is not empty.
4017 if (!resuming && AHCIPORT_DEV_TYPE(ahci_portp, addrp) !=
4018 SATA_DTYPE_NONE)
4019 ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4021 /* Return directly if no device connected */
4022 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_NONE) {
4023 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4024 "No device connected to port %d", port);
4025 goto out;
4028 /* If this is a port multiplier, we need do some initialization */
4029 if (AHCIPORT_DEV_TYPE(ahci_portp, addrp) == SATA_DTYPE_PMULT) {
4030 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4031 "Port multiplier found at port %d", port);
4032 ahci_alloc_pmult(ahci_ctlp, ahci_portp);
4035 /* Try to start the port */
4036 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
4037 != AHCI_SUCCESS) {
4038 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4039 "failed to start port %d", port);
4040 return (AHCI_FAILURE);
4042 out:
4043 /* Enable port interrupts */
4044 ahci_enable_port_intrs(ahci_ctlp, port);
4046 return (AHCI_SUCCESS);
4050 * Handle hardware defect, and check the capabilities. For example,
4051 * power management capabilty and MSI capability.
4053 static int
4054 ahci_config_space_init(ahci_ctl_t *ahci_ctlp)
4056 ushort_t caps_ptr, cap_count, cap;
4057 #if AHCI_DEBUG
4058 ushort_t pmcap, pmcsr;
4059 ushort_t msimc;
4060 #endif
4061 uint8_t revision;
4063 ahci_ctlp->ahcictl_venid =
4064 pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4065 PCI_CONF_VENID);
4067 ahci_ctlp->ahcictl_devid =
4068 pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4069 PCI_CONF_DEVID);
4072 * Modify dma_attr_align of ahcictl_buffer_dma_attr. For VT8251, those
4073 * controllers with 0x00 revision id work on 4-byte aligned buffer,
4074 * which is a bug and was fixed after 0x00 revision id controllers.
4076 * Moreover, VT8251 cannot use multiple command slots in the command
4077 * list for non-queued commands because the previous register content
4078 * of PxCI can be re-written in the register write, so a flag will be
4079 * set to record this defect - AHCI_CAP_NO_MCMDLIST_NONQUEUE.
4081 * For VT8251, software reset also has the same defect as the below
4082 * AMD/ATI chipset. That is, software reset will get failed if 0xf
4083 * is filled in pmport field. Therefore, another software reset need
4084 * to be done with 0 filled in pmport field.
4086 if (ahci_ctlp->ahcictl_venid == VIA_VENID) {
4087 revision = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4088 PCI_CONF_REVID);
4089 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4090 "revision id = 0x%x", revision);
4091 if (revision == 0x00) {
4092 ahci_ctlp->ahcictl_buffer_dma_attr.dma_attr_align = 0x4;
4093 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4094 "change ddi_attr_align to 0x4", NULL);
4097 ahci_ctlp->ahcictl_cap |= AHCI_CAP_NO_MCMDLIST_NONQUEUE;
4098 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4099 "VT8251 cannot use multiple command lists for "
4100 "non-queued commands", NULL);
4102 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4106 * AMD/ATI SB600 (0x1002,0x4380) AHCI chipset doesn't support 64-bit
4107 * DMA addressing for communication memory descriptors though S64A bit
4108 * of CAP register declares it supports. Even though 64-bit DMA for
4109 * data buffer works on ASUS M2A-VM with newer BIOS, three other
4110 * motherboards are known not, so both AHCI_CAP_BUF_32BIT_DMA and
4111 * AHCI_CAP_COMMU_32BIT_DMA are set for this controller.
4113 * Due to certain hardware issue, the chipset must do port reset during
4114 * initialization, otherwise, when retrieving device signature,
4115 * software reset will get time out. So AHCI_CAP_INIT_PORT_RESET flag
4116 * need to set.
4118 * For this chipset software reset will get failure if the pmport of
4119 * Register FIS was set with SATA_PMULT_HOSTPORT (0xf) and no port
4120 * multiplier is connected to the port. In order to fix the issue,
4121 * AHCI_CAP_SRST_NO_HOSTPORT flag need to be set, and once software
4122 * reset got failure, the driver will try to do another software reset
4123 * with pmport 0.
4125 if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4126 ahci_ctlp->ahcictl_devid == 0x4380) {
4127 ahci_ctlp->ahcictl_cap |= AHCI_CAP_BUF_32BIT_DMA;
4128 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4129 ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4130 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4132 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4133 "ATI SB600 cannot do 64-bit DMA for both data buffer and "
4134 "communication memory descriptors though CAP indicates "
4135 "support, so force it to use 32-bit DMA", NULL);
4136 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4137 "ATI SB600 need to do a port reset during initialization",
4138 NULL);
4139 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4140 "ATI SB600 will get software reset failure if pmport "
4141 "is set 0xf and no port multiplier is attached", NULL);
4145 * AMD/ATI SB700/710/750/800 and SP5100 AHCI chipset share the same
4146 * vendor ID and device ID (0x1002,0x4391).
4148 * SB700/750 AHCI chipset on some boards doesn't support 64-bit
4149 * DMA addressing for communication memory descriptors though S64A bit
4150 * of CAP register declares the support. However, it does support
4151 * 64-bit DMA for data buffer. So only AHCI_CAP_COMMU_32BIT_DMA is
4152 * set for this controller.
4154 * SB710 has the same initialization issue as SB600, so it also need
4155 * a port reset. That is AHCI_CAP_INIT_PORT_RESET need to set for it.
4157 * SB700 also has the same issue about software reset, and thus
4158 * AHCI_CAP_SRST_NO_HOSTPORT flag also is needed.
4160 if (ahci_ctlp->ahcictl_venid == 0x1002 &&
4161 ahci_ctlp->ahcictl_devid == 0x4391) {
4162 ahci_ctlp->ahcictl_cap |= AHCI_CAP_COMMU_32BIT_DMA;
4163 ahci_ctlp->ahcictl_cap |= AHCI_CAP_INIT_PORT_RESET;
4164 ahci_ctlp->ahcictl_cap |= AHCI_CAP_SRST_NO_HOSTPORT;
4166 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4167 "ATI SB700/750 cannot do 64-bit DMA for communication "
4168 "memory descriptors though CAP indicates support, "
4169 "so force it to use 32-bit DMA", NULL);
4170 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4171 "ATI SB710 need to do a port reset during initialization",
4172 NULL);
4173 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4174 "ATI SB700 will get software reset failure if pmport "
4175 "is set 0xf and no port multiplier is attached", NULL);
4179 * Check if capabilities list is supported and if so,
4180 * get initial capabilities pointer and clear bits 0,1.
4182 if (pci_config_get16(ahci_ctlp->ahcictl_pci_conf_handle,
4183 PCI_CONF_STAT) & PCI_STAT_CAP) {
4184 caps_ptr = P2ALIGN(pci_config_get8(
4185 ahci_ctlp->ahcictl_pci_conf_handle,
4186 PCI_CONF_CAP_PTR), 4);
4187 } else {
4188 caps_ptr = PCI_CAP_NEXT_PTR_NULL;
4192 * Walk capabilities if supported.
4194 for (cap_count = 0; caps_ptr != PCI_CAP_NEXT_PTR_NULL; ) {
4197 * Check that we haven't exceeded the maximum number of
4198 * capabilities and that the pointer is in a valid range.
4200 if (++cap_count > PCI_CAP_MAX_PTR) {
4201 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4202 "too many device capabilities", NULL);
4203 return (AHCI_FAILURE);
4205 if (caps_ptr < PCI_CAP_PTR_OFF) {
4206 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4207 "capabilities pointer 0x%x out of range",
4208 caps_ptr);
4209 return (AHCI_FAILURE);
4213 * Get next capability and check that it is valid.
4214 * For now, we only support power management.
4216 cap = pci_config_get8(ahci_ctlp->ahcictl_pci_conf_handle,
4217 caps_ptr);
4218 switch (cap) {
4219 case PCI_CAP_ID_PM:
4221 /* power management supported */
4222 ahci_ctlp->ahcictl_cap |= AHCI_CAP_PM;
4224 /* Save PMCSR offset */
4225 ahci_ctlp->ahcictl_pmcsr_offset = caps_ptr + PCI_PMCSR;
4227 #if AHCI_DEBUG
4228 pmcap = pci_config_get16(
4229 ahci_ctlp->ahcictl_pci_conf_handle,
4230 caps_ptr + PCI_PMCAP);
4231 pmcsr = pci_config_get16(
4232 ahci_ctlp->ahcictl_pci_conf_handle,
4233 ahci_ctlp->ahcictl_pmcsr_offset);
4234 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4235 "Power Management capability found PCI_PMCAP "
4236 "= 0x%x PCI_PMCSR = 0x%x", pmcap, pmcsr);
4237 if ((pmcap & 0x3) == 0x3)
4238 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4239 "PCI Power Management Interface "
4240 "spec 1.2 compliant", NULL);
4241 #endif
4242 break;
4244 case PCI_CAP_ID_MSI:
4245 #if AHCI_DEBUG
4246 msimc = pci_config_get16(
4247 ahci_ctlp->ahcictl_pci_conf_handle,
4248 caps_ptr + PCI_MSI_CTRL);
4249 AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4250 "Message Signaled Interrupt capability found "
4251 "MSICAP_MC.MMC = 0x%x", (msimc & 0xe) >> 1);
4252 #endif
4253 AHCIDBG(AHCIDBG_MSI, ahci_ctlp,
4254 "MSI capability found", NULL);
4255 break;
4257 case PCI_CAP_ID_PCIX:
4258 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4259 "PCI-X capability found", NULL);
4260 break;
4262 case PCI_CAP_ID_PCI_E:
4263 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4264 "PCI Express capability found", NULL);
4265 break;
4267 case PCI_CAP_ID_MSI_X:
4268 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4269 "MSI-X capability found", NULL);
4270 break;
4272 case PCI_CAP_ID_SATA:
4273 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4274 "SATA capability found", NULL);
4275 break;
4277 case PCI_CAP_ID_VS:
4278 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4279 "Vendor Specific capability found", NULL);
4280 break;
4282 default:
4283 AHCIDBG(AHCIDBG_PM, ahci_ctlp,
4284 "unrecognized capability 0x%x", cap);
4285 break;
4289 * Get next capabilities pointer and clear bits 0,1.
4291 caps_ptr = P2ALIGN(pci_config_get8(
4292 ahci_ctlp->ahcictl_pci_conf_handle,
4293 (caps_ptr + PCI_CAP_NEXT_PTR)), 4);
4296 return (AHCI_SUCCESS);
4300 * Read/Write a register at port multiplier by SATA READ PORTMULT / SATA WRITE
4301 * PORTMULT command. SYNC & POLLING mode is used.
4303 static int
4304 ahci_rdwr_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4305 uint8_t regn, uint32_t *pregv, uint8_t type)
4307 ahci_port_t *ahci_portp;
4308 ahci_addr_t pmult_addr;
4309 sata_pkt_t *spkt;
4310 sata_cmd_t *scmd;
4311 sata_device_t sata_device;
4312 uint8_t port = addrp->aa_port;
4313 uint8_t pmport = addrp->aa_pmport;
4314 uint8_t cport;
4315 uint32_t intr_mask;
4316 int rval;
4317 char portstr[10];
4319 SET_PORTSTR(portstr, addrp);
4320 cport = ahci_ctlp->ahcictl_port_to_cport[port];
4321 ahci_portp = ahci_ctlp->ahcictl_ports[port];
4323 ASSERT(AHCI_ADDR_IS_PMPORT(addrp) || AHCI_ADDR_IS_PMULT(addrp));
4324 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4326 /* Check the existence of the port multiplier */
4327 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT)
4328 return (AHCI_FAILURE);
4330 /* Request a READ/WRITE PORTMULT sata packet. */
4331 bzero(&sata_device, sizeof (sata_device_t));
4332 sata_device.satadev_addr.cport = cport;
4333 sata_device.satadev_addr.pmport = pmport;
4334 sata_device.satadev_addr.qual = SATA_ADDR_PMULT;
4335 sata_device.satadev_rev = SATA_DEVICE_REV;
4338 * Make sure no command is outstanding here. All R/W PMULT requests
4339 * come from
4341 * 1. ahci_attach()
4342 * The port should be empty.
4344 * 2. ahci_tran_probe_port()
4345 * Any request from SATA framework (via ahci_tran_start) should be
4346 * rejected if R/W PMULT command is outstanding.
4348 * If we are doing mopping, do not check those flags because no
4349 * command will be actually outstanding.
4351 * If the port has been occupied by any other commands, the probe
4352 * function will return a SATA_RETRY. SATA framework will retry
4353 * later.
4355 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
4356 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4357 "R/W PMULT failed: R/W PMULT in progress at port %d.",
4358 port, ahci_portp->ahciport_flags);
4359 return (AHCI_FAILURE);
4362 if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) && (
4363 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
4364 NCQ_CMD_IN_PROGRESS(ahci_portp) ||
4365 NON_NCQ_CMD_IN_PROGRESS(ahci_portp))) {
4366 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4367 "R/W PMULT failed: port %d is occupied (flags 0x%x).",
4368 port, ahci_portp->ahciport_flags);
4369 return (AHCI_FAILURE);
4373 * The port multiplier is gone. This may happen when
4374 * 1. Cutting off the power of an enclosure. The device lose the power
4375 * before port multiplier.
4376 * 2. Disconnecting the port multiplier during hot-plugging a sub-drive.
4378 * The issued command should be aborted and the following command
4379 * should not be continued.
4381 if (!(ahci_portp->ahciport_port_state & SATA_STATE_READY)) {
4382 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4383 "READ/WRITE PMULT failed: "
4384 "port-mult is removed from port %d", port);
4385 return (AHCI_FAILURE);
4388 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDWR_PMULT;
4390 spkt = sata_get_rdwr_pmult_pkt(ahci_ctlp->ahcictl_dip,
4391 &sata_device, regn, *pregv, type);
4394 * READ/WRITE PORTMULT command is intended to sent to the control port
4395 * of the port multiplier.
4397 AHCI_ADDR_SET_PMULT(&pmult_addr, addrp->aa_port);
4399 ahci_portp->ahciport_rdwr_pmult_pkt = spkt;
4401 /* No interrupt here. Store the interrupt enable mask. */
4402 intr_mask = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4403 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
4404 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4405 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
4407 rval = ahci_do_sync_start(ahci_ctlp, ahci_portp, &pmult_addr, spkt);
4409 if (rval == AHCI_SUCCESS &&
4410 spkt->satapkt_reason == SATA_PKT_COMPLETED) {
4411 if (type == SATA_RDWR_PMULT_PKT_TYPE_READ) {
4412 scmd = &spkt->satapkt_cmd;
4413 *pregv = scmd->satacmd_lba_high_lsb << 24 |
4414 scmd->satacmd_lba_mid_lsb << 16 |
4415 scmd->satacmd_lba_low_lsb << 8 |
4416 scmd->satacmd_sec_count_lsb;
4418 } else {
4419 /* Failed or not completed. */
4420 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4421 "ahci_rdwr_pmult: cannot [%s] %s[%d] at port %s",
4422 type == SATA_RDWR_PMULT_PKT_TYPE_READ?"Read":"Write",
4423 AHCI_ADDR_IS_PMULT(addrp)?"gscr":"pscr", regn, portstr);
4424 rval = AHCI_FAILURE;
4426 out:
4427 /* Restore the interrupt mask */
4428 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4429 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), intr_mask);
4431 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDWR_PMULT;
4432 ahci_portp->ahciport_rdwr_pmult_pkt = NULL;
4433 sata_free_rdwr_pmult_pkt(spkt);
4434 return (rval);
4437 static int
4438 ahci_read_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4439 uint8_t regn, uint32_t *pregv)
4441 return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, pregv,
4442 SATA_RDWR_PMULT_PKT_TYPE_READ);
4445 static int
4446 ahci_write_pmult(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4447 uint8_t regn, uint32_t regv)
4449 return ahci_rdwr_pmult(ahci_ctlp, addrp, regn, &regv,
4450 SATA_RDWR_PMULT_PKT_TYPE_WRITE);
4453 #define READ_PMULT(addrp, r, pv, out) \
4454 if (ahci_read_pmult(ahci_ctlp, addrp, r, pv) != AHCI_SUCCESS) \
4455 goto out;
4457 #define WRITE_PMULT(addrp, r, v, out) \
4458 if (ahci_write_pmult(ahci_ctlp, addrp, r, v) != AHCI_SUCCESS) \
4459 goto out;
4462 * Update sata registers on port multiplier, including GSCR/PSCR registers.
4463 * ahci_update_pmult_gscr()
4464 * ahci_update_pmult_pscr()
4466 static int
4467 ahci_update_pmult_gscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4468 sata_pmult_gscr_t *sg)
4470 ASSERT(MUTEX_HELD(
4471 &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4473 READ_PMULT(addrp, SATA_PMULT_GSCR0, &sg->gscr0, err);
4474 READ_PMULT(addrp, SATA_PMULT_GSCR1, &sg->gscr1, err);
4475 READ_PMULT(addrp, SATA_PMULT_GSCR2, &sg->gscr2, err);
4476 READ_PMULT(addrp, SATA_PMULT_GSCR64, &sg->gscr64, err);
4478 return (AHCI_SUCCESS);
4480 err: /* R/W PMULT error */
4481 return (AHCI_FAILURE);
4484 static int
4485 ahci_update_pmult_pscr(ahci_ctl_t *ahci_ctlp, ahci_addr_t *addrp,
4486 sata_device_t *sd)
4488 ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4489 ASSERT(MUTEX_HELD(
4490 &ahci_ctlp->ahcictl_ports[addrp->aa_port]->ahciport_mutex));
4492 READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &sd->satadev_scr.sstatus, err);
4493 READ_PMULT(addrp, SATA_PMULT_REG_SERR, &sd->satadev_scr.serror, err);
4494 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &sd->satadev_scr.scontrol, err);
4495 READ_PMULT(addrp, SATA_PMULT_REG_SACT, &sd->satadev_scr.sactive, err);
4497 return (AHCI_SUCCESS);
4499 err: /* R/W PMULT error */
4500 return (AHCI_FAILURE);
4504 * ahci_initialize_pmult()
4506 * Initialize a port multiplier, including
4507 * 1. Enable FEATURES register at port multiplier. (SATA Chp.16)
4508 * 2. Redefine MASK register. (SATA Chap 16.?)
4510 static int
4511 ahci_initialize_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4512 ahci_addr_t *addrp, sata_device_t *sd)
4514 sata_pmult_gscr_t sg;
4515 uint32_t gscr64;
4516 uint8_t port = addrp->aa_port;
4518 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4520 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4521 "[Initialize] Port-multiplier at port %d.", port);
4524 * Enable features of port multiplier. Currently only
4525 * Asynchronous Notification is enabled.
4527 /* Check gscr64 for supported features. */
4528 READ_PMULT(addrp, SATA_PMULT_GSCR64, &gscr64, err);
4530 if (gscr64 & SATA_PMULT_CAP_SNOTIF) {
4531 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4532 "port %d: Port Multiplier supports "
4533 "Asynchronous Notification.", port);
4535 /* Write to gscr96 to enabled features */
4536 WRITE_PMULT(addrp, SATA_PMULT_GSCR96,
4537 SATA_PMULT_CAP_SNOTIF, err);
4539 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4540 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4541 AHCI_SNOTIF_CLEAR_ALL);
4542 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4543 "port %d: PMult PxSNTF cleared.", port);
4548 * Now we need to update gscr33 register to enable hot-plug interrupt
4549 * for sub devices behind port multiplier.
4551 WRITE_PMULT(addrp, SATA_PMULT_GSCR33, (0x1ffff), err);
4552 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4553 "port %d: gscr33 mask set to %x.", port, (0x1ffff));
4556 * Fetch the number of device ports of the port multiplier
4558 if (ahci_update_pmult_gscr(ahci_ctlp, addrp, &sg) != AHCI_SUCCESS)
4559 return (AHCI_FAILURE);
4561 /* Register the port multiplier to SATA Framework. */
4562 mutex_exit(&ahci_portp->ahciport_mutex);
4563 sata_register_pmult(ahci_ctlp->ahcictl_dip, sd, &sg);
4564 mutex_enter(&ahci_portp->ahciport_mutex);
4566 ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports =
4567 sd->satadev_add_info & SATA_PMULT_PORTNUM_MASK;
4569 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
4570 "port %d: pmult sub-port number updated to %x.", port,
4571 ahci_portp->ahciport_pmult_info->ahcipmi_num_dev_ports);
4573 /* Till now port-mult is successfully initialized */
4574 ahci_portp->ahciport_port_state |= SATA_DSTATE_PMULT_INIT;
4575 return (AHCI_SUCCESS);
4577 err: /* R/W PMULT error */
4578 return (AHCI_FAILURE);
4582 * Initialize a port multiplier port. According to spec, firstly we need
4583 * issue a COMRESET, then a software reset to get its signature.
4585 * NOTE: This function should only be called in ahci_probe_pmport()
4587 static int
4588 ahci_initialize_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4589 ahci_addr_t *addrp)
4591 uint32_t finished_tags = 0, reset_tags = 0, slot_status = 0;
4592 uint8_t port = addrp->aa_port;
4593 uint8_t pmport = addrp->aa_pmport;
4594 int ret = AHCI_FAILURE;
4596 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4597 ASSERT(AHCI_ADDR_IS_PMPORT(addrp));
4599 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
4600 "ahci_initialize_pmport: port %d:%d", port, pmport);
4602 /* Check HBA port state */
4603 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
4604 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4605 "ahci_initialize_pmport:"
4606 "port %d:%d Port Multiplier is failed.",
4607 port, pmport);
4608 return (AHCI_FAILURE);
4611 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_HOTPLUG) {
4612 return (AHCI_FAILURE);
4614 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
4616 /* Checking for outstanding commands */
4617 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4618 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4619 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
4620 reset_tags = slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4621 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
4622 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4623 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
4624 reset_tags = slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4627 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
4628 ahci_portp->ahciport_mop_in_progress++;
4630 /* Clear status */
4631 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_UNKNOWN);
4633 /* Firstly assume an unknown device */
4634 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
4636 ahci_disable_port_intrs(ahci_ctlp, port);
4638 /* port reset is necessary for port multiplier port */
4639 if (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp) != AHCI_SUCCESS) {
4640 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ERRS, ahci_ctlp,
4641 "ahci_initialize_pmport:"
4642 "port reset failed at port %d:%d",
4643 port, pmport);
4644 goto out;
4647 /* Is port failed? */
4648 if (AHCIPORT_GET_STATE(ahci_portp, addrp) &
4649 SATA_PSTATE_FAILED) {
4650 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4651 "ahci_initialize_pmport: port %d:%d failed. "
4652 "state = 0x%x", port, pmport,
4653 ahci_portp->ahciport_port_state);
4654 goto out;
4657 /* Is there any device attached? */
4658 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, addrp)
4659 == SATA_DTYPE_NONE) {
4660 /* Do not waste time on an empty port */
4661 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
4662 "ahci_initialize_pmport: No device is found "
4663 "at port %d:%d", port, pmport);
4664 ret = AHCI_SUCCESS;
4665 goto out;
4668 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_STATE_READY);
4669 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
4670 "port %d:%d is ready now.", port, pmport);
4673 * Till now we can assure a device attached to that HBA port and work
4674 * correctly. Now try to get the device signature. This is an optional
4675 * step. If failed, unknown device is assumed, then SATA module will
4676 * continue to use IDENTIFY DEVICE to get the information of the
4677 * device.
4679 ahci_find_dev_signature(ahci_ctlp, ahci_portp, addrp);
4681 ret = AHCI_SUCCESS;
4683 out:
4684 /* Next try to mop the pending commands */
4685 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp))
4686 finished_tags = ahci_portp->ahciport_pending_tags &
4687 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
4688 else if (NCQ_CMD_IN_PROGRESS(ahci_portp))
4689 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
4690 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
4691 reset_tags &= ~finished_tags;
4693 ahci_mop_commands(ahci_ctlp,
4694 ahci_portp,
4695 slot_status,
4696 0, /* failed tags */
4697 0, /* timeout tags */
4698 0, /* aborted tags */
4699 reset_tags); /* reset tags */
4701 /* Clear PxSNTF register if supported. */
4702 if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
4703 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4704 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
4705 AHCI_SNOTIF_CLEAR_ALL);
4708 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
4709 ahci_enable_port_intrs(ahci_ctlp, port);
4710 return (ret);
4714 * ahci_probe_pmult()
4716 * This function will be called to probe a port multiplier, which will
4717 * handle hotplug events on port multiplier ports.
4719 * NOTE: Only called from ahci_tran_probe_port()
4721 static int
4722 ahci_probe_pmult(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4723 ahci_addr_t *addrp)
4725 sata_device_t sdevice;
4726 ahci_addr_t pmport_addr;
4727 uint32_t gscr32, port_hotplug_tags;
4728 uint32_t pmport_sstatus;
4729 int dev_exists_now = 0, dev_existed_previously = 0;
4730 uint8_t port = addrp->aa_port;
4731 int npmport;
4733 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4735 /* The bits in GSCR32 refers to the pmport that has a hot-plug event. */
4736 READ_PMULT(addrp, SATA_PMULT_GSCR32, &gscr32, err);
4737 port_hotplug_tags = gscr32 & AHCI_PMPORT_MASK(ahci_portp);
4739 do {
4740 npmport = ddi_ffs(port_hotplug_tags) - 1;
4741 if (npmport == -1)
4742 /* no pending hot plug events. */
4743 return (AHCI_SUCCESS);
4745 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4746 "hot-plug event at port %d:%d", port, npmport);
4748 AHCI_ADDR_SET_PMPORT(&pmport_addr, port, (uint8_t)npmport);
4750 /* Check previous device at that port */
4751 if (AHCIPORT_GET_DEV_TYPE(ahci_portp, &pmport_addr)
4752 != SATA_DTYPE_NONE)
4753 dev_existed_previously = 1;
4755 /* PxSStatus tells the presence of device. */
4756 READ_PMULT(&pmport_addr, SATA_PMULT_REG_SSTS,
4757 &pmport_sstatus, err);
4759 if (SSTATUS_GET_DET(pmport_sstatus) ==
4760 SSTATUS_DET_DEVPRE_PHYCOM)
4761 dev_exists_now = 1;
4764 * Clear PxSERR is critical. The transition from 0 to 1 will
4765 * emit a FIS which generates an asynchronous notification
4766 * event at controller. If we fail to clear the PxSERR, the
4767 * Async Notif events will no longer be activated on this
4768 * pmport.
4770 WRITE_PMULT(&pmport_addr, SATA_PMULT_REG_SERR,
4771 AHCI_SERROR_CLEAR_ALL, err);
4773 bzero((void *)&sdevice, sizeof (sata_device_t));
4774 sdevice.satadev_addr.cport = ahci_ctlp->
4775 ahcictl_port_to_cport[port];
4776 sdevice.satadev_addr.qual = SATA_ADDR_PMPORT;
4777 sdevice.satadev_addr.pmport = (uint8_t)npmport;
4778 sdevice.satadev_state = SATA_PSTATE_PWRON;
4780 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4781 "[Existence] %d -> %d", dev_existed_previously,
4782 dev_exists_now);
4784 if (dev_exists_now) {
4785 if (dev_existed_previously) {
4786 /* Link (may) not change: Exist -> Exist * */
4787 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
4788 "ahci_probe_pmult: port %d:%d "
4789 "device link lost/established",
4790 port, npmport);
4792 mutex_exit(&ahci_portp->ahciport_mutex);
4793 sata_hba_event_notify(
4794 ahci_ctlp->ahcictl_sata_hba_tran->
4795 sata_tran_hba_dip,
4796 &sdevice,
4797 SATA_EVNT_LINK_LOST|
4798 SATA_EVNT_LINK_ESTABLISHED);
4799 mutex_enter(&ahci_portp->ahciport_mutex);
4800 } else {
4801 /* Link change: None -> Exist */
4802 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4803 "ahci_probe_pmult: port %d:%d "
4804 "device link established", port, npmport);
4806 /* Clear port state */
4807 AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4808 SATA_STATE_UNKNOWN);
4809 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4810 "ahci_probe_pmult: port %d "
4811 "ahciport_port_state [Cleared].", port);
4813 mutex_exit(&ahci_portp->ahciport_mutex);
4814 sata_hba_event_notify(
4815 ahci_ctlp->ahcictl_sata_hba_tran->
4816 sata_tran_hba_dip,
4817 &sdevice,
4818 SATA_EVNT_LINK_ESTABLISHED);
4819 mutex_enter(&ahci_portp->ahciport_mutex);
4821 } else { /* No device exists now */
4822 if (dev_existed_previously) {
4824 /* Link change: Exist -> None */
4825 AHCIDBG(AHCIDBG_EVENT|AHCIDBG_PMULT, ahci_ctlp,
4826 "ahci_probe_pmult: port %d:%d "
4827 "device link lost", port, npmport);
4829 /* An existing device is lost. */
4830 AHCIPORT_SET_STATE(ahci_portp, &pmport_addr,
4831 SATA_STATE_UNKNOWN);
4832 AHCIPORT_SET_DEV_TYPE(ahci_portp, &pmport_addr,
4833 SATA_DTYPE_NONE);
4835 mutex_exit(&ahci_portp->ahciport_mutex);
4836 sata_hba_event_notify(
4837 ahci_ctlp->ahcictl_sata_hba_tran->
4838 sata_tran_hba_dip,
4839 &sdevice,
4840 SATA_EVNT_LINK_LOST);
4841 mutex_enter(&ahci_portp->ahciport_mutex);
4845 CLEAR_BIT(port_hotplug_tags, npmport);
4846 } while (port_hotplug_tags != 0);
4848 return (AHCI_SUCCESS);
4850 err: /* R/W PMULT error */
4851 return (AHCI_FAILURE);
4855 * Probe and initialize a port multiplier port.
4856 * A port multiplier port could only be initilaizer here.
4858 static int
4859 ahci_probe_pmport(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4860 ahci_addr_t *addrp, sata_device_t *sd)
4862 uint32_t port_state;
4863 uint8_t port = addrp->aa_port;
4864 ahci_addr_t addr_pmult;
4866 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4869 * Check the parent - port multiplier first.
4873 * Parent port multiplier might have been removed. This event will be
4874 * ignored and failure.
4876 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
4877 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
4878 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4879 "ahci_tran_probe_port: "
4880 "parent device removed, ignore event.", NULL);
4882 return (AHCI_FAILURE);
4885 /* The port is ready? */
4886 port_state = ahci_portp->ahciport_port_state;
4887 if (!(port_state & SATA_STATE_READY)) {
4888 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4889 "ahci_tran_probe_port: "
4890 "parent port-mult is NOT ready.", NULL);
4892 if (ahci_restart_port_wait_till_ready(ahci_ctlp,
4893 ahci_portp, port, AHCI_PORT_RESET, NULL) !=
4894 AHCI_SUCCESS) {
4895 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
4896 "ahci_tran_probe_port: "
4897 "restart port-mult failed.", NULL);
4898 return (AHCI_FAILURE);
4903 * If port-mult is restarted due to some reason, we need
4904 * re-initialized the PMult.
4906 if (!(port_state & SATA_DSTATE_PMULT_INIT)) {
4907 /* Initialize registers on a port multiplier */
4908 AHCI_ADDR_SET_PMULT(&addr_pmult, addrp->aa_port);
4909 if (ahci_initialize_pmult(ahci_ctlp, ahci_portp,
4910 &addr_pmult, sd) != AHCI_SUCCESS)
4911 return (AHCI_FAILURE);
4915 * Then we check the port-mult port
4917 /* Is this pmport initialized? */
4918 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
4919 if (!(port_state & SATA_STATE_READY)) {
4921 /* ahci_initialize_pmport() will set READY state */
4922 if (ahci_initialize_pmport(ahci_ctlp,
4923 ahci_portp, addrp) != AHCI_SUCCESS)
4924 return (AHCI_FAILURE);
4927 return (AHCI_SUCCESS);
4931 * AHCI device reset ...; a single device on one of the ports is reset,
4932 * but the HBA and physical communication remain intact. This is the
4933 * least intrusive.
4935 * When issuing a software reset sequence, there should not be other
4936 * commands in the command list, so we will first clear and then re-set
4937 * PxCMD.ST to clear PxCI. And before issuing the software reset,
4938 * the port must be idle and PxTFD.STS.BSY and PxTFD.STS.DRQ must be
4939 * cleared unless command list override (PxCMD.CLO) is supported.
4941 static int
4942 ahci_software_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
4943 ahci_addr_t *addrp)
4945 ahci_fis_h2d_register_t *h2d_register_fisp;
4946 ahci_cmd_table_t *cmd_table;
4947 ahci_cmd_header_t *cmd_header;
4948 uint32_t port_cmd_status, port_cmd_issue, port_task_file;
4949 int slot, loop_count;
4950 uint8_t port = addrp->aa_port;
4951 uint8_t pmport = addrp->aa_pmport;
4952 int rval = AHCI_FAILURE;
4954 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
4956 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
4957 "port %d:%d device software resetting (FIS)", port, pmport);
4959 /* First clear PxCMD.ST (AHCI v1.2 10.4.1) */
4960 if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
4961 port) != AHCI_SUCCESS) {
4962 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4963 "ahci_software_reset: cannot stop HBA port %d.", port);
4964 goto out;
4967 /* Check PxTFD.STS.BSY and PxTFD.STS.DRQ */
4968 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4969 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
4971 if (port_task_file & AHCI_TFD_STS_BSY ||
4972 port_task_file & AHCI_TFD_STS_DRQ) {
4973 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_SCLO)) {
4974 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4975 "PxTFD.STS.BSY/DRQ is set (PxTFD=0x%x), "
4976 "cannot issue a software reset.", port_task_file);
4977 goto out;
4981 * If HBA Support CLO, as Command List Override (CAP.SCLO is
4982 * set), PxCMD.CLO bit should be set before set PxCMD.ST, in
4983 * order to clear PxTFD.STS.BSY and PxTFD.STS.DRQ.
4985 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
4986 "PxTFD.STS.BSY/DRQ is set, try SCLO.", NULL)
4988 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
4989 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
4990 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
4991 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
4992 port_cmd_status|AHCI_CMD_STATUS_CLO);
4994 /* Waiting till PxCMD.SCLO bit is cleared */
4995 loop_count = 0;
4996 do {
4997 /* Wait for 10 millisec */
4998 drv_usecwait(AHCI_10MS_USECS);
5000 /* We are effectively timing out after 1 sec. */
5001 if (loop_count++ > 100) {
5002 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5003 "SCLO time out. port %d is busy.", port);
5004 goto out;
5007 port_cmd_status =
5008 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5009 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5010 } while (port_cmd_status & AHCI_CMD_STATUS_CLO);
5012 /* Re-check */
5013 port_task_file = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5014 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5015 if (port_task_file & AHCI_TFD_STS_BSY ||
5016 port_task_file & AHCI_TFD_STS_DRQ) {
5017 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5018 "SCLO cannot clear PxTFD.STS.BSY/DRQ (PxTFD=0x%x)",
5019 port_task_file);
5020 goto out;
5024 /* Then start port */
5025 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
5026 != AHCI_SUCCESS) {
5027 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5028 "ahci_software_reset: cannot start AHCI port %d.", port);
5029 goto out;
5033 * When ahci_port.ahciport_mop_in_progress is set, A non-zero
5034 * ahci_port.ahciport_pending_ncq_tags may fail
5035 * ahci_claim_free_slot(). Actually according to spec, by clearing
5036 * PxCMD.ST there is no command outstanding while executing software
5037 * reseting. Hence we directly use slot 0 instead of
5038 * ahci_claim_free_slot().
5040 slot = 0;
5042 /* Now send the first H2D Register FIS with SRST set to 1 */
5043 cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5044 bzero((void *)cmd_table, ahci_cmd_table_size);
5046 h2d_register_fisp =
5047 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5049 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5050 SET_FIS_PMP(h2d_register_fisp, pmport);
5051 SET_FIS_DEVCTL(h2d_register_fisp, SATA_DEVCTL_SRST);
5053 /* Set Command Header in Command List */
5054 cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5055 BZERO_DESCR_INFO(cmd_header);
5056 BZERO_PRD_BYTE_COUNT(cmd_header);
5057 SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5058 SET_PORT_MULTI_PORT(cmd_header, pmport);
5060 SET_CLEAR_BUSY_UPON_R_OK(cmd_header, 1);
5061 SET_RESET(cmd_header, 1);
5062 SET_WRITE(cmd_header, 1);
5064 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5066 ahci_cmd_table_size,
5067 DDI_DMA_SYNC_FORDEV);
5069 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5070 slot * sizeof (ahci_cmd_header_t),
5071 sizeof (ahci_cmd_header_t),
5072 DDI_DMA_SYNC_FORDEV);
5074 /* Indicate to the HBA that a command is active. */
5075 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5076 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5077 (0x1 << slot));
5079 loop_count = 0;
5081 /* Loop till the first command is finished */
5082 do {
5083 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5084 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5086 /* We are effectively timing out after 1 sec. */
5087 if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5088 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5089 "the first SRST FIS is timed out, "
5090 "loop_count = %d", loop_count);
5091 goto out;
5093 /* Wait for 10 millisec */
5094 drv_usecwait(AHCI_10MS_USECS);
5095 } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5097 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5098 "ahci_software_reset: 1st loop count: %d, "
5099 "port_cmd_issue = 0x%x, slot = 0x%x",
5100 loop_count, port_cmd_issue, slot);
5102 /* According to ATA spec, we need wait at least 5 microsecs here. */
5103 drv_usecwait(AHCI_1MS_USECS);
5105 /* Now send the second H2D Register FIS with SRST cleard to zero */
5106 cmd_table = ahci_portp->ahciport_cmd_tables[slot];
5107 bzero((void *)cmd_table, ahci_cmd_table_size);
5109 h2d_register_fisp =
5110 &(cmd_table->ahcict_command_fis.ahcifc_fis.ahcifc_h2d_register);
5112 SET_FIS_TYPE(h2d_register_fisp, AHCI_H2D_REGISTER_FIS_TYPE);
5113 SET_FIS_PMP(h2d_register_fisp, pmport);
5115 /* Set Command Header in Command List */
5116 cmd_header = &ahci_portp->ahciport_cmd_list[slot];
5117 BZERO_DESCR_INFO(cmd_header);
5118 BZERO_PRD_BYTE_COUNT(cmd_header);
5119 SET_COMMAND_FIS_LENGTH(cmd_header, 5);
5120 SET_PORT_MULTI_PORT(cmd_header, pmport);
5122 SET_WRITE(cmd_header, 1);
5124 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_tables_dma_handle[slot],
5126 ahci_cmd_table_size,
5127 DDI_DMA_SYNC_FORDEV);
5129 (void) ddi_dma_sync(ahci_portp->ahciport_cmd_list_dma_handle,
5130 slot * sizeof (ahci_cmd_header_t),
5131 sizeof (ahci_cmd_header_t),
5132 DDI_DMA_SYNC_FORDEV);
5134 /* Indicate to the HBA that a command is active. */
5135 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5136 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port),
5137 (0x1 << slot));
5139 loop_count = 0;
5141 /* Loop till the second command is finished */
5142 do {
5143 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5144 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
5146 /* We are effectively timing out after 1 sec. */
5147 if (loop_count++ > AHCI_POLLRATE_PORT_SOFTRESET) {
5148 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5149 "the second SRST FIS is timed out, "
5150 "loop_count = %d", loop_count);
5151 goto out;
5154 /* Wait for 10 millisec */
5155 drv_usecwait(AHCI_10MS_USECS);
5156 } while (port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp) & (0x1 << slot));
5158 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5159 "ahci_software_reset: 2nd loop count: %d, "
5160 "port_cmd_issue = 0x%x, slot = 0x%x",
5161 loop_count, port_cmd_issue, slot);
5163 if ((ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) ||
5164 (ahci_check_port_handle(ahci_ctlp, port) != DDI_SUCCESS)) {
5165 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
5166 DDI_SERVICE_UNAFFECTED);
5167 goto out;
5170 rval = AHCI_SUCCESS;
5171 out:
5172 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5173 "ahci_software_reset: %s at port %d:%d",
5174 rval == AHCI_SUCCESS ? "succeed" : "failed",
5175 port, pmport);
5177 return (rval);
5181 * AHCI port reset ...; the physical communication between the HBA and device
5182 * on a port are disabled. This is more intrusive.
5184 * When an HBA or port reset occurs, Phy communication is going to
5185 * be re-established with the device through a COMRESET followed by the
5186 * normal out-of-band communication sequence defined in Serial ATA. At
5187 * the end of reset, the device, if working properly, will send a D2H
5188 * Register FIS, which contains the device signature. When the HBA receives
5189 * this FIS, it updates PxTFD.STS and PxTFD.ERR register fields, and updates
5190 * the PxSIG register with the signature.
5192 * NOTE: It is expected both PxCMD.ST and PxCMD.CR are cleared before the
5193 * function is called. If not, it is assumed the interface is in hung
5194 * condition.
5196 static int
5197 ahci_port_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5198 ahci_addr_t *addrp)
5200 ahci_addr_t pmult_addr;
5201 uint32_t port_cmd_status;
5202 uint32_t port_scontrol, port_sstatus;
5203 uint32_t port_task_file;
5204 uint32_t port_state;
5205 uint8_t port = addrp->aa_port;
5207 int loop_count;
5208 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5210 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5212 /* Target is a port multiplier port? */
5213 if (AHCI_ADDR_IS_PMPORT(addrp))
5214 return (ahci_pmport_reset(ahci_ctlp, ahci_portp, addrp));
5216 /* Otherwise it must be an HBA port. */
5217 ASSERT(AHCI_ADDR_IS_PORT(addrp));
5219 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5220 "Port %d port resetting...", port);
5221 ahci_portp->ahciport_port_state = 0;
5223 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5224 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5227 * According to the spec, SUD bit should be set here,
5228 * but JMicron JMB363 doesn't follow it, so print
5229 * a debug message.
5231 if (!(port_cmd_status & AHCI_CMD_STATUS_SUD))
5232 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5233 "ahci_port_reset: port %d SUD bit not set", port);
5235 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5236 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5237 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5239 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5240 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5241 port_scontrol);
5243 /* Enable PxCMD.FRE to read device */
5244 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5245 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5246 port_cmd_status|AHCI_CMD_STATUS_FRE);
5249 * The port enters P:StartComm state, and the HBA tells the link layer
5250 * to start communication, which involves sending COMRESET to the
5251 * device. And the HBA resets PxTFD.STS to 7Fh.
5253 * Give time for COMRESET to percolate, according to the AHCI
5254 * spec, software shall wait at least 1 millisecond before
5255 * clearing PxSCTL.DET
5257 drv_usecwait(AHCI_1MS_USECS * 2);
5259 /* Fetch the SCONTROL again and rewrite the DET part with 0 */
5260 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5261 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5262 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5263 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5264 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port),
5265 port_scontrol);
5268 * When a COMINIT is received from the device, then the port enters
5269 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5270 * PxSSTS.DET to 1h to indicate a device is detected but communication
5271 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5272 * a COMINIT has been received.
5275 * The DET field is valid only if IPM field indicates
5276 * that the interface is in active state.
5278 loop_count = 0;
5279 for (;;) {
5280 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5281 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
5283 if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5285 * If the interface is not active, the DET field
5286 * is considered not accurate. So we want to
5287 * continue looping.
5289 SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5292 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM)
5293 break;
5295 if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5297 * We are effectively timing out after 0.1 sec.
5299 break;
5302 /* Wait for 10 millisec */
5303 drv_usecwait(AHCI_10MS_USECS);
5306 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5307 "ahci_port_reset: 1st loop count: %d, "
5308 "port_sstatus = 0x%x port %d",
5309 loop_count, port_sstatus, port);
5311 if (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM) {
5313 * Either the port is not active or there
5314 * is no device present.
5316 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5317 return (AHCI_SUCCESS);
5320 /* Clear port serror register for the port */
5321 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5322 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5323 AHCI_SERROR_CLEAR_ALL);
5326 * Devices should return a FIS contains its signature to HBA after
5327 * COMINIT signal. Check whether a D2H Register FIS is received by
5328 * polling PxTFD.STS.
5330 loop_count = 0;
5331 for (;;) {
5332 port_task_file =
5333 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5334 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
5336 if ((port_task_file & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ |
5337 AHCI_TFD_STS_ERR)) == 0)
5338 break;
5340 if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5342 * We are effectively timing out after 11 sec.
5344 cmn_err(CE_WARN, "!ahci%d: ahci_port_reset port %d "
5345 "the device hardware has been initialized and "
5346 "the power-up diagnostics failed",
5347 instance, port);
5349 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_port_reset: "
5350 "port %d: some or all of BSY, DRQ and ERR in "
5351 "PxTFD.STS are not clear. We need another "
5352 "software reset.", port);
5354 /* Clear port serror register for the port */
5355 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5356 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5357 AHCI_SERROR_CLEAR_ALL);
5359 AHCI_ADDR_SET_PMULT(&pmult_addr, port);
5361 /* Try another software reset. */
5362 if (ahci_software_reset(ahci_ctlp, ahci_portp,
5363 &pmult_addr) != AHCI_SUCCESS) {
5364 AHCIPORT_SET_STATE(ahci_portp, addrp,
5365 SATA_PSTATE_FAILED);
5366 return (AHCI_FAILURE);
5368 break;
5371 /* Wait for 10 millisec */
5372 drv_usecwait(AHCI_10MS_USECS);
5375 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
5376 "ahci_port_reset: 2nd loop count: %d, "
5377 "port_task_file = 0x%x port %d",
5378 loop_count, port_task_file, port);
5380 /* Clear port serror register for the port */
5381 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5382 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
5383 AHCI_SERROR_CLEAR_ALL);
5385 /* Set port as ready */
5386 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5387 AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5389 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5390 "ahci_port_reset: succeed at port %d.", port);
5391 return (AHCI_SUCCESS);
5395 * COMRESET on a port multiplier port.
5397 * NOTE: Only called in ahci_port_reset()
5399 static int
5400 ahci_pmport_reset(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5401 ahci_addr_t *addrp)
5403 uint32_t port_scontrol, port_sstatus, port_serror;
5404 uint32_t port_cmd_status, port_intr_status;
5405 uint32_t port_state;
5406 uint8_t port = addrp->aa_port;
5407 uint8_t pmport = addrp->aa_pmport;
5408 int loop_count;
5409 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
5411 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
5412 "port %d:%d: pmport resetting", port, pmport);
5414 /* Initialize pmport state */
5415 AHCIPORT_SET_STATE(ahci_portp, addrp, 0);
5417 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5418 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_COMRESET);
5419 WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5421 /* PxCMD.FRE should be set before. */
5422 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5423 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5424 ASSERT(port_cmd_status & AHCI_CMD_STATUS_FRE);
5425 if (!(port_cmd_status & AHCI_CMD_STATUS_FRE))
5426 return (AHCI_FAILURE);
5429 * Give time for COMRESET to percolate, according to the AHCI
5430 * spec, software shall wait at least 1 millisecond before
5431 * clearing PxSCTL.DET
5433 drv_usecwait(AHCI_1MS_USECS*2);
5436 * Fetch the SCONTROL again and rewrite the DET part with 0
5437 * This will generate an Asychronous Notification events.
5439 READ_PMULT(addrp, SATA_PMULT_REG_SCTL, &port_scontrol, err);
5440 SCONTROL_SET_DET(port_scontrol, SCONTROL_DET_NOACTION);
5441 WRITE_PMULT(addrp, SATA_PMULT_REG_SCTL, port_scontrol, err);
5444 * The port enters P:StartComm state, and HBA tells link layer to
5445 * start communication, which involves sending COMRESET to device.
5446 * And the HBA resets PxTFD.STS to 7Fh.
5448 * When a COMINIT is received from the device, then the port enters
5449 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5450 * PxSSTS.DET to 1h to indicate a device is detected but communication
5451 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5452 * a COMINIT has been received.
5455 * The DET field is valid only if IPM field indicates
5456 * that the interface is in active state.
5458 loop_count = 0;
5459 do {
5460 READ_PMULT(addrp, SATA_PMULT_REG_SSTS, &port_sstatus, err);
5462 if (SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) {
5464 * If the interface is not active, the DET field
5465 * is considered not accurate. So we want to
5466 * continue looping.
5468 SSTATUS_SET_DET(port_sstatus, SSTATUS_DET_NODEV);
5471 if (loop_count++ > AHCI_POLLRATE_PORT_SSTATUS) {
5473 * We are effectively timing out after 0.1 sec.
5475 break;
5478 /* Wait for 10 millisec */
5479 drv_usecwait(AHCI_10MS_USECS);
5481 } while (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM);
5483 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5484 "ahci_pmport_reset: 1st loop count: %d, "
5485 "port_sstatus = 0x%x port %d:%d",
5486 loop_count, port_sstatus, port, pmport);
5488 if ((SSTATUS_GET_IPM(port_sstatus) != SSTATUS_IPM_ACTIVE) ||
5489 (SSTATUS_GET_DET(port_sstatus) != SSTATUS_DET_DEVPRE_PHYCOM)) {
5491 * Either the port is not active or there
5492 * is no device present.
5494 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5495 "ahci_pmport_reset: "
5496 "no device attached to port %d:%d",
5497 port, pmport);
5498 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_NONE);
5499 return (AHCI_SUCCESS);
5502 /* Now we can make sure there is a device connected to the port */
5503 /* COMINIT signal is supposed to be received (PxSERR.DIAG.X = '1') */
5504 READ_PMULT(addrp, SATA_PMULT_REG_SERR, &port_serror, err);
5506 if (!(port_serror & (1 << 26))) {
5507 cmn_err(CE_WARN, "!ahci%d: ahci_pmport_reset: "
5508 "COMINIT signal from the device not received port %d:%d",
5509 instance, port, pmport);
5511 AHCIPORT_SET_STATE(ahci_portp, addrp, SATA_PSTATE_FAILED);
5512 return (AHCI_FAILURE);
5516 * After clear PxSERR register, we will receive a D2H FIS.
5517 * Normally this FIS will cause a IPMS error according to AHCI spec
5518 * v1.2 because there is no command outstanding for it. So we need
5519 * to ignore this error.
5521 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_IGNORE_IPMS;
5522 WRITE_PMULT(addrp, SATA_PMULT_REG_SERR, AHCI_SERROR_CLEAR_ALL, err);
5524 /* Now we need to check the D2H FIS by checking IPMS error. */
5525 loop_count = 0;
5526 do {
5527 port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5528 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
5530 if (loop_count++ > AHCI_POLLRATE_PORT_TFD_ERROR) {
5532 * No D2H FIS received. This is possible according
5533 * to SATA 2.6 spec.
5535 cmn_err(CE_WARN, "ahci_port_reset: port %d:%d "
5536 "PxIS.IPMS is not set, we need another "
5537 "software reset.", port, pmport);
5539 break;
5542 /* Wait for 10 millisec */
5543 mutex_exit(&ahci_portp->ahciport_mutex);
5544 delay(AHCI_10MS_TICKS);
5545 mutex_enter(&ahci_portp->ahciport_mutex);
5547 } while (!(port_intr_status & AHCI_INTR_STATUS_IPMS));
5549 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5550 "ahci_pmport_reset: 2st loop count: %d, "
5551 "port_sstatus = 0x%x port %d:%d",
5552 loop_count, port_sstatus, port, pmport);
5554 /* Clear IPMS */
5555 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5556 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
5557 AHCI_INTR_STATUS_IPMS);
5558 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5560 /* This pmport is now ready for ahci_tran_start() */
5561 port_state = AHCIPORT_GET_STATE(ahci_portp, addrp);
5562 AHCIPORT_SET_STATE(ahci_portp, addrp, port_state|SATA_STATE_READY);
5564 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5565 "ahci_pmport_reset: succeed at port %d:%d", port, pmport);
5566 return (AHCI_SUCCESS);
5568 err: /* R/W PMULT error */
5569 /* IPMS flags might be set before. */
5570 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_IGNORE_IPMS;
5571 AHCIDBG(AHCIDBG_INFO|AHCIDBG_ERRS, ahci_ctlp,
5572 "ahci_pmport_reset: failed at port %d:%d", port, pmport);
5574 return (AHCI_FAILURE);
5578 * AHCI HBA reset ...; the entire HBA is reset, and all ports are disabled.
5579 * This is the most intrusive.
5581 * When an HBA reset occurs, Phy communication will be re-established with
5582 * the device through a COMRESET followed by the normal out-of-band
5583 * communication sequence defined in Serial ATA. At the end of reset, the
5584 * device, if working properly, will send a D2H Register FIS, which contains
5585 * the device signature. When the HBA receives this FIS, it updates PxTFD.STS
5586 * and PxTFD.ERR register fields, and updates the PxSIG register with the
5587 * signature.
5589 * Remember to set GHC.AE to 1 before calling ahci_hba_reset.
5591 static int
5592 ahci_hba_reset(ahci_ctl_t *ahci_ctlp)
5594 ahci_port_t *ahci_portp;
5595 uint32_t ghc_control;
5596 uint8_t port;
5597 int loop_count;
5598 int rval = AHCI_SUCCESS;
5600 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp, "HBA resetting",
5601 NULL);
5603 mutex_enter(&ahci_ctlp->ahcictl_mutex);
5605 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5606 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5608 /* Setting GHC.HR to 1, remember GHC.AE is already set to 1 before */
5609 ghc_control |= AHCI_HBA_GHC_HR;
5610 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5611 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5614 * Wait until HBA Reset complete or timeout
5616 loop_count = 0;
5617 do {
5618 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5619 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5621 if (loop_count++ > AHCI_POLLRATE_HBA_RESET) {
5622 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5623 "ahci hba reset is timing out, "
5624 "ghc_control = 0x%x", ghc_control);
5625 /* We are effectively timing out after 1 sec. */
5626 break;
5629 /* Wait for 10 millisec */
5630 drv_usecwait(AHCI_10MS_USECS);
5631 } while (ghc_control & AHCI_HBA_GHC_HR);
5633 AHCIDBG(AHCIDBG_POLL_LOOP, ahci_ctlp,
5634 "ahci_hba_reset: 1st loop count: %d, "
5635 "ghc_control = 0x%x", loop_count, ghc_control);
5637 if (ghc_control & AHCI_HBA_GHC_HR) {
5638 /* The hba is not reset for some reasons */
5639 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
5640 "hba reset failed: HBA in a hung or locked state", NULL);
5641 mutex_exit(&ahci_ctlp->ahcictl_mutex);
5642 return (AHCI_FAILURE);
5646 * HBA reset will clear (AHCI Spec v1.2 10.4.3) GHC.IE / GHC.AE
5648 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5649 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
5650 ghc_control |= (AHCI_HBA_GHC_AE | AHCI_HBA_GHC_IE);
5651 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5652 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
5654 mutex_exit(&ahci_ctlp->ahcictl_mutex);
5656 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
5657 /* Only check implemented ports */
5658 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
5659 continue;
5662 ahci_portp = ahci_ctlp->ahcictl_ports[port];
5663 mutex_enter(&ahci_portp->ahciport_mutex);
5665 /* Make sure the drive is spun-up */
5666 ahci_staggered_spin_up(ahci_ctlp, port);
5668 if (ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
5669 port, AHCI_PORT_RESET|AHCI_RESET_NO_EVENTS_UP, NULL) !=
5670 AHCI_SUCCESS) {
5671 rval = AHCI_FAILURE;
5672 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5673 "ahci_hba_reset: port %d failed", port);
5675 * Set the port state to SATA_PSTATE_FAILED if
5676 * failed to initialize it.
5678 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5681 mutex_exit(&ahci_portp->ahciport_mutex);
5684 return (rval);
5688 * This routine is only called from AHCI_ATTACH or phyrdy change
5689 * case. It first calls software reset, then stop the port and try to
5690 * read PxSIG register to find the type of device attached to the port.
5692 * The caller should make sure a valid device exists on specified port and
5693 * physical communication has been established so that the signature could
5694 * be retrieved by software reset.
5696 * NOTE: The port interrupts should be disabled before the function is called.
5698 static void
5699 ahci_find_dev_signature(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
5700 ahci_addr_t *addrp)
5702 ahci_addr_t dev_addr;
5703 uint32_t signature;
5704 uint8_t port = addrp->aa_port;
5705 uint8_t pmport = addrp->aa_pmport;
5706 int rval;
5708 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5709 ASSERT(AHCI_ADDR_IS_VALID(addrp));
5712 * If the HBA doesn't support port multiplier, then the driver
5713 * doesn't need to bother to check port multiplier device.
5715 * The second port of ICH7 on ASUS P5W DH deluxe motherboard is
5716 * connected to Silicon Image 4723, to which the two sata drives
5717 * attached can be set with RAID1, RAID0 or Spanning mode.
5719 * We found software reset will get failure if port multiplier address
5720 * 0xf is used by software reset, so just ignore the check since
5721 * ICH7 doesn't support port multiplier device at all.
5723 if (AHCI_ADDR_IS_PORT(addrp) &&
5724 (ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_CBSS)) {
5725 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5726 "ahci_find_dev_signature enter: port %d", port);
5729 * NOTE: when the ahci address is a HBA port, we do not know
5730 * it is a device or a port multiplier that attached. we need
5731 * try a software reset at port multiplier address (0xf
5732 * pmport)
5734 AHCI_ADDR_SET_PMULT(&dev_addr, addrp->aa_port);
5735 } else {
5736 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
5737 "ahci_find_dev_signature enter: port %d:%d",
5738 port, pmport);
5739 dev_addr = *addrp;
5742 /* Assume it is unknown. */
5743 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5745 /* Issue a software reset to get the signature */
5746 rval = ahci_software_reset(ahci_ctlp, ahci_portp, &dev_addr);
5747 if (rval != AHCI_SUCCESS) {
5750 * Try to do software reset again with pmport set with 0 if
5751 * the controller is set with AHCI_CAP_SRST_NO_HOSTPORT and
5752 * the original pmport is set with SATA_PMULT_HOSTPORT (0xf)
5754 if ((ahci_ctlp->ahcictl_cap & AHCI_CAP_SRST_NO_HOSTPORT) &&
5755 (dev_addr.aa_pmport == SATA_PMULT_HOSTPORT)) {
5756 dev_addr.aa_pmport = 0;
5757 rval = ahci_software_reset(ahci_ctlp, ahci_portp,
5758 &dev_addr);
5761 if (rval != AHCI_SUCCESS) {
5762 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
5763 "ahci_find_dev_signature: software reset failed "
5764 "at port %d:%d, cannot get signature.",
5765 port, pmport);
5767 AHCIPORT_SET_STATE(ahci_portp, addrp,
5768 SATA_PSTATE_FAILED);
5769 return;
5774 * ahci_software_reset has started the port, so we need manually stop
5775 * the port again.
5777 if (AHCI_ADDR_IS_PORT(addrp)) {
5778 if (ahci_put_port_into_notrunning_state(ahci_ctlp,
5779 ahci_portp, port) != AHCI_SUCCESS) {
5780 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5781 "ahci_find_dev_signature: cannot stop port %d.",
5782 port);
5783 ahci_portp->ahciport_port_state = SATA_PSTATE_FAILED;
5784 return;
5788 /* Now we can make sure that a valid signature is received. */
5789 signature = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5790 (uint32_t *)AHCI_PORT_PxSIG(ahci_ctlp, port));
5792 if (AHCI_ADDR_IS_PMPORT(addrp)) {
5793 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
5794 "ahci_find_dev_signature: signature = 0x%x at port %d:%d",
5795 signature, port, pmport);
5796 } else {
5797 AHCIDBG(AHCIDBG_INIT|AHCIDBG_INFO, ahci_ctlp,
5798 "ahci_find_dev_signature: signature = 0x%x at port %d",
5799 signature, port);
5802 /* NOTE: Only support ATAPI device at controller port. */
5803 if (signature == AHCI_SIGNATURE_ATAPI && !AHCI_ADDR_IS_PORT(addrp))
5804 signature = SATA_DTYPE_UNKNOWN;
5806 switch (signature) {
5808 case AHCI_SIGNATURE_DISK:
5809 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATADISK);
5810 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5811 "Disk is found at port: %d", port);
5812 break;
5814 case AHCI_SIGNATURE_ATAPI:
5815 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_ATAPI);
5816 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5817 "ATAPI device is found at port: %d", port);
5818 break;
5820 case AHCI_SIGNATURE_PORT_MULTIPLIER:
5821 /* Port Multiplier cannot recursively attached. */
5822 ASSERT(AHCI_ADDR_IS_PORT(addrp));
5823 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_PMULT);
5824 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5825 "Port Multiplier is found at port: %d", port);
5826 break;
5828 default:
5829 AHCIPORT_SET_DEV_TYPE(ahci_portp, addrp, SATA_DTYPE_UNKNOWN);
5830 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
5831 "Unknown device is found at port: %d", port);
5836 * According to the spec, to reliably detect hot plug removals, software
5837 * must disable interface power management. Software should perform the
5838 * following initialization on a port after a device is attached:
5839 * Set PxSCTL.IPM to 3h to disable interface state transitions
5840 * Set PxCMD.ALPE to '0' to disable aggressive power management
5841 * Disable device initiated interface power management by SET FEATURE
5843 * We can ignore the last item because by default the feature is disabled
5845 static void
5846 ahci_disable_interface_pm(ahci_ctl_t *ahci_ctlp, uint8_t port)
5848 uint32_t port_scontrol, port_cmd_status;
5850 port_scontrol = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5851 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port));
5852 SCONTROL_SET_IPM(port_scontrol, SCONTROL_IPM_DISABLE_BOTH);
5853 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5854 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp, port), port_scontrol);
5856 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5857 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5858 port_cmd_status &= ~AHCI_CMD_STATUS_ALPE;
5859 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5860 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
5864 * Start the port - set PxCMD.ST to 1, if PxCMD.FRE is not set
5865 * to 1, then set it firstly.
5867 * Each port contains two major DMA engines. One DMA engine walks through
5868 * the command list, and is controlled by PxCMD.ST. The second DMA engine
5869 * copies received FISes into system memory, and is controlled by PxCMD.FRE.
5871 * Software shall not set PxCMD.ST to '1' until it verifies that PxCMD.CR
5872 * is '0' and has set PxCMD.FRE is '1'. And software shall not clear
5873 * PxCMD.FRE while PxCMD.ST or PxCMD.CR is set '1'.
5875 * Software shall not set PxCMD.ST to '1' unless a functional device is
5876 * present on the port(as determined by PxTFD.STS.BSY = '0',
5877 * PxTFD.STS.DRQ = '0', and PxSSTS.DET = 3h).
5879 static int
5880 ahci_start_port(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
5882 uint32_t port_cmd_status;
5884 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5886 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_start_port: %d enter", port);
5888 if (ahci_portp->ahciport_port_state & SATA_PSTATE_FAILED) {
5889 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5890 "the state for port %d is 0x%x",
5891 port, ahci_portp->ahciport_port_state);
5892 return (AHCI_FAILURE);
5895 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
5896 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port failed "
5897 "no device is attached at port %d", port);
5898 return (AHCI_FAILURE);
5901 /* First to set PxCMD.FRE before setting PxCMD.ST. */
5902 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5903 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5905 if (!(port_cmd_status & AHCI_CMD_STATUS_FRE)) {
5906 port_cmd_status |= AHCI_CMD_STATUS_FRE;
5907 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5908 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5909 port_cmd_status);
5912 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5913 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5915 port_cmd_status |= AHCI_CMD_STATUS_ST;
5917 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5918 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5919 port_cmd_status);
5921 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_STARTED;
5923 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_start_port: "
5924 "PxCMD.ST set to '1' at port %d", port);
5926 return (AHCI_SUCCESS);
5930 * Setup PxCLB, PxCLBU, PxFB, and PxFBU for particular port. First, we need
5931 * to make sure PxCMD.ST, PxCMD.CR, PxCMD.FRE, and PxCMD.FR are all cleared.
5932 * Then set PxCLB, PxCLBU, PxFB, and PxFBU.
5934 static int
5935 ahci_setup_port_base_addresses(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
5937 uint8_t port = ahci_portp->ahciport_port_num;
5938 uint32_t port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5939 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5941 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
5943 /* Step 1: Make sure both PxCMD.ST and PxCMD.CR are cleared. */
5944 if (port_cmd_status & (AHCI_CMD_STATUS_ST | AHCI_CMD_STATUS_CR)) {
5945 if (ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
5946 port) != AHCI_SUCCESS)
5947 return (AHCI_FAILURE);
5949 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5950 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5953 /* Step 2: Make sure both PxCMD.FRE and PxCMD.FR are cleared. */
5954 if (port_cmd_status & (AHCI_CMD_STATUS_FRE | AHCI_CMD_STATUS_FR)) {
5955 int loop_count = 0;
5957 /* Clear PxCMD.FRE */
5958 port_cmd_status &= ~AHCI_CMD_STATUS_FRE;
5959 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5960 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port),
5961 port_cmd_status);
5963 /* Wait until PxCMD.FR is cleared */
5964 for (;;) {
5965 port_cmd_status =
5966 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
5967 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
5969 if (!(port_cmd_status & AHCI_CMD_STATUS_FR))
5970 break;
5972 if (loop_count++ >= AHCI_POLLRATE_PORT_IDLE_FR) {
5973 AHCIDBG(AHCIDBG_INIT | AHCIDBG_ERRS, ahci_ctlp,
5974 "ahci_setup_port_base_addresses: cannot "
5975 "clear PxCMD.FR for port %d.", port);
5978 * We are effectively timing out after 0.5 sec.
5979 * This value is specified in AHCI spec.
5981 return (AHCI_FAILURE);
5984 /* Wait for 1 millisec */
5985 drv_usecwait(AHCI_1MS_USECS);
5989 /* Step 3: Config Port Command List Base Address */
5990 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5991 (uint32_t *)AHCI_PORT_PxCLB(ahci_ctlp, port),
5992 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
5994 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
5995 (uint32_t *)AHCI_PORT_PxCLBU(ahci_ctlp, port),
5996 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_notused);
5998 /* Step 4: Config Port Received FIS Base Address */
5999 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6000 (uint32_t *)AHCI_PORT_PxFB(ahci_ctlp, port),
6001 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6003 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6004 (uint32_t *)AHCI_PORT_PxFBU(ahci_ctlp, port),
6005 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_notused);
6007 return (AHCI_SUCCESS);
6011 * Allocate the ahci_port_t including Received FIS and Command List.
6012 * The argument - port is the physical port number, and not logical
6013 * port number seen by the SATA framework.
6015 static int
6016 ahci_alloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6018 dev_info_t *dip = ahci_ctlp->ahcictl_dip;
6019 ahci_port_t *ahci_portp;
6020 char taskq_name[64] = "event_handle_taskq";
6022 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6024 ahci_portp =
6025 (ahci_port_t *)kmem_zalloc(sizeof (ahci_port_t), KM_SLEEP);
6027 ahci_ctlp->ahcictl_ports[port] = ahci_portp;
6028 ahci_portp->ahciport_port_num = port;
6030 /* Initialize the port condition variable */
6031 cv_init(&ahci_portp->ahciport_cv, NULL, CV_DRIVER, NULL);
6033 /* Initialize the port mutex */
6034 mutex_init(&ahci_portp->ahciport_mutex, NULL, MUTEX_DRIVER,
6035 (void *)(uintptr_t)ahci_ctlp->ahcictl_intr_pri);
6037 mutex_enter(&ahci_portp->ahciport_mutex);
6040 * Allocate memory for received FIS structure and
6041 * command list for this port
6043 if (ahci_alloc_rcvd_fis(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6044 goto err_case1;
6047 if (ahci_alloc_cmd_list(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6048 goto err_case2;
6051 /* Setup PxCMD.CLB, PxCMD.CLBU, PxCMD.FB, and PxCMD.FBU */
6052 if (ahci_setup_port_base_addresses(ahci_ctlp, ahci_portp) !=
6053 AHCI_SUCCESS) {
6054 goto err_case3;
6057 (void) snprintf(taskq_name + strlen(taskq_name),
6058 sizeof (taskq_name) - strlen(taskq_name),
6059 "_port%d", port);
6061 /* Create the taskq for the port */
6062 if ((ahci_portp->ahciport_event_taskq = ddi_taskq_create(dip,
6063 taskq_name, 2, TASKQ_DEFAULTPRI, 0)) == NULL) {
6064 cmn_err(CE_WARN, "!ahci%d: ddi_taskq_create failed for event "
6065 "handle", ddi_get_instance(ahci_ctlp->ahcictl_dip));
6066 goto err_case3;
6069 /* Allocate the argument for the taskq */
6070 ahci_portp->ahciport_event_args =
6071 kmem_zalloc(sizeof (ahci_event_arg_t), KM_SLEEP);
6073 ahci_portp->ahciport_event_args->ahciea_addrp =
6074 kmem_zalloc(sizeof (ahci_addr_t), KM_SLEEP);
6076 if (ahci_portp->ahciport_event_args == NULL)
6077 goto err_case4;
6079 /* Initialize the done queue */
6080 ahci_portp->ahciport_doneq = NULL;
6081 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
6082 ahci_portp->ahciport_doneq_len = 0;
6084 mutex_exit(&ahci_portp->ahciport_mutex);
6086 return (AHCI_SUCCESS);
6088 err_case4:
6089 ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6091 err_case3:
6092 ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6094 err_case2:
6095 ahci_dealloc_rcvd_fis(ahci_portp);
6097 err_case1:
6098 mutex_exit(&ahci_portp->ahciport_mutex);
6099 mutex_destroy(&ahci_portp->ahciport_mutex);
6100 cv_destroy(&ahci_portp->ahciport_cv);
6102 kmem_free(ahci_portp, sizeof (ahci_port_t));
6104 return (AHCI_FAILURE);
6108 * Reverse of ahci_alloc_port_state().
6110 static void
6111 ahci_dealloc_port_state(ahci_ctl_t *ahci_ctlp, uint8_t port)
6113 ahci_port_t *ahci_portp = ahci_ctlp->ahcictl_ports[port];
6115 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
6116 ASSERT(ahci_portp != NULL);
6118 mutex_enter(&ahci_portp->ahciport_mutex);
6119 kmem_free(ahci_portp->ahciport_event_args->ahciea_addrp,
6120 sizeof (ahci_addr_t));
6121 ahci_portp->ahciport_event_args->ahciea_addrp = NULL;
6122 kmem_free(ahci_portp->ahciport_event_args, sizeof (ahci_event_arg_t));
6123 ahci_portp->ahciport_event_args = NULL;
6124 ddi_taskq_destroy(ahci_portp->ahciport_event_taskq);
6125 ahci_dealloc_cmd_list(ahci_ctlp, ahci_portp);
6126 ahci_dealloc_rcvd_fis(ahci_portp);
6127 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
6128 mutex_exit(&ahci_portp->ahciport_mutex);
6130 mutex_destroy(&ahci_portp->ahciport_mutex);
6131 cv_destroy(&ahci_portp->ahciport_cv);
6133 kmem_free(ahci_portp, sizeof (ahci_port_t));
6135 ahci_ctlp->ahcictl_ports[port] = NULL;
6139 * Allocates memory for the Received FIS Structure
6141 static int
6142 ahci_alloc_rcvd_fis(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6144 size_t rcvd_fis_size;
6145 size_t ret_len;
6146 uint_t cookie_count;
6148 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6150 rcvd_fis_size = sizeof (ahci_rcvd_fis_t);
6152 /* allocate rcvd FIS dma handle. */
6153 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6154 &ahci_ctlp->ahcictl_rcvd_fis_dma_attr,
6155 DDI_DMA_SLEEP,
6156 NULL,
6157 &ahci_portp->ahciport_rcvd_fis_dma_handle) !=
6158 DDI_SUCCESS) {
6159 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6160 "rcvd FIS dma handle alloc failed", NULL);
6162 return (AHCI_FAILURE);
6165 if (ddi_dma_mem_alloc(ahci_portp->ahciport_rcvd_fis_dma_handle,
6166 rcvd_fis_size,
6167 &accattr,
6168 DDI_DMA_CONSISTENT,
6169 DDI_DMA_SLEEP,
6170 NULL,
6171 (caddr_t *)&ahci_portp->ahciport_rcvd_fis,
6172 &ret_len,
6173 &ahci_portp->ahciport_rcvd_fis_acc_handle) != 0) {
6175 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6176 "rcvd FIS dma mem alloc fail", NULL);
6177 /* error.. free the dma handle. */
6178 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6179 return (AHCI_FAILURE);
6182 if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle,
6183 NULL,
6184 (caddr_t)ahci_portp->ahciport_rcvd_fis,
6185 rcvd_fis_size,
6186 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6187 DDI_DMA_SLEEP,
6188 NULL,
6189 &ahci_portp->ahciport_rcvd_fis_dma_cookie,
6190 &cookie_count) != DDI_DMA_MAPPED) {
6192 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6193 "rcvd FIS dma handle bind fail", NULL);
6194 /* error.. free the dma handle & free the memory. */
6195 ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6196 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6197 return (AHCI_FAILURE);
6200 bzero((void *)ahci_portp->ahciport_rcvd_fis, rcvd_fis_size);
6202 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6203 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_laddress);
6204 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6205 ahci_portp->ahciport_rcvd_fis_dma_cookie.dmac_address);
6207 return (AHCI_SUCCESS);
6211 * Deallocates the Received FIS Structure
6213 static void
6214 ahci_dealloc_rcvd_fis(ahci_port_t *ahci_portp)
6216 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6218 /* Unbind the cmd list dma handle first. */
6219 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_rcvd_fis_dma_handle);
6221 /* Then free the underlying memory. */
6222 ddi_dma_mem_free(&ahci_portp->ahciport_rcvd_fis_acc_handle);
6224 /* Now free the handle itself. */
6225 ddi_dma_free_handle(&ahci_portp->ahciport_rcvd_fis_dma_handle);
6229 * Allocates memory for the Command List, which contains up to 32 entries.
6230 * Each entry contains a command header, which is a 32-byte structure that
6231 * includes the pointer to the command table.
6233 static int
6234 ahci_alloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6236 size_t cmd_list_size;
6237 size_t ret_len;
6238 uint_t cookie_count;
6240 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6242 cmd_list_size =
6243 ahci_ctlp->ahcictl_num_cmd_slots * sizeof (ahci_cmd_header_t);
6245 /* allocate cmd list dma handle. */
6246 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6247 &ahci_ctlp->ahcictl_cmd_list_dma_attr,
6248 DDI_DMA_SLEEP,
6249 NULL,
6250 &ahci_portp->ahciport_cmd_list_dma_handle) != DDI_SUCCESS) {
6252 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6253 "cmd list dma handle alloc failed", NULL);
6254 return (AHCI_FAILURE);
6257 if (ddi_dma_mem_alloc(ahci_portp->ahciport_cmd_list_dma_handle,
6258 cmd_list_size,
6259 &accattr,
6260 DDI_DMA_CONSISTENT,
6261 DDI_DMA_SLEEP,
6262 NULL,
6263 (caddr_t *)&ahci_portp->ahciport_cmd_list,
6264 &ret_len,
6265 &ahci_portp->ahciport_cmd_list_acc_handle) != 0) {
6267 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6268 "cmd list dma mem alloc fail", NULL);
6269 /* error.. free the dma handle. */
6270 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6271 return (AHCI_FAILURE);
6274 if (ddi_dma_addr_bind_handle(ahci_portp->ahciport_cmd_list_dma_handle,
6275 NULL,
6276 (caddr_t)ahci_portp->ahciport_cmd_list,
6277 cmd_list_size,
6278 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6279 DDI_DMA_SLEEP,
6280 NULL,
6281 &ahci_portp->ahciport_cmd_list_dma_cookie,
6282 &cookie_count) != DDI_DMA_MAPPED) {
6284 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6285 "cmd list dma handle bind fail", NULL);
6286 /* error.. free the dma handle & free the memory. */
6287 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6288 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6289 return (AHCI_FAILURE);
6292 bzero((void *)ahci_portp->ahciport_cmd_list, cmd_list_size);
6294 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "64-bit, dma address: 0x%llx",
6295 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_laddress);
6297 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "32-bit, dma address: 0x%x",
6298 ahci_portp->ahciport_cmd_list_dma_cookie.dmac_address);
6300 if (ahci_alloc_cmd_tables(ahci_ctlp, ahci_portp) != AHCI_SUCCESS) {
6301 goto err_out;
6304 return (AHCI_SUCCESS);
6306 err_out:
6307 /* Unbind the cmd list dma handle first. */
6308 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6310 /* Then free the underlying memory. */
6311 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6313 /* Now free the handle itself. */
6314 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6316 return (AHCI_FAILURE);
6320 * Deallocates the Command List
6322 static void
6323 ahci_dealloc_cmd_list(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6325 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6327 /* First dealloc command table */
6328 ahci_dealloc_cmd_tables(ahci_ctlp, ahci_portp);
6330 /* Unbind the cmd list dma handle first. */
6331 (void) ddi_dma_unbind_handle(ahci_portp->ahciport_cmd_list_dma_handle);
6333 /* Then free the underlying memory. */
6334 ddi_dma_mem_free(&ahci_portp->ahciport_cmd_list_acc_handle);
6336 /* Now free the handle itself. */
6337 ddi_dma_free_handle(&ahci_portp->ahciport_cmd_list_dma_handle);
6341 * Allocates memory for all Command Tables, which contains Command FIS,
6342 * ATAPI Command and Physical Region Descriptor Table.
6344 static int
6345 ahci_alloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6347 size_t ret_len;
6348 ddi_dma_cookie_t cmd_table_dma_cookie;
6349 uint_t cookie_count;
6350 int slot;
6352 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6354 AHCIDBG(AHCIDBG_INIT|AHCIDBG_ENTRY, ahci_ctlp,
6355 "ahci_alloc_cmd_tables: port %d enter",
6356 ahci_portp->ahciport_port_num);
6358 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6359 /* Allocate cmd table dma handle. */
6360 if (ddi_dma_alloc_handle(ahci_ctlp->ahcictl_dip,
6361 &ahci_ctlp->ahcictl_cmd_table_dma_attr,
6362 DDI_DMA_SLEEP,
6363 NULL,
6364 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]) !=
6365 DDI_SUCCESS) {
6367 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6368 "cmd table dma handle alloc failed", NULL);
6370 goto err_out;
6373 if (ddi_dma_mem_alloc(
6374 ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6375 ahci_cmd_table_size,
6376 &accattr,
6377 DDI_DMA_CONSISTENT,
6378 DDI_DMA_SLEEP,
6379 NULL,
6380 (caddr_t *)&ahci_portp->ahciport_cmd_tables[slot],
6381 &ret_len,
6382 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]) !=
6383 0) {
6385 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6386 "cmd table dma mem alloc fail", NULL);
6388 /* error.. free the dma handle. */
6389 ddi_dma_free_handle(
6390 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6391 goto err_out;
6394 if (ddi_dma_addr_bind_handle(
6395 ahci_portp->ahciport_cmd_tables_dma_handle[slot],
6396 NULL,
6397 (caddr_t)ahci_portp->ahciport_cmd_tables[slot],
6398 ahci_cmd_table_size,
6399 DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
6400 DDI_DMA_SLEEP,
6401 NULL,
6402 &cmd_table_dma_cookie,
6403 &cookie_count) != DDI_DMA_MAPPED) {
6405 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
6406 "cmd table dma handle bind fail", NULL);
6407 /* error.. free the dma handle & free the memory. */
6408 ddi_dma_mem_free(
6409 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6410 ddi_dma_free_handle(
6411 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6412 goto err_out;
6415 bzero((void *)ahci_portp->ahciport_cmd_tables[slot],
6416 ahci_cmd_table_size);
6418 /* Config Port Command Table Base Address */
6419 SET_COMMAND_TABLE_BASE_ADDR(
6420 (&ahci_portp->ahciport_cmd_list[slot]),
6421 cmd_table_dma_cookie.dmac_laddress & 0xffffffffull);
6423 #ifndef __lock_lint
6424 SET_COMMAND_TABLE_BASE_ADDR_UPPER(
6425 (&ahci_portp->ahciport_cmd_list[slot]),
6426 cmd_table_dma_cookie.dmac_laddress >> 32);
6427 #endif
6430 return (AHCI_SUCCESS);
6431 err_out:
6433 for (slot--; slot >= 0; slot--) {
6434 /* Unbind the cmd table dma handle first */
6435 (void) ddi_dma_unbind_handle(
6436 ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6438 /* Then free the underlying memory */
6439 ddi_dma_mem_free(
6440 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6442 /* Now free the handle itself */
6443 ddi_dma_free_handle(
6444 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6447 return (AHCI_FAILURE);
6451 * Deallocates memory for all Command Tables.
6453 static void
6454 ahci_dealloc_cmd_tables(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp)
6456 int slot;
6458 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
6460 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
6461 "ahci_dealloc_cmd_tables: %d enter",
6462 ahci_portp->ahciport_port_num);
6464 for (slot = 0; slot < ahci_ctlp->ahcictl_num_cmd_slots; slot++) {
6465 /* Unbind the cmd table dma handle first. */
6466 (void) ddi_dma_unbind_handle(
6467 ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6469 /* Then free the underlying memory. */
6470 ddi_dma_mem_free(
6471 &ahci_portp->ahciport_cmd_tables_acc_handle[slot]);
6473 /* Now free the handle itself. */
6474 ddi_dma_free_handle(
6475 &ahci_portp->ahciport_cmd_tables_dma_handle[slot]);
6480 * Update SATA registers at controller ports
6482 static void
6483 ahci_update_sata_registers(ahci_ctl_t *ahci_ctlp, uint8_t port,
6484 sata_device_t *sd)
6486 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
6488 sd->satadev_scr.sstatus =
6489 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6490 (uint32_t *)(AHCI_PORT_PxSSTS(ahci_ctlp, port)));
6491 sd->satadev_scr.serror =
6492 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6493 (uint32_t *)(AHCI_PORT_PxSERR(ahci_ctlp, port)));
6494 sd->satadev_scr.scontrol =
6495 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6496 (uint32_t *)(AHCI_PORT_PxSCTL(ahci_ctlp, port)));
6497 sd->satadev_scr.sactive =
6498 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6499 (uint32_t *)(AHCI_PORT_PxSACT(ahci_ctlp, port)));
6503 * For poll mode, ahci_port_intr will be called to emulate the interrupt
6505 static void
6506 ahci_port_intr(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp, uint8_t port)
6508 uint32_t port_intr_status;
6509 uint32_t port_intr_enable;
6511 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
6512 "ahci_port_intr enter: port %d", port);
6514 mutex_enter(&ahci_portp->ahciport_mutex);
6515 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_POLLING) {
6516 /* For SATA_OPMODE_POLLING commands */
6517 port_intr_enable =
6518 (AHCI_INTR_STATUS_DHRS |
6519 AHCI_INTR_STATUS_PSS |
6520 AHCI_INTR_STATUS_SDBS |
6521 AHCI_INTR_STATUS_UFS |
6522 AHCI_INTR_STATUS_PCS |
6523 AHCI_INTR_STATUS_PRCS |
6524 AHCI_INTR_STATUS_OFS |
6525 AHCI_INTR_STATUS_INFS |
6526 AHCI_INTR_STATUS_IFS |
6527 AHCI_INTR_STATUS_HBDS |
6528 AHCI_INTR_STATUS_HBFS |
6529 AHCI_INTR_STATUS_TFES);
6530 } else {
6532 * port_intr_enable indicates that the corresponding interrrupt
6533 * reporting is enabled.
6535 port_intr_enable = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6536 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port));
6539 /* IPMS error in port reset should be ignored according AHCI spec. */
6540 if (!(ahci_portp->ahciport_flags & AHCI_PORT_FLAG_IGNORE_IPMS))
6541 port_intr_enable |= AHCI_INTR_STATUS_IPMS;
6542 mutex_exit(&ahci_portp->ahciport_mutex);
6545 * port_intr_stats indicates that the corresponding interrupt
6546 * condition is active.
6548 port_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6549 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port));
6551 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6552 "ahci_port_intr: port %d, port_intr_status = 0x%x, "
6553 "port_intr_enable = 0x%x",
6554 port, port_intr_status, port_intr_enable);
6556 port_intr_status &= port_intr_enable;
6559 * Pending interrupt events are indicated by the PxIS register.
6560 * Make sure we don't miss any event.
6562 if (ahci_check_ctl_handle(ahci_ctlp) != DDI_SUCCESS) {
6563 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6564 DDI_SERVICE_UNAFFECTED);
6565 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6566 DDI_FME_VERSION);
6567 return;
6570 /* First clear the port interrupts status */
6571 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6572 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
6573 port_intr_status);
6575 /* Check the completed non-queued commands */
6576 if (port_intr_status & (AHCI_INTR_STATUS_DHRS |
6577 AHCI_INTR_STATUS_PSS)) {
6578 (void) ahci_intr_cmd_cmplt(ahci_ctlp,
6579 ahci_portp, port);
6582 /* Check the completed queued commands */
6583 if (port_intr_status & AHCI_INTR_STATUS_SDBS) {
6584 (void) ahci_intr_set_device_bits(ahci_ctlp,
6585 ahci_portp, port);
6588 /* Check the port connect change status interrupt bit */
6589 if (port_intr_status & AHCI_INTR_STATUS_PCS) {
6590 (void) ahci_intr_port_connect_change(ahci_ctlp,
6591 ahci_portp, port);
6594 /* Check the device mechanical presence status interrupt bit */
6595 if (port_intr_status & AHCI_INTR_STATUS_DMPS) {
6596 (void) ahci_intr_device_mechanical_presence_status(
6597 ahci_ctlp, ahci_portp, port);
6600 /* Check the PhyRdy change status interrupt bit */
6601 if (port_intr_status & AHCI_INTR_STATUS_PRCS) {
6602 (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp,
6603 port);
6607 * Check the non-fatal error interrupt bits, there are four
6608 * kinds of non-fatal errors at the time being:
6610 * PxIS.UFS - Unknown FIS Error
6611 * PxIS.OFS - Overflow Error
6612 * PxIS.INFS - Interface Non-Fatal Error
6613 * PxIS.IPMS - Incorrect Port Multiplier Status Error
6615 * For these non-fatal errors, the HBA can continue to operate,
6616 * so the driver just log the error messages.
6618 if (port_intr_status & (AHCI_INTR_STATUS_UFS |
6619 AHCI_INTR_STATUS_OFS |
6620 AHCI_INTR_STATUS_IPMS |
6621 AHCI_INTR_STATUS_INFS)) {
6622 (void) ahci_intr_non_fatal_error(ahci_ctlp, ahci_portp,
6623 port, port_intr_status);
6627 * Check the fatal error interrupt bits, there are four kinds
6628 * of fatal errors for AHCI controllers:
6630 * PxIS.HBFS - Host Bus Fatal Error
6631 * PxIS.HBDS - Host Bus Data Error
6632 * PxIS.IFS - Interface Fatal Error
6633 * PxIS.TFES - Task File Error
6635 * The fatal error means the HBA can not recover from it by
6636 * itself, and it will try to abort the transfer, and the software
6637 * must intervene to restart the port.
6639 if (port_intr_status & (AHCI_INTR_STATUS_IFS |
6640 AHCI_INTR_STATUS_HBDS |
6641 AHCI_INTR_STATUS_HBFS |
6642 AHCI_INTR_STATUS_TFES))
6643 (void) ahci_intr_fatal_error(ahci_ctlp, ahci_portp,
6644 port, port_intr_status);
6646 /* Check the cold port detect interrupt bit */
6647 if (port_intr_status & AHCI_INTR_STATUS_CPDS) {
6648 (void) ahci_intr_cold_port_detect(ahci_ctlp, ahci_portp, port);
6651 /* Second clear the corresponding bit in IS.IPS */
6652 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
6653 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (0x1 << port));
6655 /* Try to recover at the end of the interrupt handler. */
6656 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6657 DDI_FM_OK) {
6658 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6659 DDI_SERVICE_UNAFFECTED);
6660 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6661 DDI_FME_VERSION);
6666 * Interrupt service handler
6668 static uint_t
6669 ahci_intr(caddr_t arg1, caddr_t arg2)
6671 #ifndef __lock_lint
6672 _NOTE(ARGUNUSED(arg2))
6673 #endif
6674 /* LINTED */
6675 ahci_ctl_t *ahci_ctlp = (ahci_ctl_t *)arg1;
6676 ahci_port_t *ahci_portp;
6677 int32_t global_intr_status;
6678 uint8_t port;
6681 * global_intr_status indicates that the corresponding port has
6682 * an interrupt pending.
6684 global_intr_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6685 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp));
6687 if (!(global_intr_status & ahci_ctlp->ahcictl_ports_implemented)) {
6688 /* The interrupt is not ours */
6689 return (DDI_INTR_UNCLAIMED);
6693 * Check the handle after reading global_intr_status - we don't want
6694 * to miss any port with pending interrupts.
6696 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle) !=
6697 DDI_FM_OK) {
6698 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip,
6699 DDI_SERVICE_UNAFFECTED);
6700 ddi_fm_acc_err_clear(ahci_ctlp->ahcictl_ahci_acc_handle,
6701 DDI_FME_VERSION);
6702 return (DDI_INTR_UNCLAIMED);
6705 /* Loop for all the ports */
6706 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
6707 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
6708 continue;
6710 if (!((0x1 << port) & global_intr_status)) {
6711 continue;
6714 ahci_portp = ahci_ctlp->ahcictl_ports[port];
6716 /* Call ahci_port_intr */
6717 ahci_port_intr(ahci_ctlp, ahci_portp, port);
6720 return (DDI_INTR_CLAIMED);
6724 * For non-queued commands, when the corresponding bit in the PxCI register
6725 * is cleared, it means the command is completed successfully. And according
6726 * to the HBA state machine, there are three conditions which possibly will
6727 * try to clear the PxCI register bit.
6728 * 1. Receive one D2H Register FIS which is with 'I' bit set
6729 * 2. Update PIO Setup FIS
6730 * 3. Transmit a command and receive R_OK if CTBA.C is set (software reset)
6732 * Process completed non-queued commands when the interrupt status bit -
6733 * AHCI_INTR_STATUS_DHRS or AHCI_INTR_STATUS_PSS is set.
6735 * AHCI_INTR_STATUS_DHRS means a D2H Register FIS has been received
6736 * with the 'I' bit set. And the following commands will send thus
6737 * FIS with 'I' bit set upon the successful completion:
6738 * 1. Non-data commands
6739 * 2. DMA data-in command
6740 * 3. DMA data-out command
6741 * 4. PIO data-out command
6742 * 5. PACKET non-data commands
6743 * 6. PACKET PIO data-in command
6744 * 7. PACKET PIO data-out command
6745 * 8. PACKET DMA data-in command
6746 * 9. PACKET DMA data-out command
6748 * AHCI_INTR_STATUS_PSS means a PIO Setup FIS has been received
6749 * with the 'I' bit set. And the following commands will send this
6750 * FIS upon the successful completion:
6751 * 1. PIO data-in command
6753 static int
6754 ahci_intr_cmd_cmplt(ahci_ctl_t *ahci_ctlp,
6755 ahci_port_t *ahci_portp, uint8_t port)
6757 uint32_t port_cmd_issue = 0;
6758 uint32_t finished_tags;
6759 int finished_slot;
6760 sata_pkt_t *satapkt;
6761 ahci_fis_d2h_register_t *rcvd_fisp;
6762 #if AHCI_DEBUG
6763 ahci_cmd_header_t *cmd_header;
6764 uint32_t cmd_dmacount;
6765 #endif
6767 mutex_enter(&ahci_portp->ahciport_mutex);
6769 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6770 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6771 !NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
6773 * Spurious interrupt. Nothing to be done.
6775 mutex_exit(&ahci_portp->ahciport_mutex);
6776 return (AHCI_SUCCESS);
6779 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
6780 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
6782 /* If the PxCI corrupts, don't complete the commmands. */
6783 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
6784 != DDI_FM_OK) {
6785 mutex_exit(&ahci_portp->ahciport_mutex);
6786 return (AHCI_FAILURE);
6789 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
6790 /* Slot 0 is always used during error recovery */
6791 finished_tags = 0x1 & ~port_cmd_issue;
6792 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
6793 "ahci_intr_cmd_cmplt: port %d the sata pkt for error "
6794 "retrieval is finished, and finished_tags = 0x%x",
6795 port, finished_tags);
6796 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
6797 finished_tags = 0x1 & ~port_cmd_issue;
6798 AHCIDBG(AHCIDBG_INFO, ahci_ctlp,
6799 "ahci_intr_cmd_cmplt: port %d the sata pkt for r/w "
6800 "port multiplier is finished, and finished_tags = 0x%x",
6801 port, finished_tags);
6803 } else {
6805 finished_tags = ahci_portp->ahciport_pending_tags &
6806 ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
6809 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6810 "ahci_intr_cmd_cmplt: pending_tags = 0x%x, "
6811 "port_cmd_issue = 0x%x finished_tags = 0x%x",
6812 ahci_portp->ahciport_pending_tags, port_cmd_issue,
6813 finished_tags);
6815 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&
6816 (finished_tags == 0x1)) {
6817 satapkt = ahci_portp->ahciport_err_retri_pkt;
6818 ASSERT(satapkt != NULL);
6820 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6821 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6822 "with SATA_PKT_COMPLETED", (void *)satapkt);
6824 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6825 goto out;
6828 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) &&
6829 (finished_tags == 0x1)) {
6830 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
6831 ASSERT(satapkt != NULL);
6833 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6834 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6835 "with SATA_PKT_COMPLETED", (void *)satapkt);
6837 /* READ PORTMULT need copy out FIS content. */
6838 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
6839 rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
6840 ahcirf_d2h_register_fis);
6841 satapkt->satapkt_cmd.satacmd_status_reg =
6842 GET_RFIS_STATUS(rcvd_fisp);
6843 ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
6846 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6847 goto out;
6850 while (finished_tags) {
6851 finished_slot = ddi_ffs(finished_tags) - 1;
6852 if (finished_slot == -1) {
6853 goto out;
6856 satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
6857 ASSERT(satapkt != NULL);
6858 #if AHCI_DEBUG
6860 * For non-native queued commands, the PRD byte count field
6861 * shall contain an accurate count of the number of bytes
6862 * transferred for the command before the PxCI bit is cleared
6863 * to '0' for the command.
6865 * The purpose of this field is to let software know how many
6866 * bytes transferred for a given operation in order to
6867 * determine if underflow occurred. When issuing native command
6868 * queuing commands, this field should not be used and is not
6869 * required to be valid since in this case underflow is always
6870 * illegal.
6872 * For data reads, the HBA will update its PRD byte count with
6873 * the total number of bytes received from the last FIS, and
6874 * may be able to continue normally. For data writes, the
6875 * device will detect an error, and HBA most likely will get
6876 * a fatal error.
6878 * Therefore, here just put code to debug part. And please
6879 * refer to the comment above ahci_intr_fatal_error for the
6880 * definition of underflow error.
6882 cmd_dmacount =
6883 ahci_portp->ahciport_prd_bytecounts[finished_slot];
6884 if (cmd_dmacount) {
6885 cmd_header =
6886 &ahci_portp->ahciport_cmd_list[finished_slot];
6887 AHCIDBG(AHCIDBG_INTR|AHCIDBG_PRDT, ahci_ctlp,
6888 "ahci_intr_cmd_cmplt: port %d, "
6889 "PRD Byte Count = 0x%x, "
6890 "ahciport_prd_bytecounts = 0x%x", port,
6891 cmd_header->ahcich_prd_byte_count,
6892 cmd_dmacount);
6894 if (cmd_header->ahcich_prd_byte_count != cmd_dmacount) {
6895 AHCIDBG(AHCIDBG_UNDERFLOW, ahci_ctlp,
6896 "ahci_intr_cmd_cmplt: port %d, "
6897 "an underflow occurred", port);
6900 #endif
6903 * For SATAC_SMART command with SATA_SMART_RETURN_STATUS
6904 * feature, sata_special_regs flag will be set, and the
6905 * driver should copy the status and the other corresponding
6906 * register values in the D2H Register FIS received (It's
6907 * working on Non-data protocol) from the device back to
6908 * the sata_cmd.
6910 * For every AHCI port, there is only one Received FIS
6911 * structure, which contains the FISes received from the
6912 * device, So we're trying to copy the content of D2H
6913 * Register FIS in the Received FIS structure back to
6914 * the sata_cmd.
6916 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
6917 rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
6918 ahcirf_d2h_register_fis);
6919 satapkt->satapkt_cmd.satacmd_status_reg =
6920 GET_RFIS_STATUS(rcvd_fisp);
6921 ahci_copy_out_regs(&satapkt->satapkt_cmd, rcvd_fisp);
6924 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
6925 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6926 "with SATA_PKT_COMPLETED", (void *)satapkt);
6928 CLEAR_BIT(ahci_portp->ahciport_pending_tags, finished_slot);
6929 CLEAR_BIT(finished_tags, finished_slot);
6930 ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
6932 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
6934 out:
6935 AHCIDBG(AHCIDBG_PKTCOMP, ahci_ctlp,
6936 "ahci_intr_cmd_cmplt: pending_tags = 0x%x",
6937 ahci_portp->ahciport_pending_tags);
6939 ahci_flush_doneq(ahci_portp);
6941 mutex_exit(&ahci_portp->ahciport_mutex);
6943 return (AHCI_SUCCESS);
6947 * AHCI_INTR_STATUS_SDBS means a Set Device Bits FIS has been received
6948 * with the 'I' bit set and has been copied into system memory. It will
6949 * be sent under the following situations:
6951 * 1. NCQ command is completed
6953 * The completion of NCQ commands (READ/WRITE FPDMA QUEUED) is performed
6954 * via the Set Device Bits FIS. When such event is generated, the software
6955 * needs to read PxSACT register and compares the current value to the
6956 * list of commands previously issue by software. ahciport_pending_ncq_tags
6957 * keeps the tags of previously issued commands.
6959 * 2. Asynchronous Notification
6961 * Asynchronous Notification is a feature in SATA spec 2.6.
6963 * 1) ATAPI device will send a signal to the host when media is inserted or
6964 * removed and avoids polling the device for media changes. The signal
6965 * sent to the host is a Set Device Bits FIS with the 'I' and 'N' bits
6966 * set to '1'. At the moment, it's not supported yet.
6968 * 2) Port multiplier will send a signal to the host when a hot plug event
6969 * has occured on a port multiplier port. It is used when command based
6970 * switching is employed. This is handled by ahci_intr_pmult_sntf_events()
6972 static int
6973 ahci_intr_set_device_bits(ahci_ctl_t *ahci_ctlp,
6974 ahci_port_t *ahci_portp, uint8_t port)
6976 ahci_addr_t addr;
6978 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
6979 "ahci_intr_set_device_bits enter: port %d", port);
6981 /* Initialize HBA port address */
6982 AHCI_ADDR_SET_PORT(&addr, port);
6984 /* NCQ plug handler */
6985 (void) ahci_intr_ncq_events(ahci_ctlp, ahci_portp, &addr);
6987 /* Check port multiplier's asynchronous notification events */
6988 if (ahci_ctlp->ahcictl_cap & AHCI_CAP_SNTF) {
6989 (void) ahci_intr_pmult_sntf_events(ahci_ctlp,
6990 ahci_portp, port);
6993 /* ATAPI events is not supported yet */
6995 return (AHCI_SUCCESS);
6998 * NCQ interrupt handler. Called upon a NCQ command is completed.
6999 * Only be called from ahci_intr_set_device_bits().
7001 static int
7002 ahci_intr_ncq_events(ahci_ctl_t *ahci_ctlp,
7003 ahci_port_t *ahci_portp, ahci_addr_t *addrp)
7005 uint32_t port_sactive;
7006 uint32_t port_cmd_issue;
7007 uint32_t issued_tags;
7008 int issued_slot;
7009 uint32_t finished_tags;
7010 int finished_slot;
7011 uint8_t port = addrp->aa_port;
7012 sata_pkt_t *satapkt;
7014 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7015 "ahci_intr_set_device_bits enter: port %d", port);
7017 mutex_enter(&ahci_portp->ahciport_mutex);
7018 if (!NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7019 mutex_exit(&ahci_portp->ahciport_mutex);
7020 return (AHCI_SUCCESS);
7024 * First the handler got which commands are finished by checking
7025 * PxSACT register
7027 port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7028 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7030 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
7031 ~port_sactive & AHCI_NCQ_SLOT_MASK(ahci_portp);
7033 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7034 "ahci_intr_set_device_bits: port %d pending_ncq_tags = 0x%x "
7035 "port_sactive = 0x%x", port,
7036 ahci_portp->ahciport_pending_ncq_tags, port_sactive);
7038 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7039 "ahci_intr_set_device_bits: finished_tags = 0x%x", finished_tags);
7042 * For NCQ commands, the software can determine which command has
7043 * already been transmitted to the device by checking PxCI register.
7045 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7046 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7048 issued_tags = ahci_portp->ahciport_pending_tags &
7049 ~port_cmd_issue & AHCI_SLOT_MASK(ahci_ctlp);
7051 /* If the PxSACT/PxCI corrupts, don't complete the NCQ commmands. */
7052 if (ahci_check_acc_handle(ahci_ctlp->ahcictl_ahci_acc_handle)
7053 != DDI_FM_OK) {
7054 mutex_exit(&ahci_portp->ahciport_mutex);
7055 return (AHCI_FAILURE);
7058 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7059 "ahci_intr_set_device_bits: port %d pending_tags = 0x%x "
7060 "port_cmd_issue = 0x%x", port,
7061 ahci_portp->ahciport_pending_tags, port_cmd_issue);
7063 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7064 "ahci_intr_set_device_bits: issued_tags = 0x%x", issued_tags);
7067 * Clear ahciport_pending_tags bit when the corresponding command
7068 * is already sent down to the device.
7070 while (issued_tags) {
7071 issued_slot = ddi_ffs(issued_tags) - 1;
7072 if (issued_slot == -1) {
7073 goto next;
7075 CLEAR_BIT(ahci_portp->ahciport_pending_tags, issued_slot);
7076 CLEAR_BIT(issued_tags, issued_slot);
7079 next:
7080 while (finished_tags) {
7081 finished_slot = ddi_ffs(finished_tags) - 1;
7082 if (finished_slot == -1) {
7083 goto out;
7086 /* The command is certainly transmitted to the device */
7087 ASSERT(!(ahci_portp->ahciport_pending_tags &
7088 (0x1 << finished_slot)));
7090 satapkt = ahci_portp->ahciport_slot_pkts[finished_slot];
7091 ASSERT(satapkt != NULL);
7093 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ, ahci_ctlp,
7094 "ahci_intr_set_device_bits: sending up pkt 0x%p "
7095 "with SATA_PKT_COMPLETED", (void *)satapkt);
7097 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags, finished_slot);
7098 CLEAR_BIT(finished_tags, finished_slot);
7099 ahci_portp->ahciport_slot_pkts[finished_slot] = NULL;
7101 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
7103 out:
7104 AHCIDBG(AHCIDBG_PKTCOMP|AHCIDBG_NCQ, ahci_ctlp,
7105 "ahci_intr_set_device_bits: port %d "
7106 "pending_ncq_tags = 0x%x pending_tags = 0x%x",
7107 port, ahci_portp->ahciport_pending_ncq_tags,
7108 ahci_portp->ahciport_pending_tags);
7110 ahci_flush_doneq(ahci_portp);
7112 mutex_exit(&ahci_portp->ahciport_mutex);
7114 return (AHCI_SUCCESS);
7118 * Port multiplier asynchronous notification event handler. Called upon a
7119 * device is hot plugged/pulled.
7121 * The async-notification event will only be recorded by ahcipmi_snotif_tags
7122 * here and will be handled by ahci_probe_pmult().
7124 * NOTE: called only from ahci_port_intr().
7126 static int
7127 ahci_intr_pmult_sntf_events(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7128 uint8_t port)
7130 sata_device_t sdevice;
7132 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7133 "ahci_intr_pmult_sntf_events enter: port %d ", port);
7135 /* no hot-plug while attaching process */
7136 mutex_enter(&ahci_ctlp->ahcictl_mutex);
7137 if (ahci_ctlp->ahcictl_flags & AHCI_ATTACH) {
7138 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7139 return (AHCI_SUCCESS);
7141 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7143 mutex_enter(&ahci_portp->ahciport_mutex);
7144 if (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
7145 mutex_exit(&ahci_portp->ahciport_mutex);
7146 return (AHCI_SUCCESS);
7149 ASSERT(ahci_portp->ahciport_pmult_info != NULL);
7151 ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags =
7152 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7153 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port));
7154 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7155 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp, port),
7156 AHCI_SNOTIF_CLEAR_ALL);
7158 if (ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags == 0) {
7159 mutex_exit(&ahci_portp->ahciport_mutex);
7160 return (AHCI_SUCCESS);
7163 /* Port Multiplier sub-device hot-plug handler */
7164 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
7165 mutex_exit(&ahci_portp->ahciport_mutex);
7166 return (AHCI_SUCCESS);
7169 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_PMULT_SNTF) {
7170 /* Not allowed to re-enter. */
7171 mutex_exit(&ahci_portp->ahciport_mutex);
7172 return (AHCI_SUCCESS);
7175 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_PMULT_SNTF;
7178 * NOTE:
7179 * Even if Asynchronous Notification is supported (and enabled) by
7180 * both controller and the port multiplier, the content of PxSNTF
7181 * register is always set to 0x8000 by async notification event. We
7182 * need to check GSCR[32] on the port multiplier to find out the
7183 * owner of this event.
7184 * This is not accord with SATA spec 2.6 and needs further
7185 * clarification.
7187 /* hot-plug will not reported while reseting. */
7188 if (ahci_portp->ahciport_reset_in_progress == 1) {
7189 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7190 "port %d snotif event ignored", port);
7191 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7192 mutex_exit(&ahci_portp->ahciport_mutex);
7193 return (AHCI_SUCCESS);
7196 AHCIDBG(AHCIDBG_INFO|AHCIDBG_PMULT, ahci_ctlp,
7197 "PxSNTF is set to 0x%x by port multiplier",
7198 ahci_portp->ahciport_pmult_info->ahcipmi_snotif_tags);
7201 * Now we need do some necessary operation and inform SATA framework
7202 * that link/device events has happened.
7204 bzero((void *)&sdevice, sizeof (sata_device_t));
7205 sdevice.satadev_addr.cport = ahci_ctlp->
7206 ahcictl_port_to_cport[port];
7207 sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
7208 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
7209 sdevice.satadev_state = SATA_PSTATE_PWRON;
7211 /* Just reject packets, do not stop that port. */
7212 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7214 mutex_exit(&ahci_portp->ahciport_mutex);
7215 sata_hba_event_notify(
7216 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7217 &sdevice,
7218 SATA_EVNT_PMULT_LINK_CHANGED);
7219 mutex_enter(&ahci_portp->ahciport_mutex);
7221 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_PMULT_SNTF;
7222 mutex_exit(&ahci_portp->ahciport_mutex);
7224 return (AHCI_SUCCESS);
7228 * 1=Change in Current Connect Status. 0=No change in Current Connect Status.
7229 * This bit reflects the state of PxSERR.DIAG.X. This bit is only cleared
7230 * when PxSERR.DIAG.X is cleared. When PxSERR.DIAG.X is set to one, it
7231 * indicates a COMINIT signal was received.
7233 * Hot plug insertion is detected by reception of a COMINIT signal from the
7234 * device. On reception of unsolicited COMINIT, the HBA shall generate a
7235 * COMRESET. If the COMINIT is in responce to a COMRESET, then the HBA shall
7236 * begin the normal communication negotiation sequence as outlined in the
7237 * Serial ATA 1.0a specification. When a COMRESET is sent to the device the
7238 * PxSSTS.DET field shall be cleared to 0h. When a COMINIT is received, the
7239 * PxSSTS.DET field shall be set to 1h. When the communication negotiation
7240 * sequence is complete and PhyRdy is true the PxSSTS.DET field shall be set
7241 * to 3h. Therefore, at the moment the ahci driver is going to check PhyRdy
7242 * to handle hot plug insertion. In this interrupt handler, just do nothing
7243 * but print some log message and clear the bit.
7245 static int
7246 ahci_intr_port_connect_change(ahci_ctl_t *ahci_ctlp,
7247 ahci_port_t *ahci_portp, uint8_t port)
7249 #if AHCI_DEBUG
7250 uint32_t port_serror;
7251 #endif
7253 mutex_enter(&ahci_portp->ahciport_mutex);
7255 #if AHCI_DEBUG
7256 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7257 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7259 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7260 "ahci_intr_port_connect_change: port %d, "
7261 "port_serror = 0x%x", port, port_serror);
7262 #endif
7264 /* Clear PxSERR.DIAG.X to clear the interrupt bit */
7265 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7266 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7267 SERROR_EXCHANGED_ERR);
7269 mutex_exit(&ahci_portp->ahciport_mutex);
7271 return (AHCI_SUCCESS);
7275 * Hot Plug Operation for platforms that support Mechanical Presence
7276 * Switches.
7278 * When set, it indicates that a mechanical presence switch attached to this
7279 * port has been opened or closed, which may lead to a change in the connection
7280 * state of the device. This bit is only valid if both CAP.SMPS and PxCMD.MPSP
7281 * are set to '1'.
7283 * At the moment, this interrupt is not needed and disabled and we just log
7284 * the debug message.
7286 static int
7287 ahci_intr_device_mechanical_presence_status(ahci_ctl_t *ahci_ctlp,
7288 ahci_port_t *ahci_portp, uint8_t port)
7290 uint32_t cap_status, port_cmd_status;
7292 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7293 "ahci_intr_device_mechanical_presence_status enter, "
7294 "port %d", port);
7296 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7297 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
7299 mutex_enter(&ahci_portp->ahciport_mutex);
7300 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7301 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7303 if (!(cap_status & AHCI_HBA_CAP_SMPS) ||
7304 !(port_cmd_status & AHCI_CMD_STATUS_MPSP)) {
7305 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7306 "CAP.SMPS or PxCMD.MPSP is not set, so just ignore "
7307 "the interrupt: cap_status = 0x%x, "
7308 "port_cmd_status = 0x%x", cap_status, port_cmd_status);
7309 mutex_exit(&ahci_portp->ahciport_mutex);
7311 return (AHCI_SUCCESS);
7314 #if AHCI_DEBUG
7315 if (port_cmd_status & AHCI_CMD_STATUS_MPSS) {
7316 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7317 "The mechanical presence switch is open: "
7318 "port %d, port_cmd_status = 0x%x",
7319 port, port_cmd_status);
7320 } else {
7321 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7322 "The mechanical presence switch is close: "
7323 "port %d, port_cmd_status = 0x%x",
7324 port, port_cmd_status);
7326 #endif
7328 mutex_exit(&ahci_portp->ahciport_mutex);
7330 return (AHCI_SUCCESS);
7334 * Native Hot Plug Support.
7336 * When set, it indicates that the internal PHYRDY signal changed state.
7337 * This bit reflects the state of PxSERR.DIAG.N.
7339 * There are three kinds of conditions to generate this interrupt event:
7340 * 1. a device is inserted
7341 * 2. a device is disconnected
7342 * 3. when the link enters/exits a Partial or Slumber interface power
7343 * management state
7345 * If inteface power management is enabled for a port, the PxSERR.DIAG.N
7346 * bit may be set due to the link entering the Partial or Slumber power
7347 * management state, rather than due to a hot plug insertion or removal
7348 * event. So far, the interface power management is disabled, so the
7349 * driver can reliably get removal detection notification via the
7350 * PxSERR.DIAG.N bit.
7352 static int
7353 ahci_intr_phyrdy_change(ahci_ctl_t *ahci_ctlp,
7354 ahci_port_t *ahci_portp, uint8_t port)
7356 uint32_t port_sstatus = 0; /* No dev present & PHY not established. */
7357 sata_device_t sdevice;
7358 int dev_exists_now = 0;
7359 int dev_existed_previously = 0;
7360 ahci_addr_t port_addr;
7362 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY, ahci_ctlp,
7363 "ahci_intr_phyrdy_change enter, port %d", port);
7365 /* Clear PxSERR.DIAG.N to clear the interrupt bit */
7366 mutex_enter(&ahci_portp->ahciport_mutex);
7367 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7368 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7369 SERROR_PHY_RDY_CHG);
7370 mutex_exit(&ahci_portp->ahciport_mutex);
7372 mutex_enter(&ahci_ctlp->ahcictl_mutex);
7373 if ((ahci_ctlp->ahcictl_sata_hba_tran == NULL) ||
7374 (ahci_portp == NULL)) {
7375 /* The whole controller setup is not yet done. */
7376 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7377 return (AHCI_SUCCESS);
7379 mutex_exit(&ahci_ctlp->ahcictl_mutex);
7381 mutex_enter(&ahci_portp->ahciport_mutex);
7383 /* SStatus tells the presence of device. */
7384 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7385 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
7387 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
7388 dev_exists_now = 1;
7391 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) {
7392 dev_existed_previously = 1;
7395 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_NODEV) {
7396 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_NODEV;
7397 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7398 "ahci_intr_phyrdy_change: port %d "
7399 "AHCI_PORT_FLAG_NODEV is cleared", port);
7400 if (dev_exists_now == 0)
7401 dev_existed_previously = 1;
7404 bzero((void *)&sdevice, sizeof (sata_device_t));
7405 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
7406 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
7407 sdevice.satadev_addr.pmport = 0;
7408 sdevice.satadev_state = SATA_PSTATE_PWRON;
7409 ahci_portp->ahciport_port_state = SATA_PSTATE_PWRON;
7411 AHCI_ADDR_SET_PORT(&port_addr, port);
7413 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_HOTPLUG;
7414 if (dev_exists_now) {
7415 if (dev_existed_previously) { /* 1 -> 1 */
7416 /* Things are fine now. The loss was temporary. */
7417 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7418 "ahci_intr_phyrdy_change port %d "
7419 "device link lost/established", port);
7421 mutex_exit(&ahci_portp->ahciport_mutex);
7422 sata_hba_event_notify(
7423 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7424 &sdevice,
7425 SATA_EVNT_LINK_LOST|SATA_EVNT_LINK_ESTABLISHED);
7426 mutex_enter(&ahci_portp->ahciport_mutex);
7428 } else { /* 0 -> 1 */
7429 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7430 "ahci_intr_phyrdy_change: port %d "
7431 "device link established", port);
7434 * A new device has been detected. The new device
7435 * might be a port multiplier instead of a drive, so
7436 * we cannot update the signature directly.
7438 (void) ahci_initialize_port(ahci_ctlp,
7439 ahci_portp, &port_addr);
7441 /* Try to start the port */
7442 if (ahci_start_port(ahci_ctlp, ahci_portp, port)
7443 != AHCI_SUCCESS) {
7444 sdevice.satadev_state |= SATA_PSTATE_FAILED;
7445 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7446 "ahci_intr_phyrdy_change: port %d failed "
7447 "at start port", port);
7450 /* Clear the max queue depth for inserted device */
7451 ahci_portp->ahciport_max_ncq_tags = 0;
7453 mutex_exit(&ahci_portp->ahciport_mutex);
7454 sata_hba_event_notify(
7455 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7456 &sdevice,
7457 SATA_EVNT_LINK_ESTABLISHED);
7458 mutex_enter(&ahci_portp->ahciport_mutex);
7461 } else { /* No device exists now */
7463 if (dev_existed_previously) { /* 1 -> 0 */
7464 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
7465 "ahci_intr_phyrdy_change: port %d "
7466 "device link lost", port);
7468 ahci_reject_all_abort_pkts(ahci_ctlp, ahci_portp, port);
7469 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
7470 ahci_portp, port);
7472 if (ahci_portp->ahciport_device_type ==
7473 SATA_DTYPE_PMULT) {
7474 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
7477 /* An existing device is lost. */
7478 ahci_portp->ahciport_device_type = SATA_DTYPE_NONE;
7479 ahci_portp->ahciport_port_state = SATA_STATE_UNKNOWN;
7481 mutex_exit(&ahci_portp->ahciport_mutex);
7482 sata_hba_event_notify(
7483 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7484 &sdevice,
7485 SATA_EVNT_LINK_LOST);
7486 mutex_enter(&ahci_portp->ahciport_mutex);
7489 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_HOTPLUG;
7491 mutex_exit(&ahci_portp->ahciport_mutex);
7493 return (AHCI_SUCCESS);
7497 * PxIS.UFS - Unknown FIS Error
7499 * This interrupt event means an unknown FIS was received and has been
7500 * copied into system memory. An unknown FIS is not considered an illegal
7501 * FIS, unless the length received is more than 64 bytes. If an unknown
7502 * FIS arrives with length <= 64 bytes, it is posted and the HBA continues
7503 * normal operation. If the unknown FIS is more than 64 bytes, then it
7504 * won't be posted to memory and PxSERR.ERR.P will be set, which is then
7505 * a fatal error.
7507 * PxIS.IPMS - Incorrect Port Multiplier Status
7509 * IPMS Indicates that the HBA received a FIS from a device that did not
7510 * have a command outstanding. The IPMS bit may be set during enumeration
7511 * of devices on a Port Multiplier due to the normal Port Multiplier
7512 * enumeration process. It is recommended that IPMS only be used after
7513 * enumeration is complete on the Port Multiplier (copied from spec).
7515 * PxIS.OFS - Overflow Error
7517 * Command list overflow is defined as software building a command table
7518 * that has fewer total bytes than the transaction given to the device.
7519 * On device writes, the HBA will run out of data, and on reads, there
7520 * will be no room to put the data.
7522 * For an overflow on data read, either PIO or DMA, the HBA will set
7523 * PxIS.OFS, and the HBA will do a best effort to continue, and it's a
7524 * non-fatal error when the HBA can continues. Sometimes, it will cause
7525 * a fatal error and need the software to do something.
7527 * For an overflow on data write, setting PxIS.OFS is optional for both
7528 * DMA and PIO, and it's a fatal error, and a COMRESET is required by
7529 * software to clean up from this serious error.
7531 * PxIS.INFS - Interface Non-Fatal Error
7533 * This interrupt event indicates that the HBA encountered an error on
7534 * the Serial ATA interface but was able to continue operation. The kind
7535 * of error usually occurred during a non-Data FIS, and under this condition
7536 * the FIS will be re-transmitted by HBA automatically.
7538 * When the FMA is implemented, there should be a stat structure to
7539 * record how many every kind of error happens.
7541 static int
7542 ahci_intr_non_fatal_error(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
7543 uint8_t port, uint32_t intr_status)
7545 uint32_t port_serror;
7546 #if AHCI_DEBUG
7547 uint32_t port_cmd_status;
7548 uint32_t port_cmd_issue;
7549 uint32_t port_sactive;
7550 int current_slot;
7551 uint32_t current_tags;
7552 sata_pkt_t *satapkt;
7553 ahci_cmd_header_t *cmd_header;
7554 uint32_t cmd_dmacount;
7555 #endif
7557 mutex_enter(&ahci_portp->ahciport_mutex);
7559 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7560 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7562 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ENTRY|AHCIDBG_ERRS, ahci_ctlp,
7563 "ahci_intr_non_fatal_error: port %d, "
7564 "PxSERR = 0x%x, PxIS = 0x%x ", port, port_serror, intr_status);
7566 ahci_log_serror_message(ahci_ctlp, port, port_serror, 1);
7568 if (intr_status & AHCI_INTR_STATUS_UFS) {
7569 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
7570 "ahci port %d has unknown FIS error", port);
7572 /* Clear the interrupt bit by clearing PxSERR.DIAG.F */
7573 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7574 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
7575 SERROR_FIS_TYPE);
7578 #if AHCI_DEBUG
7579 if (intr_status & AHCI_INTR_STATUS_IPMS) {
7580 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci port %d "
7581 "has Incorrect Port Multiplier Status error", port);
7584 if (intr_status & AHCI_INTR_STATUS_OFS) {
7585 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7586 "ahci port %d has overflow error", port);
7589 if (intr_status & AHCI_INTR_STATUS_INFS) {
7590 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7591 "ahci port %d has interface non fatal error", port);
7595 * Record the error occurred command's slot.
7597 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
7598 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7599 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7600 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7602 current_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7603 AHCI_CMD_STATUS_CCS_SHIFT;
7605 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
7606 satapkt = ahci_portp->ahciport_err_retri_pkt;
7607 ASSERT(satapkt != NULL);
7608 ASSERT(current_slot == 0);
7609 } else {
7610 satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7613 if (satapkt != NULL) {
7614 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7615 "ahci_intr_non_fatal_error: pending_tags = 0x%x "
7616 "cmd 0x%x", ahci_portp->ahciport_pending_tags,
7617 satapkt->satapkt_cmd.satacmd_cmd_reg);
7619 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7620 "ahci_intr_non_fatal_error: port %d, "
7621 "satapkt 0x%p is being processed when error occurs",
7622 port, (void *)satapkt);
7625 * PRD Byte Count field of command header is not
7626 * required to reflect the total number of bytes
7627 * transferred when an overflow occurs, so here
7628 * just log the value.
7630 cmd_dmacount =
7631 ahci_portp->ahciport_prd_bytecounts[current_slot];
7632 if (cmd_dmacount) {
7633 cmd_header = &ahci_portp->
7634 ahciport_cmd_list[current_slot];
7635 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7636 "ahci_intr_non_fatal_error: port %d, "
7637 "PRD Byte Count = 0x%x, "
7638 "ahciport_prd_bytecounts = 0x%x", port,
7639 cmd_header->ahcich_prd_byte_count,
7640 cmd_dmacount);
7643 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7645 * For queued command, list those command which have already
7646 * been transmitted to the device and still not completed.
7648 port_sactive = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7649 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7651 port_cmd_issue = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7652 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
7654 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS, ahci_ctlp,
7655 "ahci_intr_non_fatal_error: pending_ncq_tags = 0x%x "
7656 "port_sactive = 0x%x port_cmd_issue = 0x%x",
7657 ahci_portp->ahciport_pending_ncq_tags,
7658 port_sactive, port_cmd_issue);
7660 current_tags = ahci_portp->ahciport_pending_ncq_tags &
7661 port_sactive & ~port_cmd_issue &
7662 AHCI_NCQ_SLOT_MASK(ahci_portp);
7664 while (current_tags) {
7665 current_slot = ddi_ffs(current_tags) - 1;
7666 if (current_slot == -1) {
7667 goto out;
7670 satapkt = ahci_portp->ahciport_slot_pkts[current_slot];
7671 AHCIDBG(AHCIDBG_INTR|AHCIDBG_NCQ|AHCIDBG_ERRS,
7672 ahci_ctlp, "ahci_intr_non_fatal_error: "
7673 "port %d, satapkt 0x%p is outstanding when "
7674 "error occurs", port, (void *)satapkt);
7676 CLEAR_BIT(current_tags, current_slot);
7679 out:
7680 #endif
7681 mutex_exit(&ahci_portp->ahciport_mutex);
7683 return (AHCI_SUCCESS);
7687 * According to the AHCI spec, the error types include system memory
7688 * errors, interface errors, port multiplier errors, device errors,
7689 * command list overflow, command list underflow, native command
7690 * queuing tag errors and pio data transfer errors.
7692 * System memory errors such as target abort, master abort, and parity
7693 * may cause the host to stop, and they are serious errors and needed
7694 * to be recovered with software intervention. When system software
7695 * has given a pointer to the HBA that doesn't exist in physical memory,
7696 * a master/target abort error occurs, and PxIS.HBFS will be set. A
7697 * data error such as CRC or parity occurs, the HBA aborts the transfer
7698 * (if necessary) and PxIS.HBDS will be set.
7700 * Interface errors are errors that occur due to electrical issues on
7701 * the interface, or protocol miscommunication between the device and
7702 * HBA, and the respective PxSERR register bit will be set. And PxIS.IFS
7703 * (fatal) or PxIS.INFS (non-fatal) will be set. The conditions that
7704 * causes PxIS.IFS/PxIS.INFS to be set are
7705 * 1. in PxSERR.ERR, P bit is set to '1'
7706 * 2. in PxSERR.DIAG, C or H bit is set to '1'
7707 * 3. PhyRdy drop unexpectly, N bit is set to '1'
7708 * If the error occurred during a non-data FIS, the FIS must be
7709 * retransmitted, and the error is non-fatal and PxIS.INFS is set. If
7710 * the error occurred during a data FIS, the transfer will stop, so
7711 * the error is fatal and PxIS.IFS is set.
7713 * When a FIS arrives that updates the taskfile, the HBA checks to see
7714 * if PxTFD.STS.ERR is set. If yes, PxIS.TFES will be set and the HBA
7715 * stops processing any more commands.
7717 * Command list overflow is defined as software building a command table
7718 * that has fewer total bytes than the transaction given to the device.
7719 * On device writes, the HBA will run out of data, and on reads, there
7720 * will be no room to put the data. For an overflow on data read, either
7721 * PIO or DMA, the HBA will set PxIS.OFS, and it's a non-fatal error.
7722 * For an overflow on data write, setting PxIS.OFS is optional for both
7723 * DMA and PIO, and a COMRESET is required by software to clean up from
7724 * this serious error.
7726 * Command list underflow is defined as software building a command
7727 * table that has more total bytes than the transaction given to the
7728 * device. For data writes, both PIO and DMA, the device will detect
7729 * an error and end the transfer. And these errors are most likely going
7730 * to be fatal errors that will cause the port to be restarted. For
7731 * data reads, the HBA updates its PRD byte count, and may be
7732 * able to continue normally, but is not required to. And The HBA is
7733 * not required to detect underflow conditions for native command
7734 * queuing command.
7736 * The HBA does not actively check incoming DMA Setup FISes to ensure
7737 * that the PxSACT register bit for that slot is set. Existing error
7738 * mechanisms, such as host bus failure, or bad protocol, are used to
7739 * recover from this case.
7741 * In accordance with Serial ATA 1.0a, DATA FISes prior to the final
7742 * DATA FIS must be an integral number of Dwords. If the HBA receives
7743 * a request which is not an integral number of Dwords, the HBA
7744 * set PxSERR.ERR.P to '1', set PxIS.IFS to '1' and stop running until
7745 * software restarts the port. And the HBA ensures that the size
7746 * of the DATA FIS received during a PIO command matches the size in
7747 * the Transfer Cound field of the preceding PIO Setup FIS, if not, the
7748 * HBA sets PxSERR.ERR.P to '1', set PxIS.IFS to '1', and then
7749 * stop running until software restarts the port.
7752 * the fatal errors include PxIS.IFS, PxIS.HBDS, PxIS.HBFS and PxIS.TFES.
7754 * PxIS.IFS indicates that the hba encountered an error on the serial ata
7755 * interface which caused the transfer to stop.
7757 * PxIS.HBDS indicates that the hba encountered a data error
7758 * (uncorrectable ecc/parity) when reading from or writing to system memory.
7760 * PxIS.HBFS indicates that the hba encountered a host bus error that it
7761 * cannot recover from, such as a bad software pointer.
7763 * PxIS.TFES is set whenever the status register is updated by the device
7764 * and the error bit (bit 0) is set.
7766 static int
7767 ahci_intr_fatal_error(ahci_ctl_t *ahci_ctlp,
7768 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
7770 uint32_t port_cmd_status;
7771 uint32_t port_serror;
7772 uint32_t task_file_status;
7773 int failed_slot;
7774 sata_pkt_t *spkt = NULL;
7775 uint8_t err_byte;
7776 ahci_event_arg_t *args;
7777 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
7778 uint32_t failed_tags = 0;
7779 int task_fail_flag = 0, task_abort_flag = 0;
7780 uint32_t slot_status;
7782 mutex_enter(&ahci_portp->ahciport_mutex);
7785 * ahci_intr_phyrdy_change() may have rendered it to
7786 * SATA_DTYPE_NONE.
7788 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
7789 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
7790 "ahci_intr_fatal_error: port %d no device attached, "
7791 "and just return without doing anything", port);
7792 goto out0;
7795 if (intr_status & AHCI_INTR_STATUS_TFES) {
7796 task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7797 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
7798 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7799 "ahci_intr_fatal_error: port %d "
7800 "task_file_status = 0x%x", port, task_file_status);
7801 task_fail_flag = 1;
7803 err_byte = (task_file_status & AHCI_TFD_ERR_MASK)
7804 >> AHCI_TFD_ERR_SHIFT;
7805 if (err_byte == SATA_ERROR_ABORT)
7806 task_abort_flag = 1;
7810 * Here we just log the fatal error info in interrupt context.
7811 * Misc recovery processing will be handled in task queue.
7813 if (task_fail_flag == 1) {
7814 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7816 * Read PxCMD.CCS to determine the slot that the HBA
7817 * was processing when the error occurred.
7819 port_cmd_status = ddi_get32(
7820 ahci_ctlp->ahcictl_ahci_acc_handle,
7821 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7822 failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
7823 AHCI_CMD_STATUS_CCS_SHIFT;
7824 failed_tags = 0x1 << failed_slot;
7826 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
7827 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
7828 "ahci_intr_fatal_error: spkt 0x%p is being "
7829 "processed when fatal error occurred for port %d",
7830 spkt, port);
7833 * Won't emit the error message if it is an IDENTIFY
7834 * DEVICE command sent to an ATAPI device.
7836 if ((spkt != NULL) &&
7837 (spkt->satapkt_cmd.satacmd_cmd_reg ==
7838 SATAC_ID_DEVICE) &&
7839 (task_abort_flag == 1))
7840 goto out1;
7843 * Won't emit the error message if it is an ATAPI PACKET
7844 * command
7846 if ((spkt != NULL) &&
7847 (spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_PACKET))
7848 goto out1;
7850 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
7851 slot_status = ddi_get32(
7852 ahci_ctlp->ahcictl_ahci_acc_handle,
7853 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
7854 failed_tags = slot_status &
7855 AHCI_NCQ_SLOT_MASK(ahci_portp);
7859 /* print the fatal error type */
7860 ahci_log_fatal_error_message(ahci_ctlp, port, intr_status);
7861 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_ERRPRINT;
7863 port_serror = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7864 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port));
7866 /* print PxSERR related error message */
7867 ahci_log_serror_message(ahci_ctlp, port, port_serror, 0);
7869 /* print task file register value */
7870 if (task_fail_flag == 1) {
7871 cmn_err(CE_WARN, "!ahci%d: ahci port %d task_file_status "
7872 "= 0x%x", instance, port, task_file_status);
7873 if (task_abort_flag == 1) {
7874 cmn_err(CE_WARN, "!ahci%d: the below command (s) on "
7875 "port %d are aborted", instance, port);
7876 ahci_dump_commands(ahci_ctlp, port, failed_tags);
7880 out1:
7881 /* Prepare the argument for the taskq */
7882 args = ahci_portp->ahciport_event_args;
7883 args->ahciea_ctlp = (void *)ahci_ctlp;
7884 args->ahciea_portp = (void *)ahci_portp;
7885 args->ahciea_event = intr_status;
7886 AHCI_ADDR_SET_PORT((ahci_addr_t *)args->ahciea_addrp, port);
7888 /* Start the taskq to handle error recovery */
7889 if ((ddi_taskq_dispatch(ahci_portp->ahciport_event_taskq,
7890 ahci_events_handler,
7891 (void *)args, DDI_NOSLEEP)) != DDI_SUCCESS) {
7892 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
7893 cmn_err(CE_WARN, "!ahci%d: start taskq for error recovery "
7894 "port %d failed", instance, port);
7896 out0:
7897 mutex_exit(&ahci_portp->ahciport_mutex);
7899 return (AHCI_SUCCESS);
7903 * Hot Plug Operation for platforms that support Cold Presence Detect.
7905 * When set, a device status has changed as detected by the cold presence
7906 * detect logic. This bit can either be set due to a non-connected port
7907 * receiving a device, or a connected port having its device removed.
7908 * This bit is only valid if the port supports cold presence detect as
7909 * indicated by PxCMD.CPD set to '1'.
7911 * At the moment, this interrupt is not needed and disabled and we just
7912 * log the debug message.
7914 static int
7915 ahci_intr_cold_port_detect(ahci_ctl_t *ahci_ctlp,
7916 ahci_port_t *ahci_portp, uint8_t port)
7918 uint32_t port_cmd_status;
7919 sata_device_t sdevice;
7921 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7922 "ahci_intr_cold_port_detect enter, port %d", port);
7924 mutex_enter(&ahci_portp->ahciport_mutex);
7926 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
7927 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
7928 if (!(port_cmd_status & AHCI_CMD_STATUS_CPD)) {
7929 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7930 "port %d does not support cold presence detect, so "
7931 "we just ignore this interrupt", port);
7932 mutex_exit(&ahci_portp->ahciport_mutex);
7933 return (AHCI_SUCCESS);
7936 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7937 "port %d device status has changed", port);
7939 bzero((void *)&sdevice, sizeof (sata_device_t));
7940 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
7941 sdevice.satadev_addr.qual = SATA_ADDR_CPORT;
7942 sdevice.satadev_addr.pmport = 0;
7943 sdevice.satadev_state = SATA_PSTATE_PWRON;
7945 if (port_cmd_status & AHCI_CMD_STATUS_CPS) {
7946 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7947 "port %d: a device is hot plugged", port);
7948 mutex_exit(&ahci_portp->ahciport_mutex);
7949 sata_hba_event_notify(
7950 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7951 &sdevice,
7952 SATA_EVNT_DEVICE_ATTACHED);
7953 mutex_enter(&ahci_portp->ahciport_mutex);
7955 } else {
7956 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
7957 "port %d: a device is hot unplugged", port);
7958 mutex_exit(&ahci_portp->ahciport_mutex);
7959 sata_hba_event_notify(
7960 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
7961 &sdevice,
7962 SATA_EVNT_DEVICE_DETACHED);
7963 mutex_enter(&ahci_portp->ahciport_mutex);
7966 mutex_exit(&ahci_portp->ahciport_mutex);
7968 return (AHCI_SUCCESS);
7972 * Enable the interrupts for a particular port.
7974 static void
7975 ahci_enable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
7977 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
7979 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
7980 "ahci_enable_port_intrs enter, port %d", port);
7983 * Clear port interrupt status before enabling interrupt
7985 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7986 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp, port),
7987 AHCI_PORT_INTR_MASK);
7990 * Clear the pending bit from IS.IPS
7992 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
7993 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp), (1 << port));
7996 * Enable the following interrupts:
7997 * Device to Host Register FIS Interrupt (DHRS)
7998 * PIO Setup FIS Interrupt (PSS)
7999 * Set Device Bits Interrupt (SDBS)
8000 * Unknown FIS Interrupt (UFS)
8001 * Port Connect Change Status (PCS)
8002 * PhyRdy Change Status (PRCS)
8003 * Overflow Status (OFS)
8004 * Interface Non-fatal Error Status (INFS)
8005 * Interface Fatal Error Status (IFS)
8006 * Host Bus Data Error Status (HBDS)
8007 * Host Bus Fatal Error Status (HBFS)
8008 * Task File Error Status (TFES)
8010 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8011 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port),
8012 (AHCI_INTR_STATUS_DHRS |
8013 AHCI_INTR_STATUS_PSS |
8014 AHCI_INTR_STATUS_SDBS |
8015 AHCI_INTR_STATUS_UFS |
8016 AHCI_INTR_STATUS_DPS |
8017 AHCI_INTR_STATUS_PCS |
8018 AHCI_INTR_STATUS_PRCS |
8019 AHCI_INTR_STATUS_OFS |
8020 AHCI_INTR_STATUS_INFS |
8021 AHCI_INTR_STATUS_IFS |
8022 AHCI_INTR_STATUS_HBDS |
8023 AHCI_INTR_STATUS_HBFS |
8024 AHCI_INTR_STATUS_TFES));
8028 * Enable interrupts for all the ports.
8030 static void
8031 ahci_enable_all_intrs(ahci_ctl_t *ahci_ctlp)
8033 uint32_t ghc_control;
8035 ASSERT(MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8037 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_enable_all_intrs enter", NULL);
8039 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8040 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8042 ghc_control |= AHCI_HBA_GHC_IE;
8044 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8045 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8049 * Disable interrupts for a particular port.
8051 static void
8052 ahci_disable_port_intrs(ahci_ctl_t *ahci_ctlp, uint8_t port)
8054 ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8055 MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8057 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8058 "ahci_disable_port_intrs enter, port %d", port);
8060 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8061 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp, port), 0);
8065 * Disable interrupts for the whole HBA.
8067 * The global bit is cleared, then all interrupt sources from all
8068 * ports are disabled.
8070 static void
8071 ahci_disable_all_intrs(ahci_ctl_t *ahci_ctlp)
8073 uint32_t ghc_control;
8075 ASSERT(ahci_ctlp->ahcictl_flags & (AHCI_ATTACH | AHCI_QUIESCE) ||
8076 MUTEX_HELD(&ahci_ctlp->ahcictl_mutex));
8078 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_disable_all_intrs enter",
8079 NULL);
8081 ghc_control = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8082 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp));
8084 ghc_control &= ~AHCI_HBA_GHC_IE;
8086 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8087 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp), ghc_control);
8091 * Handle FIXED or MSI interrupts.
8094 * According to AHCI spec, the HBA may support several interrupt modes:
8095 * * pin based interrupts (FIXED)
8096 * * single MSI message interrupts
8097 * * multiple MSI based message interrupts
8099 * For pin based interrupts, the software interrupt handler need to check IS
8100 * register to find out which port has pending interrupts. And then check
8101 * PxIS register to find out which interrupt events happened on that port.
8103 * For single MSI message interrupts, MSICAP.MC.MSIE is set with '1', and
8104 * MSICAP.MC.MME is set with '0'. This mode is similar to pin based interrupts
8105 * in that software interrupt handler need to check IS register to determine
8106 * which port triggered the interrupts since it uses a single message for all
8107 * port interrupts.
8109 * HBA may optionally support multiple MSI message for better performance. In
8110 * this mode, each port may have its own interrupt message, and thus generation
8111 * of interrupts is no longer controlled through the IS register. MSICAP.MC.MMC
8112 * represents a power-of-2 wrapper on the number of implemented ports, and
8113 * the mapping of ports to interrupts is done in a 1-1 relationship, up to the
8114 * maximum number of assigned interrupts. When the number of MSI messages
8115 * allocated is less than the number requested, then hardware may have two
8116 * implementation behaviors:
8117 * * assign each ports its own interrupt and then force all additional
8118 * ports to share the last interrupt message, and this condition is
8119 * indicated by clearing GHC.MRSM to '0'
8120 * * revert to single MSI mode, indicated by setting GHC.MRSM to '1'
8121 * When multiple-message MSI is enabled, hardware will still set IS register
8122 * as single message case. And this IS register may be used by software when
8123 * fewer than the requested number of messages is granted in order to determine
8124 * which port had the interrupt.
8126 * Note: The current ahci driver only supports the first two interrupt modes:
8127 * pin based interrupts and single MSI message interrupts, and the reason
8128 * is indicated in below code.
8130 static int
8131 ahci_add_intrs(ahci_ctl_t *ahci_ctlp, int intr_type)
8133 dev_info_t *dip = ahci_ctlp->ahcictl_dip;
8134 int count, avail, actual;
8135 int i, rc;
8137 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INIT|AHCIDBG_INTR, ahci_ctlp,
8138 "ahci_add_intrs enter interrupt type 0x%x", intr_type);
8140 /* get number of interrupts. */
8141 rc = ddi_intr_get_nintrs(dip, intr_type, &count);
8142 if ((rc != DDI_SUCCESS) || (count == 0)) {
8143 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8144 "ddi_intr_get_nintrs() failed, "
8145 "rc %d count %d\n", rc, count);
8146 return (DDI_FAILURE);
8149 /* get number of available interrupts. */
8150 rc = ddi_intr_get_navail(dip, intr_type, &avail);
8151 if ((rc != DDI_SUCCESS) || (avail == 0)) {
8152 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8153 "ddi_intr_get_navail() failed, "
8154 "rc %d avail %d\n", rc, avail);
8155 return (DDI_FAILURE);
8158 #if AHCI_DEBUG
8159 if (avail < count) {
8160 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8161 "ddi_intr_get_nintrs returned %d, navail() returned %d",
8162 count, avail);
8164 #endif
8167 * Note: So far Solaris restricts the maximum number of messages for
8168 * x86 to 2, that is avail is 2, so here we set the count with 1 to
8169 * force the driver to use single MSI message interrupt. In future if
8170 * Solaris remove the restriction, then we need to delete the below
8171 * code and try to use multiple interrupt routine to gain better
8172 * performance.
8174 if ((intr_type == DDI_INTR_TYPE_MSI) && (count > 1)) {
8175 AHCIDBG(AHCIDBG_INTR, ahci_ctlp,
8176 "force to use one interrupt routine though the "
8177 "HBA supports %d interrupt", count);
8178 count = 1;
8181 /* Allocate an array of interrupt handles. */
8182 ahci_ctlp->ahcictl_intr_size = count * sizeof (ddi_intr_handle_t);
8183 ahci_ctlp->ahcictl_intr_htable =
8184 kmem_alloc(ahci_ctlp->ahcictl_intr_size, KM_SLEEP);
8186 /* call ddi_intr_alloc(). */
8187 rc = ddi_intr_alloc(dip, ahci_ctlp->ahcictl_intr_htable,
8188 intr_type, 0, count, &actual, DDI_INTR_ALLOC_NORMAL);
8190 if ((rc != DDI_SUCCESS) || (actual == 0)) {
8191 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8192 "ddi_intr_alloc() failed, rc %d count %d actual %d "
8193 "avail %d\n", rc, count, actual, avail);
8194 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8195 ahci_ctlp->ahcictl_intr_size);
8196 return (DDI_FAILURE);
8199 /* use interrupt count returned */
8200 #if AHCI_DEBUG
8201 if (actual < count) {
8202 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8203 "Requested: %d, Received: %d", count, actual);
8205 #endif
8207 ahci_ctlp->ahcictl_intr_cnt = actual;
8210 * Get priority for first, assume remaining are all the same.
8212 if (ddi_intr_get_pri(ahci_ctlp->ahcictl_intr_htable[0],
8213 &ahci_ctlp->ahcictl_intr_pri) != DDI_SUCCESS) {
8214 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8215 "ddi_intr_get_pri() failed", NULL);
8217 /* Free already allocated intr. */
8218 for (i = 0; i < actual; i++) {
8219 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8222 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8223 ahci_ctlp->ahcictl_intr_size);
8224 return (DDI_FAILURE);
8227 /* Test for high level interrupt. */
8228 if (ahci_ctlp->ahcictl_intr_pri >= ddi_intr_get_hilevel_pri()) {
8229 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8230 "ahci_add_intrs: Hi level intr not supported", NULL);
8232 /* Free already allocated intr. */
8233 for (i = 0; i < actual; i++) {
8234 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[i]);
8237 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8238 sizeof (ddi_intr_handle_t));
8240 return (DDI_FAILURE);
8243 /* Call ddi_intr_add_handler(). */
8244 for (i = 0; i < actual; i++) {
8245 if (ddi_intr_add_handler(ahci_ctlp->ahcictl_intr_htable[i],
8246 ahci_intr, (caddr_t)ahci_ctlp, NULL) != DDI_SUCCESS) {
8247 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8248 "ddi_intr_add_handler() failed", NULL);
8250 /* Free already allocated intr. */
8251 for (i = 0; i < actual; i++) {
8252 (void) ddi_intr_free(
8253 ahci_ctlp->ahcictl_intr_htable[i]);
8256 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8257 ahci_ctlp->ahcictl_intr_size);
8258 return (DDI_FAILURE);
8262 if (ddi_intr_get_cap(ahci_ctlp->ahcictl_intr_htable[0],
8263 &ahci_ctlp->ahcictl_intr_cap) != DDI_SUCCESS) {
8264 AHCIDBG(AHCIDBG_INTR|AHCIDBG_INIT, ahci_ctlp,
8265 "ddi_intr_get_cap() failed", NULL);
8267 /* Free already allocated intr. */
8268 for (i = 0; i < actual; i++) {
8269 (void) ddi_intr_free(
8270 ahci_ctlp->ahcictl_intr_htable[i]);
8273 kmem_free(ahci_ctlp->ahcictl_intr_htable,
8274 ahci_ctlp->ahcictl_intr_size);
8275 return (DDI_FAILURE);
8278 if (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK) {
8279 /* Call ddi_intr_block_enable() for MSI. */
8280 (void) ddi_intr_block_enable(ahci_ctlp->ahcictl_intr_htable,
8281 ahci_ctlp->ahcictl_intr_cnt);
8282 } else {
8283 /* Call ddi_intr_enable() for FIXED or MSI non block enable. */
8284 for (i = 0; i < ahci_ctlp->ahcictl_intr_cnt; i++) {
8285 (void) ddi_intr_enable(
8286 ahci_ctlp->ahcictl_intr_htable[i]);
8290 return (DDI_SUCCESS);
8294 * Removes the registered interrupts irrespective of whether they
8295 * were legacy or MSI.
8297 * NOTE: The controller interrupts must be disabled before calling
8298 * this routine.
8300 static void
8301 ahci_rem_intrs(ahci_ctl_t *ahci_ctlp)
8303 int x;
8305 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_rem_intrs entered", NULL);
8307 /* Disable all interrupts. */
8308 if ((ahci_ctlp->ahcictl_intr_type == DDI_INTR_TYPE_MSI) &&
8309 (ahci_ctlp->ahcictl_intr_cap & DDI_INTR_FLAG_BLOCK)) {
8310 /* Call ddi_intr_block_disable(). */
8311 (void) ddi_intr_block_disable(ahci_ctlp->ahcictl_intr_htable,
8312 ahci_ctlp->ahcictl_intr_cnt);
8313 } else {
8314 for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8315 (void) ddi_intr_disable(
8316 ahci_ctlp->ahcictl_intr_htable[x]);
8320 /* Call ddi_intr_remove_handler(). */
8321 for (x = 0; x < ahci_ctlp->ahcictl_intr_cnt; x++) {
8322 (void) ddi_intr_remove_handler(
8323 ahci_ctlp->ahcictl_intr_htable[x]);
8324 (void) ddi_intr_free(ahci_ctlp->ahcictl_intr_htable[x]);
8327 kmem_free(ahci_ctlp->ahcictl_intr_htable, ahci_ctlp->ahcictl_intr_size);
8331 * This routine tries to put port into P:NotRunning state by clearing
8332 * PxCMD.ST. HBA will clear PxCI to 0h, PxSACT to 0h, PxCMD.CCS to 0h
8333 * and PxCMD.CR to '0'.
8335 static int
8336 ahci_put_port_into_notrunning_state(ahci_ctl_t *ahci_ctlp,
8337 ahci_port_t *ahci_portp, uint8_t port)
8339 uint32_t port_cmd_status;
8340 int loop_count;
8342 ASSERT(ahci_ctlp->ahcictl_flags & AHCI_QUIESCE ||
8343 MUTEX_HELD(&ahci_ctlp->ahcictl_ports[port]->ahciport_mutex));
8345 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8346 "ahci_put_port_into_notrunning_state enter: port %d", port);
8348 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8349 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8351 port_cmd_status &= ~AHCI_CMD_STATUS_ST;
8352 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8353 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port), port_cmd_status);
8355 /* Wait until PxCMD.CR is cleared */
8356 loop_count = 0;
8357 do {
8358 port_cmd_status =
8359 ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8360 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
8362 if (loop_count++ > AHCI_POLLRATE_PORT_IDLE) {
8363 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
8364 "clearing port %d CMD.CR timeout, "
8365 "port_cmd_status = 0x%x", port,
8366 port_cmd_status);
8368 * We are effectively timing out after 0.5 sec.
8369 * This value is specified in AHCI spec.
8371 break;
8374 /* Wait for 10 millisec */
8375 drv_usecwait(AHCI_10MS_USECS);
8376 } while (port_cmd_status & AHCI_CMD_STATUS_CR);
8378 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_STARTED;
8380 if (port_cmd_status & AHCI_CMD_STATUS_CR) {
8381 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8382 "ahci_put_port_into_notrunning_state: failed to clear "
8383 "PxCMD.CR to '0' after loop count: %d, and "
8384 "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8385 return (AHCI_FAILURE);
8386 } else {
8387 AHCIDBG(AHCIDBG_INIT|AHCIDBG_POLL_LOOP, ahci_ctlp,
8388 "ahci_put_port_into_notrunning_state: succeeded to clear "
8389 "PxCMD.CR to '0' after loop count: %d, and "
8390 "port_cmd_status = 0x%x", loop_count, port_cmd_status);
8391 return (AHCI_SUCCESS);
8396 * First clear PxCMD.ST, and then check PxTFD. If both PxTFD.STS.BSY
8397 * and PxTFD.STS.DRQ cleared to '0', it means the device is in a
8398 * stable state, then set PxCMD.ST to '1' to start the port directly.
8399 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue a
8400 * COMRESET to the device to put it in an idle state.
8402 * The fifth argument returns whether the port reset is involved during
8403 * the process.
8405 * The routine will be called under following scenarios:
8406 * + To reset the HBA
8407 * + To abort the packet(s)
8408 * + To reset the port
8409 * + To activate the port
8410 * + Fatal error recovery
8411 * + To abort the timeout packet(s)
8413 * NOTES!!! During this procedure, PxSERR register will be cleared, and
8414 * according to the spec, the clearance of three bits will also clear
8415 * three interrupt status bits.
8416 * 1. PxSERR.DIAG.F will clear PxIS.UFS
8417 * 2. PxSERR.DIAG.X will clear PxIS.PCS
8418 * 3. PxSERR.DIAG.N will clear PxIS.PRCS
8420 * Among these three interrupt events, the driver needs to take care of
8421 * PxIS.PRCS, which is the hot plug event. When the driver found out
8422 * a device was unplugged, it will call the interrupt handler.
8424 static int
8425 ahci_restart_port_wait_till_ready(ahci_ctl_t *ahci_ctlp,
8426 ahci_port_t *ahci_portp, uint8_t port, int flag, int *reset_flag)
8428 uint32_t port_sstatus;
8429 uint32_t task_file_status;
8430 sata_device_t sdevice;
8431 int rval;
8432 ahci_addr_t addr_port;
8433 ahci_pmult_info_t *pminfo = NULL;
8434 int dev_exists_begin = 0;
8435 int dev_exists_end = 0;
8436 uint32_t previous_dev_type = ahci_portp->ahciport_device_type;
8437 int npmport = 0;
8438 uint8_t cport = ahci_ctlp->ahcictl_port_to_cport[port];
8440 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8442 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
8443 "ahci_restart_port_wait_till_ready: port %d enter", port);
8445 AHCI_ADDR_SET_PORT(&addr_port, port);
8447 if (ahci_portp->ahciport_device_type != SATA_DTYPE_NONE)
8448 dev_exists_begin = 1;
8450 /* First clear PxCMD.ST */
8451 rval = ahci_put_port_into_notrunning_state(ahci_ctlp, ahci_portp,
8452 port);
8453 if (rval != AHCI_SUCCESS)
8455 * If PxCMD.CR does not clear within a reasonable time, it
8456 * may assume the interface is in a hung condition and may
8457 * continue with issuing the port reset.
8459 goto reset;
8461 /* Then clear PxSERR */
8462 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
8463 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp, port),
8464 AHCI_SERROR_CLEAR_ALL);
8466 /* Then get PxTFD */
8467 task_file_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8468 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp, port));
8471 * Check whether the device is in a stable status, if yes,
8472 * then start the port directly. However for ahci_tran_reset_dport,
8473 * we may have to perform a port reset.
8475 if (!(task_file_status & (AHCI_TFD_STS_BSY | AHCI_TFD_STS_DRQ)) &&
8476 !(flag & AHCI_PORT_RESET))
8477 goto out;
8479 reset:
8481 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue
8482 * a COMRESET to the device
8484 ahci_disable_port_intrs(ahci_ctlp, port);
8485 rval = ahci_port_reset(ahci_ctlp, ahci_portp, &addr_port);
8486 ahci_enable_port_intrs(ahci_ctlp, port);
8488 #ifdef AHCI_DEBUG
8489 if (rval != AHCI_SUCCESS)
8490 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8491 "ahci_restart_port_wait_till_ready: port %d failed",
8492 port);
8493 #endif
8495 if (reset_flag != NULL)
8496 *reset_flag = 1;
8498 /* Indicate to the framework that a reset has happened. */
8499 if ((ahci_portp->ahciport_device_type != SATA_DTYPE_NONE) &&
8500 (ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) &&
8501 !(flag & AHCI_RESET_NO_EVENTS_UP)) {
8502 /* Set the reset in progress flag */
8503 ahci_portp->ahciport_reset_in_progress = 1;
8505 bzero((void *)&sdevice, sizeof (sata_device_t));
8506 sdevice.satadev_addr.cport =
8507 ahci_ctlp->ahcictl_port_to_cport[port];
8508 sdevice.satadev_addr.pmport = 0;
8509 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8511 sdevice.satadev_state = SATA_DSTATE_RESET |
8512 SATA_DSTATE_PWR_ACTIVE;
8513 if (ahci_ctlp->ahcictl_sata_hba_tran) {
8514 mutex_exit(&ahci_portp->ahciport_mutex);
8515 sata_hba_event_notify(
8516 ahci_ctlp->ahcictl_sata_hba_tran->sata_tran_hba_dip,
8517 &sdevice,
8518 SATA_EVNT_DEVICE_RESET);
8519 mutex_enter(&ahci_portp->ahciport_mutex);
8522 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8523 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8524 } else {
8525 ahci_portp->ahciport_reset_in_progress = 0;
8528 out:
8529 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8531 /* SStatus tells the presence of device. */
8532 port_sstatus = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
8533 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp, port));
8535 if (SSTATUS_GET_DET(port_sstatus) == SSTATUS_DET_DEVPRE_PHYCOM) {
8536 dev_exists_end = 1;
8539 if (dev_exists_begin == 0 && dev_exists_end == 0) /* 0 -> 0 */
8540 return (rval);
8542 /* Check whether a hot plug event happened */
8543 if (dev_exists_begin == 1 && dev_exists_end == 0) { /* 1 -> 0 */
8544 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8545 "ahci_restart_port_wait_till_ready: port %d "
8546 "device is removed", port);
8547 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_NODEV;
8548 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8549 "ahci_restart_port_wait_till_ready: port %d "
8550 "AHCI_PORT_FLAG_NODEV flag is set", port);
8551 mutex_exit(&ahci_portp->ahciport_mutex);
8552 (void) ahci_intr_phyrdy_change(ahci_ctlp, ahci_portp, port);
8553 mutex_enter(&ahci_portp->ahciport_mutex);
8555 return (rval);
8559 /* 0/1 -> 1 : device may change */
8561 * May be called by ahci_fatal_error_recovery_handler, so
8562 * don't issue software if the previous device is ATAPI.
8564 if (ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
8565 return (rval);
8568 * The COMRESET will make port multiplier enter legacy mode.
8569 * Issue a software reset to make it work again.
8571 ahci_disable_port_intrs(ahci_ctlp, port);
8572 ahci_find_dev_signature(ahci_ctlp, ahci_portp, &addr_port);
8573 ahci_enable_port_intrs(ahci_ctlp, port);
8576 * Following codes are specific for the port multiplier
8578 if (previous_dev_type != SATA_DTYPE_PMULT &&
8579 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8580 /* in case previous_dev_type is corrupt */
8581 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8582 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8583 return (rval);
8586 /* Device change: PMult -> Non-PMult */
8587 if (previous_dev_type == SATA_DTYPE_PMULT &&
8588 ahci_portp->ahciport_device_type != SATA_DTYPE_PMULT) {
8590 * This might happen because
8591 * 1. Software reset failed. Port multiplier is not correctly
8592 * enumerated.
8593 * 2. Another non-port-multiplier device is attached. Perhaps
8594 * the port multiplier was replaced by another device by
8595 * whatever reason, but AHCI driver missed hot-plug event.
8597 * Now that the port has been initialized, we just need to
8598 * update the port structure according new device, then report
8599 * and wait SATA framework to probe new device.
8602 /* Force to release pmult resource */
8603 ahci_dealloc_pmult(ahci_ctlp, ahci_portp);
8604 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8606 bzero((void *)&sdevice, sizeof (sata_device_t));
8607 sdevice.satadev_addr.cport =
8608 ahci_ctlp->ahcictl_port_to_cport[port];
8609 sdevice.satadev_addr.pmport = 0;
8610 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
8612 sdevice.satadev_state = SATA_DSTATE_RESET |
8613 SATA_DSTATE_PWR_ACTIVE;
8615 mutex_exit(&ahci_portp->ahciport_mutex);
8616 sata_hba_event_notify(
8617 ahci_ctlp->ahcictl_dip,
8618 &sdevice,
8619 SATA_EVNT_DEVICE_RESET);
8620 mutex_enter(&ahci_portp->ahciport_mutex);
8622 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8623 "Port multiplier is [Gone] at port %d ", port);
8624 AHCIDBG(AHCIDBG_EVENT, ahci_ctlp,
8625 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port);
8627 return (AHCI_SUCCESS);
8630 /* Device change: Non-PMult -> PMult */
8631 if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
8633 /* NOTE: The PxCMD.PMA may be cleared by HBA reset. */
8634 ahci_alloc_pmult(ahci_ctlp, ahci_portp);
8636 (void) ahci_start_port(ahci_ctlp, ahci_portp, port);
8638 pminfo = ahci_portp->ahciport_pmult_info;
8639 ASSERT(pminfo != NULL);
8641 /* Device (may) change: PMult -> PMult */
8643 * First initialize port multiplier. Set state to READY and wait for
8644 * probe entry point to initialize it
8646 ahci_portp->ahciport_port_state = SATA_STATE_READY;
8649 * It's a little complicated while target is a port multiplier. we
8650 * need to COMRESET all pmports behind that PMult otherwise those
8651 * sub-links between the PMult and the sub-devices will be in an
8652 * inactive state (indicated by PSCR0/PxSSTS) and the following access
8653 * to those sub-devices will be rejected by Link-Fatal-Error.
8656 * The PxSNTF will be set soon after the pmult is plugged. While the
8657 * pmult itself is attaching, sata_hba_event_notfiy will fail. so we
8658 * simply mark every sub-port as 'unknown', then ahci_probe_pmport
8659 * will initialized it.
8661 for (npmport = 0; npmport < pminfo->ahcipmi_num_dev_ports; npmport++)
8662 pminfo->ahcipmi_port_state[npmport] = SATA_STATE_UNKNOWN;
8664 /* Report reset event. */
8665 ahci_portp->ahciport_reset_in_progress = 1;
8667 bzero((void *)&sdevice, sizeof (sata_device_t));
8668 sdevice.satadev_addr.cport = cport;
8669 sdevice.satadev_addr.pmport = SATA_PMULT_HOSTPORT;
8670 sdevice.satadev_addr.qual = SATA_ADDR_PMULT;
8671 sdevice.satadev_state = SATA_DSTATE_RESET | SATA_DSTATE_PWR_ACTIVE;
8672 sata_hba_event_notify(ahci_ctlp->ahcictl_dip, &sdevice,
8673 SATA_EVNT_DEVICE_RESET);
8675 return (rval);
8679 * This routine may be called under four scenarios:
8680 * a) do the recovery from fatal error
8681 * b) or we need to timeout some commands
8682 * c) or we need to abort some commands
8683 * d) or we need reset device/port/controller
8685 * In all these scenarios, we need to send any pending unfinished
8686 * commands up to sata framework.
8688 static void
8689 ahci_mop_commands(ahci_ctl_t *ahci_ctlp,
8690 ahci_port_t *ahci_portp,
8691 uint32_t slot_status,
8692 uint32_t failed_tags,
8693 uint32_t timeout_tags,
8694 uint32_t aborted_tags,
8695 uint32_t reset_tags)
8697 uint32_t finished_tags = 0;
8698 uint32_t unfinished_tags = 0;
8699 int tmp_slot;
8700 sata_pkt_t *satapkt;
8701 int ncq_cmd_in_progress = 0;
8702 int err_retri_cmd_in_progress = 0;
8703 int rdwr_pmult_cmd_in_progress = 0;
8705 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
8707 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8708 "ahci_mop_commands entered: port: %d slot_status: 0x%x",
8709 ahci_portp->ahciport_port_num, slot_status);
8711 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8712 "ahci_mop_commands: failed_tags: 0x%x, "
8713 "timeout_tags: 0x%x aborted_tags: 0x%x, "
8714 "reset_tags: 0x%x", failed_tags,
8715 timeout_tags, aborted_tags, reset_tags);
8717 #ifdef AHCI_DEBUG
8718 if (ahci_debug_flags & AHCIDBG_ERRS) {
8719 int i;
8720 char msg_buf[200] = {0, };
8721 for (i = 0x1f; i >= 0; i--) {
8722 if (ahci_portp->ahciport_slot_pkts[i] != NULL)
8723 msg_buf[i] = 'X';
8724 else
8725 msg_buf[i] = '.';
8727 msg_buf[0x20] = '\0';
8728 cmn_err(CE_NOTE, "port[%d] slots: %s",
8729 ahci_portp->ahciport_port_num, msg_buf);
8730 cmn_err(CE_NOTE, "[ERR-RT] %p [RW-PM] %p ",
8731 (void *)ahci_portp->ahciport_err_retri_pkt,
8732 (void *)ahci_portp->ahciport_rdwr_pmult_pkt);
8734 #endif
8736 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8737 finished_tags = ahci_portp->ahciport_pending_tags &
8738 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
8740 unfinished_tags = slot_status &
8741 AHCI_SLOT_MASK(ahci_ctlp) &
8742 ~failed_tags &
8743 ~aborted_tags &
8744 ~reset_tags &
8745 ~timeout_tags;
8746 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
8747 ncq_cmd_in_progress = 1;
8748 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
8749 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
8751 unfinished_tags = slot_status &
8752 AHCI_NCQ_SLOT_MASK(ahci_portp) &
8753 ~failed_tags &
8754 ~aborted_tags &
8755 ~reset_tags &
8756 ~timeout_tags;
8757 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
8760 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT is
8761 * set, it means REQUEST SENSE or READ LOG EXT command doesn't
8762 * complete successfully due to one of the following three
8763 * conditions:
8765 * 1. Fatal error - failed_tags includes its slot
8766 * 2. Timed out - timeout_tags includes its slot
8767 * 3. Aborted when hot unplug - aborted_tags includes its
8768 * slot
8770 * Please note that the command is always sent down in Slot 0
8772 err_retri_cmd_in_progress = 1;
8773 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_NCQ, ahci_ctlp,
8774 "ahci_mop_commands is called for port %d while "
8775 "REQUEST SENSE or READ LOG EXT for error retrieval "
8776 "is being executed slot_status = 0x%x",
8777 ahci_portp->ahciport_port_num, slot_status);
8778 ASSERT(ahci_portp->ahciport_mop_in_progress > 1);
8779 ASSERT(slot_status == 0x1);
8780 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
8781 rdwr_pmult_cmd_in_progress = 1;
8782 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PMULT, ahci_ctlp,
8783 "ahci_mop_commands is called for port %d while "
8784 "READ/WRITE PORTMULT command is being executed",
8785 ahci_portp->ahciport_port_num);
8787 ASSERT(slot_status == 0x1);
8790 #ifdef AHCI_DEBUG
8791 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_ENTRY, ahci_ctlp,
8792 "ahci_mop_commands: finished_tags: 0x%x, "
8793 "unfinished_tags 0x%x", finished_tags, unfinished_tags);
8794 #endif
8796 /* Send up finished packets with SATA_PKT_COMPLETED */
8797 while (finished_tags) {
8798 tmp_slot = ddi_ffs(finished_tags) - 1;
8799 if (tmp_slot == -1) {
8800 break;
8803 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8804 ASSERT(satapkt != NULL);
8806 AHCIDBG(AHCIDBG_INFO, ahci_ctlp, "ahci_mop_commands: "
8807 "sending up pkt 0x%p with SATA_PKT_COMPLETED",
8808 (void *)satapkt);
8811 * Cannot fetch the return register content since the port
8812 * was restarted, so the corresponding tag will be set to
8813 * aborted tags.
8815 if (satapkt->satapkt_cmd.satacmd_flags.sata_special_regs) {
8816 CLEAR_BIT(finished_tags, tmp_slot);
8817 aborted_tags |= tmp_slot;
8818 continue;
8821 if (ncq_cmd_in_progress)
8822 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8823 tmp_slot);
8824 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8825 CLEAR_BIT(finished_tags, tmp_slot);
8826 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8828 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_COMPLETED);
8831 /* Send up failed packets with SATA_PKT_DEV_ERROR. */
8832 while (failed_tags) {
8833 if (err_retri_cmd_in_progress) {
8834 satapkt = ahci_portp->ahciport_err_retri_pkt;
8835 ASSERT(satapkt != NULL);
8836 ASSERT(failed_tags == 0x1);
8838 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8839 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8840 (void *)satapkt);
8841 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8842 break;
8844 if (rdwr_pmult_cmd_in_progress) {
8845 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8846 ASSERT(satapkt != NULL);
8847 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8848 "ahci_mop_commands: sending up "
8849 "rdwr pmult pkt 0x%p with SATA_PKT_DEV_ERROR",
8850 (void *)satapkt);
8851 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8852 break;
8855 tmp_slot = ddi_ffs(failed_tags) - 1;
8856 if (tmp_slot == -1) {
8857 break;
8860 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8861 ASSERT(satapkt != NULL);
8863 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8864 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8865 (void *)satapkt);
8867 if (ncq_cmd_in_progress)
8868 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8869 tmp_slot);
8870 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8871 CLEAR_BIT(failed_tags, tmp_slot);
8872 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8874 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_DEV_ERROR);
8877 /* Send up timeout packets with SATA_PKT_TIMEOUT. */
8878 while (timeout_tags) {
8879 if (err_retri_cmd_in_progress) {
8880 satapkt = ahci_portp->ahciport_err_retri_pkt;
8881 ASSERT(satapkt != NULL);
8882 ASSERT(timeout_tags == 0x1);
8884 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8885 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
8886 (void *)satapkt);
8887 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8888 break;
8890 if (rdwr_pmult_cmd_in_progress) {
8891 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8892 ASSERT(satapkt != NULL);
8893 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8894 "ahci_mop_commands: sending up "
8895 "rdwr pmult pkt 0x%p with SATA_PKT_TIMEOUT",
8896 (void *)satapkt);
8897 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8898 break;
8901 tmp_slot = ddi_ffs(timeout_tags) - 1;
8902 if (tmp_slot == -1) {
8903 break;
8906 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8907 ASSERT(satapkt != NULL);
8909 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8910 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
8911 (void *)satapkt);
8913 if (ncq_cmd_in_progress)
8914 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8915 tmp_slot);
8916 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
8917 CLEAR_BIT(timeout_tags, tmp_slot);
8918 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8920 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_TIMEOUT);
8923 /* Send up aborted packets with SATA_PKT_ABORTED */
8924 while (aborted_tags) {
8925 if (err_retri_cmd_in_progress) {
8926 satapkt = ahci_portp->ahciport_err_retri_pkt;
8927 ASSERT(satapkt != NULL);
8928 ASSERT(aborted_tags == 0x1);
8930 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8931 "sending up pkt 0x%p with SATA_PKT_ABORTED",
8932 (void *)satapkt);
8933 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
8934 break;
8936 if (rdwr_pmult_cmd_in_progress) {
8937 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8938 ASSERT(satapkt != NULL);
8939 ASSERT(aborted_tags == 0x1);
8940 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8941 "ahci_mop_commands: sending up "
8942 "rdwr pmult pkt 0x%p with SATA_PKT_ABORTED",
8943 (void *)satapkt);
8944 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
8945 break;
8948 tmp_slot = ddi_ffs(aborted_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_ABORTED",
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(aborted_tags, tmp_slot);
8965 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
8967 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_ABORTED);
8970 /* Send up reset packets with SATA_PKT_RESET. */
8971 while (reset_tags) {
8972 if (rdwr_pmult_cmd_in_progress) {
8973 satapkt = ahci_portp->ahciport_rdwr_pmult_pkt;
8974 ASSERT(satapkt != NULL);
8975 ASSERT(aborted_tags == 0x1);
8976 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
8977 "ahci_mop_commands: sending up "
8978 "rdwr pmult pkt 0x%p with SATA_PKT_RESET",
8979 (void *)satapkt);
8980 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
8981 break;
8984 tmp_slot = ddi_ffs(reset_tags) - 1;
8985 if (tmp_slot == -1) {
8986 break;
8989 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
8990 ASSERT(satapkt != NULL);
8992 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
8993 "sending up pkt 0x%p with SATA_PKT_RESET",
8994 (void *)satapkt);
8996 if (ncq_cmd_in_progress)
8997 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
8998 tmp_slot);
8999 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9000 CLEAR_BIT(reset_tags, tmp_slot);
9001 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9003 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9006 /* Send up unfinished packets with SATA_PKT_RESET */
9007 while (unfinished_tags) {
9008 tmp_slot = ddi_ffs(unfinished_tags) - 1;
9009 if (tmp_slot == -1) {
9010 break;
9013 satapkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9014 ASSERT(satapkt != NULL);
9016 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, "ahci_mop_commands: "
9017 "sending up pkt 0x%p with SATA_PKT_RESET",
9018 (void *)satapkt);
9020 if (ncq_cmd_in_progress)
9021 CLEAR_BIT(ahci_portp->ahciport_pending_ncq_tags,
9022 tmp_slot);
9023 CLEAR_BIT(ahci_portp->ahciport_pending_tags, tmp_slot);
9024 CLEAR_BIT(unfinished_tags, tmp_slot);
9025 ahci_portp->ahciport_slot_pkts[tmp_slot] = NULL;
9027 ahci_add_doneq(ahci_portp, satapkt, SATA_PKT_RESET);
9030 ahci_portp->ahciport_mop_in_progress--;
9031 ASSERT(ahci_portp->ahciport_mop_in_progress >= 0);
9033 if (ahci_portp->ahciport_mop_in_progress == 0)
9034 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_MOPPING;
9036 ahci_flush_doneq(ahci_portp);
9040 * This routine is going to first request a READ LOG EXT sata pkt from sata
9041 * module, and then deliver it to the HBA to get the ncq failure context.
9042 * The return value is the exactly failed tags.
9044 static uint32_t
9045 ahci_get_rdlogext_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9046 uint8_t port)
9048 sata_device_t sdevice;
9049 sata_pkt_t *rdlog_spkt, *spkt;
9050 ddi_dma_handle_t buf_dma_handle;
9051 ahci_addr_t addr;
9052 int loop_count;
9053 int rval;
9054 int failed_slot;
9055 uint32_t failed_tags = 0;
9056 struct sata_ncq_error_recovery_page *ncq_err_page;
9058 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_NCQ, ahci_ctlp,
9059 "ahci_get_rdlogext_data enter: port %d", port);
9061 /* Prepare the sdevice data */
9062 bzero((void *)&sdevice, sizeof (sata_device_t));
9063 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9065 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9066 sdevice.satadev_addr.pmport = 0;
9068 /* Translate sata_device.satadev_addr -> ahci_addr */
9069 ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9072 * Call the sata hba interface to get a rdlog spkt
9074 loop_count = 0;
9075 loop:
9076 rdlog_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9077 &sdevice, SATA_ERR_RETR_PKT_TYPE_NCQ);
9078 if (rdlog_spkt == NULL) {
9079 if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9080 /* Sleep for a while */
9081 drv_usecwait(AHCI_10MS_USECS);
9082 goto loop;
9084 /* Timed out after 1s */
9085 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9086 "failed to get rdlog spkt for port %d", port);
9087 return (failed_tags);
9090 ASSERT(rdlog_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9093 * This flag is used to handle the specific error recovery when the
9094 * READ LOG EXT command gets a failure (fatal error or time-out).
9096 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RDLOGEXT;
9099 * This start is not supposed to fail because after port is restarted,
9100 * the whole command list is empty.
9102 ahci_portp->ahciport_err_retri_pkt = rdlog_spkt;
9103 (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rdlog_spkt);
9104 ahci_portp->ahciport_err_retri_pkt = NULL;
9106 /* Remove the flag after READ LOG EXT command is completed */
9107 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RDLOGEXT;
9109 if (rdlog_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9110 /* Update the request log data */
9111 buf_dma_handle = *(ddi_dma_handle_t *)
9112 (rdlog_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9113 rval = ddi_dma_sync(buf_dma_handle, 0, 0,
9114 DDI_DMA_SYNC_FORKERNEL);
9115 if (rval == DDI_SUCCESS) {
9116 ncq_err_page =
9117 (struct sata_ncq_error_recovery_page *)rdlog_spkt->
9118 satapkt_cmd.satacmd_bp->b_un.b_addr;
9120 /* Get the failed tag */
9121 failed_slot = ncq_err_page->ncq_tag;
9122 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9123 "ahci_get_rdlogext_data: port %d "
9124 "failed slot %d", port, failed_slot);
9125 if (failed_slot & NQ) {
9126 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9127 "the failed slot is not a valid tag", NULL);
9128 goto out;
9131 failed_slot &= NCQ_TAG_MASK;
9132 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9133 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9134 "ahci_get_rdlogext_data: failed spkt 0x%p",
9135 (void *)spkt);
9136 if (spkt == NULL) {
9137 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9138 "the failed slot spkt is NULL", NULL);
9139 goto out;
9142 failed_tags = 0x1 << failed_slot;
9144 /* Fill out the error context */
9145 ahci_copy_ncq_err_page(&spkt->satapkt_cmd,
9146 ncq_err_page);
9147 ahci_update_sata_registers(ahci_ctlp, port,
9148 &spkt->satapkt_device);
9151 out:
9152 sata_free_error_retrieval_pkt(rdlog_spkt);
9154 return (failed_tags);
9158 * This routine is going to first request a REQUEST SENSE sata pkt from sata
9159 * module, and then deliver it to the HBA to get the sense data and copy
9160 * the sense data back to the orignal failed sata pkt, and free the REQUEST
9161 * SENSE sata pkt later.
9163 static void
9164 ahci_get_rqsense_data(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9165 uint8_t port, sata_pkt_t *spkt)
9167 sata_device_t sdevice;
9168 sata_pkt_t *rs_spkt;
9169 sata_cmd_t *sata_cmd;
9170 ddi_dma_handle_t buf_dma_handle;
9171 ahci_addr_t addr;
9172 int loop_count;
9173 #if AHCI_DEBUG
9174 struct scsi_extended_sense *rqsense;
9175 #endif
9177 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9178 "ahci_get_rqsense_data enter: port %d", port);
9180 /* Prepare the sdevice data */
9181 bzero((void *)&sdevice, sizeof (sata_device_t));
9182 sdevice.satadev_addr.cport = ahci_ctlp->ahcictl_port_to_cport[port];
9184 sdevice.satadev_addr.qual = SATA_ADDR_DCPORT;
9185 sdevice.satadev_addr.pmport = 0;
9187 /* Translate sata_device.satadev_addr -> ahci_addr */
9188 ahci_get_ahci_addr(ahci_ctlp, &sdevice, &addr);
9190 sata_cmd = &spkt->satapkt_cmd;
9193 * Call the sata hba interface to get a rs spkt
9195 loop_count = 0;
9196 loop:
9197 rs_spkt = sata_get_error_retrieval_pkt(ahci_ctlp->ahcictl_dip,
9198 &sdevice, SATA_ERR_RETR_PKT_TYPE_ATAPI);
9199 if (rs_spkt == NULL) {
9200 if (loop_count++ < AHCI_POLLRATE_GET_SPKT) {
9201 /* Sleep for a while */
9202 drv_usecwait(AHCI_10MS_USECS);
9203 goto loop;
9206 /* Timed out after 1s */
9207 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9208 "failed to get rs spkt for port %d", port);
9209 return;
9212 ASSERT(rs_spkt->satapkt_op_mode & SATA_OPMODE_SYNCH);
9215 * This flag is used to handle the specific error recovery when the
9216 * REQUEST SENSE command gets a faiure (fatal error or time-out).
9218 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_RQSENSE;
9221 * This start is not supposed to fail because after port is restarted,
9222 * the whole command list is empty.
9224 ahci_portp->ahciport_err_retri_pkt = rs_spkt;
9225 (void) ahci_do_sync_start(ahci_ctlp, ahci_portp, &addr, rs_spkt);
9226 ahci_portp->ahciport_err_retri_pkt = NULL;
9228 /* Remove the flag after REQUEST SENSE command is completed */
9229 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_RQSENSE;
9231 if (rs_spkt->satapkt_reason == SATA_PKT_COMPLETED) {
9232 /* Update the request sense data */
9233 buf_dma_handle = *(ddi_dma_handle_t *)
9234 (rs_spkt->satapkt_cmd.satacmd_err_ret_buf_handle);
9235 (void) ddi_dma_sync(buf_dma_handle, 0, 0,
9236 DDI_DMA_SYNC_FORKERNEL);
9237 /* Copy the request sense data */
9238 bcopy(rs_spkt->
9239 satapkt_cmd.satacmd_bp->b_un.b_addr,
9240 &sata_cmd->satacmd_rqsense,
9241 SATA_ATAPI_MIN_RQSENSE_LEN);
9242 #if AHCI_DEBUG
9243 rqsense = (struct scsi_extended_sense *)
9244 sata_cmd->satacmd_rqsense;
9246 /* Dump the sense data */
9247 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp, "\n", NULL);
9248 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9249 "Sense data for satapkt %p ATAPI cmd 0x%x",
9250 spkt, sata_cmd->satacmd_acdb[0]);
9251 AHCIDBG(AHCIDBG_SENSEDATA, ahci_ctlp,
9252 " es_code 0x%x es_class 0x%x "
9253 "es_key 0x%x es_add_code 0x%x "
9254 "es_qual_code 0x%x",
9255 rqsense->es_code, rqsense->es_class,
9256 rqsense->es_key, rqsense->es_add_code,
9257 rqsense->es_qual_code);
9258 #endif
9261 sata_free_error_retrieval_pkt(rs_spkt);
9265 * Fatal errors will cause the HBA to enter the ERR: Fatal state. To recover,
9266 * the port must be restarted. When the HBA detects thus error, it may try
9267 * to abort a transfer. And if the transfer was aborted, the device is
9268 * expected to send a D2H Register FIS with PxTFD.STS.ERR set to '1' and both
9269 * PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0'. Then system software knows
9270 * that the device is in a stable status and transfers may be restarted without
9271 * issuing a COMRESET to the device. If PxTFD.STS.BSY or PxTFD.STS.DRQ is set,
9272 * then the software will send the COMRESET to do the port reset.
9274 * Software should perform the appropriate error recovery actions based on
9275 * whether non-queued commands were being issued or natived command queuing
9276 * commands were being issued.
9278 * And software will complete the command that had the error with error mark
9279 * to higher level software.
9281 * Fatal errors include the following:
9282 * PxIS.IFS - Interface Fatal Error Status
9283 * PxIS.HBDS - Host Bus Data Error Status
9284 * PxIS.HBFS - Host Bus Fatal Error Status
9285 * PxIS.TFES - Task File Error Status
9287 static void
9288 ahci_fatal_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9289 ahci_port_t *ahci_portp, ahci_addr_t *addrp, uint32_t intr_status)
9291 uint32_t port_cmd_status;
9292 uint32_t slot_status = 0;
9293 uint32_t failed_tags = 0;
9294 int failed_slot;
9295 int reset_flag = 0, flag = 0;
9296 ahci_fis_d2h_register_t *ahci_rcvd_fisp;
9297 sata_cmd_t *sata_cmd = NULL;
9298 sata_pkt_t *spkt = NULL;
9299 #if AHCI_DEBUG
9300 ahci_cmd_header_t *cmd_header;
9301 #endif
9302 uint8_t port = addrp->aa_port;
9303 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9304 int rval;
9306 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9308 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9309 "ahci_fatal_error_recovery_handler enter: port %d", port);
9311 /* Port multiplier error */
9312 if (ahci_portp->ahciport_device_type == SATA_DTYPE_PMULT) {
9313 /* FBS code is neither completed nor tested. */
9314 ahci_pmult_error_recovery_handler(ahci_ctlp, ahci_portp,
9315 port, intr_status);
9317 /* Force a port reset */
9318 flag = AHCI_PORT_RESET;
9321 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9322 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9324 /* Read PxCI to see which commands are still outstanding */
9325 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9326 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9329 * Read PxCMD.CCS to determine the slot that the HBA
9330 * was processing when the error occurred.
9332 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9333 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9334 failed_slot = (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9335 AHCI_CMD_STATUS_CCS_SHIFT;
9337 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9338 spkt = ahci_portp->ahciport_err_retri_pkt;
9339 ASSERT(spkt != NULL);
9340 } else {
9341 spkt = ahci_portp->ahciport_slot_pkts[failed_slot];
9342 if (spkt == NULL) {
9343 /* May happen when interface errors occur? */
9344 goto next;
9348 #if AHCI_DEBUG
9350 * Debugging purpose...
9352 if (ahci_portp->ahciport_prd_bytecounts[failed_slot]) {
9353 cmd_header =
9354 &ahci_portp->ahciport_cmd_list[failed_slot];
9355 AHCIDBG(AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9356 "ahci_fatal_error_recovery_handler: port %d, "
9357 "PRD Byte Count = 0x%x, "
9358 "ahciport_prd_bytecounts = 0x%x", port,
9359 cmd_header->ahcich_prd_byte_count,
9360 ahci_portp->ahciport_prd_bytecounts[failed_slot]);
9362 #endif
9364 sata_cmd = &spkt->satapkt_cmd;
9366 /* Fill out the status and error registers for PxIS.TFES */
9367 if (intr_status & AHCI_INTR_STATUS_TFES) {
9368 ahci_rcvd_fisp = &(ahci_portp->ahciport_rcvd_fis->
9369 ahcirf_d2h_register_fis);
9371 /* Copy the error context back to the sata_cmd */
9372 ahci_copy_err_cnxt(sata_cmd, ahci_rcvd_fisp);
9375 /* The failed command must be one of the outstanding commands */
9376 failed_tags = 0x1 << failed_slot;
9377 ASSERT(failed_tags & slot_status);
9379 /* Update the sata registers, especially PxSERR register */
9380 ahci_update_sata_registers(ahci_ctlp, port,
9381 &spkt->satapkt_device);
9383 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9384 /* Read PxSACT to see which commands are still outstanding */
9385 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9386 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9388 next:
9390 #if AHCI_DEBUG
9392 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9393 * set, it means a fatal error happened after REQUEST SENSE command
9394 * or READ LOG EXT command is delivered to the HBA during the error
9395 * recovery process. At this time, the only outstanding command is
9396 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9398 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9399 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9400 "ahci_fatal_error_recovery_handler: port %d REQUEST SENSE "
9401 "command or READ LOG EXT command for error data retrieval "
9402 "failed", port);
9403 ASSERT(slot_status == 0x1);
9404 ASSERT(failed_slot == 0);
9405 ASSERT(spkt->satapkt_cmd.satacmd_acdb[0] ==
9406 SCMD_REQUEST_SENSE ||
9407 spkt->satapkt_cmd.satacmd_cmd_reg ==
9408 SATAC_READ_LOG_EXT);
9410 #endif
9412 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9413 ahci_portp->ahciport_mop_in_progress++;
9415 rval = ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9416 port, flag, &reset_flag);
9418 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9419 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9420 if (rval == AHCI_SUCCESS)
9421 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9422 "succeed", instance, port);
9423 else
9424 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9425 "failed", instance, port);
9429 * Won't retrieve error information:
9430 * 1. Port reset was involved to recover
9431 * 2. Device is gone
9432 * 3. IDENTIFY DEVICE command sent to ATAPI device
9433 * 4. REQUEST SENSE or READ LOG EXT command during error recovery
9435 if (reset_flag ||
9436 ahci_portp->ahciport_device_type == SATA_DTYPE_NONE ||
9437 spkt && spkt->satapkt_cmd.satacmd_cmd_reg == SATAC_ID_DEVICE ||
9438 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9439 goto out;
9442 * Deliver READ LOG EXT to gather information about the error when
9443 * a COMRESET has not been performed as part of the error recovery
9444 * during NCQ command processing.
9446 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9447 failed_tags = ahci_get_rdlogext_data(ahci_ctlp,
9448 ahci_portp, port);
9449 goto out;
9453 * Deliver REQUEST SENSE for ATAPI command to gather information about
9454 * the error when a COMRESET has not been performed as part of the
9455 * error recovery.
9457 if (spkt && ahci_portp->ahciport_device_type == SATA_DTYPE_ATAPI)
9458 ahci_get_rqsense_data(ahci_ctlp, ahci_portp, port, spkt);
9459 out:
9460 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9461 "ahci_fatal_error_recovery_handler: port %d fatal error "
9462 "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9463 "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9464 port, slot_status, ahci_portp->ahciport_pending_tags,
9465 ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9467 ahci_mop_commands(ahci_ctlp,
9468 ahci_portp,
9469 slot_status,
9470 failed_tags, /* failed tags */
9471 0, /* timeout tags */
9472 0, /* aborted tags */
9473 0); /* reset tags */
9477 * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9478 * 1. device specific.PxFBS.SDE=1
9479 * 2. Non-Deivce specific.
9480 * Nothing will be done when Command-based switching is employed.
9482 * Currently code is neither completed nor tested.
9484 static void
9485 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9486 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9488 #ifndef __lock_lint
9489 _NOTE(ARGUNUSED(intr_status))
9490 #endif
9491 uint32_t port_fbs_ctrl;
9492 int loop_count = 0;
9493 ahci_addr_t addr;
9495 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9497 /* Nothing will be done under Command-based switching. */
9498 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9499 return;
9501 port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9502 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9504 if (!(port_fbs_ctrl & AHCI_FBS_EN))
9505 /* FBS is not enabled. */
9506 return;
9508 /* Problem's getting complicated now. */
9510 * If FIS-based switching is used, we need to check
9511 * the PxFBS to see the error type.
9513 port_fbs_ctrl = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9514 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port));
9516 /* Refer to spec(v1.2) 9.3.6.1 */
9517 if (port_fbs_ctrl & AHCI_FBS_SDE) {
9518 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9519 "A Device Sepcific Error: port %d", port);
9521 * Controller has paused commands for all other
9522 * sub-devices until PxFBS.DEC is set.
9524 ahci_reject_all_abort_pkts(ahci_ctlp,
9525 ahci_portp, 0);
9527 ddi_put32(ahci_ctlp->ahcictl_ahci_acc_handle,
9528 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp, port),
9529 port_fbs_ctrl | AHCI_FBS_DEC);
9532 * Wait controller clear PxFBS.DEC,
9533 * then we can continue.
9535 loop_count = 0;
9536 do {
9537 port_fbs_ctrl = ddi_get32(ahci_ctlp->
9538 ahcictl_ahci_acc_handle, (uint32_t *)
9539 AHCI_PORT_PxFBS(ahci_ctlp, port));
9541 if (loop_count++ > 1000)
9543 * Esclate the error. Follow
9544 * non-device specific error
9545 * procedure.
9547 return;
9549 drv_usecwait(AHCI_100US_USECS);
9550 } while (port_fbs_ctrl & AHCI_FBS_DEC);
9553 * Issue a software reset to ensure drive is in
9554 * a known state.
9556 (void) ahci_software_reset(ahci_ctlp,
9557 ahci_portp, &addr);
9559 } else {
9561 /* Process Non-Device Specific Error. */
9562 /* This will be handled later on. */
9563 cmn_err(CE_NOTE, "!FBS is not supported now.");
9567 * Handle events - fatal error recovery
9569 static void
9570 ahci_events_handler(void *args)
9572 ahci_event_arg_t *ahci_event_arg;
9573 ahci_ctl_t *ahci_ctlp;
9574 ahci_port_t *ahci_portp;
9575 ahci_addr_t *addrp;
9576 uint32_t event;
9577 int instance;
9579 ahci_event_arg = (ahci_event_arg_t *)args;
9581 ahci_ctlp = ahci_event_arg->ahciea_ctlp;
9582 ahci_portp = ahci_event_arg->ahciea_portp;
9583 addrp = ahci_event_arg->ahciea_addrp;
9584 event = ahci_event_arg->ahciea_event;
9585 instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9587 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR|AHCIDBG_ERRS, ahci_ctlp,
9588 "ahci_events_handler enter: port %d intr_status = 0x%x",
9589 ahci_portp->ahciport_port_num, event);
9591 mutex_enter(&ahci_portp->ahciport_mutex);
9594 * ahci_intr_phyrdy_change() may have rendered it to
9595 * SATA_DTYPE_NONE.
9597 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9598 AHCIDBG(AHCIDBG_ENTRY|AHCIDBG_INTR, ahci_ctlp,
9599 "ahci_events_handler: port %d no device attached, "
9600 "and just return without doing anything",
9601 ahci_portp->ahciport_port_num);
9603 if (ahci_portp->ahciport_flags & AHCI_PORT_FLAG_ERRPRINT) {
9604 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_ERRPRINT;
9605 cmn_err(CE_WARN, "!ahci%d: error recovery for port %d "
9606 "succeed", instance, ahci_portp->ahciport_port_num);
9609 goto out;
9612 if (event & (AHCI_INTR_STATUS_IFS |
9613 AHCI_INTR_STATUS_HBDS |
9614 AHCI_INTR_STATUS_HBFS |
9615 AHCI_INTR_STATUS_TFES))
9616 ahci_fatal_error_recovery_handler(ahci_ctlp, ahci_portp,
9617 addrp, event);
9619 out:
9620 mutex_exit(&ahci_portp->ahciport_mutex);
9624 * ahci_watchdog_handler() and ahci_do_sync_start will call us if they
9625 * detect there are some commands which are timed out.
9627 static void
9628 ahci_timeout_pkts(ahci_ctl_t *ahci_ctlp, ahci_port_t *ahci_portp,
9629 uint8_t port, uint32_t tmp_timeout_tags)
9631 uint32_t slot_status = 0;
9632 uint32_t finished_tags = 0;
9633 uint32_t timeout_tags = 0;
9635 AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_ENTRY, ahci_ctlp,
9636 "ahci_timeout_pkts enter: port %d", port);
9638 mutex_enter(&ahci_portp->ahciport_mutex);
9640 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) ||
9641 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp) ||
9642 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9643 /* Read PxCI to see which commands are still outstanding */
9644 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9645 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp, port));
9646 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9647 /* Read PxSACT to see which commands are still outstanding */
9648 slot_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9649 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9652 #if AHCI_DEBUG
9654 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9655 * set, it means a fatal error happened after REQUEST SENSE command
9656 * or READ LOG EXT command is delivered to the HBA during the error
9657 * recovery process. At this time, the only outstanding command is
9658 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9660 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)) {
9661 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9662 "ahci_timeout_pkts called while REQUEST SENSE "
9663 "command or READ LOG EXT command for error recovery "
9664 "timed out timeout_tags = 0x%x, slot_status = 0x%x, "
9665 "pending_tags = 0x%x, pending_ncq_tags = 0x%x",
9666 tmp_timeout_tags, slot_status,
9667 ahci_portp->ahciport_pending_tags,
9668 ahci_portp->ahciport_pending_ncq_tags);
9669 ASSERT(slot_status == 0x1);
9670 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9671 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT, ahci_ctlp,
9672 "ahci_timeout_pkts called while executing R/W PMULT "
9673 "command timeout_tags = 0x%x, slot_status = 0x%x",
9674 tmp_timeout_tags, slot_status);
9675 ASSERT(slot_status == 0x1);
9677 #endif
9679 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_MOPPING;
9680 ahci_portp->ahciport_mop_in_progress++;
9682 (void) ahci_restart_port_wait_till_ready(ahci_ctlp, ahci_portp,
9683 port, AHCI_PORT_RESET, NULL);
9686 * Re-identify timeout tags because some previously checked commands
9687 * could already complete.
9689 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9690 finished_tags = ahci_portp->ahciport_pending_tags &
9691 ~slot_status & AHCI_SLOT_MASK(ahci_ctlp);
9692 timeout_tags = tmp_timeout_tags & ~finished_tags;
9694 AHCIDBG(AHCIDBG_TIMEOUT, ahci_ctlp,
9695 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9696 "timeout_tags = 0x%x, port_cmd_issue = 0x%x, "
9697 "pending_tags = 0x%x ",
9698 port, finished_tags, timeout_tags,
9699 slot_status, ahci_portp->ahciport_pending_tags);
9700 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9701 finished_tags = ahci_portp->ahciport_pending_ncq_tags &
9702 ~slot_status & AHCI_NCQ_SLOT_MASK(ahci_portp);
9703 timeout_tags = tmp_timeout_tags & ~finished_tags;
9705 AHCIDBG(AHCIDBG_TIMEOUT|AHCIDBG_NCQ, ahci_ctlp,
9706 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9707 "timeout_tags = 0x%x, port_sactive = 0x%x, "
9708 "pending_ncq_tags = 0x%x ",
9709 port, finished_tags, timeout_tags,
9710 slot_status, ahci_portp->ahciport_pending_ncq_tags);
9711 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9712 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9713 timeout_tags = tmp_timeout_tags;
9716 ahci_mop_commands(ahci_ctlp,
9717 ahci_portp,
9718 slot_status,
9719 0, /* failed tags */
9720 timeout_tags, /* timeout tags */
9721 0, /* aborted tags */
9722 0); /* reset tags */
9724 mutex_exit(&ahci_portp->ahciport_mutex);
9728 * Watchdog handler kicks in every 5 seconds to timeout any commands pending
9729 * for long time.
9731 static void
9732 ahci_watchdog_handler(ahci_ctl_t *ahci_ctlp)
9734 ahci_port_t *ahci_portp;
9735 sata_pkt_t *spkt;
9736 uint32_t pending_tags;
9737 uint32_t timeout_tags;
9738 uint32_t port_cmd_status;
9739 uint32_t port_sactive;
9740 uint8_t port;
9741 int tmp_slot;
9742 int current_slot;
9743 uint32_t current_tags;
9744 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9746 mutex_enter(&ahci_ctlp->ahcictl_mutex);
9748 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp,
9749 "ahci_watchdog_handler entered", NULL);
9751 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
9752 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
9753 continue;
9756 ahci_portp = ahci_ctlp->ahcictl_ports[port];
9758 mutex_enter(&ahci_portp->ahciport_mutex);
9759 if (ahci_portp->ahciport_device_type == SATA_DTYPE_NONE) {
9760 mutex_exit(&ahci_portp->ahciport_mutex);
9761 continue;
9764 /* Skip the check for those ports in error recovery */
9765 if ((ahci_portp->ahciport_flags & AHCI_PORT_FLAG_MOPPING) &&
9766 !(ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))) {
9767 mutex_exit(&ahci_portp->ahciport_mutex);
9768 continue;
9771 pending_tags = 0;
9772 port_cmd_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
9773 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp, port));
9775 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) ||
9776 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)) {
9777 current_slot = 0;
9778 pending_tags = 0x1;
9779 } else if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9780 current_slot =
9781 (port_cmd_status & AHCI_CMD_STATUS_CCS) >>
9782 AHCI_CMD_STATUS_CCS_SHIFT;
9783 pending_tags = ahci_portp->ahciport_pending_tags;
9784 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9785 port_sactive = ddi_get32(
9786 ahci_ctlp->ahcictl_ahci_acc_handle,
9787 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp, port));
9788 current_tags = port_sactive &
9789 ~port_cmd_status &
9790 AHCI_NCQ_SLOT_MASK(ahci_portp);
9791 pending_tags = ahci_portp->ahciport_pending_ncq_tags;
9794 timeout_tags = 0;
9795 while (pending_tags) {
9796 tmp_slot = ddi_ffs(pending_tags) - 1;
9797 if (tmp_slot == -1) {
9798 break;
9801 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
9802 spkt = ahci_portp->ahciport_err_retri_pkt;
9803 else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp))
9804 spkt = ahci_portp->ahciport_rdwr_pmult_pkt;
9805 else
9806 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9808 if ((spkt != NULL) && spkt->satapkt_time &&
9809 !(spkt->satapkt_op_mode & SATA_OPMODE_POLLING)) {
9811 * If a packet has survived for more than it's
9812 * max life cycles, it is a candidate for time
9813 * out.
9815 ahci_portp->ahciport_slot_timeout[tmp_slot] -=
9816 ahci_watchdog_timeout;
9818 if (ahci_portp->ahciport_slot_timeout[tmp_slot]
9819 > 0)
9820 goto next;
9822 #if AHCI_DEBUG
9823 if (NCQ_CMD_IN_PROGRESS(ahci_portp)) {
9824 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9825 ahci_ctlp, "watchdog: the current "
9826 "tags is 0x%x", current_tags);
9827 } else {
9828 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_TIMEOUT,
9829 ahci_ctlp, "watchdog: the current "
9830 "slot is %d", current_slot);
9832 #endif
9835 * We need to check whether the HBA has
9836 * begun to execute the command, if not,
9837 * then re-set the timer of the command.
9839 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9840 (tmp_slot != current_slot) ||
9841 NCQ_CMD_IN_PROGRESS(ahci_portp) &&
9842 ((0x1 << tmp_slot) & current_tags)) {
9843 ahci_portp->ahciport_slot_timeout \
9844 [tmp_slot] = spkt->satapkt_time;
9845 } else {
9846 timeout_tags |= (0x1 << tmp_slot);
9847 cmn_err(CE_WARN, "!ahci%d: watchdog "
9848 "port %d satapkt 0x%p timed out\n",
9849 instance, port, (void *)spkt);
9852 next:
9853 CLEAR_BIT(pending_tags, tmp_slot);
9856 if (timeout_tags) {
9857 mutex_exit(&ahci_portp->ahciport_mutex);
9858 mutex_exit(&ahci_ctlp->ahcictl_mutex);
9859 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
9860 port, timeout_tags);
9861 mutex_enter(&ahci_ctlp->ahcictl_mutex);
9862 mutex_enter(&ahci_portp->ahciport_mutex);
9865 mutex_exit(&ahci_portp->ahciport_mutex);
9868 /* Re-install the watchdog timeout handler */
9869 if (ahci_ctlp->ahcictl_timeout_id != 0) {
9870 ahci_ctlp->ahcictl_timeout_id =
9871 timeout((void (*)(void *))ahci_watchdog_handler,
9872 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
9875 mutex_exit(&ahci_ctlp->ahcictl_mutex);
9879 * Fill the error context into sata_cmd for non-queued command error.
9881 static void
9882 ahci_copy_err_cnxt(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
9884 scmd->satacmd_status_reg = GET_RFIS_STATUS(rfisp);
9885 scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
9886 scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
9887 scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
9888 scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
9889 scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
9890 scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
9892 if (scmd->satacmd_addr_type == ATA_ADDR_LBA48) {
9893 scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
9894 scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
9895 scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
9896 scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
9901 * Fill the ncq error page into sata_cmd for queued command error.
9903 static void
9904 ahci_copy_ncq_err_page(sata_cmd_t *scmd,
9905 struct sata_ncq_error_recovery_page *ncq_err_page)
9907 scmd->satacmd_sec_count_msb = ncq_err_page->ncq_sector_count_ext;
9908 scmd->satacmd_sec_count_lsb = ncq_err_page->ncq_sector_count;
9909 scmd->satacmd_lba_low_msb = ncq_err_page->ncq_sector_number_ext;
9910 scmd->satacmd_lba_low_lsb = ncq_err_page->ncq_sector_number;
9911 scmd->satacmd_lba_mid_msb = ncq_err_page->ncq_cyl_low_ext;
9912 scmd->satacmd_lba_mid_lsb = ncq_err_page->ncq_cyl_low;
9913 scmd->satacmd_lba_high_msb = ncq_err_page->ncq_cyl_high_ext;
9914 scmd->satacmd_lba_high_lsb = ncq_err_page->ncq_cyl_high;
9915 scmd->satacmd_device_reg = ncq_err_page->ncq_dev_head;
9916 scmd->satacmd_status_reg = ncq_err_page->ncq_status;
9917 scmd->satacmd_error_reg = ncq_err_page->ncq_error;
9921 * Put the respective register value to sata_cmd_t for satacmd_flags.
9923 static void
9924 ahci_copy_out_regs(sata_cmd_t *scmd, ahci_fis_d2h_register_t *rfisp)
9926 if (scmd->satacmd_flags.sata_copy_out_sec_count_msb)
9927 scmd->satacmd_sec_count_msb = GET_RFIS_SECTOR_COUNT_EXP(rfisp);
9928 if (scmd->satacmd_flags.sata_copy_out_lba_low_msb)
9929 scmd->satacmd_lba_low_msb = GET_RFIS_CYL_LOW_EXP(rfisp);
9930 if (scmd->satacmd_flags.sata_copy_out_lba_mid_msb)
9931 scmd->satacmd_lba_mid_msb = GET_RFIS_CYL_MID_EXP(rfisp);
9932 if (scmd->satacmd_flags.sata_copy_out_lba_high_msb)
9933 scmd->satacmd_lba_high_msb = GET_RFIS_CYL_HI_EXP(rfisp);
9934 if (scmd->satacmd_flags.sata_copy_out_sec_count_lsb)
9935 scmd->satacmd_sec_count_lsb = GET_RFIS_SECTOR_COUNT(rfisp);
9936 if (scmd->satacmd_flags.sata_copy_out_lba_low_lsb)
9937 scmd->satacmd_lba_low_lsb = GET_RFIS_CYL_LOW(rfisp);
9938 if (scmd->satacmd_flags.sata_copy_out_lba_mid_lsb)
9939 scmd->satacmd_lba_mid_lsb = GET_RFIS_CYL_MID(rfisp);
9940 if (scmd->satacmd_flags.sata_copy_out_lba_high_lsb)
9941 scmd->satacmd_lba_high_lsb = GET_RFIS_CYL_HI(rfisp);
9942 if (scmd->satacmd_flags.sata_copy_out_device_reg)
9943 scmd->satacmd_device_reg = GET_RFIS_DEV_HEAD(rfisp);
9944 if (scmd->satacmd_flags.sata_copy_out_error_reg)
9945 scmd->satacmd_error_reg = GET_RFIS_ERROR(rfisp);
9948 static void
9949 ahci_log_fatal_error_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
9950 uint32_t intr_status)
9952 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
9954 if (intr_status & AHCI_INTR_STATUS_IFS)
9955 cmn_err(CE_WARN, "!ahci%d: ahci port %d has interface fatal "
9956 "error", instance, port);
9958 if (intr_status & AHCI_INTR_STATUS_HBDS)
9959 cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus data error",
9960 instance, port);
9962 if (intr_status & AHCI_INTR_STATUS_HBFS)
9963 cmn_err(CE_WARN, "!ahci%d: ahci port %d has bus fatal error",
9964 instance, port);
9966 if (intr_status & AHCI_INTR_STATUS_TFES)
9967 cmn_err(CE_WARN, "!ahci%d: ahci port %d has task file error",
9968 instance, port);
9970 cmn_err(CE_WARN, "!ahci%d: ahci port %d is trying to do error "
9971 "recovery", instance, port);
9974 static void
9975 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
9976 uint32_t slot_tags)
9978 ahci_port_t *ahci_portp;
9979 int tmp_slot;
9980 sata_pkt_t *spkt;
9981 sata_cmd_t cmd;
9983 ahci_portp = ahci_ctlp->ahcictl_ports[port];
9984 ASSERT(ahci_portp != NULL);
9986 while (slot_tags) {
9987 tmp_slot = ddi_ffs(slot_tags) - 1;
9988 if (tmp_slot == -1) {
9989 break;
9992 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9993 ASSERT(spkt != NULL);
9994 cmd = spkt->satapkt_cmd;
9996 cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
9997 "features_reg = 0x%x sec_count_msb = 0x%x "
9998 "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
9999 "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
10000 "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
10001 "lba_high_lsb = 0x%x device_reg = 0x%x "
10002 "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10003 cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10004 cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10005 cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10006 cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10007 cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10008 cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10009 *((uint32_t *)&(cmd.satacmd_flags)));
10011 CLEAR_BIT(slot_tags, tmp_slot);
10016 * Dump the serror message to the log.
10018 static void
10019 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10020 uint32_t port_serror, int debug_only)
10022 static char err_buf[512];
10023 static char err_msg_header[16];
10024 char *err_msg = err_buf;
10026 *err_buf = '\0';
10027 *err_msg_header = '\0';
10029 if (port_serror & SERROR_DATA_ERR_FIXED) {
10030 err_msg = strcat(err_msg,
10031 "\tRecovered Data Integrity Error (I)\n");
10034 if (port_serror & SERROR_COMM_ERR_FIXED) {
10035 err_msg = strcat(err_msg,
10036 "\tRecovered Communication Error (M)\n");
10039 if (port_serror & SERROR_DATA_ERR) {
10040 err_msg = strcat(err_msg,
10041 "\tTransient Data Integrity Error (T)\n");
10044 if (port_serror & SERROR_PERSISTENT_ERR) {
10045 err_msg = strcat(err_msg,
10046 "\tPersistent Communication or Data Integrity Error (C)\n");
10049 if (port_serror & SERROR_PROTOCOL_ERR) {
10050 err_msg = strcat(err_msg, "\tProtocol Error (P)\n");
10053 if (port_serror & SERROR_INT_ERR) {
10054 err_msg = strcat(err_msg, "\tInternal Error (E)\n");
10057 if (port_serror & SERROR_PHY_RDY_CHG) {
10058 err_msg = strcat(err_msg, "\tPhyRdy Change (N)\n");
10061 if (port_serror & SERROR_PHY_INT_ERR) {
10062 err_msg = strcat(err_msg, "\tPhy Internal Error (I)\n");
10065 if (port_serror & SERROR_COMM_WAKE) {
10066 err_msg = strcat(err_msg, "\tComm Wake (W)\n");
10069 if (port_serror & SERROR_10B_TO_8B_ERR) {
10070 err_msg = strcat(err_msg, "\t10B to 8B Decode Error (B)\n");
10073 if (port_serror & SERROR_DISPARITY_ERR) {
10074 err_msg = strcat(err_msg, "\tDisparity Error (D)\n");
10077 if (port_serror & SERROR_CRC_ERR) {
10078 err_msg = strcat(err_msg, "\tCRC Error (C)\n");
10081 if (port_serror & SERROR_HANDSHAKE_ERR) {
10082 err_msg = strcat(err_msg, "\tHandshake Error (H)\n");
10085 if (port_serror & SERROR_LINK_SEQ_ERR) {
10086 err_msg = strcat(err_msg, "\tLink Sequence Error (S)\n");
10089 if (port_serror & SERROR_TRANS_ERR) {
10090 err_msg = strcat(err_msg,
10091 "\tTransport state transition error (T)\n");
10094 if (port_serror & SERROR_FIS_TYPE) {
10095 err_msg = strcat(err_msg, "\tUnknown FIS Type (F)\n");
10098 if (port_serror & SERROR_EXCHANGED_ERR) {
10099 err_msg = strcat(err_msg, "\tExchanged (X)\n");
10102 if (*err_msg == '\0')
10103 return;
10105 if (debug_only) {
10106 (void) sprintf(err_msg_header, "port %d", port);
10107 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg_header, NULL);
10108 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp, err_msg, NULL);
10109 } else if (ahci_ctlp) {
10110 cmn_err(CE_WARN, "!ahci%d: %s %s",
10111 ddi_get_instance(ahci_ctlp->ahcictl_dip),
10112 err_msg_header, err_msg);
10114 /* sata trace debug */
10115 sata_trace_debug(ahci_ctlp->ahcictl_dip,
10116 "ahci%d: %s %s", ddi_get_instance(ahci_ctlp->ahcictl_dip),
10117 err_msg_header, err_msg);
10118 } else {
10119 cmn_err(CE_WARN, "!ahci: %s %s", err_msg_header, err_msg);
10121 /* sata trace debug */
10122 sata_trace_debug(NULL, "ahci: %s %s", err_msg_header, err_msg);
10127 * Translate the sata_address_t type into the ahci_addr_t type.
10128 * sata_device.satadev_addr structure is used as source.
10130 static void
10131 ahci_get_ahci_addr(ahci_ctl_t *ahci_ctlp, sata_device_t *sd,
10132 ahci_addr_t *ahci_addrp)
10134 sata_address_t *sata_addrp = &sd->satadev_addr;
10135 ahci_addrp->aa_port =
10136 ahci_ctlp->ahcictl_cport_to_port[sata_addrp->cport];
10137 ahci_addrp->aa_pmport = sata_addrp->pmport;
10139 switch (sata_addrp->qual) {
10140 case SATA_ADDR_DCPORT:
10141 case SATA_ADDR_CPORT:
10142 ahci_addrp->aa_qual = AHCI_ADDR_PORT;
10143 break;
10144 case SATA_ADDR_PMULT:
10145 case SATA_ADDR_PMULT_SPEC:
10146 ahci_addrp->aa_qual = AHCI_ADDR_PMULT;
10147 break;
10148 case SATA_ADDR_DPMPORT:
10149 case SATA_ADDR_PMPORT:
10150 ahci_addrp->aa_qual = AHCI_ADDR_PMPORT;
10151 break;
10152 case SATA_ADDR_NULL:
10153 default:
10154 /* something went wrong */
10155 ahci_addrp->aa_qual = AHCI_ADDR_NULL;
10156 break;
10161 * This routine is to calculate the total number of ports implemented
10162 * by the HBA.
10164 static int
10165 ahci_get_num_implemented_ports(uint32_t ports_implemented)
10167 uint8_t i;
10168 int num = 0;
10170 for (i = 0; i < AHCI_MAX_PORTS; i++) {
10171 if (((uint32_t)0x1 << i) & ports_implemented)
10172 num++;
10175 return (num);
10178 #if AHCI_DEBUG
10179 static void
10180 ahci_log(ahci_ctl_t *ahci_ctlp, uint_t level, char *fmt, ...)
10182 static char name[16];
10183 va_list ap;
10185 mutex_enter(&ahci_log_mutex);
10187 va_start(ap, fmt);
10188 if (ahci_ctlp) {
10189 (void) sprintf(name, "ahci%d: ",
10190 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10191 } else {
10192 (void) sprintf(name, "ahci: ");
10195 (void) vsprintf(ahci_log_buf, fmt, ap);
10196 va_end(ap);
10198 cmn_err(level, "%s%s", name, ahci_log_buf);
10200 mutex_exit(&ahci_log_mutex);
10202 #endif
10205 * quiesce(9E) entry point.
10207 * This function is called when the system is single-threaded at high
10208 * PIL with preemption disabled. Therefore, this function must not be
10209 * blocked.
10211 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10212 * DDI_FAILURE indicates an error condition and should almost never happen.
10214 static int
10215 ahci_quiesce(dev_info_t *dip)
10217 ahci_ctl_t *ahci_ctlp;
10218 ahci_port_t *ahci_portp;
10219 int instance, port;
10221 instance = ddi_get_instance(dip);
10222 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10224 if (ahci_ctlp == NULL)
10225 return (DDI_FAILURE);
10227 #if AHCI_DEBUG
10228 ahci_debug_flags = 0;
10229 #endif
10231 ahci_ctlp->ahcictl_flags |= AHCI_QUIESCE;
10233 /* disable all the interrupts. */
10234 ahci_disable_all_intrs(ahci_ctlp);
10236 for (port = 0; port < ahci_ctlp->ahcictl_num_ports; port++) {
10237 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, port)) {
10238 continue;
10241 ahci_portp = ahci_ctlp->ahcictl_ports[port];
10244 * Stop the port by clearing PxCMD.ST
10246 * Here we must disable the port interrupt because
10247 * ahci_disable_all_intrs only clear GHC.IE, and IS
10248 * register will be still set if PxIE is enabled.
10249 * When ahci shares one IRQ with other drivers, the
10250 * intr handler may claim the intr mistakenly.
10252 ahci_disable_port_intrs(ahci_ctlp, port);
10253 (void) ahci_put_port_into_notrunning_state(ahci_ctlp,
10254 ahci_portp, port);
10257 ahci_ctlp->ahcictl_flags &= ~AHCI_QUIESCE;
10259 return (DDI_SUCCESS);
10263 * The function will add a sata packet to the done queue.
10265 static void
10266 ahci_add_doneq(ahci_port_t *ahci_portp, sata_pkt_t *satapkt, int reason)
10268 ASSERT(satapkt != NULL);
10269 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10271 /* set the reason for all packets */
10272 satapkt->satapkt_reason = reason;
10273 satapkt->satapkt_hba_driver_private = NULL;
10275 if (! (satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10276 satapkt->satapkt_comp) {
10278 * only add to queue when mode is not synch and there is
10279 * completion callback
10281 *ahci_portp->ahciport_doneqtail = satapkt;
10282 ahci_portp->ahciport_doneqtail =
10283 (sata_pkt_t **)&(satapkt->satapkt_hba_driver_private);
10284 ahci_portp->ahciport_doneq_len++;
10286 } else if ((satapkt->satapkt_op_mode & SATA_OPMODE_SYNCH) &&
10287 ! (satapkt->satapkt_op_mode & SATA_OPMODE_POLLING))
10289 * for sync/non-poll mode, just call cv_broadcast
10291 cv_broadcast(&ahci_portp->ahciport_cv);
10295 * The function will call completion callback of sata packet on the
10296 * completed queue
10298 static void
10299 ahci_flush_doneq(ahci_port_t *ahci_portp)
10301 sata_pkt_t *satapkt, *next;
10303 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
10305 if (ahci_portp->ahciport_doneq) {
10306 satapkt = ahci_portp->ahciport_doneq;
10308 ahci_portp->ahciport_doneq = NULL;
10309 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10310 ahci_portp->ahciport_doneq_len = 0;
10312 mutex_exit(&ahci_portp->ahciport_mutex);
10314 while (satapkt != NULL) {
10315 next = satapkt->satapkt_hba_driver_private;
10316 satapkt->satapkt_hba_driver_private = NULL;
10318 /* Call the callback */
10319 (*satapkt->satapkt_comp)(satapkt);
10321 satapkt = next;
10324 mutex_enter(&ahci_portp->ahciport_mutex);