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]
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
25 * Copyright (c) 2018, Joyent, Inc.
26 * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
30 * AHCI (Advanced Host Controller Interface) SATA HBA Driver
32 * Power Management Support
33 * ------------------------
35 * At the moment, the ahci driver only implements suspend/resume to
36 * support Suspend to RAM on X86 feature. Device power management isn't
37 * implemented, link power management is disabled, and hot plug isn't
38 * allowed during the period from suspend to resume.
40 * For s/r support, the ahci driver only need to implement DDI_SUSPEND
41 * and DDI_RESUME entries, and don't need to take care of new requests
42 * sent down after suspend because the target driver (sd) has already
43 * handled these conditions, and blocked these requests. For the detailed
44 * information, please check with sdopen, sdclose and sdioctl routines.
47 * Enclosure Management Support
48 * ----------------------------
50 * The ahci driver has basic support for AHCI Enclosure Management (EM)
51 * services. The AHCI specification provides an area in the primary ahci BAR for
52 * posting data to send out to the enclosure management and provides a register
53 * that provides both information and control about this. While the
54 * specification allows for multiple forms of enclosure management, the only
55 * supported, and commonly found form, is the AHCI specified LED format. The LED
56 * format is often implemented as a one-way communication mechanism. Software
57 * can write out what it cares about into the aforementioned data buffer and
58 * then we wait for the transmission to be sent.
60 * This has some drawbacks. It means that we cannot know whether or not it has
61 * succeeded. This means we cannot ask hardware what it thinks the LEDs are
62 * set to. There's also the added unfortunate reality that firmware on the
63 * microcontroller driving this will often not show the LEDs if no drive is
64 * present and that actions taken may potentially cause this to get out of sync
65 * with what we expect it to be. For example, the specification does not
66 * describe what should happen if a drive is removed from the enclosure while
67 * this is set and what should happen when it returns. We can only infer that it
70 * Because only a single command can be sent at any time and we don't want to
71 * interfere with controller I/O, we create a taskq dedicated to this that has a
72 * single thread. Both resets (which occur on attach and resume) and normal
73 * changes to the LED state will be driven through this taskq. Because the taskq
74 * has a single thread, this guarantees serial processing.
76 * Each userland-submitted task (basically not resets) has a reference counted
77 * task structure. This allows the thread that called it to be cancelled and
78 * have the system clean itself up. The user thread in ioctl blocks on a CV that
79 * can receive signals as it waits for completion. Note, there is no guarantee
80 * provided by the kernel that the first thread to enter the kernel will be the
81 * first one to change state.
85 #include <sys/scsi/scsi.h>
88 #include <sys/sata/sata_hba.h>
89 #include <sys/sata/adapters/ahci/ahcireg.h>
90 #include <sys/sata/adapters/ahci/ahcivar.h>
95 #include <sys/ddifm.h>
96 #include <sys/fm/protocol.h>
97 #include <sys/fm/util.h>
98 #include <sys/fm/io/ddi.h>
101 * EM Control header files
103 #include <sys/types.h>
104 #include <sys/file.h>
105 #include <sys/errno.h>
106 #include <sys/open.h>
107 #include <sys/cred.h>
109 #include <sys/sunddi.h>
112 * This is the string displayed by modinfo, etc.
114 static char ahci_ident
[] = "ahci driver";
117 * Function prototypes for driver entry points
119 static int ahci_attach(dev_info_t
*, ddi_attach_cmd_t
);
120 static int ahci_detach(dev_info_t
*, ddi_detach_cmd_t
);
121 static int ahci_getinfo(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
122 static int ahci_quiesce(dev_info_t
*);
125 * Function prototypes for SATA Framework interfaces
127 static int ahci_register_sata_hba_tran(ahci_ctl_t
*, uint32_t);
128 static int ahci_unregister_sata_hba_tran(ahci_ctl_t
*);
130 static int ahci_tran_probe_port(dev_info_t
*, sata_device_t
*);
131 static int ahci_tran_start(dev_info_t
*, sata_pkt_t
*spkt
);
132 static int ahci_tran_abort(dev_info_t
*, sata_pkt_t
*, int);
133 static int ahci_tran_reset_dport(dev_info_t
*, sata_device_t
*);
134 static int ahci_tran_hotplug_port_activate(dev_info_t
*, sata_device_t
*);
135 static int ahci_tran_hotplug_port_deactivate(dev_info_t
*, sata_device_t
*);
136 #if defined(__lock_lint)
137 static int ahci_selftest(dev_info_t
*, sata_device_t
*);
143 static void ahci_fm_init(ahci_ctl_t
*);
144 static void ahci_fm_fini(ahci_ctl_t
*);
145 static int ahci_fm_error_cb(dev_info_t
*, ddi_fm_error_t
*, const void*);
146 int ahci_check_acc_handle(ddi_acc_handle_t
);
147 int ahci_check_dma_handle(ddi_dma_handle_t
);
148 void ahci_fm_ereport(ahci_ctl_t
*, char *);
149 static int ahci_check_all_handle(ahci_ctl_t
*);
150 static int ahci_check_ctl_handle(ahci_ctl_t
*);
151 static int ahci_check_port_handle(ahci_ctl_t
*, int);
152 static int ahci_check_slot_handle(ahci_port_t
*, int);
155 * Local function prototypes
157 static int ahci_setup_port_base_addresses(ahci_ctl_t
*, ahci_port_t
*);
158 static int ahci_alloc_ports_state(ahci_ctl_t
*);
159 static void ahci_dealloc_ports_state(ahci_ctl_t
*);
160 static int ahci_alloc_port_state(ahci_ctl_t
*, uint8_t);
161 static void ahci_dealloc_port_state(ahci_ctl_t
*, uint8_t);
162 static int ahci_alloc_rcvd_fis(ahci_ctl_t
*, ahci_port_t
*);
163 static void ahci_dealloc_rcvd_fis(ahci_port_t
*);
164 static int ahci_alloc_cmd_list(ahci_ctl_t
*, ahci_port_t
*);
165 static void ahci_dealloc_cmd_list(ahci_ctl_t
*, ahci_port_t
*);
166 static int ahci_alloc_cmd_tables(ahci_ctl_t
*, ahci_port_t
*);
167 static void ahci_dealloc_cmd_tables(ahci_ctl_t
*, ahci_port_t
*);
168 static void ahci_alloc_pmult(ahci_ctl_t
*, ahci_port_t
*);
169 static void ahci_dealloc_pmult(ahci_ctl_t
*, ahci_port_t
*);
171 static int ahci_initialize_controller(ahci_ctl_t
*);
172 static void ahci_uninitialize_controller(ahci_ctl_t
*);
173 static int ahci_initialize_port(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
174 static int ahci_config_space_init(ahci_ctl_t
*);
175 static void ahci_staggered_spin_up(ahci_ctl_t
*, uint8_t);
177 static void ahci_drain_ports_taskq(ahci_ctl_t
*);
178 static int ahci_rdwr_pmult(ahci_ctl_t
*, ahci_addr_t
*, uint8_t, uint32_t *,
180 static int ahci_read_pmult(ahci_ctl_t
*, ahci_addr_t
*, uint8_t, uint32_t *);
181 static int ahci_write_pmult(ahci_ctl_t
*, ahci_addr_t
*, uint8_t, uint32_t);
182 static int ahci_update_pmult_pscr(ahci_ctl_t
*, ahci_addr_t
*,
184 static int ahci_update_pmult_gscr(ahci_ctl_t
*, ahci_addr_t
*,
185 sata_pmult_gscr_t
*);
186 static int ahci_initialize_pmult(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*,
188 static int ahci_initialize_pmport(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
189 static int ahci_probe_pmult(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
190 static int ahci_probe_pmport(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*,
193 static void ahci_disable_interface_pm(ahci_ctl_t
*, uint8_t);
194 static int ahci_start_port(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
195 static void ahci_find_dev_signature(ahci_ctl_t
*, ahci_port_t
*,
197 static void ahci_update_sata_registers(ahci_ctl_t
*, uint8_t, sata_device_t
*);
198 static int ahci_deliver_satapkt(ahci_ctl_t
*, ahci_port_t
*,
199 ahci_addr_t
*, sata_pkt_t
*);
200 static int ahci_do_sync_start(ahci_ctl_t
*, ahci_port_t
*,
201 ahci_addr_t
*, sata_pkt_t
*);
202 static int ahci_claim_free_slot(ahci_ctl_t
*, ahci_port_t
*,
204 static void ahci_copy_err_cnxt(sata_cmd_t
*, ahci_fis_d2h_register_t
*);
205 static void ahci_copy_ncq_err_page(sata_cmd_t
*,
206 struct sata_ncq_error_recovery_page
*);
207 static void ahci_copy_out_regs(sata_cmd_t
*, ahci_fis_d2h_register_t
*);
208 static void ahci_add_doneq(ahci_port_t
*, sata_pkt_t
*, int);
209 static void ahci_flush_doneq(ahci_port_t
*);
211 static int ahci_software_reset(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
212 static int ahci_hba_reset(ahci_ctl_t
*);
213 static int ahci_port_reset(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
214 static int ahci_pmport_reset(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
215 static void ahci_reject_all_abort_pkts(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
216 static int ahci_reset_device_reject_pkts(ahci_ctl_t
*, ahci_port_t
*,
218 static int ahci_reset_pmdevice_reject_pkts(ahci_ctl_t
*, ahci_port_t
*,
220 static int ahci_reset_port_reject_pkts(ahci_ctl_t
*, ahci_port_t
*,
222 static int ahci_reset_hba_reject_pkts(ahci_ctl_t
*);
223 static int ahci_put_port_into_notrunning_state(ahci_ctl_t
*, ahci_port_t
*,
225 static int ahci_restart_port_wait_till_ready(ahci_ctl_t
*, ahci_port_t
*,
226 uint8_t, int, int *);
227 static void ahci_mop_commands(ahci_ctl_t
*, ahci_port_t
*, uint32_t,
228 uint32_t, uint32_t, uint32_t, uint32_t);
229 static uint32_t ahci_get_rdlogext_data(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
230 static void ahci_get_rqsense_data(ahci_ctl_t
*, ahci_port_t
*,
231 uint8_t, sata_pkt_t
*);
232 static void ahci_fatal_error_recovery_handler(ahci_ctl_t
*, ahci_port_t
*,
233 ahci_addr_t
*, uint32_t);
234 static void ahci_pmult_error_recovery_handler(ahci_ctl_t
*, ahci_port_t
*,
236 static void ahci_timeout_pkts(ahci_ctl_t
*, ahci_port_t
*,
238 static void ahci_events_handler(void *);
239 static void ahci_watchdog_handler(ahci_ctl_t
*);
241 static uint_t
ahci_intr(caddr_t
, caddr_t
);
242 static void ahci_port_intr(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
243 static int ahci_add_intrs(ahci_ctl_t
*, int);
244 static void ahci_rem_intrs(ahci_ctl_t
*);
245 static void ahci_enable_all_intrs(ahci_ctl_t
*);
246 static void ahci_disable_all_intrs(ahci_ctl_t
*);
247 static void ahci_enable_port_intrs(ahci_ctl_t
*, uint8_t);
248 static void ahci_disable_port_intrs(ahci_ctl_t
*, uint8_t);
250 static int ahci_intr_cmd_cmplt(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
251 static int ahci_intr_set_device_bits(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
252 static int ahci_intr_ncq_events(ahci_ctl_t
*, ahci_port_t
*, ahci_addr_t
*);
253 static int ahci_intr_pmult_sntf_events(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
254 static int ahci_intr_port_connect_change(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
255 static int ahci_intr_device_mechanical_presence_status(ahci_ctl_t
*,
256 ahci_port_t
*, uint8_t);
257 static int ahci_intr_phyrdy_change(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
258 static int ahci_intr_non_fatal_error(ahci_ctl_t
*, ahci_port_t
*,
260 static int ahci_intr_fatal_error(ahci_ctl_t
*, ahci_port_t
*,
262 static int ahci_intr_cold_port_detect(ahci_ctl_t
*, ahci_port_t
*, uint8_t);
264 static void ahci_get_ahci_addr(ahci_ctl_t
*, sata_device_t
*, ahci_addr_t
*);
265 static int ahci_get_num_implemented_ports(uint32_t);
266 static void ahci_log_fatal_error_message(ahci_ctl_t
*, uint8_t, uint32_t);
267 static void ahci_dump_commands(ahci_ctl_t
*, uint8_t, uint32_t);
268 static void ahci_log_serror_message(ahci_ctl_t
*, uint8_t, uint32_t, int);
270 static void ahci_log(ahci_ctl_t
*, uint_t
, char *, ...);
273 static boolean_t
ahci_em_init(ahci_ctl_t
*);
274 static void ahci_em_fini(ahci_ctl_t
*);
275 static void ahci_em_suspend(ahci_ctl_t
*);
276 static void ahci_em_resume(ahci_ctl_t
*);
277 static int ahci_em_ioctl(dev_info_t
*, int, intptr_t);
281 * DMA attributes for the data buffer
283 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
284 * does not support 64-bit addressing
286 static ddi_dma_attr_t buffer_dma_attr
= {
287 DMA_ATTR_V0
, /* dma_attr_version */
288 0x0ull
, /* dma_attr_addr_lo: lowest bus address */
289 0xffffffffffffffffull
, /* dma_attr_addr_hi: highest bus address */
290 0x3fffffull
, /* dma_attr_count_max i.e. for one cookie */
291 0x2ull
, /* dma_attr_align: word aligned */
292 1, /* dma_attr_burstsizes */
293 1, /* dma_attr_minxfer */
294 0xffffffffull
, /* dma_attr_maxxfer i.e. includes all cookies */
295 0xffffffffull
, /* dma_attr_seg */
296 AHCI_PRDT_NUMBER
, /* dma_attr_sgllen */
297 512, /* dma_attr_granular */
298 0, /* dma_attr_flags */
302 * DMA attributes for the rcvd FIS
304 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
305 * does not support 64-bit addressing
307 static ddi_dma_attr_t rcvd_fis_dma_attr
= {
308 DMA_ATTR_V0
, /* dma_attr_version */
309 0x0ull
, /* dma_attr_addr_lo: lowest bus address */
310 0xffffffffffffffffull
, /* dma_attr_addr_hi: highest bus address */
311 0xffffffffull
, /* dma_attr_count_max i.e. for one cookie */
312 0x100ull
, /* dma_attr_align: 256-byte aligned */
313 1, /* dma_attr_burstsizes */
314 1, /* dma_attr_minxfer */
315 0xffffffffull
, /* dma_attr_maxxfer i.e. includes all cookies */
316 0xffffffffull
, /* dma_attr_seg */
317 1, /* dma_attr_sgllen */
318 1, /* dma_attr_granular */
319 0, /* dma_attr_flags */
323 * DMA attributes for the command list
325 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
326 * does not support 64-bit addressing
328 static ddi_dma_attr_t cmd_list_dma_attr
= {
329 DMA_ATTR_V0
, /* dma_attr_version */
330 0x0ull
, /* dma_attr_addr_lo: lowest bus address */
331 0xffffffffffffffffull
, /* dma_attr_addr_hi: highest bus address */
332 0xffffffffull
, /* dma_attr_count_max i.e. for one cookie */
333 0x400ull
, /* dma_attr_align: 1K-byte aligned */
334 1, /* dma_attr_burstsizes */
335 1, /* dma_attr_minxfer */
336 0xffffffffull
, /* dma_attr_maxxfer i.e. includes all cookies */
337 0xffffffffull
, /* dma_attr_seg */
338 1, /* dma_attr_sgllen */
339 1, /* dma_attr_granular */
340 0, /* dma_attr_flags */
344 * DMA attributes for cmd tables
346 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
347 * does not support 64-bit addressing
349 static ddi_dma_attr_t cmd_table_dma_attr
= {
350 DMA_ATTR_V0
, /* dma_attr_version */
351 0x0ull
, /* dma_attr_addr_lo: lowest bus address */
352 0xffffffffffffffffull
, /* dma_attr_addr_hi: highest bus address */
353 0xffffffffull
, /* dma_attr_count_max i.e. for one cookie */
354 0x80ull
, /* dma_attr_align: 128-byte aligned */
355 1, /* dma_attr_burstsizes */
356 1, /* dma_attr_minxfer */
357 0xffffffffull
, /* dma_attr_maxxfer i.e. includes all cookies */
358 0xffffffffull
, /* dma_attr_seg */
359 1, /* dma_attr_sgllen */
360 1, /* dma_attr_granular */
361 0, /* dma_attr_flags */
365 /* Device access attributes */
366 static ddi_device_acc_attr_t accattr
= {
368 DDI_STRUCTURE_LE_ACC
,
373 static struct dev_ops ahcictl_dev_ops
= {
374 DEVO_REV
, /* devo_rev */
376 ahci_getinfo
, /* info */
377 nulldev
, /* identify */
379 ahci_attach
, /* attach */
380 ahci_detach
, /* detach */
381 nodev
, /* no reset */
382 NULL
, /* driver operations */
383 NULL
, /* bus operations */
385 ahci_quiesce
, /* quiesce */
388 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops
= {
389 SATA_TRAN_HOTPLUG_OPS_REV_1
,
390 ahci_tran_hotplug_port_activate
,
391 ahci_tran_hotplug_port_deactivate
394 extern struct mod_ops mod_driverops
;
396 static struct modldrv modldrv
= {
397 &mod_driverops
, /* driverops */
398 ahci_ident
, /* short description */
399 &ahcictl_dev_ops
, /* driver ops */
402 static struct modlinkage modlinkage
= {
408 /* The following variables are watchdog handler related */
409 static clock_t ahci_watchdog_timeout
= 5; /* 5 seconds */
410 static clock_t ahci_watchdog_tick
;
413 * This static variable indicates the size of command table,
414 * and it's changeable with prdt number, which ahci_dma_prdt_number
417 static size_t ahci_cmd_table_size
;
420 * The below global variables are tunable via /etc/system
422 * ahci_dma_prdt_number
425 * ahci_commu_64bit_dma
428 /* The number of Physical Region Descriptor Table(PRDT) in Command Table */
429 int ahci_dma_prdt_number
= AHCI_PRDT_NUMBER
;
431 /* AHCI MSI is tunable */
432 boolean_t ahci_msi_enabled
= B_TRUE
;
435 * 64-bit dma addressing for data buffer is tunable
437 * The variable controls only the below value:
438 * DBAU (upper 32-bits physical address of data block)
440 boolean_t ahci_buf_64bit_dma
= B_TRUE
;
443 * 64-bit dma addressing for communication system descriptors is tunable
445 * The variable controls the below three values:
447 * PxCLBU (upper 32-bits for the command list base physical address)
448 * PxFBU (upper 32-bits for the received FIS base physical address)
449 * CTBAU (upper 32-bits of command table base)
451 boolean_t ahci_commu_64bit_dma
= B_TRUE
;
454 * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
455 * chipset. If the users want to have a try with 64-bit dma, please change
456 * the below variable value to enable it.
458 boolean_t sb600_buf_64bit_dma_disable
= B_TRUE
;
461 * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
462 * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
463 * please change the below value to enable it.
465 boolean_t sbxxx_commu_64bit_dma_disable
= B_TRUE
;
468 * These values control the default delay and default number of times to wait
469 * for an enclosure message to complete.
471 uint_t ahci_em_reset_delay_ms
= 1;
472 uint_t ahci_em_reset_delay_count
= 1000;
473 uint_t ahci_em_tx_delay_ms
= 1;
474 uint_t ahci_em_tx_delay_count
= 1000;
478 * End of global tunable variable definition
482 uint32_t ahci_debug_flags
= 0;
484 uint32_t ahci_debug_flags
= (AHCIDBG_ERRS
|AHCIDBG_TIMEOUT
);
489 /* The following is needed for ahci_log() */
490 static kmutex_t ahci_log_mutex
;
491 static char ahci_log_buf
[512];
494 /* Opaque state pointer initialized by ddi_soft_state_init() */
495 static void *ahci_statep
= NULL
;
498 * ahci module initialization.
505 ret
= ddi_soft_state_init(&ahci_statep
, sizeof (ahci_ctl_t
), 0);
511 mutex_init(&ahci_log_mutex
, NULL
, MUTEX_DRIVER
, NULL
);
514 if ((ret
= sata_hba_init(&modlinkage
)) != 0) {
516 mutex_destroy(&ahci_log_mutex
);
518 ddi_soft_state_fini(&ahci_statep
);
523 ahci_watchdog_tick
= drv_usectohz(
524 (clock_t)ahci_watchdog_timeout
* 1000000);
526 ret
= mod_install(&modlinkage
);
528 sata_hba_fini(&modlinkage
);
530 mutex_destroy(&ahci_log_mutex
);
532 ddi_soft_state_fini(&ahci_statep
);
539 cmn_err(CE_WARN
, "!ahci: Module init failed");
544 * ahci module uninitialize.
551 ret
= mod_remove(&modlinkage
);
556 /* Remove the resources allocated in _init(). */
557 sata_hba_fini(&modlinkage
);
559 mutex_destroy(&ahci_log_mutex
);
561 ddi_soft_state_fini(&ahci_statep
);
570 _info(struct modinfo
*modinfop
)
572 return (mod_info(&modlinkage
, modinfop
));
576 * The attach entry point for dev_ops.
579 ahci_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
581 ahci_ctl_t
*ahci_ctlp
= NULL
;
582 int instance
= ddi_get_instance(dip
);
585 uint32_t cap_status
, ahci_version
;
586 uint32_t ghc_control
;
596 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_attach enter",
606 * During DDI_RESUME, the hardware state of the device
607 * (power may have been removed from the device) must be
608 * restored, allow pending requests to continue, and
609 * service new requests.
611 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
612 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
615 * GHC.AE must be set to 1 before any other AHCI register
618 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
619 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
620 ghc_control
|= AHCI_HBA_GHC_AE
;
621 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
622 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
), ghc_control
);
624 /* Restart watch thread */
625 if (ahci_ctlp
->ahcictl_timeout_id
== 0)
626 ahci_ctlp
->ahcictl_timeout_id
= timeout(
627 (void (*)(void *))ahci_watchdog_handler
,
628 (caddr_t
)ahci_ctlp
, ahci_watchdog_tick
);
630 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
633 * Re-initialize the controller and enable the interrupts and
634 * restart all the ports.
636 * Note that so far we don't support hot-plug during
639 if (ahci_initialize_controller(ahci_ctlp
) != AHCI_SUCCESS
) {
640 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PM
, ahci_ctlp
,
641 "Failed to initialize the controller "
642 "during DDI_RESUME", NULL
);
643 return (DDI_FAILURE
);
647 * Reset the enclosure services.
649 ahci_em_resume(ahci_ctlp
);
651 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
652 ahci_ctlp
->ahcictl_flags
&= ~AHCI_SUSPEND
;
653 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
655 return (DDI_SUCCESS
);
658 return (DDI_FAILURE
);
661 attach_state
= AHCI_ATTACH_STATE_NONE
;
663 /* Allocate soft state */
664 status
= ddi_soft_state_zalloc(ahci_statep
, instance
);
665 if (status
!= DDI_SUCCESS
) {
666 cmn_err(CE_WARN
, "!ahci%d: Cannot allocate soft state",
671 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
672 ahci_ctlp
->ahcictl_flags
|= AHCI_ATTACH
;
673 ahci_ctlp
->ahcictl_dip
= dip
;
675 /* Initialize the cport/port mapping */
676 for (i
= 0; i
< AHCI_MAX_PORTS
; i
++) {
677 ahci_ctlp
->ahcictl_port_to_cport
[i
] = 0xff;
678 ahci_ctlp
->ahcictl_cport_to_port
[i
] = 0xff;
681 attach_state
|= AHCI_ATTACH_STATE_STATEP_ALLOC
;
683 /* Initialize FMA properties */
684 ahci_fm_init(ahci_ctlp
);
686 attach_state
|= AHCI_ATTACH_STATE_FMA
;
689 * Now map the AHCI base address; which includes global
690 * registers and port control registers
692 * According to the spec, the AHCI Base Address is BAR5,
693 * but BAR0-BAR4 are optional, so we need to check which
694 * rnumber is used for BAR5.
698 * search through DDI "reg" property for the AHCI register set
700 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY
, dip
,
701 DDI_PROP_DONTPASS
, "reg", (int **)®s
,
702 (uint_t
*)®s_length
) != DDI_PROP_SUCCESS
) {
703 cmn_err(CE_WARN
, "!ahci%d: Cannot lookup reg property",
708 /* AHCI Base Address is located at 0x24 offset */
709 for (rnumber
= 0; rnumber
< regs_length
; ++rnumber
) {
710 if ((regs
[rnumber
].pci_phys_hi
& PCI_REG_REG_M
)
717 if (rnumber
== regs_length
) {
718 cmn_err(CE_WARN
, "!ahci%d: Cannot find AHCI register set",
723 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "rnumber = %d", rnumber
);
725 status
= ddi_regs_map_setup(dip
,
727 (caddr_t
*)&ahci_ctlp
->ahcictl_ahci_addr
,
731 &ahci_ctlp
->ahcictl_ahci_acc_handle
);
732 if (status
!= DDI_SUCCESS
) {
733 cmn_err(CE_WARN
, "!ahci%d: Cannot map register space",
738 attach_state
|= AHCI_ATTACH_STATE_REG_MAP
;
741 * GHC.AE must be set to 1 before any other AHCI register
744 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
745 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
746 ghc_control
|= AHCI_HBA_GHC_AE
;
747 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
748 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
), ghc_control
);
750 /* Get the AHCI version information */
751 ahci_version
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
752 (uint32_t *)AHCI_GLOBAL_VS(ahci_ctlp
));
754 cmn_err(CE_NOTE
, "!ahci%d: hba AHCI version = %x.%x", instance
,
755 (ahci_version
& 0xffff0000) >> 16,
756 ((ahci_version
& 0x0000ff00) >> 4 |
757 (ahci_version
& 0x000000ff)));
759 /* We don't support controllers whose versions are lower than 1.0 */
760 if (!(ahci_version
& 0xffff0000)) {
761 cmn_err(CE_WARN
, "ahci%d: Don't support AHCI HBA with lower "
762 "than version 1.0", instance
);
766 /* Get the HBA capabilities information */
767 cap_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
768 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp
));
770 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "hba capabilities = 0x%x",
773 /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
774 if (ahci_version
>= 0x00010200) {
775 uint32_t cap2_status
;
777 /* Get the HBA capabilities extended information */
778 cap2_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
779 (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp
));
781 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
782 "hba capabilities extended = 0x%x", cap2_status
);
785 if (cap_status
& AHCI_HBA_CAP_EMS
) {
786 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_EMS
;
787 ahci_ctlp
->ahcictl_em_loc
=
788 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
789 (uint32_t *)AHCI_GLOBAL_EM_LOC(ahci_ctlp
));
790 ahci_ctlp
->ahcictl_em_ctl
=
791 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
792 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp
));
796 /* Get the interface speed supported by the HBA */
797 speed
= (cap_status
& AHCI_HBA_CAP_ISS
) >> AHCI_HBA_CAP_ISS_SHIFT
;
799 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
800 "hba interface speed support: Gen 1 (1.5Gbps)", NULL
);
801 } else if (speed
== 0x10) {
802 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
803 "hba interface speed support: Gen 2 (3 Gbps)", NULL
);
804 } else if (speed
== 0x11) {
805 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
806 "hba interface speed support: Gen 3 (6 Gbps)", NULL
);
810 /* Get the number of command slots supported by the HBA */
811 ahci_ctlp
->ahcictl_num_cmd_slots
=
812 ((cap_status
& AHCI_HBA_CAP_NCS
) >>
813 AHCI_HBA_CAP_NCS_SHIFT
) + 1;
815 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "hba number of cmd slots: %d",
816 ahci_ctlp
->ahcictl_num_cmd_slots
);
818 /* Get the bit map which indicates ports implemented by the HBA */
819 ahci_ctlp
->ahcictl_ports_implemented
=
820 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
821 (uint32_t *)AHCI_GLOBAL_PI(ahci_ctlp
));
823 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "hba implementation of ports: 0x%x",
824 ahci_ctlp
->ahcictl_ports_implemented
);
826 /* Max port number implemented */
827 ahci_ctlp
->ahcictl_num_ports
=
828 ddi_fls(ahci_ctlp
->ahcictl_ports_implemented
);
830 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "hba number of ports: %d",
831 (cap_status
& AHCI_HBA_CAP_NP
) + 1);
833 /* Get the number of implemented ports by the HBA */
834 ahci_ctlp
->ahcictl_num_implemented_ports
=
835 ahci_get_num_implemented_ports(
836 ahci_ctlp
->ahcictl_ports_implemented
);
838 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
839 "hba number of implemented ports: %d",
840 ahci_ctlp
->ahcictl_num_implemented_ports
);
842 /* Check whether HBA supports 64bit DMA addressing */
843 if (!(cap_status
& AHCI_HBA_CAP_S64A
)) {
844 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_BUF_32BIT_DMA
;
845 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_COMMU_32BIT_DMA
;
846 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
847 "hba does not support 64-bit addressing", NULL
);
850 /* Checking for the support of Port Multiplier */
851 if (cap_status
& AHCI_HBA_CAP_SPM
) {
852 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_PMULT_CBSS
;
853 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_PMULT
, ahci_ctlp
,
854 "hba supports port multiplier (CBSS)", NULL
);
856 /* Support FIS-based switching ? */
857 if (cap_status
& AHCI_HBA_CAP_FBSS
) {
858 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_PMULT_FBSS
;
859 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_PMULT
, ahci_ctlp
,
860 "hba supports FIS-based switching (FBSS)", NULL
);
864 /* Checking for Support Command List Override */
865 if (cap_status
& AHCI_HBA_CAP_SCLO
) {
866 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_SCLO
;
867 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_PMULT
, ahci_ctlp
,
868 "hba supports command list override.", NULL
);
871 /* Checking for Asynchronous Notification */
872 if (cap_status
& AHCI_HBA_CAP_SSNTF
) {
873 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_SNTF
;
874 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_PMULT
, ahci_ctlp
,
875 "hba supports asynchronous notification.", NULL
);
878 if (pci_config_setup(dip
, &ahci_ctlp
->ahcictl_pci_conf_handle
)
880 cmn_err(CE_WARN
, "!ahci%d: Cannot set up pci configure space",
885 attach_state
|= AHCI_ATTACH_STATE_PCICFG_SETUP
;
888 * Check the pci configuration space, and set caps. We also
889 * handle the hardware defect in this function.
891 * For example, force ATI SB600 to use 32-bit dma addressing
892 * since it doesn't support 64-bit dma though its CAP register
893 * declares it support.
895 if (ahci_config_space_init(ahci_ctlp
) == AHCI_FAILURE
) {
896 cmn_err(CE_WARN
, "!ahci%d: ahci_config_space_init failed",
902 * Disable the whole controller interrupts before adding
903 * interrupt handlers(s).
905 ahci_disable_all_intrs(ahci_ctlp
);
907 /* Get supported interrupt types */
908 if (ddi_intr_get_supported_types(dip
, &intr_types
) != DDI_SUCCESS
) {
909 cmn_err(CE_WARN
, "!ahci%d: ddi_intr_get_supported_types failed",
914 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INTR
, ahci_ctlp
,
915 "ddi_intr_get_supported_types() returned: 0x%x",
918 if (ahci_msi_enabled
&& (intr_types
& DDI_INTR_TYPE_MSI
)) {
920 * Try MSI first, but fall back to FIXED if failed
922 if (ahci_add_intrs(ahci_ctlp
, DDI_INTR_TYPE_MSI
) ==
924 ahci_ctlp
->ahcictl_intr_type
= DDI_INTR_TYPE_MSI
;
925 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INTR
, ahci_ctlp
,
926 "Using MSI interrupt type", NULL
);
930 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INTR
, ahci_ctlp
,
931 "MSI registration failed, "
932 "trying FIXED interrupts", NULL
);
935 if (intr_types
& DDI_INTR_TYPE_FIXED
) {
936 if (ahci_add_intrs(ahci_ctlp
, DDI_INTR_TYPE_FIXED
) ==
938 ahci_ctlp
->ahcictl_intr_type
= DDI_INTR_TYPE_FIXED
;
939 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INTR
, ahci_ctlp
,
940 "Using FIXED interrupt type", NULL
);
944 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INTR
, ahci_ctlp
,
945 "FIXED interrupt registration failed", NULL
);
948 cmn_err(CE_WARN
, "!ahci%d: Interrupt registration failed", instance
);
954 attach_state
|= AHCI_ATTACH_STATE_INTR_ADDED
;
956 /* Initialize the controller mutex */
957 mutex_init(&ahci_ctlp
->ahcictl_mutex
, NULL
, MUTEX_DRIVER
,
958 (void *)(uintptr_t)ahci_ctlp
->ahcictl_intr_pri
);
960 attach_state
|= AHCI_ATTACH_STATE_MUTEX_INIT
;
962 if (ahci_dma_prdt_number
< AHCI_MIN_PRDT_NUMBER
) {
963 ahci_dma_prdt_number
= AHCI_MIN_PRDT_NUMBER
;
964 } else if (ahci_dma_prdt_number
> AHCI_MAX_PRDT_NUMBER
) {
965 ahci_dma_prdt_number
= AHCI_MAX_PRDT_NUMBER
;
968 ahci_cmd_table_size
= (sizeof (ahci_cmd_table_t
) +
969 (ahci_dma_prdt_number
- AHCI_PRDT_NUMBER
) *
970 sizeof (ahci_prdt_item_t
));
972 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
973 "ahci_attach: ahci_dma_prdt_number set by user is 0x%x,"
974 " ahci_cmd_table_size is 0x%x",
975 ahci_dma_prdt_number
, ahci_cmd_table_size
);
977 if (ahci_dma_prdt_number
!= AHCI_PRDT_NUMBER
)
978 ahci_ctlp
->ahcictl_buffer_dma_attr
.dma_attr_sgllen
=
979 ahci_dma_prdt_number
;
981 ahci_ctlp
->ahcictl_buffer_dma_attr
= buffer_dma_attr
;
982 ahci_ctlp
->ahcictl_rcvd_fis_dma_attr
= rcvd_fis_dma_attr
;
983 ahci_ctlp
->ahcictl_cmd_list_dma_attr
= cmd_list_dma_attr
;
984 ahci_ctlp
->ahcictl_cmd_table_dma_attr
= cmd_table_dma_attr
;
987 * enable 64bit dma for data buffer for SB600 if
988 * sb600_buf_64bit_dma_disable is B_FALSE
990 if ((ahci_buf_64bit_dma
== B_FALSE
) ||
991 ((ahci_ctlp
->ahcictl_cap
& AHCI_CAP_BUF_32BIT_DMA
) &&
992 !(sb600_buf_64bit_dma_disable
== B_FALSE
&&
993 ahci_ctlp
->ahcictl_venid
== 0x1002 &&
994 ahci_ctlp
->ahcictl_devid
== 0x4380))) {
995 ahci_ctlp
->ahcictl_buffer_dma_attr
.dma_attr_addr_hi
=
1000 * enable 64bit dma for command buffer for SB600/700/710/800
1001 * if sbxxx_commu_64bit_dma_disable is B_FALSE
1003 if ((ahci_commu_64bit_dma
== B_FALSE
) ||
1004 ((ahci_ctlp
->ahcictl_cap
& AHCI_CAP_COMMU_32BIT_DMA
) &&
1005 !(sbxxx_commu_64bit_dma_disable
== B_FALSE
&&
1006 ahci_ctlp
->ahcictl_venid
== 0x1002 &&
1007 (ahci_ctlp
->ahcictl_devid
== 0x4380 ||
1008 ahci_ctlp
->ahcictl_devid
== 0x4391)))) {
1009 ahci_ctlp
->ahcictl_rcvd_fis_dma_attr
.dma_attr_addr_hi
=
1011 ahci_ctlp
->ahcictl_cmd_list_dma_attr
.dma_attr_addr_hi
=
1013 ahci_ctlp
->ahcictl_cmd_table_dma_attr
.dma_attr_addr_hi
=
1017 /* Allocate the ports structure */
1018 status
= ahci_alloc_ports_state(ahci_ctlp
);
1019 if (status
!= AHCI_SUCCESS
) {
1020 cmn_err(CE_WARN
, "!ahci%d: Cannot allocate ports structure",
1025 attach_state
|= AHCI_ATTACH_STATE_PORT_ALLOC
;
1028 * Initialize the controller and ports.
1030 status
= ahci_initialize_controller(ahci_ctlp
);
1031 if (status
!= AHCI_SUCCESS
) {
1032 cmn_err(CE_WARN
, "!ahci%d: HBA initialization failed",
1037 attach_state
|= AHCI_ATTACH_STATE_HW_INIT
;
1039 /* Start one thread to check packet timeouts */
1040 ahci_ctlp
->ahcictl_timeout_id
= timeout(
1041 (void (*)(void *))ahci_watchdog_handler
,
1042 (caddr_t
)ahci_ctlp
, ahci_watchdog_tick
);
1044 attach_state
|= AHCI_ATTACH_STATE_TIMEOUT_ENABLED
;
1046 if (!ahci_em_init(ahci_ctlp
)) {
1047 cmn_err(CE_WARN
, "!ahci%d: failed to initialize enclosure "
1048 "services", instance
);
1051 attach_state
|= AHCI_ATTACH_STATE_ENCLOSURE
;
1053 if (ahci_register_sata_hba_tran(ahci_ctlp
, cap_status
)) {
1054 cmn_err(CE_WARN
, "!ahci%d: sata hba tran registration failed",
1059 /* Check all handles at the end of the attach operation. */
1060 if (ahci_check_all_handle(ahci_ctlp
) != DDI_SUCCESS
) {
1061 cmn_err(CE_WARN
, "!ahci%d: invalid dma/acc handles",
1066 ahci_ctlp
->ahcictl_flags
&= ~AHCI_ATTACH
;
1068 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "ahci_attach success!", NULL
);
1070 return (DDI_SUCCESS
);
1074 ahci_fm_ereport(ahci_ctlp
, DDI_FM_DEVICE_NO_RESPONSE
);
1075 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
, DDI_SERVICE_LOST
);
1077 if (attach_state
& AHCI_ATTACH_STATE_ENCLOSURE
) {
1078 ahci_em_fini(ahci_ctlp
);
1081 if (attach_state
& AHCI_ATTACH_STATE_TIMEOUT_ENABLED
) {
1082 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1083 (void) untimeout(ahci_ctlp
->ahcictl_timeout_id
);
1084 ahci_ctlp
->ahcictl_timeout_id
= 0;
1085 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1088 if (attach_state
& AHCI_ATTACH_STATE_HW_INIT
) {
1089 ahci_uninitialize_controller(ahci_ctlp
);
1092 if (attach_state
& AHCI_ATTACH_STATE_PORT_ALLOC
) {
1093 ahci_dealloc_ports_state(ahci_ctlp
);
1096 if (attach_state
& AHCI_ATTACH_STATE_MUTEX_INIT
) {
1097 mutex_destroy(&ahci_ctlp
->ahcictl_mutex
);
1100 if (attach_state
& AHCI_ATTACH_STATE_INTR_ADDED
) {
1101 ahci_rem_intrs(ahci_ctlp
);
1104 if (attach_state
& AHCI_ATTACH_STATE_PCICFG_SETUP
) {
1105 pci_config_teardown(&ahci_ctlp
->ahcictl_pci_conf_handle
);
1108 if (attach_state
& AHCI_ATTACH_STATE_REG_MAP
) {
1109 ddi_regs_map_free(&ahci_ctlp
->ahcictl_ahci_acc_handle
);
1112 if (attach_state
& AHCI_ATTACH_STATE_FMA
) {
1113 ahci_fm_fini(ahci_ctlp
);
1116 if (attach_state
& AHCI_ATTACH_STATE_STATEP_ALLOC
) {
1117 ddi_soft_state_free(ahci_statep
, instance
);
1120 return (DDI_FAILURE
);
1124 * The detach entry point for dev_ops.
1127 ahci_detach(dev_info_t
*dip
, ddi_detach_cmd_t cmd
)
1129 ahci_ctl_t
*ahci_ctlp
;
1133 instance
= ddi_get_instance(dip
);
1134 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
1136 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_detach enter", NULL
);
1141 /* disable the interrupts for an uninterrupted detach */
1142 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1143 ahci_disable_all_intrs(ahci_ctlp
);
1144 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1146 /* unregister from the sata framework. */
1147 ret
= ahci_unregister_sata_hba_tran(ahci_ctlp
);
1148 if (ret
!= AHCI_SUCCESS
) {
1149 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1150 ahci_enable_all_intrs(ahci_ctlp
);
1151 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1152 return (DDI_FAILURE
);
1155 ahci_em_fini(ahci_ctlp
);
1157 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1159 /* stop the watchdog handler */
1160 (void) untimeout(ahci_ctlp
->ahcictl_timeout_id
);
1161 ahci_ctlp
->ahcictl_timeout_id
= 0;
1163 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1165 /* uninitialize the controller */
1166 ahci_uninitialize_controller(ahci_ctlp
);
1168 /* remove the interrupts */
1169 ahci_rem_intrs(ahci_ctlp
);
1171 /* deallocate the ports structures */
1172 ahci_dealloc_ports_state(ahci_ctlp
);
1175 mutex_destroy(&ahci_ctlp
->ahcictl_mutex
);
1177 /* teardown the pci config */
1178 pci_config_teardown(&ahci_ctlp
->ahcictl_pci_conf_handle
);
1180 /* remove the reg maps. */
1181 ddi_regs_map_free(&ahci_ctlp
->ahcictl_ahci_acc_handle
);
1183 /* release fma resource */
1184 ahci_fm_fini(ahci_ctlp
);
1186 /* free the soft state. */
1187 ddi_soft_state_free(ahci_statep
, instance
);
1189 return (DDI_SUCCESS
);
1194 * The steps associated with suspension must include putting
1195 * the underlying device into a quiescent state so that it
1196 * will not generate interrupts or modify or access memory.
1198 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1199 if (ahci_ctlp
->ahcictl_flags
& AHCI_SUSPEND
) {
1200 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1201 return (DDI_SUCCESS
);
1204 ahci_ctlp
->ahcictl_flags
|= AHCI_SUSPEND
;
1206 ahci_em_suspend(ahci_ctlp
);
1208 /* stop the watchdog handler */
1209 if (ahci_ctlp
->ahcictl_timeout_id
) {
1210 (void) untimeout(ahci_ctlp
->ahcictl_timeout_id
);
1211 ahci_ctlp
->ahcictl_timeout_id
= 0;
1214 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1219 ahci_drain_ports_taskq(ahci_ctlp
);
1222 * Disable the interrupts and stop all the ports.
1224 ahci_uninitialize_controller(ahci_ctlp
);
1226 return (DDI_SUCCESS
);
1229 return (DDI_FAILURE
);
1234 * The info entry point for dev_ops.
1238 ahci_getinfo(dev_info_t
*dip
, ddi_info_cmd_t infocmd
,
1239 void *arg
, void **result
)
1242 _NOTE(ARGUNUSED(dip
))
1243 #endif /* __lock_lint */
1245 ahci_ctl_t
*ahci_ctlp
;
1250 instance
= getminor(dev
);
1253 case DDI_INFO_DEVT2DEVINFO
:
1254 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
1255 if (ahci_ctlp
!= NULL
) {
1256 *result
= ahci_ctlp
->ahcictl_dip
;
1257 return (DDI_SUCCESS
);
1260 return (DDI_FAILURE
);
1262 case DDI_INFO_DEVT2INSTANCE
:
1263 *(int *)result
= instance
;
1269 return (DDI_SUCCESS
);
1273 * Registers the ahci with sata framework.
1276 ahci_register_sata_hba_tran(ahci_ctl_t
*ahci_ctlp
, uint32_t cap_status
)
1278 struct sata_hba_tran
*sata_hba_tran
;
1280 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
1281 "ahci_register_sata_hba_tran enter", NULL
);
1283 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1285 /* Allocate memory for the sata_hba_tran */
1286 sata_hba_tran
= kmem_zalloc(sizeof (sata_hba_tran_t
), KM_SLEEP
);
1288 sata_hba_tran
->sata_tran_hba_rev
= SATA_TRAN_HBA_REV
;
1289 sata_hba_tran
->sata_tran_hba_dip
= ahci_ctlp
->ahcictl_dip
;
1290 sata_hba_tran
->sata_tran_hba_dma_attr
=
1291 &ahci_ctlp
->ahcictl_buffer_dma_attr
;
1293 /* Report the number of implemented ports */
1294 sata_hba_tran
->sata_tran_hba_num_cports
=
1295 ahci_ctlp
->ahcictl_num_implemented_ports
;
1297 /* Support ATAPI device */
1298 sata_hba_tran
->sata_tran_hba_features_support
= SATA_CTLF_ATAPI
;
1300 /* Get the data transfer capability for PIO command by the HBA */
1301 if (cap_status
& AHCI_HBA_CAP_PMD
) {
1302 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_PIO_MDRQ
;
1303 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "HBA supports multiple "
1304 "DRQ block data transfer for PIO command protocol", NULL
);
1308 * According to the AHCI spec, the ATA/ATAPI-7 queued feature set
1309 * is not supported by AHCI (including the READ QUEUED (EXT), WRITE
1310 * QUEUED (EXT), and SERVICE commands). Queued operations are
1311 * supported in AHCI using the READ FPDMA QUEUED and WRITE FPDMA
1312 * QUEUED commands when the HBA and device support native command
1315 * SATA_CTLF_NCQ will be set to sata_tran_hba_features_support if the
1316 * CAP register of the HBA indicates NCQ is supported.
1318 * SATA_CTLF_NCQ cannot be set if AHCI_CAP_NO_MCMDLIST_NONQUEUE is
1319 * set because the previous register content of PxCI can be re-written
1320 * in the register write.
1322 if ((cap_status
& AHCI_HBA_CAP_SNCQ
) &&
1323 !(ahci_ctlp
->ahcictl_cap
& AHCI_CAP_NO_MCMDLIST_NONQUEUE
)) {
1324 sata_hba_tran
->sata_tran_hba_features_support
|= SATA_CTLF_NCQ
;
1325 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_NCQ
;
1326 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "HBA supports Native "
1327 "Command Queuing", NULL
);
1330 /* Support port multiplier? */
1331 if (cap_status
& AHCI_HBA_CAP_SPM
) {
1332 sata_hba_tran
->sata_tran_hba_features_support
|=
1333 SATA_CTLF_PORT_MULTIPLIER
;
1335 /* Support FIS-based switching for port multiplier? */
1336 if (cap_status
& AHCI_HBA_CAP_FBSS
) {
1337 sata_hba_tran
->sata_tran_hba_features_support
|=
1338 SATA_CTLF_PMULT_FBS
;
1342 /* Report the number of command slots */
1343 sata_hba_tran
->sata_tran_hba_qdepth
= ahci_ctlp
->ahcictl_num_cmd_slots
;
1345 sata_hba_tran
->sata_tran_probe_port
= ahci_tran_probe_port
;
1346 sata_hba_tran
->sata_tran_start
= ahci_tran_start
;
1347 sata_hba_tran
->sata_tran_abort
= ahci_tran_abort
;
1348 sata_hba_tran
->sata_tran_reset_dport
= ahci_tran_reset_dport
;
1349 sata_hba_tran
->sata_tran_hotplug_ops
= &ahci_tran_hotplug_ops
;
1351 sata_hba_tran
->sata_tran_selftest
= ahci_selftest
;
1354 * When SATA framework adds support for pwrmgt the
1355 * pwrmgt_ops needs to be updated
1357 sata_hba_tran
->sata_tran_pwrmgt_ops
= NULL
;
1358 sata_hba_tran
->sata_tran_ioctl
= ahci_em_ioctl
;
1360 ahci_ctlp
->ahcictl_sata_hba_tran
= sata_hba_tran
;
1362 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1364 /* Attach it to SATA framework */
1365 if (sata_hba_attach(ahci_ctlp
->ahcictl_dip
, sata_hba_tran
, DDI_ATTACH
)
1367 kmem_free((void *)sata_hba_tran
, sizeof (sata_hba_tran_t
));
1368 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1369 ahci_ctlp
->ahcictl_sata_hba_tran
= NULL
;
1370 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1371 return (AHCI_FAILURE
);
1374 return (AHCI_SUCCESS
);
1378 * Unregisters the ahci with sata framework.
1381 ahci_unregister_sata_hba_tran(ahci_ctl_t
*ahci_ctlp
)
1383 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
1384 "ahci_unregister_sata_hba_tran enter", NULL
);
1386 /* Detach from the SATA framework. */
1387 if (sata_hba_detach(ahci_ctlp
->ahcictl_dip
, DDI_DETACH
) !=
1389 return (AHCI_FAILURE
);
1392 /* Deallocate sata_hba_tran. */
1393 kmem_free((void *)ahci_ctlp
->ahcictl_sata_hba_tran
,
1394 sizeof (sata_hba_tran_t
));
1396 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
1397 ahci_ctlp
->ahcictl_sata_hba_tran
= NULL
;
1398 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
1400 return (AHCI_SUCCESS
);
1403 #define SET_PORTSTR(str, addrp) \
1404 if (AHCI_ADDR_IS_PORT(addrp)) \
1405 (void) sprintf((str), "%d", (addrp)->aa_port); \
1406 else if (AHCI_ADDR_IS_PMULT(addrp)) \
1407 (void) sprintf((str), "%d (pmult)", (addrp)->aa_port); \
1409 (void) sprintf((str), "%d:%d", (addrp)->aa_port, \
1410 (addrp)->aa_pmport);
1413 * ahci_tran_probe_port is called by SATA framework. It returns port state,
1414 * port status registers and an attached device type via sata_device
1417 * We return the cached information from a previous hardware probe. The
1418 * actual hardware probing itself was done either from within
1419 * ahci_initialize_controller() during the driver attach or from a phy
1420 * ready change interrupt handler.
1423 ahci_tran_probe_port(dev_info_t
*dip
, sata_device_t
*sd
)
1425 ahci_ctl_t
*ahci_ctlp
;
1426 ahci_port_t
*ahci_portp
;
1427 ahci_addr_t addr
, pmult_addr
;
1428 uint8_t cport
= sd
->satadev_addr
.cport
;
1430 uint8_t device_type
;
1431 uint32_t port_state
;
1433 int rval
= SATA_SUCCESS
, rval_init
;
1435 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, ddi_get_instance(dip
));
1436 port
= ahci_ctlp
->ahcictl_cport_to_port
[cport
];
1438 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
1440 mutex_enter(&ahci_portp
->ahciport_mutex
);
1442 ahci_get_ahci_addr(ahci_ctlp
, sd
, &addr
);
1443 ASSERT(AHCI_ADDR_IS_VALID(&addr
));
1444 SET_PORTSTR(portstr
, &addr
);
1446 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
1447 "ahci_tran_probe_port enter: port %s", portstr
);
1449 if ((AHCI_ADDR_IS_PMULT(&addr
) || AHCI_ADDR_IS_PMPORT(&addr
)) &&
1450 (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
||
1451 ahci_portp
->ahciport_pmult_info
== NULL
)) {
1452 /* port mutliplier is removed. */
1453 AHCIDBG(AHCIDBG_PMULT
, ahci_ctlp
,
1454 "ahci_tran_probe_port: "
1455 "pmult is removed from port %s", portstr
);
1456 mutex_exit(&ahci_portp
->ahciport_mutex
);
1457 return (SATA_FAILURE
);
1461 * The sata_device may refer to
1462 * 1. A controller port.
1463 * A controller port should be ready here.
1464 * 2. A port multiplier.
1465 * SATA_ADDR_PMULT_SPEC - if it is not initialized yet, initialize
1466 * it and register the port multiplier to the framework.
1467 * SATA_ADDR_PMULT - check the status of all its device ports.
1468 * 3. A port multiplier port.
1469 * If it has not been initialized, initialized it.
1471 * A port multiplier or a port multiplier port may require some
1472 * initialization because we cannot do these time-consuming jobs in an
1473 * interrupt context.
1475 if (sd
->satadev_addr
.qual
& SATA_ADDR_PMULT_SPEC
) {
1476 AHCI_ADDR_SET_PMULT(&pmult_addr
, port
);
1477 /* Initialize registers on a port multiplier */
1478 rval_init
= ahci_initialize_pmult(ahci_ctlp
,
1479 ahci_portp
, &pmult_addr
, sd
);
1480 if (rval_init
!= AHCI_SUCCESS
) {
1481 AHCIDBG(AHCIDBG_PMULT
, ahci_ctlp
,
1482 "ahci_tran_probe_port: "
1483 "pmult initialization failed.", NULL
);
1484 mutex_exit(&ahci_portp
->ahciport_mutex
);
1485 return (SATA_FAILURE
);
1487 } else if (sd
->satadev_addr
.qual
& SATA_ADDR_PMULT
) {
1488 /* Check pmports hotplug events */
1489 (void) ahci_probe_pmult(ahci_ctlp
, ahci_portp
, &addr
);
1490 } else if (sd
->satadev_addr
.qual
& (SATA_ADDR_PMPORT
|
1491 SATA_ADDR_DPMPORT
)) {
1492 if (ahci_probe_pmport(ahci_ctlp
, ahci_portp
,
1493 &addr
, sd
) != AHCI_SUCCESS
) {
1494 rval
= SATA_FAILURE
;
1499 /* Update port state and device type */
1500 port_state
= AHCIPORT_GET_STATE(ahci_portp
, &addr
);
1502 switch (port_state
) {
1504 case SATA_PSTATE_FAILED
:
1505 sd
->satadev_state
= SATA_PSTATE_FAILED
;
1506 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1507 "ahci_tran_probe_port: port %s PORT FAILED", portstr
);
1510 case SATA_PSTATE_SHUTDOWN
:
1511 sd
->satadev_state
= SATA_PSTATE_SHUTDOWN
;
1512 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1513 "ahci_tran_probe_port: port %s PORT SHUTDOWN", portstr
);
1516 case SATA_PSTATE_PWROFF
:
1517 sd
->satadev_state
= SATA_PSTATE_PWROFF
;
1518 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1519 "ahci_tran_probe_port: port %s PORT PWROFF", portstr
);
1522 case SATA_PSTATE_PWRON
:
1523 sd
->satadev_state
= SATA_PSTATE_PWRON
;
1524 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1525 "ahci_tran_probe_port: port %s PORT PWRON", portstr
);
1529 sd
->satadev_state
= port_state
;
1530 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1531 "ahci_tran_probe_port: port %s PORT NORMAL %x",
1532 portstr
, port_state
);
1536 device_type
= AHCIPORT_GET_DEV_TYPE(ahci_portp
, &addr
);
1538 switch (device_type
) {
1540 case SATA_DTYPE_ATADISK
:
1541 sd
->satadev_type
= SATA_DTYPE_ATADISK
;
1542 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1543 "ahci_tran_probe_port: port %s DISK found", portstr
);
1546 case SATA_DTYPE_ATAPI
:
1548 * HBA driver only knows it's an ATAPI device, and don't know
1549 * it's CD/DVD, tape or ATAPI disk because the ATAPI device
1550 * type need to be determined by checking IDENTIFY PACKET
1553 sd
->satadev_type
= SATA_DTYPE_ATAPI
;
1554 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1555 "ahci_tran_probe_port: port %s ATAPI found", portstr
);
1558 case SATA_DTYPE_PMULT
:
1559 ASSERT(AHCI_ADDR_IS_PORT(&addr
) || AHCI_ADDR_IS_PMULT(&addr
));
1560 sd
->satadev_type
= SATA_DTYPE_PMULT
;
1562 /* Update the number of pmports. */
1563 ASSERT(ahci_portp
->ahciport_pmult_info
!= NULL
);
1564 sd
->satadev_add_info
= ahci_portp
->
1565 ahciport_pmult_info
->ahcipmi_num_dev_ports
;
1567 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1568 "ahci_tran_probe_port: port %s Port Multiplier found",
1572 case SATA_DTYPE_UNKNOWN
:
1573 sd
->satadev_type
= SATA_DTYPE_UNKNOWN
;
1574 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1575 "ahci_tran_probe_port: port %s Unknown device found",
1580 /* we don't support any other device types */
1581 sd
->satadev_type
= SATA_DTYPE_NONE
;
1582 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
1583 "ahci_tran_probe_port: port %s No device found", portstr
);
1588 /* Register update only fails while probing a pmult/pmport */
1589 if (AHCI_ADDR_IS_PORT(&addr
) || AHCI_ADDR_IS_PMULT(&addr
)) {
1590 ahci_update_sata_registers(ahci_ctlp
, port
, sd
);
1591 } else if (AHCI_ADDR_IS_PMPORT(&addr
)) {
1592 if (port_state
& SATA_STATE_READY
)
1593 if (ahci_update_pmult_pscr(ahci_ctlp
,
1594 &addr
, sd
) != AHCI_SUCCESS
)
1595 rval
= SATA_FAILURE
;
1598 /* Check handles for the sata registers access */
1599 if ((ahci_check_ctl_handle(ahci_ctlp
) != DDI_SUCCESS
) ||
1600 (ahci_check_port_handle(ahci_ctlp
, port
) != DDI_SUCCESS
)) {
1601 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
1602 DDI_SERVICE_UNAFFECTED
);
1603 rval
= SATA_FAILURE
;
1606 mutex_exit(&ahci_portp
->ahciport_mutex
);
1611 * There are four operation modes in sata framework:
1612 * SATA_OPMODE_INTERRUPTS
1613 * SATA_OPMODE_POLLING
1614 * SATA_OPMODE_ASYNCH
1617 * Their combined meanings as following:
1620 * The command has to be completed before sata_tran_start functions returns.
1621 * Either interrupts or polling could be used - it's up to the driver.
1622 * Mode used currently for internal, sata-module initiated operations.
1624 * SATA_OPMODE_SYNCH | SATA_OPMODE_INTERRUPTS
1625 * It is the same as the one above.
1627 * SATA_OPMODE_SYNCH | SATA_OPMODE_POLLING
1628 * The command has to be completed before sata_tran_start function returns.
1629 * No interrupt used, polling only. This should be the mode used for scsi
1630 * packets with FLAG_NOINTR.
1632 * SATA_OPMODE_ASYNCH | SATA_OPMODE_INTERRUPTS
1633 * The command may be queued (callback function specified). Interrupts could
1634 * be used. It's normal operation mode.
1637 * Called by sata framework to transport a sata packet down stream.
1640 ahci_tran_start(dev_info_t
*dip
, sata_pkt_t
*spkt
)
1642 ahci_ctl_t
*ahci_ctlp
;
1643 ahci_port_t
*ahci_portp
;
1645 uint8_t cport
= spkt
->satapkt_device
.satadev_addr
.cport
;
1649 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, ddi_get_instance(dip
));
1650 port
= ahci_ctlp
->ahcictl_cport_to_port
[cport
];
1652 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
1653 "ahci_tran_start enter: cport %d satapkt 0x%p",
1654 cport
, (void *)spkt
);
1656 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
1658 mutex_enter(&ahci_portp
->ahciport_mutex
);
1659 ahci_get_ahci_addr(ahci_ctlp
, &spkt
->satapkt_device
, &addr
);
1660 SET_PORTSTR(portstr
, &addr
);
1663 if (AHCI_ADDR_IS_PMPORT(&addr
)) {
1664 if (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
||
1665 ahci_portp
->ahciport_pmult_info
== NULL
) {
1667 spkt
->satapkt_reason
= SATA_PKT_PORT_ERROR
;
1668 spkt
->satapkt_device
.satadev_type
= SATA_DTYPE_NONE
;
1669 spkt
->satapkt_device
.satadev_state
= SATA_STATE_UNKNOWN
;
1670 ahci_update_sata_registers(ahci_ctlp
, port
,
1671 &spkt
->satapkt_device
);
1672 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1673 "ahci_tran_start returning PORT_ERROR while "
1674 "pmult removed: port: %s", portstr
);
1675 mutex_exit(&ahci_portp
->ahciport_mutex
);
1676 return (SATA_TRAN_PORT_ERROR
);
1679 if (!(AHCIPORT_GET_STATE(ahci_portp
, &addr
) &
1680 SATA_STATE_READY
)) {
1681 if (!ddi_in_panic() ||
1682 ahci_initialize_pmport(ahci_ctlp
,
1683 ahci_portp
, &addr
) != AHCI_SUCCESS
) {
1684 spkt
->satapkt_reason
= SATA_PKT_PORT_ERROR
;
1685 spkt
->satapkt_device
.satadev_type
=
1686 AHCIPORT_GET_DEV_TYPE(ahci_portp
, &addr
);
1687 spkt
->satapkt_device
.satadev_state
=
1688 AHCIPORT_GET_STATE(ahci_portp
, &addr
);
1689 ahci_update_sata_registers(ahci_ctlp
, port
,
1690 &spkt
->satapkt_device
);
1691 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1692 "ahci_tran_start returning PORT_ERROR "
1693 "while sub-link is not initialized "
1694 "at port: %s", portstr
);
1695 mutex_exit(&ahci_portp
->ahciport_mutex
);
1696 return (SATA_TRAN_PORT_ERROR
);
1701 if (AHCIPORT_GET_STATE(ahci_portp
, &addr
) & SATA_PSTATE_FAILED
||
1702 AHCIPORT_GET_STATE(ahci_portp
, &addr
) & SATA_PSTATE_SHUTDOWN
||
1703 AHCIPORT_GET_STATE(ahci_portp
, &addr
) & SATA_PSTATE_PWROFF
) {
1705 * In case the target driver would send the packet before
1706 * sata framework can have the opportunity to process those
1709 spkt
->satapkt_reason
= SATA_PKT_PORT_ERROR
;
1710 spkt
->satapkt_device
.satadev_state
=
1711 ahci_portp
->ahciport_port_state
;
1712 ahci_update_sata_registers(ahci_ctlp
, port
,
1713 &spkt
->satapkt_device
);
1714 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1715 "ahci_tran_start returning PORT_ERROR while "
1716 "port in FAILED/SHUTDOWN/PWROFF state: "
1717 "port: %s", portstr
);
1718 mutex_exit(&ahci_portp
->ahciport_mutex
);
1719 return (SATA_TRAN_PORT_ERROR
);
1722 if (AHCIPORT_GET_DEV_TYPE(ahci_portp
, &addr
) == SATA_DTYPE_NONE
) {
1724 * ahci_intr_phyrdy_change() may have rendered it to
1727 spkt
->satapkt_reason
= SATA_PKT_PORT_ERROR
;
1728 spkt
->satapkt_device
.satadev_type
= SATA_DTYPE_NONE
;
1729 spkt
->satapkt_device
.satadev_state
=
1730 ahci_portp
->ahciport_port_state
;
1731 ahci_update_sata_registers(ahci_ctlp
, port
,
1732 &spkt
->satapkt_device
);
1733 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1734 "ahci_tran_start returning PORT_ERROR while "
1735 "no device attached: port: %s", portstr
);
1736 mutex_exit(&ahci_portp
->ahciport_mutex
);
1737 return (SATA_TRAN_PORT_ERROR
);
1740 /* R/W PMULT command will occupy the whole HBA port */
1741 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
1742 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1743 "ahci_tran_start returning BUSY while "
1744 "executing READ/WRITE PORT-MULT command: "
1745 "port: %s", portstr
);
1746 spkt
->satapkt_reason
= SATA_PKT_BUSY
;
1747 mutex_exit(&ahci_portp
->ahciport_mutex
);
1748 return (SATA_TRAN_BUSY
);
1751 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_HOTPLUG
) {
1752 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1753 "ahci_tran_start returning BUSY while "
1754 "hot-plug in progress: port: %s", portstr
);
1755 spkt
->satapkt_reason
= SATA_PKT_BUSY
;
1756 mutex_exit(&ahci_portp
->ahciport_mutex
);
1757 return (SATA_TRAN_BUSY
);
1761 * SATA HBA driver should remember that a device was reset and it
1762 * is supposed to reject any packets which do not specify either
1763 * SATA_IGNORE_DEV_RESET_STATE or SATA_CLEAR_DEV_RESET_STATE.
1765 * This is to prevent a race condition when a device was arbitrarily
1766 * reset by the HBA driver (and lost it's setting) and a target
1767 * driver sending some commands to a device before the sata framework
1768 * has a chance to restore the device setting (such as cache enable/
1769 * disable or other resettable stuff).
1772 * It is unnecessary to use specific flags to indicate
1773 * reset_in_progress for a pmport. While mopping, all command will be
1774 * mopped so that the entire HBA port is being dealt as a single
1777 if (spkt
->satapkt_cmd
.satacmd_flags
.sata_clear_dev_reset
) {
1778 ahci_portp
->ahciport_reset_in_progress
= 0;
1779 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1780 "ahci_tran_start [CLEAR] the "
1781 "reset_in_progress for port: %d", port
);
1784 if (ahci_portp
->ahciport_reset_in_progress
&&
1785 ! spkt
->satapkt_cmd
.satacmd_flags
.sata_ignore_dev_reset
&&
1787 spkt
->satapkt_reason
= SATA_PKT_BUSY
;
1788 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1789 "ahci_tran_start returning BUSY while "
1790 "reset in progress: port: %d", port
);
1791 mutex_exit(&ahci_portp
->ahciport_mutex
);
1792 return (SATA_TRAN_BUSY
);
1796 if (spkt
->satapkt_cmd
.satacmd_flags
.sata_ignore_dev_reset
) {
1797 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1798 "ahci_tran_start: packet 0x%p [PASSTHRU] at port %d",
1803 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
1804 spkt
->satapkt_reason
= SATA_PKT_BUSY
;
1805 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1806 "ahci_tran_start returning BUSY while "
1807 "mopping in progress: port: %d", port
);
1808 mutex_exit(&ahci_portp
->ahciport_mutex
);
1809 return (SATA_TRAN_BUSY
);
1812 if (ahci_check_ctl_handle(ahci_ctlp
) != DDI_SUCCESS
) {
1813 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
1814 DDI_SERVICE_UNAFFECTED
);
1815 mutex_exit(&ahci_portp
->ahciport_mutex
);
1816 return (SATA_TRAN_BUSY
);
1819 if (spkt
->satapkt_op_mode
&
1820 (SATA_OPMODE_SYNCH
| SATA_OPMODE_POLLING
)) {
1822 * If a SYNC command to be executed in interrupt context,
1823 * bounce it back to sata module.
1825 if (!(spkt
->satapkt_op_mode
& SATA_OPMODE_POLLING
) &&
1826 servicing_interrupt()) {
1827 spkt
->satapkt_reason
= SATA_PKT_BUSY
;
1828 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
1829 "ahci_tran_start returning BUSY while "
1830 "sending SYNC mode under interrupt context: "
1832 mutex_exit(&ahci_portp
->ahciport_mutex
);
1833 return (SATA_TRAN_BUSY
);
1836 /* We need to do the sync start now */
1837 if (ahci_do_sync_start(ahci_ctlp
, ahci_portp
, &addr
,
1838 spkt
) == AHCI_FAILURE
) {
1842 /* Async start, using interrupt */
1843 if (ahci_deliver_satapkt(ahci_ctlp
, ahci_portp
, &addr
, spkt
)
1845 spkt
->satapkt_reason
= SATA_PKT_QUEUE_FULL
;
1850 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "ahci_tran_start "
1851 "sata tran accepted: port %s", portstr
);
1853 mutex_exit(&ahci_portp
->ahciport_mutex
);
1854 return (SATA_TRAN_ACCEPTED
);
1858 * Failed to deliver packet to the controller.
1859 * Check if it's caused by invalid handles.
1861 if (ahci_check_ctl_handle(ahci_ctlp
) != DDI_SUCCESS
||
1862 ahci_check_port_handle(ahci_ctlp
, port
) != DDI_SUCCESS
) {
1863 spkt
->satapkt_device
.satadev_type
=
1864 AHCIPORT_GET_DEV_TYPE(ahci_portp
, &addr
);
1865 spkt
->satapkt_device
.satadev_state
=
1866 AHCIPORT_GET_STATE(ahci_portp
, &addr
);
1867 spkt
->satapkt_reason
= SATA_PKT_DEV_ERROR
;
1868 mutex_exit(&ahci_portp
->ahciport_mutex
);
1869 return (SATA_TRAN_PORT_ERROR
);
1872 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_tran_start "
1873 "return QUEUE_FULL: port %d", port
);
1874 mutex_exit(&ahci_portp
->ahciport_mutex
);
1875 return (SATA_TRAN_QUEUE_FULL
);
1879 * SATA_OPMODE_SYNCH flag is set
1881 * If SATA_OPMODE_POLLING flag is set, then we must poll the command
1882 * without interrupt, otherwise we can still use the interrupt.
1885 ahci_do_sync_start(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
1886 ahci_addr_t
*addrp
, sata_pkt_t
*spkt
)
1888 int pkt_timeout_ticks
;
1889 uint32_t timeout_tags
;
1891 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
1892 uint8_t port
= addrp
->aa_port
;
1894 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
1896 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_do_sync_start enter: "
1897 "port %d:%d spkt 0x%p", port
, addrp
->aa_pmport
, spkt
);
1899 if (spkt
->satapkt_op_mode
& SATA_OPMODE_POLLING
) {
1900 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_POLLING
;
1901 if ((rval
= ahci_deliver_satapkt(ahci_ctlp
, ahci_portp
,
1902 addrp
, spkt
)) == AHCI_FAILURE
) {
1903 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_POLLING
;
1908 drv_usectohz((clock_t)spkt
->satapkt_time
* 1000000);
1910 while (spkt
->satapkt_reason
== SATA_PKT_BUSY
) {
1911 /* Simulate the interrupt */
1912 mutex_exit(&ahci_portp
->ahciport_mutex
);
1913 ahci_port_intr(ahci_ctlp
, ahci_portp
, port
);
1914 mutex_enter(&ahci_portp
->ahciport_mutex
);
1916 if (spkt
->satapkt_reason
!= SATA_PKT_BUSY
)
1919 mutex_exit(&ahci_portp
->ahciport_mutex
);
1920 drv_usecwait(AHCI_1MS_USECS
);
1921 mutex_enter(&ahci_portp
->ahciport_mutex
);
1923 pkt_timeout_ticks
-= AHCI_1MS_TICKS
;
1924 if (pkt_timeout_ticks
< 0) {
1925 cmn_err(CE_WARN
, "!ahci%d: ahci_do_sync_start "
1926 "port %d satapkt 0x%p timed out\n",
1927 instance
, port
, (void *)spkt
);
1928 timeout_tags
= (0x1 << rval
);
1929 mutex_exit(&ahci_portp
->ahciport_mutex
);
1930 ahci_timeout_pkts(ahci_ctlp
, ahci_portp
,
1931 port
, timeout_tags
);
1932 mutex_enter(&ahci_portp
->ahciport_mutex
);
1936 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_POLLING
;
1937 return (AHCI_SUCCESS
);
1940 if ((rval
= ahci_deliver_satapkt(ahci_ctlp
, ahci_portp
,
1941 addrp
, spkt
)) == AHCI_FAILURE
)
1946 * Note that the driver always uses the slot 0 to deliver
1947 * REQUEST SENSE or READ LOG EXT command
1949 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
))
1953 while (spkt
->satapkt_reason
== SATA_PKT_BUSY
)
1954 cv_wait(&ahci_portp
->ahciport_cv
,
1955 &ahci_portp
->ahciport_mutex
);
1957 return (AHCI_SUCCESS
);
1962 * Searches for and claims a free command slot.
1966 * AHCI_FAILURE returned only if
1967 * 1. No empty slot left
1968 * 2. Non-queued command requested while queued command(s) is outstanding
1969 * 3. Queued command requested while non-queued command(s) is outstanding
1970 * 4. HBA doesn't support multiple-use of command list while already a
1971 * non-queued command is oustanding
1972 * 5. Queued command requested while some queued command(s) has been
1973 * outstanding on a different port multiplier port. (AHCI spec 1.2,
1976 * claimed slot number returned if succeeded
1978 * NOTE: it will always return slot 0 for following commands to simplify the
1980 * 1. REQUEST SENSE or READ LOG EXT command during error recovery process
1981 * 2. READ/WRITE PORTMULT command
1984 ahci_claim_free_slot(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
1985 ahci_addr_t
*addrp
, int command_type
)
1987 uint32_t port_cmd_issue
;
1988 uint32_t free_slots
;
1991 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
1993 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_claim_free_slot enter "
1994 "ahciport_pending_tags = 0x%x "
1995 "ahciport_pending_ncq_tags = 0x%x",
1996 ahci_portp
->ahciport_pending_tags
,
1997 ahci_portp
->ahciport_pending_ncq_tags
);
2000 * According to the AHCI spec, system software is responsible to
2001 * ensure that queued and non-queued commands are not mixed in
2004 if (command_type
== AHCI_NON_NCQ_CMD
) {
2005 /* Non-NCQ command request */
2006 if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2007 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_NCQ
, ahci_ctlp
,
2008 "ahci_claim_free_slot: there is still pending "
2009 "queued command(s) in the command list, "
2010 "so no available slot for the non-queued "
2012 return (AHCI_FAILURE
);
2014 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
2015 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
2016 "ahci_claim_free_slot: there is still pending "
2017 "read/write port-mult command(s) in command list, "
2018 "so no available slot for the non-queued command",
2020 return (AHCI_FAILURE
);
2022 if ((ahci_ctlp
->ahcictl_cap
& AHCI_CAP_NO_MCMDLIST_NONQUEUE
) &&
2023 NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2024 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
2025 "ahci_claim_free_slot: HBA cannot support multiple-"
2026 "use of the command list for non-queued commands",
2028 return (AHCI_FAILURE
);
2030 free_slots
= (~ahci_portp
->ahciport_pending_tags
) &
2031 AHCI_SLOT_MASK(ahci_ctlp
);
2032 } else if (command_type
== AHCI_NCQ_CMD
) {
2033 /* NCQ command request */
2034 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2035 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_NCQ
, ahci_ctlp
,
2036 "ahci_claim_free_slot: there is still pending "
2037 "non-queued command(s) in the command list, "
2038 "so no available slot for the queued command",
2040 return (AHCI_FAILURE
);
2044 * NCQ commands cannot be sent to different port multiplier
2045 * ports in Command-Based Switching mode
2048 * NOTE: In Command-Based Switching mode, AHCI controller
2049 * usually reports a 'Handshake Error' when multiple NCQ
2050 * commands are outstanding simultaneously.
2052 if (AHCIPORT_DEV_TYPE(ahci_portp
, addrp
) == SATA_DTYPE_PMULT
) {
2053 ASSERT(ahci_portp
->ahciport_pmult_info
!= NULL
);
2054 if (!(ahci_ctlp
->ahcictl_cap
& AHCI_CAP_PMULT_FBSS
) &&
2055 NCQ_CMD_IN_PROGRESS(ahci_portp
) &&
2056 AHCIPORT_NCQ_PMPORT(ahci_portp
) !=
2058 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
2059 "ahci_claim_free_slot: there is still "
2060 "pending queued command(s) in the "
2061 "command list for another Port Multiplier "
2062 "port, so no available slot.", NULL
);
2063 return (AHCI_FAILURE
);
2067 free_slots
= (~ahci_portp
->ahciport_pending_ncq_tags
) &
2068 AHCI_NCQ_SLOT_MASK(ahci_portp
);
2069 } else if (command_type
== AHCI_ERR_RETRI_CMD
) {
2070 /* Error retrieval command request */
2071 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2072 "ahci_claim_free_slot: slot 0 is allocated for REQUEST "
2073 "SENSE or READ LOG EXT command", NULL
);
2076 } else if (command_type
== AHCI_RDWR_PMULT_CMD
) {
2078 * An extra check on PxCI. Sometimes PxCI bits may not be
2079 * cleared during hot-plug or error recovery process.
2081 port_cmd_issue
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2082 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, addrp
->aa_port
));
2084 if (port_cmd_issue
!= 0) {
2085 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
2086 "ahci_claim_free_slot: there is still pending "
2087 "command(s) in command list (0x%x/0x%x, PxCI %x),"
2088 "so no available slot for R/W PMULT command.",
2089 NON_NCQ_CMD_IN_PROGRESS(ahci_portp
),
2090 NCQ_CMD_IN_PROGRESS(ahci_portp
),
2092 return (AHCI_FAILURE
);
2095 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
2096 "ahci_claim_free_slot: slot 0 is allocated for "
2097 "READ/WRITE PORTMULT command", NULL
);
2102 slot
= ddi_ffs(free_slots
) - 1;
2104 AHCIDBG(AHCIDBG_VERBOSE
, ahci_ctlp
,
2105 "ahci_claim_free_slot: no empty slots", NULL
);
2106 return (AHCI_FAILURE
);
2110 * According to the AHCI spec, to allow a simple mechanism for the
2111 * HBA to map command list slots to queue entries, software must
2112 * match the tag number it uses to the slot it is placing the command
2113 * in. For example, if a queued command is placed in slot 5, the tag
2114 * for that command must be 5.
2116 if (command_type
== AHCI_NCQ_CMD
) {
2117 ahci_portp
->ahciport_pending_ncq_tags
|= (0x1 << slot
);
2118 if (AHCI_ADDR_IS_PMPORT(addrp
)) {
2119 ASSERT(ahci_portp
->ahciport_pmult_info
!= NULL
);
2120 AHCIPORT_NCQ_PMPORT(ahci_portp
) = addrp
->aa_pmport
;
2124 ahci_portp
->ahciport_pending_tags
|= (0x1 << slot
);
2127 AHCIDBG(AHCIDBG_VERBOSE
, ahci_ctlp
,
2128 "ahci_claim_free_slot: found slot: 0x%x", slot
);
2134 * Builds the Command Table for the sata packet and delivers it to controller.
2137 * slot number if we can obtain a slot successfully
2138 * otherwise, return AHCI_FAILURE
2141 ahci_deliver_satapkt(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
2142 ahci_addr_t
*addrp
, sata_pkt_t
*spkt
)
2146 ahci_fis_h2d_register_t
*h2d_register_fisp
;
2147 ahci_cmd_table_t
*cmd_table
;
2148 ahci_cmd_header_t
*cmd_header
;
2151 int command_type
= AHCI_NON_NCQ_CMD
;
2153 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
2154 uint8_t port
, pmport
;
2160 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
2162 port
= addrp
->aa_port
;
2163 pmport
= addrp
->aa_pmport
;
2165 spkt
->satapkt_reason
= SATA_PKT_BUSY
;
2167 scmd
= &spkt
->satapkt_cmd
;
2169 /* Check if the command is a NCQ command */
2170 if (scmd
->satacmd_cmd_reg
== SATAC_READ_FPDMA_QUEUED
||
2171 scmd
->satacmd_cmd_reg
== SATAC_WRITE_FPDMA_QUEUED
) {
2172 command_type
= AHCI_NCQ_CMD
;
2175 * When NCQ is support, system software must determine the
2176 * maximum tag allowed by the device and the HBA, and it
2177 * must use a value not beyond of the lower bound of the two.
2179 * Sata module is going to calculate the qdepth and send
2180 * down to HBA driver via sata_cmd.
2182 ncq_qdepth
= scmd
->satacmd_flags
.sata_max_queue_depth
+ 1;
2185 * At the moment, the driver doesn't support the dynamic
2186 * setting of the maximum ncq depth, and the value can be
2187 * set either during the attach or after hot-plug insertion.
2189 if (ahci_portp
->ahciport_max_ncq_tags
== 0) {
2190 ahci_portp
->ahciport_max_ncq_tags
= ncq_qdepth
;
2191 AHCIDBG(AHCIDBG_NCQ
, ahci_ctlp
,
2192 "ahci_deliver_satapkt: port %d the max tags for "
2193 "NCQ command is %d", port
, ncq_qdepth
);
2195 if (ncq_qdepth
!= ahci_portp
->ahciport_max_ncq_tags
) {
2196 cmn_err(CE_WARN
, "!ahci%d: ahci_deliver_satapkt"
2197 " port %d the max tag for NCQ command is "
2198 "requested to change from %d to %d, at the"
2199 " moment the driver doesn't support the "
2200 "dynamic change so it's going to "
2201 "still use the previous tag value",
2203 ahci_portp
->ahciport_max_ncq_tags
,
2209 /* Check if the command is an error retrieval command */
2210 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
))
2211 command_type
= AHCI_ERR_RETRI_CMD
;
2213 /* Check if the command is an read/write pmult command */
2214 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
))
2215 command_type
= AHCI_RDWR_PMULT_CMD
;
2217 /* Check if there is an empty command slot */
2218 cmd_slot
= ahci_claim_free_slot(ahci_ctlp
, ahci_portp
,
2219 addrp
, command_type
);
2220 if (cmd_slot
== AHCI_FAILURE
) {
2221 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "no free command slot", NULL
);
2222 return (AHCI_FAILURE
);
2225 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INFO
, ahci_ctlp
,
2226 "ahci_deliver_satapkt enter: cmd_reg: 0x%x, cmd_slot: 0x%x, "
2227 "port: %d, satapkt: 0x%p", scmd
->satacmd_cmd_reg
,
2228 cmd_slot
, port
, (void *)spkt
);
2230 cmd_table
= ahci_portp
->ahciport_cmd_tables
[cmd_slot
];
2231 bzero((void *)cmd_table
, ahci_cmd_table_size
);
2233 /* For data transfer operations, it is the H2D Register FIS */
2235 &(cmd_table
->ahcict_command_fis
.ahcifc_fis
.ahcifc_h2d_register
);
2237 SET_FIS_TYPE(h2d_register_fisp
, AHCI_H2D_REGISTER_FIS_TYPE
);
2240 * PMP field only make sense when target is a port multiplier or a
2241 * device behind a port multiplier. Otherwise should set it to 0.
2243 if (AHCI_ADDR_IS_PMULT(addrp
) || AHCI_ADDR_IS_PMPORT(addrp
))
2244 SET_FIS_PMP(h2d_register_fisp
, pmport
);
2246 SET_FIS_CDMDEVCTL(h2d_register_fisp
, 1);
2247 SET_FIS_COMMAND(h2d_register_fisp
, scmd
->satacmd_cmd_reg
);
2248 SET_FIS_FEATURES(h2d_register_fisp
, scmd
->satacmd_features_reg
);
2249 SET_FIS_SECTOR_COUNT(h2d_register_fisp
, scmd
->satacmd_sec_count_lsb
);
2251 switch (scmd
->satacmd_addr_type
) {
2255 * satacmd_addr_type will be 0 for the commands below:
2259 * SATAC_DOWNLOAD_MICROCODE
2261 * SATAC_SET_FEATURES
2263 * SATAC_ID_PACKET_DEVICE
2265 * SATAC_READ_PORTMULT
2266 * SATAC_WRITE_PORTMULT
2273 case ATA_ADDR_LBA28
:
2275 SET_FIS_SECTOR(h2d_register_fisp
, scmd
->satacmd_lba_low_lsb
);
2278 SET_FIS_CYL_LOW(h2d_register_fisp
, scmd
->satacmd_lba_mid_lsb
);
2281 SET_FIS_CYL_HI(h2d_register_fisp
, scmd
->satacmd_lba_high_lsb
);
2283 /* LBA [27:24] (also called dev_head) */
2284 SET_FIS_DEV_HEAD(h2d_register_fisp
, scmd
->satacmd_device_reg
);
2288 case ATA_ADDR_LBA48
:
2290 SET_FIS_SECTOR(h2d_register_fisp
, scmd
->satacmd_lba_low_lsb
);
2293 SET_FIS_CYL_LOW(h2d_register_fisp
, scmd
->satacmd_lba_mid_lsb
);
2296 SET_FIS_CYL_HI(h2d_register_fisp
, scmd
->satacmd_lba_high_lsb
);
2299 SET_FIS_SECTOR_EXP(h2d_register_fisp
,
2300 scmd
->satacmd_lba_low_msb
);
2303 SET_FIS_CYL_LOW_EXP(h2d_register_fisp
,
2304 scmd
->satacmd_lba_mid_msb
);
2307 SET_FIS_CYL_HI_EXP(h2d_register_fisp
,
2308 scmd
->satacmd_lba_high_msb
);
2311 SET_FIS_DEV_HEAD(h2d_register_fisp
,
2312 scmd
->satacmd_device_reg
);
2314 /* Set the extended sector count and features */
2315 SET_FIS_SECTOR_COUNT_EXP(h2d_register_fisp
,
2316 scmd
->satacmd_sec_count_msb
);
2317 SET_FIS_FEATURES_EXP(h2d_register_fisp
,
2318 scmd
->satacmd_features_reg_ext
);
2323 * For NCQ command (READ/WRITE FPDMA QUEUED), sector count 7:0 is
2324 * filled into features field, and sector count 8:15 is filled into
2325 * features (exp) field. The hba driver doesn't need to anything
2326 * special with regard to this, since sata framework has already
2329 * However the driver needs to make sure TAG is filled into sector
2332 if (command_type
== AHCI_NCQ_CMD
) {
2333 SET_FIS_SECTOR_COUNT(h2d_register_fisp
,
2334 (cmd_slot
<< SATA_TAG_QUEUING_SHIFT
));
2337 ncookies
= scmd
->satacmd_num_dma_cookies
;
2338 AHCIDBG(AHCIDBG_PRDT
, ahci_ctlp
,
2339 "ncookies = 0x%x, ahci_dma_prdt_number = 0x%x",
2340 ncookies
, ahci_dma_prdt_number
);
2342 ASSERT(ncookies
<= ahci_dma_prdt_number
);
2343 ahci_portp
->ahciport_prd_bytecounts
[cmd_slot
] = 0;
2345 /* *** now fill the scatter gather list ******* */
2346 for (i
= 0; i
< ncookies
; i
++) {
2347 cmd_table
->ahcict_prdt
[i
].ahcipi_data_base_addr
=
2348 scmd
->satacmd_dma_cookie_list
[i
]._dmu
._dmac_la
[0];
2349 cmd_table
->ahcict_prdt
[i
].ahcipi_data_base_addr_upper
=
2350 scmd
->satacmd_dma_cookie_list
[i
]._dmu
._dmac_la
[1];
2351 cmd_table
->ahcict_prdt
[i
].ahcipi_descr_info
=
2352 scmd
->satacmd_dma_cookie_list
[i
].dmac_size
- 1;
2353 ahci_portp
->ahciport_prd_bytecounts
[cmd_slot
] +=
2354 scmd
->satacmd_dma_cookie_list
[i
].dmac_size
;
2357 AHCIDBG(AHCIDBG_PRDT
, ahci_ctlp
,
2358 "ahciport_prd_bytecounts 0x%x for cmd_slot 0x%x",
2359 ahci_portp
->ahciport_prd_bytecounts
[cmd_slot
], cmd_slot
);
2361 /* The ACMD field is filled in for ATAPI command */
2362 if (scmd
->satacmd_cmd_reg
== SATAC_PACKET
) {
2363 bcopy(scmd
->satacmd_acdb
, cmd_table
->ahcict_atapi_cmd
,
2364 SATA_ATAPI_MAX_CDB_LEN
);
2367 /* Set Command Header in Command List */
2368 cmd_header
= &ahci_portp
->ahciport_cmd_list
[cmd_slot
];
2369 BZERO_DESCR_INFO(cmd_header
);
2370 BZERO_PRD_BYTE_COUNT(cmd_header
);
2372 /* Set the number of entries in the PRD table */
2373 SET_PRD_TABLE_LENGTH(cmd_header
, ncookies
);
2375 /* Set the length of the command in the CFIS area */
2376 SET_COMMAND_FIS_LENGTH(cmd_header
, AHCI_H2D_REGISTER_FIS_LENGTH
);
2379 * PMP field only make sense when target is a port multiplier or a
2380 * device behind a port multiplier. Otherwise should set it to 0.
2382 if (AHCI_ADDR_IS_PMULT(addrp
) || AHCI_ADDR_IS_PMPORT(addrp
))
2383 SET_PORT_MULTI_PORT(cmd_header
, pmport
);
2385 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "command data direction is "
2386 "sata_data_direction = 0x%x",
2387 scmd
->satacmd_flags
.sata_data_direction
);
2389 /* Set A bit if it is an ATAPI command */
2390 if (scmd
->satacmd_cmd_reg
== SATAC_PACKET
)
2391 SET_ATAPI(cmd_header
, AHCI_CMDHEAD_ATAPI
);
2393 /* Set W bit if data is going to the device */
2394 if (scmd
->satacmd_flags
.sata_data_direction
== SATA_DIR_WRITE
)
2395 SET_WRITE(cmd_header
, AHCI_CMDHEAD_DATA_WRITE
);
2398 * Set the prefetchable bit - this bit is only valid if the PRDTL
2399 * field is non-zero or the ATAPI 'A' bit is set in the command
2400 * header. This bit cannot be set when using native command
2401 * queuing commands or when using FIS-based switching with a Port
2404 if (command_type
!= AHCI_NCQ_CMD
)
2405 SET_PREFETCHABLE(cmd_header
, AHCI_CMDHEAD_PREFETCHABLE
);
2408 * Now remember the sata packet in ahciport_slot_pkts[].
2409 * Error retrieval command and r/w port multiplier command will
2410 * be stored specifically for each port.
2412 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
) &&
2413 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
))
2414 ahci_portp
->ahciport_slot_pkts
[cmd_slot
] = spkt
;
2417 * Keep the timeout value
2419 ahci_portp
->ahciport_slot_timeout
[cmd_slot
] = spkt
->satapkt_time
;
2422 * If the intial timout is less than 1 tick, then make it longer by
2423 * 1 tick to avoid immediate timeout
2425 if (ahci_portp
->ahciport_slot_timeout
[cmd_slot
] <=
2426 ahci_watchdog_timeout
)
2427 ahci_portp
->ahciport_slot_timeout
[cmd_slot
] +=
2428 ahci_watchdog_timeout
;
2431 if (ahci_debug_flags
& AHCIDBG_ATACMD
&&
2432 scmd
->satacmd_cmd_reg
!= SATAC_PACKET
||
2433 ahci_debug_flags
& AHCIDBG_ATAPICMD
&&
2434 scmd
->satacmd_cmd_reg
== SATAC_PACKET
) {
2436 /* Dump the command header and table */
2437 ahci_log(ahci_ctlp
, CE_WARN
, "\n");
2438 ahci_log(ahci_ctlp
, CE_WARN
, "Command header&table for spkt "
2439 "0x%p cmd_reg 0x%x port %d", spkt
,
2440 scmd
->satacmd_cmd_reg
, port
);
2441 ptr
= (uint32_t *)cmd_header
;
2442 ahci_log(ahci_ctlp
, CE_WARN
,
2443 " Command Header:%8x %8x %8x %8x",
2444 ptr
[0], ptr
[1], ptr
[2], ptr
[3]);
2446 /* Dump the H2D register FIS */
2447 ptr
= (uint32_t *)h2d_register_fisp
;
2448 ahci_log(ahci_ctlp
, CE_WARN
,
2449 " Command FIS: %8x %8x %8x %8x",
2450 ptr
[0], ptr
[1], ptr
[2], ptr
[3]);
2452 /* Dump the ACMD register FIS */
2453 ptr2
= (uint8_t *)&(cmd_table
->ahcict_atapi_cmd
);
2454 for (i
= 0; i
< SATA_ATAPI_MAX_CDB_LEN
/8; i
++)
2455 if (ahci_debug_flags
& AHCIDBG_ATAPICMD
)
2456 ahci_log(ahci_ctlp
, CE_WARN
,
2457 " ATAPI command: %2x %2x %2x %2x "
2459 ptr2
[8 * i
], ptr2
[8 * i
+ 1],
2460 ptr2
[8 * i
+ 2], ptr2
[8 * i
+ 3],
2461 ptr2
[8 * i
+ 4], ptr2
[8 * i
+ 5],
2462 ptr2
[8 * i
+ 6], ptr2
[8 * i
+ 7]);
2465 for (i
= 0; i
< ncookies
; i
++) {
2466 ptr
= (uint32_t *)&(cmd_table
->ahcict_prdt
[i
]);
2467 ahci_log(ahci_ctlp
, CE_WARN
,
2468 " Cookie %d: %8x %8x %8x %8x",
2469 i
, ptr
[0], ptr
[1], ptr
[2], ptr
[3]);
2474 (void) ddi_dma_sync(
2475 ahci_portp
->ahciport_cmd_tables_dma_handle
[cmd_slot
],
2477 ahci_cmd_table_size
,
2478 DDI_DMA_SYNC_FORDEV
);
2480 (void) ddi_dma_sync(ahci_portp
->ahciport_cmd_list_dma_handle
,
2481 cmd_slot
* sizeof (ahci_cmd_header_t
),
2482 sizeof (ahci_cmd_header_t
),
2483 DDI_DMA_SYNC_FORDEV
);
2485 if ((ahci_check_dma_handle(ahci_portp
->
2486 ahciport_cmd_tables_dma_handle
[cmd_slot
]) != DDI_FM_OK
) ||
2487 ahci_check_dma_handle(ahci_portp
->
2488 ahciport_cmd_list_dma_handle
) != DDI_FM_OK
) {
2489 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
2490 DDI_SERVICE_UNAFFECTED
);
2491 return (AHCI_FAILURE
);
2494 /* Set the corresponding bit in the PxSACT.DS for queued command */
2495 if (command_type
== AHCI_NCQ_CMD
) {
2496 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2497 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
),
2501 /* Indicate to the HBA that a command is active. */
2502 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2503 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
),
2506 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "ahci_deliver_satapkt "
2507 "exit: port %d", port
);
2509 /* Make sure the command is started by the PxSACT/PxCI */
2510 if (ahci_check_acc_handle(ahci_ctlp
->
2511 ahcictl_ahci_acc_handle
) != DDI_FM_OK
) {
2512 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
2513 DDI_SERVICE_UNAFFECTED
);
2514 return (AHCI_FAILURE
);
2521 * Called by the sata framework to abort the previously sent packet(s).
2523 * Reset device to abort commands.
2526 ahci_tran_abort(dev_info_t
*dip
, sata_pkt_t
*spkt
, int flag
)
2528 ahci_ctl_t
*ahci_ctlp
;
2529 ahci_port_t
*ahci_portp
;
2530 uint32_t slot_status
= 0;
2531 uint32_t aborted_tags
= 0;
2532 uint32_t finished_tags
= 0;
2533 uint8_t cport
= spkt
->satapkt_device
.satadev_addr
.cport
;
2536 int instance
= ddi_get_instance(dip
);
2538 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
2539 port
= ahci_ctlp
->ahcictl_cport_to_port
[cport
];
2541 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
2542 "ahci_tran_abort enter: port %d", port
);
2544 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
2545 mutex_enter(&ahci_portp
->ahciport_mutex
);
2548 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2549 * commands are being mopped, therefore there is nothing else to do
2551 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
2552 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
2553 "ahci_tran_abort: port %d is in "
2554 "mopping process, so just return directly ", port
);
2555 mutex_exit(&ahci_portp
->ahciport_mutex
);
2556 return (SATA_SUCCESS
);
2560 * If AHCI_PORT_FLAG_RDWR_PMULT flag is set, it means a R/W PMULT
2561 * command is being executed so no other commands is outstanding,
2564 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_RDWR_PMULT
) {
2565 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
2566 "ahci_tran_abort: port %d is reading/writing "
2567 "port multiplier, so just return directly ", port
);
2568 mutex_exit(&ahci_portp
->ahciport_mutex
);
2569 return (SATA_SUCCESS
);
2572 if (ahci_portp
->ahciport_port_state
& SATA_PSTATE_FAILED
|
2573 ahci_portp
->ahciport_port_state
& SATA_PSTATE_SHUTDOWN
|
2574 ahci_portp
->ahciport_port_state
& SATA_PSTATE_PWROFF
) {
2576 * In case the targer driver would send the request before
2577 * sata framework can have the opportunity to process those
2580 spkt
->satapkt_reason
= SATA_PKT_PORT_ERROR
;
2581 spkt
->satapkt_device
.satadev_state
=
2582 ahci_portp
->ahciport_port_state
;
2583 ahci_update_sata_registers(ahci_ctlp
, port
,
2584 &spkt
->satapkt_device
);
2585 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2586 "ahci_tran_abort returning SATA_FAILURE while "
2587 "port in FAILED/SHUTDOWN/PWROFF state: "
2589 mutex_exit(&ahci_portp
->ahciport_mutex
);
2590 return (SATA_FAILURE
);
2593 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
) {
2595 * ahci_intr_phyrdy_change() may have rendered it to
2596 * AHCI_PORT_TYPE_NODEV.
2598 spkt
->satapkt_reason
= SATA_PKT_PORT_ERROR
;
2599 spkt
->satapkt_device
.satadev_type
= SATA_DTYPE_NONE
;
2600 spkt
->satapkt_device
.satadev_state
=
2601 ahci_portp
->ahciport_port_state
;
2602 ahci_update_sata_registers(ahci_ctlp
, port
,
2603 &spkt
->satapkt_device
);
2604 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2605 "ahci_tran_abort returning SATA_FAILURE while "
2606 "no device attached: port: %d", port
);
2607 mutex_exit(&ahci_portp
->ahciport_mutex
);
2608 return (SATA_FAILURE
);
2611 if (flag
== SATA_ABORT_ALL_PACKETS
) {
2612 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
2613 aborted_tags
= ahci_portp
->ahciport_pending_tags
;
2614 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
2615 aborted_tags
= ahci_portp
->ahciport_pending_ncq_tags
;
2617 cmn_err(CE_NOTE
, "!ahci%d: ahci port %d abort all packets",
2620 aborted_tags
= 0xffffffff;
2622 * Aborting one specific packet, first search the
2623 * ahciport_slot_pkts[] list for matching spkt.
2626 tmp_slot
< ahci_ctlp
->ahcictl_num_cmd_slots
; tmp_slot
++) {
2627 if (ahci_portp
->ahciport_slot_pkts
[tmp_slot
] == spkt
) {
2628 aborted_tags
= (0x1 << tmp_slot
);
2633 if (aborted_tags
== 0xffffffff) {
2634 /* request packet is not on the pending list */
2635 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
2636 "Cannot find the aborting pkt 0x%p on the "
2637 "pending list", (void *)spkt
);
2638 ahci_update_sata_registers(ahci_ctlp
, port
,
2639 &spkt
->satapkt_device
);
2640 mutex_exit(&ahci_portp
->ahciport_mutex
);
2641 return (SATA_FAILURE
);
2643 cmn_err(CE_NOTE
, "!ahci%d: ahci port %d abort satapkt 0x%p",
2644 instance
, port
, (void *)spkt
);
2647 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
2648 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2649 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
2650 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
2651 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2652 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
2654 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
2655 ahci_portp
->ahciport_mop_in_progress
++;
2658 * To abort the packet(s), first we are trying to clear PxCMD.ST
2659 * to stop the port, and if the port can be stopped
2660 * successfully with PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0',
2661 * then we just send back the aborted packet(s) with ABORTED flag
2662 * and then restart the port by setting PxCMD.ST and PxCMD.FRE.
2663 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then we
2664 * perform a COMRESET.
2666 (void) ahci_restart_port_wait_till_ready(ahci_ctlp
,
2667 ahci_portp
, port
, NULL
, NULL
);
2670 * Compute which have finished and which need to be retried.
2672 * The finished tags are ahciport_pending_tags/ahciport_pending_ncq_tags
2673 * minus the slot_status. The aborted_tags has to be deducted by
2674 * finished_tags since we can't possibly abort a tag which had finished
2677 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
2678 finished_tags
= ahci_portp
->ahciport_pending_tags
&
2679 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2680 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
2681 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
2682 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2684 aborted_tags
&= ~finished_tags
;
2686 ahci_mop_commands(ahci_ctlp
,
2689 0, /* failed tags */
2690 0, /* timeout tags */
2692 0); /* reset tags */
2694 ahci_update_sata_registers(ahci_ctlp
, port
, &spkt
->satapkt_device
);
2695 mutex_exit(&ahci_portp
->ahciport_mutex
);
2697 return (SATA_SUCCESS
);
2701 * Used to do device reset and reject all the pending packets on a device
2702 * during the reset operation.
2704 * NOTE: ONLY called by ahci_tran_reset_dport
2707 ahci_reset_device_reject_pkts(ahci_ctl_t
*ahci_ctlp
,
2708 ahci_port_t
*ahci_portp
, ahci_addr_t
*addrp
)
2710 uint32_t slot_status
= 0;
2711 uint32_t reset_tags
= 0;
2712 uint32_t finished_tags
= 0;
2713 uint8_t port
= addrp
->aa_port
;
2714 sata_device_t sdevice
;
2717 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
2719 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
2720 "ahci_reset_device_reject_pkts on port: %d", port
);
2723 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2724 * commands are being mopped, therefore there is nothing else to do
2726 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
2727 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2728 "ahci_reset_device_reject_pkts: port %d is in "
2729 "mopping process, so return directly ", port
);
2730 return (SATA_SUCCESS
);
2733 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2734 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2735 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
2736 reset_tags
= slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2737 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2738 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2739 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
2740 reset_tags
= slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2743 if (ahci_software_reset(ahci_ctlp
, ahci_portp
, addrp
)
2745 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2746 "Try to do a port reset after software "
2747 "reset failed", port
);
2748 ret
= ahci_port_reset(ahci_ctlp
, ahci_portp
, addrp
);
2749 if (ret
!= AHCI_SUCCESS
) {
2750 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2751 "ahci_reset_device_reject_pkts: port %d "
2753 return (SATA_FAILURE
);
2756 /* Set the reset in progress flag */
2757 ahci_portp
->ahciport_reset_in_progress
= 1;
2759 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
2760 ahci_portp
->ahciport_mop_in_progress
++;
2762 /* Indicate to the framework that a reset has happened */
2763 bzero((void *)&sdevice
, sizeof (sata_device_t
));
2764 sdevice
.satadev_addr
.cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
2765 sdevice
.satadev_addr
.pmport
= 0;
2766 sdevice
.satadev_addr
.qual
= SATA_ADDR_DCPORT
;
2767 sdevice
.satadev_state
= SATA_DSTATE_RESET
|
2768 SATA_DSTATE_PWR_ACTIVE
;
2769 mutex_exit(&ahci_portp
->ahciport_mutex
);
2770 sata_hba_event_notify(
2771 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
2773 SATA_EVNT_DEVICE_RESET
);
2774 mutex_enter(&ahci_portp
->ahciport_mutex
);
2776 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
2777 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port
);
2779 /* Next try to mop the pending commands */
2780 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
2781 finished_tags
= ahci_portp
->ahciport_pending_tags
&
2782 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2783 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
2784 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
2785 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2787 reset_tags
&= ~finished_tags
;
2789 ahci_mop_commands(ahci_ctlp
,
2792 0, /* failed tags */
2793 0, /* timeout tags */
2794 0, /* aborted tags */
2795 reset_tags
); /* reset tags */
2797 return (SATA_SUCCESS
);
2801 * Used to do device reset and reject all the pending packets on a device
2802 * during the reset operation.
2804 * NOTE: ONLY called by ahci_tran_reset_dport
2807 ahci_reset_pmdevice_reject_pkts(ahci_ctl_t
*ahci_ctlp
,
2808 ahci_port_t
*ahci_portp
, ahci_addr_t
*addrp
)
2810 uint32_t finished_tags
= 0, reset_tags
= 0, slot_status
= 0;
2811 uint8_t port
= addrp
->aa_port
;
2812 uint8_t pmport
= addrp
->aa_pmport
;
2813 sata_device_t sdevice
;
2815 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
2817 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_PMULT
, ahci_ctlp
,
2818 "ahci_reset_pmdevice_reject_pkts at port %d:%d", port
, pmport
);
2820 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
2821 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2822 "ahci_reset_pmdevice_reject_pkts: port %d is in "
2823 "mopping process, so return directly ", port
);
2824 return (SATA_SUCCESS
);
2827 /* Checking for outstanding commands */
2828 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2829 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2830 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
2831 reset_tags
= slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2832 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2833 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2834 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
2835 reset_tags
= slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2838 /* Issue SOFTWARE reset command. */
2839 if (ahci_software_reset(ahci_ctlp
, ahci_portp
, addrp
)
2841 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2842 "Try to do a port reset after software "
2843 "reset failed", port
);
2844 return (SATA_FAILURE
);
2847 /* Set the reset in progress flag */
2848 ahci_portp
->ahciport_reset_in_progress
= 1;
2850 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
2851 ahci_portp
->ahciport_mop_in_progress
++;
2853 /* Indicate to the framework that a reset has happened */
2854 bzero((void *)&sdevice
, sizeof (sata_device_t
));
2855 sdevice
.satadev_addr
.cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
2856 sdevice
.satadev_addr
.pmport
= pmport
;
2857 if (AHCI_ADDR_IS_PMULT(addrp
))
2858 sdevice
.satadev_addr
.qual
= SATA_ADDR_PMULT
;
2860 sdevice
.satadev_addr
.qual
= SATA_ADDR_DPMPORT
;
2861 sdevice
.satadev_state
= SATA_DSTATE_RESET
|
2862 SATA_DSTATE_PWR_ACTIVE
;
2863 mutex_exit(&ahci_portp
->ahciport_mutex
);
2864 sata_hba_event_notify(
2865 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
2867 SATA_EVNT_DEVICE_RESET
);
2868 mutex_enter(&ahci_portp
->ahciport_mutex
);
2870 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
2871 "port %d:%d sending event up: SATA_EVNT_DEVICE_RESET",
2874 /* Next try to mop the pending commands */
2875 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
2876 finished_tags
= ahci_portp
->ahciport_pending_tags
&
2877 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2878 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
2879 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
2880 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2881 reset_tags
&= ~finished_tags
;
2883 AHCIDBG(AHCIDBG_EVENT
|AHCIDBG_PMULT
, ahci_ctlp
,
2884 "reset_tags = %x, finished_tags = %x, slot_status = %x",
2885 reset_tags
, finished_tags
, slot_status
);
2888 * NOTE: Because PxCI be only erased by unset PxCMD.ST bit, so even we
2889 * try to reset a single device behind a port multiplier will
2890 * terminate all the commands on that HBA port. We need mop these
2893 ahci_mop_commands(ahci_ctlp
,
2896 0, /* failed tags */
2897 0, /* timeout tags */
2898 0, /* aborted tags */
2899 reset_tags
); /* reset tags */
2901 return (SATA_SUCCESS
);
2905 * Used to do port reset and reject all the pending packets on a port during
2906 * the reset operation.
2909 ahci_reset_port_reject_pkts(ahci_ctl_t
*ahci_ctlp
,
2910 ahci_port_t
*ahci_portp
, ahci_addr_t
*addrp
)
2912 uint32_t slot_status
= 0;
2913 uint32_t reset_tags
= 0;
2914 uint32_t finished_tags
= 0;
2915 uint8_t port
= addrp
->aa_port
;
2917 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
2919 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
2920 "ahci_reset_port_reject_pkts at port: %d", port
);
2923 * If AHCI_PORT_FLAG_MOPPING flag is set, it means all the pending
2924 * commands are being mopped, therefore there is nothing else to do
2926 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
2927 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
2928 "ahci_reset_port_reject_pkts: port %d is in "
2929 "mopping process, so return directly ", port
);
2930 return (SATA_SUCCESS
);
2933 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
2934 ahci_portp
->ahciport_mop_in_progress
++;
2936 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2937 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2938 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
2939 reset_tags
= slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2940 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
2941 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
2942 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
2943 reset_tags
= slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2946 if (ahci_restart_port_wait_till_ready(ahci_ctlp
,
2947 ahci_portp
, port
, AHCI_PORT_RESET
|AHCI_RESET_NO_EVENTS_UP
,
2948 NULL
) != AHCI_SUCCESS
) {
2950 /* Clear mop flag */
2951 ahci_portp
->ahciport_mop_in_progress
--;
2952 if (ahci_portp
->ahciport_mop_in_progress
== 0)
2953 ahci_portp
->ahciport_flags
&=
2954 ~AHCI_PORT_FLAG_MOPPING
;
2955 return (SATA_FAILURE
);
2958 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
2959 finished_tags
= ahci_portp
->ahciport_pending_tags
&
2960 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
2961 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
2962 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
2963 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
2965 reset_tags
&= ~finished_tags
;
2967 ahci_mop_commands(ahci_ctlp
,
2970 0, /* failed tags */
2971 0, /* timeout tags */
2972 0, /* aborted tags */
2973 reset_tags
); /* reset tags */
2975 return (SATA_SUCCESS
);
2979 * Used to do hba reset and reject all the pending packets on all ports
2980 * during the reset operation.
2983 ahci_reset_hba_reject_pkts(ahci_ctl_t
*ahci_ctlp
)
2985 ahci_port_t
*ahci_portp
;
2986 uint32_t slot_status
[AHCI_MAX_PORTS
];
2987 uint32_t reset_tags
[AHCI_MAX_PORTS
];
2988 uint32_t finished_tags
[AHCI_MAX_PORTS
];
2990 int ret
= SATA_SUCCESS
;
2992 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
2993 "ahci_reset_hba_reject_pkts enter", NULL
);
2995 bzero(slot_status
, sizeof (slot_status
));
2996 bzero(reset_tags
, sizeof (reset_tags
));
2997 bzero(finished_tags
, sizeof (finished_tags
));
2999 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3000 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3004 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3006 mutex_enter(&ahci_portp
->ahciport_mutex
);
3007 ahci_portp
->ahciport_reset_in_progress
= 1;
3008 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
3009 slot_status
[port
] = ddi_get32(
3010 ahci_ctlp
->ahcictl_ahci_acc_handle
,
3011 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
3012 reset_tags
[port
] = slot_status
[port
] &
3013 AHCI_SLOT_MASK(ahci_ctlp
);
3014 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
3015 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3016 port
, reset_tags
[port
],
3017 ahci_portp
->ahciport_pending_tags
);
3018 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
3019 slot_status
[port
] = ddi_get32(
3020 ahci_ctlp
->ahcictl_ahci_acc_handle
,
3021 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
3022 reset_tags
[port
] = slot_status
[port
] &
3023 AHCI_NCQ_SLOT_MASK(ahci_portp
);
3024 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
3025 "port %d: reset_tags = 0x%x pending_tags = 0x%x",
3026 port
, reset_tags
[port
],
3027 ahci_portp
->ahciport_pending_tags
);
3029 mutex_exit(&ahci_portp
->ahciport_mutex
);
3032 if (ahci_hba_reset(ahci_ctlp
) != AHCI_SUCCESS
) {
3036 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3037 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3041 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3043 mutex_enter(&ahci_portp
->ahciport_mutex
);
3045 * To prevent recursive enter to ahci_mop_commands, we need
3046 * check AHCI_PORT_FLAG_MOPPING flag.
3048 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
3049 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
3050 "ahci_reset_hba_reject_pkts: port %d is in "
3051 "mopping process, so return directly ", port
);
3052 mutex_exit(&ahci_portp
->ahciport_mutex
);
3056 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
3057 ahci_portp
->ahciport_mop_in_progress
++;
3059 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
3060 finished_tags
[port
] =
3061 ahci_portp
->ahciport_pending_tags
&
3062 ~slot_status
[port
] & AHCI_SLOT_MASK(ahci_ctlp
);
3063 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
3064 finished_tags
[port
] =
3065 ahci_portp
->ahciport_pending_ncq_tags
&
3066 ~slot_status
[port
] & AHCI_NCQ_SLOT_MASK(ahci_portp
);
3068 reset_tags
[port
] &= ~finished_tags
[port
];
3070 ahci_mop_commands(ahci_ctlp
,
3073 0, /* failed tags */
3074 0, /* timeout tags */
3075 0, /* aborted tags */
3076 reset_tags
[port
]); /* reset tags */
3077 mutex_exit(&ahci_portp
->ahciport_mutex
);
3084 * Called by sata framework to reset a port(s) or device.
3087 ahci_tran_reset_dport(dev_info_t
*dip
, sata_device_t
*sd
)
3089 ahci_ctl_t
*ahci_ctlp
;
3090 ahci_port_t
*ahci_portp
;
3092 uint8_t cport
= sd
->satadev_addr
.cport
;
3093 uint8_t pmport
= sd
->satadev_addr
.pmport
;
3095 int ret
= SATA_SUCCESS
;
3096 int instance
= ddi_get_instance(dip
);
3098 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
3099 port
= ahci_ctlp
->ahcictl_cport_to_port
[cport
];
3100 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3102 ahci_get_ahci_addr(ahci_ctlp
, sd
, &addr
);
3104 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
3105 "ahci_tran_reset_dport enter: cport %d", cport
);
3107 switch (sd
->satadev_addr
.qual
) {
3108 case SATA_ADDR_PMPORT
:
3110 * If we want to issue a COMRESET on a pmport, we need to
3111 * reject the outstanding commands on that pmport. According
3112 * to AHCI spec, PxCI register could only be cleared by
3113 * clearing PxCMD.ST, which will halt the controller port - as
3114 * well as other pmports.
3116 * Therefore we directly reset the controller port for
3117 * simplicity. ahci_tran_probe_port() will handle reset stuff
3118 * like initializing the given pmport.
3121 case SATA_ADDR_CPORT
:
3123 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3124 cmn_err(CE_NOTE
, "!ahci%d: ahci_tran_reset_dport "
3125 "port %d reset port", instance
, port
);
3127 mutex_enter(&ahci_portp
->ahciport_mutex
);
3128 ret
= ahci_reset_port_reject_pkts(ahci_ctlp
, ahci_portp
, &addr
);
3129 mutex_exit(&ahci_portp
->ahciport_mutex
);
3133 case SATA_ADDR_DPMPORT
:
3134 cmn_err(CE_NOTE
, "!ahci%d: ahci_tran_reset_dport "
3135 "port %d:%d reset device", instance
, port
, pmport
);
3137 case SATA_ADDR_DCPORT
:
3139 if (sd
->satadev_addr
.qual
== SATA_ADDR_DCPORT
)
3140 cmn_err(CE_NOTE
, "!ahci%d: ahci_tran_reset_dport "
3141 "port %d reset device", instance
, port
);
3143 mutex_enter(&ahci_portp
->ahciport_mutex
);
3145 * software reset request must be sent to SATA_PMULT_HOSTPORT
3146 * if target is a port multiplier:
3148 if (sd
->satadev_addr
.qual
== SATA_ADDR_DCPORT
&&
3149 ahci_portp
->ahciport_device_type
== SATA_DTYPE_PMULT
)
3150 AHCI_ADDR_SET_PMULT(&addr
, port
);
3152 if (ahci_portp
->ahciport_port_state
& SATA_PSTATE_FAILED
|
3153 ahci_portp
->ahciport_port_state
& SATA_PSTATE_SHUTDOWN
|
3154 ahci_portp
->ahciport_port_state
& SATA_PSTATE_PWROFF
) {
3156 * In case the targer driver would send the request
3157 * before sata framework can have the opportunity to
3158 * process those event reports.
3160 sd
->satadev_state
= ahci_portp
->ahciport_port_state
;
3161 ahci_update_sata_registers(ahci_ctlp
, port
, sd
);
3162 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
3163 "ahci_tran_reset_dport returning SATA_FAILURE "
3164 "while port in FAILED/SHUTDOWN/PWROFF state: "
3166 mutex_exit(&ahci_portp
->ahciport_mutex
);
3171 if (AHCIPORT_GET_DEV_TYPE(ahci_portp
, &addr
) ==
3174 * ahci_intr_phyrdy_change() may have rendered it to
3175 * AHCI_PORT_TYPE_NODEV.
3177 sd
->satadev_type
= SATA_DTYPE_NONE
;
3178 sd
->satadev_state
= AHCIPORT_GET_STATE(ahci_portp
,
3180 ahci_update_sata_registers(ahci_ctlp
, port
, sd
);
3181 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
3182 "ahci_tran_reset_dport returning SATA_FAILURE "
3183 "while no device attached: port: %d", port
);
3184 mutex_exit(&ahci_portp
->ahciport_mutex
);
3189 if (AHCI_ADDR_IS_PORT(&addr
)) {
3190 ret
= ahci_reset_device_reject_pkts(ahci_ctlp
,
3193 ret
= ahci_reset_pmdevice_reject_pkts(ahci_ctlp
,
3197 mutex_exit(&ahci_portp
->ahciport_mutex
);
3200 case SATA_ADDR_CNTRL
:
3201 /* Reset the whole controller */
3202 cmn_err(CE_NOTE
, "!ahci%d: ahci_tran_reset_dport "
3203 "reset the whole hba", instance
);
3204 ret
= ahci_reset_hba_reject_pkts(ahci_ctlp
);
3215 * Called by sata framework to activate a port as part of hotplug.
3216 * (cfgadm -c connect satax/y)
3217 * Support port multiplier.
3220 ahci_tran_hotplug_port_activate(dev_info_t
*dip
, sata_device_t
*satadev
)
3222 ahci_ctl_t
*ahci_ctlp
;
3223 ahci_port_t
*ahci_portp
;
3225 uint8_t cport
= satadev
->satadev_addr
.cport
;
3226 uint8_t pmport
= satadev
->satadev_addr
.pmport
;
3228 int instance
= ddi_get_instance(dip
);
3230 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
3231 port
= ahci_ctlp
->ahcictl_cport_to_port
[cport
];
3233 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
3234 "ahci_tran_hotplug_port_activate enter: cport %d", cport
);
3236 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3238 mutex_enter(&ahci_portp
->ahciport_mutex
);
3239 ahci_get_ahci_addr(ahci_ctlp
, satadev
, &addr
);
3240 ASSERT(AHCI_ADDR_IS_PORT(&addr
) || AHCI_ADDR_IS_PMPORT(&addr
));
3242 if (AHCI_ADDR_IS_PORT(&addr
)) {
3243 cmn_err(CE_NOTE
, "!ahci%d: ahci port %d is activated",
3246 /* Enable the interrupts on the port */
3247 ahci_enable_port_intrs(ahci_ctlp
, port
);
3250 * Reset the port so that the PHY communication would be
3251 * re-established. But this reset is an internal operation
3252 * and the sata module doesn't need to know about it.
3253 * Moreover, the port with a device attached will be started
3256 (void) ahci_restart_port_wait_till_ready(ahci_ctlp
,
3258 AHCI_PORT_RESET
|AHCI_RESET_NO_EVENTS_UP
,
3262 * Need to check the link status and device status of the port
3263 * and consider raising power if the port was in D3 state
3265 ahci_portp
->ahciport_port_state
|= SATA_PSTATE_PWRON
;
3266 ahci_portp
->ahciport_port_state
&= ~SATA_PSTATE_PWROFF
;
3267 ahci_portp
->ahciport_port_state
&= ~SATA_PSTATE_SHUTDOWN
;
3268 } else if (AHCI_ADDR_IS_PMPORT(&addr
)) {
3269 cmn_err(CE_NOTE
, "!ahci%d: ahci port %d:%d is activated",
3270 instance
, port
, pmport
);
3271 /* AHCI_ADDR_PMPORT */
3272 AHCIPORT_PMSTATE(ahci_portp
, &addr
) |= SATA_PSTATE_PWRON
;
3273 AHCIPORT_PMSTATE(ahci_portp
, &addr
) &=
3274 ~(SATA_PSTATE_PWROFF
|SATA_PSTATE_SHUTDOWN
);
3277 satadev
->satadev_state
= ahci_portp
->ahciport_port_state
;
3279 ahci_update_sata_registers(ahci_ctlp
, port
, satadev
);
3281 mutex_exit(&ahci_portp
->ahciport_mutex
);
3282 return (SATA_SUCCESS
);
3286 * Called by sata framework to deactivate a port as part of hotplug.
3287 * (cfgadm -c disconnect satax/y)
3288 * Support port multiplier.
3291 ahci_tran_hotplug_port_deactivate(dev_info_t
*dip
, sata_device_t
*satadev
)
3293 ahci_ctl_t
*ahci_ctlp
;
3294 ahci_port_t
*ahci_portp
;
3296 uint8_t cport
= satadev
->satadev_addr
.cport
;
3297 uint8_t pmport
= satadev
->satadev_addr
.pmport
;
3299 uint32_t port_scontrol
;
3300 int instance
= ddi_get_instance(dip
);
3302 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
3303 port
= ahci_ctlp
->ahcictl_cport_to_port
[cport
];
3305 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
3306 "ahci_tran_hotplug_port_deactivate enter: cport %d", cport
);
3308 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3309 mutex_enter(&ahci_portp
->ahciport_mutex
);
3310 ahci_get_ahci_addr(ahci_ctlp
, satadev
, &addr
);
3311 ASSERT(AHCI_ADDR_IS_PORT(&addr
) || AHCI_ADDR_IS_PMPORT(&addr
));
3313 if (AHCI_ADDR_IS_PORT(&addr
)) {
3314 cmn_err(CE_NOTE
, "!ahci%d: ahci port %d is deactivated",
3317 /* Disable the interrupts on the port */
3318 ahci_disable_port_intrs(ahci_ctlp
, port
);
3320 if (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_NONE
) {
3322 /* First to abort all the pending commands */
3323 ahci_reject_all_abort_pkts(ahci_ctlp
, ahci_portp
, port
);
3325 /* Then stop the port */
3326 (void) ahci_put_port_into_notrunning_state(ahci_ctlp
,
3330 /* Next put the PHY offline */
3331 port_scontrol
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3332 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
));
3333 SCONTROL_SET_DET(port_scontrol
, SCONTROL_DET_DISABLE
);
3334 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
, (uint32_t *)
3335 AHCI_PORT_PxSCTL(ahci_ctlp
, port
), port_scontrol
);
3336 } else if (AHCI_ADDR_IS_PMPORT(&addr
)) {
3337 cmn_err(CE_NOTE
, "!ahci%d: ahci port %d:%d is deactivated",
3338 instance
, port
, pmport
);
3340 ahci_disable_port_intrs(ahci_ctlp
, port
);
3341 if (AHCIPORT_GET_DEV_TYPE(ahci_portp
, &addr
)
3343 ahci_reject_all_abort_pkts(ahci_ctlp
, ahci_portp
, port
);
3345 /* Re-enable the interrupts for the other pmports */
3346 ahci_enable_port_intrs(ahci_ctlp
, port
);
3349 /* Update port state */
3350 AHCIPORT_SET_STATE(ahci_portp
, &addr
, SATA_PSTATE_SHUTDOWN
);
3351 satadev
->satadev_state
= SATA_PSTATE_SHUTDOWN
;
3353 ahci_update_sata_registers(ahci_ctlp
, port
, satadev
);
3355 mutex_exit(&ahci_portp
->ahciport_mutex
);
3356 return (SATA_SUCCESS
);
3360 * To be used to mark all the outstanding pkts with SATA_PKT_ABORTED
3361 * when a device is unplugged or a port is deactivated.
3364 ahci_reject_all_abort_pkts(ahci_ctl_t
*ahci_ctlp
,
3365 ahci_port_t
*ahci_portp
, uint8_t port
)
3367 uint32_t slot_status
= 0;
3368 uint32_t abort_tags
= 0;
3370 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
3372 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
, ahci_ctlp
,
3373 "ahci_reject_all_abort_pkts at port: %d", port
);
3375 /* Read/write port multiplier command takes highest priority */
3376 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
3383 * When AHCI_PORT_FLAG_MOPPING is set, we need to check whether a
3384 * REQUEST SENSE command or READ LOG EXT command is delivered to HBA
3385 * to get the error data, if yes when the device is removed, the
3386 * command needs to be aborted too.
3388 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) {
3389 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
3394 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
3395 "ahci_reject_all_abort_pkts return directly "
3396 "port %d no needs to reject any outstanding "
3402 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
3403 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3404 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
3405 abort_tags
= slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
3406 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
3407 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3408 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
3409 abort_tags
= slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
3413 /* No need to do mop when there is no outstanding commands */
3414 if (slot_status
!= 0) {
3415 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
3416 ahci_portp
->ahciport_mop_in_progress
++;
3418 ahci_mop_commands(ahci_ctlp
,
3421 0, /* failed tags */
3422 0, /* timeout tags */
3423 abort_tags
, /* aborting tags */
3424 0); /* reset tags */
3428 #if defined(__lock_lint)
3430 ahci_selftest(dev_info_t
*dip
, sata_device_t
*device
)
3432 return (SATA_SUCCESS
);
3437 * Initialize fma capabilities and register with IO fault services.
3440 ahci_fm_init(ahci_ctl_t
*ahci_ctlp
)
3443 * Need to change iblock to priority for new MSI intr
3445 ddi_iblock_cookie_t fm_ibc
;
3447 ahci_ctlp
->ahcictl_fm_cap
= ddi_getprop(DDI_DEV_T_ANY
,
3448 ahci_ctlp
->ahcictl_dip
,
3449 DDI_PROP_CANSLEEP
| DDI_PROP_DONTPASS
, "fm-capable",
3450 DDI_FM_EREPORT_CAPABLE
| DDI_FM_ACCCHK_CAPABLE
|
3451 DDI_FM_DMACHK_CAPABLE
| DDI_FM_ERRCB_CAPABLE
);
3453 /* Only register with IO Fault Services if we have some capability */
3454 if (ahci_ctlp
->ahcictl_fm_cap
) {
3455 /* Adjust access and dma attributes for FMA */
3456 accattr
.devacc_attr_access
= DDI_FLAGERR_ACC
;
3457 buffer_dma_attr
.dma_attr_flags
|= DDI_DMA_FLAGERR
;
3458 rcvd_fis_dma_attr
.dma_attr_flags
|= DDI_DMA_FLAGERR
;
3459 cmd_list_dma_attr
.dma_attr_flags
|= DDI_DMA_FLAGERR
;
3460 cmd_table_dma_attr
.dma_attr_flags
|= DDI_DMA_FLAGERR
;
3463 * Register capabilities with IO Fault Services.
3464 * ahcictl_fm_cap will be updated to indicate
3465 * capabilities actually supported (not requested.)
3467 ddi_fm_init(ahci_ctlp
->ahcictl_dip
,
3468 &ahci_ctlp
->ahcictl_fm_cap
, &fm_ibc
);
3470 if (ahci_ctlp
->ahcictl_fm_cap
== DDI_FM_NOT_CAPABLE
) {
3471 cmn_err(CE_WARN
, "!ahci%d: fma init failed.",
3472 ddi_get_instance(ahci_ctlp
->ahcictl_dip
));
3476 * Initialize pci ereport capabilities if ereport
3477 * capable (should always be.)
3479 if (DDI_FM_EREPORT_CAP(ahci_ctlp
->ahcictl_fm_cap
) ||
3480 DDI_FM_ERRCB_CAP(ahci_ctlp
->ahcictl_fm_cap
)) {
3481 pci_ereport_setup(ahci_ctlp
->ahcictl_dip
);
3485 * Register error callback if error callback capable.
3487 if (DDI_FM_ERRCB_CAP(ahci_ctlp
->ahcictl_fm_cap
)) {
3488 ddi_fm_handler_register(ahci_ctlp
->ahcictl_dip
,
3489 ahci_fm_error_cb
, (void *) ahci_ctlp
);
3492 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
3493 "ahci_fm_fini: fma enabled.", NULL
);
3498 * Releases fma capabilities and un-registers with IO fault services.
3501 ahci_fm_fini(ahci_ctl_t
*ahci_ctlp
)
3503 /* Only unregister FMA capabilities if registered */
3504 if (ahci_ctlp
->ahcictl_fm_cap
) {
3506 * Un-register error callback if error callback capable.
3508 if (DDI_FM_ERRCB_CAP(ahci_ctlp
->ahcictl_fm_cap
)) {
3509 ddi_fm_handler_unregister(ahci_ctlp
->ahcictl_dip
);
3513 * Release any resources allocated by pci_ereport_setup()
3515 if (DDI_FM_EREPORT_CAP(ahci_ctlp
->ahcictl_fm_cap
) ||
3516 DDI_FM_ERRCB_CAP(ahci_ctlp
->ahcictl_fm_cap
)) {
3517 pci_ereport_teardown(ahci_ctlp
->ahcictl_dip
);
3520 /* Unregister from IO Fault Services */
3521 ddi_fm_fini(ahci_ctlp
->ahcictl_dip
);
3523 /* Adjust access and dma attributes for FMA */
3524 accattr
.devacc_attr_access
= DDI_DEFAULT_ACC
;
3525 buffer_dma_attr
.dma_attr_flags
&= ~DDI_DMA_FLAGERR
;
3526 rcvd_fis_dma_attr
.dma_attr_flags
&= ~DDI_DMA_FLAGERR
;
3527 cmd_list_dma_attr
.dma_attr_flags
&= ~DDI_DMA_FLAGERR
;
3528 cmd_table_dma_attr
.dma_attr_flags
&= ~DDI_DMA_FLAGERR
;
3530 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
3531 "ahci_fm_fini: fma disabled.", NULL
);
3537 ahci_fm_error_cb(dev_info_t
*dip
, ddi_fm_error_t
*err
, const void *impl_data
)
3540 * as the driver can always deal with an error in any dma or
3541 * access handle, we can just return the fme_status value.
3543 pci_ereport_post(dip
, err
, NULL
);
3544 return (err
->fme_status
);
3548 ahci_check_acc_handle(ddi_acc_handle_t handle
)
3552 ddi_fm_acc_err_get(handle
, &de
, DDI_FME_VERSION
);
3553 return (de
.fme_status
);
3557 ahci_check_dma_handle(ddi_dma_handle_t handle
)
3561 ddi_fm_dma_err_get(handle
, &de
, DDI_FME_VERSION
);
3562 return (de
.fme_status
);
3566 * Generate an ereport
3569 ahci_fm_ereport(ahci_ctl_t
*ahci_ctlp
, char *detail
)
3572 char buf
[FM_MAX_CLASS
];
3574 (void) snprintf(buf
, FM_MAX_CLASS
, "%s.%s", DDI_FM_DEVICE
, detail
);
3575 ena
= fm_ena_generate(0, FM_ENA_FMT1
);
3576 if (DDI_FM_EREPORT_CAP(ahci_ctlp
->ahcictl_fm_cap
)) {
3577 ddi_fm_ereport_post(ahci_ctlp
->ahcictl_dip
, buf
, ena
,
3578 DDI_NOSLEEP
, FM_VERSION
, DATA_TYPE_UINT8
,
3579 FM_EREPORT_VERSION
, NULL
);
3584 * Check if all handles are correctly allocated.
3587 ahci_check_all_handle(ahci_ctl_t
*ahci_ctlp
)
3591 if (ahci_check_ctl_handle(ahci_ctlp
) != DDI_SUCCESS
) {
3592 return (DDI_FAILURE
);
3595 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3596 ahci_port_t
*ahci_portp
;
3598 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
))
3601 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3603 mutex_enter(&ahci_portp
->ahciport_mutex
);
3604 if (ahci_check_port_handle(ahci_ctlp
, port
) != DDI_SUCCESS
) {
3605 mutex_exit(&ahci_portp
->ahciport_mutex
);
3606 return (DDI_FAILURE
);
3608 mutex_exit(&ahci_portp
->ahciport_mutex
);
3611 return (DDI_SUCCESS
);
3615 * Check the access handles for the controller. Note that
3616 * ahcictl_pci_conf_handle is only used in attach process.
3619 ahci_check_ctl_handle(ahci_ctl_t
*ahci_ctlp
)
3621 if ((ahci_check_acc_handle(ahci_ctlp
->
3622 ahcictl_pci_conf_handle
) != DDI_FM_OK
) ||
3623 (ahci_check_acc_handle(ahci_ctlp
->
3624 ahcictl_ahci_acc_handle
) != DDI_FM_OK
)) {
3625 return (DDI_FAILURE
);
3627 return (DDI_SUCCESS
);
3631 * Check the DMA handles and the access handles of a controller port.
3634 ahci_check_port_handle(ahci_ctl_t
*ahci_ctlp
, int port
)
3636 ahci_port_t
*ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3639 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
3641 if ((ahci_check_dma_handle(ahci_portp
->
3642 ahciport_rcvd_fis_dma_handle
) != DDI_FM_OK
) ||
3643 (ahci_check_dma_handle(ahci_portp
->
3644 ahciport_cmd_list_dma_handle
) != DDI_FM_OK
) ||
3645 (ahci_check_acc_handle(ahci_portp
->
3646 ahciport_rcvd_fis_acc_handle
) != DDI_FM_OK
) ||
3647 (ahci_check_acc_handle(ahci_portp
->
3648 ahciport_cmd_list_acc_handle
) != DDI_FM_OK
)) {
3649 return (DDI_FAILURE
);
3651 for (slot
= 0; slot
< ahci_ctlp
->ahcictl_num_cmd_slots
; slot
++) {
3652 if (ahci_check_slot_handle(ahci_portp
, slot
)
3654 return (DDI_FAILURE
);
3657 return (DDI_SUCCESS
);
3661 * Check the DMA handles and the access handles of a cmd table slot.
3664 ahci_check_slot_handle(ahci_port_t
*ahci_portp
, int slot
)
3666 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
3668 if ((ahci_check_acc_handle(ahci_portp
->
3669 ahciport_cmd_tables_acc_handle
[slot
]) != DDI_FM_OK
) ||
3670 (ahci_check_dma_handle(ahci_portp
->
3671 ahciport_cmd_tables_dma_handle
[slot
]) != DDI_FM_OK
)) {
3672 return (DDI_FAILURE
);
3674 return (DDI_SUCCESS
);
3678 * Allocate the ports structure, only called by ahci_attach
3681 ahci_alloc_ports_state(ahci_ctl_t
*ahci_ctlp
)
3683 int port
, cport
= 0;
3685 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
3686 "ahci_alloc_ports_state enter", NULL
);
3688 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
3690 /* Allocate structures only for the implemented ports */
3691 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3692 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3693 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
3694 "hba port %d not implemented", port
);
3698 ahci_ctlp
->ahcictl_cport_to_port
[cport
] = (uint8_t)port
;
3699 ahci_ctlp
->ahcictl_port_to_cport
[port
] =
3702 if (ahci_alloc_port_state(ahci_ctlp
, port
) != AHCI_SUCCESS
) {
3707 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
3708 return (AHCI_SUCCESS
);
3711 for (port
--; port
>= 0; port
--) {
3712 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3713 ahci_dealloc_port_state(ahci_ctlp
, port
);
3717 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
3718 return (AHCI_FAILURE
);
3722 * Reverse of ahci_alloc_ports_state(), only called by ahci_detach
3725 ahci_dealloc_ports_state(ahci_ctl_t
*ahci_ctlp
)
3729 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
3730 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3731 /* if this port is implemented by the HBA */
3732 if (AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
))
3733 ahci_dealloc_port_state(ahci_ctlp
, port
);
3735 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
3742 ahci_drain_ports_taskq(ahci_ctl_t
*ahci_ctlp
)
3744 ahci_port_t
*ahci_portp
;
3747 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3748 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3752 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3754 mutex_enter(&ahci_portp
->ahciport_mutex
);
3755 ddi_taskq_wait(ahci_portp
->ahciport_event_taskq
);
3756 mutex_exit(&ahci_portp
->ahciport_mutex
);
3761 * Initialize the controller and all ports. And then try to start the ports
3762 * if there are devices attached.
3764 * This routine can be called from three seperate cases: DDI_ATTACH,
3765 * PM_LEVEL_D0 and DDI_RESUME. The DDI_ATTACH case is different from
3766 * other two cases; device signature probing are attempted only during
3770 ahci_initialize_controller(ahci_ctl_t
*ahci_ctlp
)
3772 ahci_port_t
*ahci_portp
;
3776 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
3777 "ahci_initialize_controller enter", NULL
);
3779 /* Disable the whole controller interrupts */
3780 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
3781 ahci_disable_all_intrs(ahci_ctlp
);
3782 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
3784 /* Initialize the implemented ports and structures */
3785 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3786 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3790 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3791 mutex_enter(&ahci_portp
->ahciport_mutex
);
3794 * Ensure that the controller is not in the running state
3795 * by checking every implemented port's PxCMD register
3797 AHCI_ADDR_SET_PORT(&addr
, (uint8_t)port
);
3799 if (ahci_initialize_port(ahci_ctlp
, ahci_portp
, &addr
)
3801 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
3802 "ahci_initialize_controller: failed to "
3803 "initialize port %d", port
);
3805 * Set the port state to SATA_PSTATE_FAILED if
3806 * failed to initialize it.
3808 ahci_portp
->ahciport_port_state
= SATA_PSTATE_FAILED
;
3811 mutex_exit(&ahci_portp
->ahciport_mutex
);
3814 /* Enable the whole controller interrupts */
3815 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
3816 ahci_enable_all_intrs(ahci_ctlp
);
3817 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
3819 return (AHCI_SUCCESS
);
3823 * Reverse of ahci_initialize_controller()
3825 * We only need to stop the ports and disable the interrupt.
3828 ahci_uninitialize_controller(ahci_ctl_t
*ahci_ctlp
)
3830 ahci_port_t
*ahci_portp
;
3833 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
3834 "ahci_uninitialize_controller enter", NULL
);
3836 /* disable all the interrupts. */
3837 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
3838 ahci_disable_all_intrs(ahci_ctlp
);
3839 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
3841 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
3842 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
3846 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
3848 /* Stop the port by clearing PxCMD.ST */
3849 mutex_enter(&ahci_portp
->ahciport_mutex
);
3852 * Here we must disable the port interrupt because
3853 * ahci_disable_all_intrs only clear GHC.IE, and IS
3854 * register will be still set if PxIE is enabled.
3855 * When ahci shares one IRQ with other drivers, the
3856 * intr handler may claim the intr mistakenly.
3858 ahci_disable_port_intrs(ahci_ctlp
, port
);
3859 (void) ahci_put_port_into_notrunning_state(ahci_ctlp
,
3861 mutex_exit(&ahci_portp
->ahciport_mutex
);
3866 * ahci_alloc_pmult()
3867 * 1. Setting HBA port registers which are necessary for a port multiplier.
3868 * (Set PxCMD.PMA while PxCMD.ST is '0')
3869 * 2. Allocate ahci_pmult_info structure.
3871 * NOTE: Must stop port before the function is called.
3874 ahci_alloc_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
3876 uint32_t port_cmd_status
;
3877 uint8_t port
= ahci_portp
->ahciport_port_num
;
3879 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
3881 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3882 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
3884 /* The port must have been stopped before. */
3885 ASSERT(!(port_cmd_status
& AHCI_CMD_STATUS_ST
));
3887 if (!(port_cmd_status
& AHCI_CMD_STATUS_PMA
)) {
3889 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3890 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
3891 port_cmd_status
|AHCI_CMD_STATUS_PMA
);
3893 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_PMULT
, ahci_ctlp
,
3894 "ahci_alloc_pmult: "
3895 "PxCMD.PMA bit set at port %d.", port
);
3898 /* Allocate port multiplier information structure */
3899 if (ahci_portp
->ahciport_pmult_info
== NULL
) {
3900 ahci_portp
->ahciport_pmult_info
= (ahci_pmult_info_t
*)
3901 kmem_zalloc(sizeof (ahci_pmult_info_t
), KM_SLEEP
);
3904 ASSERT(ahci_portp
->ahciport_pmult_info
!= NULL
);
3908 * ahci_dealloc_pmult()
3909 * 1. Clearing related registers when a port multiplier is detached.
3910 * (Clear PxCMD.PMA while PxCMD.ST is '0')
3911 * 2. Deallocate ahci_pmult_info structure.
3913 * NOTE: Must stop port before the function is called.
3916 ahci_dealloc_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
3918 uint32_t port_cmd_status
;
3919 uint8_t port
= ahci_portp
->ahciport_port_num
;
3921 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
3923 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3924 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
3926 if (port_cmd_status
& AHCI_CMD_STATUS_PMA
) {
3928 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3929 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
3930 (port_cmd_status
& (~AHCI_CMD_STATUS_PMA
)));
3932 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_PMULT
, ahci_ctlp
,
3933 "ahci_dealloc_pmult: "
3934 "PxCMD.PMA bit cleared at port %d.", port
);
3937 /* Release port multiplier information structure */
3938 if (ahci_portp
->ahciport_pmult_info
!= NULL
) {
3939 kmem_free(ahci_portp
->ahciport_pmult_info
,
3940 sizeof (ahci_pmult_info_t
));
3941 ahci_portp
->ahciport_pmult_info
= NULL
;
3946 * Staggered Spin-up.
3949 ahci_staggered_spin_up(ahci_ctl_t
*ahci_ctlp
, uint8_t port
)
3951 uint32_t cap_status
;
3952 uint32_t port_cmd_status
;
3954 ASSERT(MUTEX_HELD(&ahci_ctlp
->ahcictl_ports
[port
]->ahciport_mutex
));
3956 cap_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3957 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp
));
3959 /* Check for staggered spin-up support */
3960 if (!(cap_status
& AHCI_HBA_CAP_SSS
))
3963 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3964 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
3966 /* If PxCMD.SUD == 1, no staggered spin-up is needed */
3967 if (port_cmd_status
& AHCI_CMD_STATUS_SUD
)
3970 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "Spin-up at port %d", port
);
3973 port_cmd_status
|= AHCI_CMD_STATUS_SUD
;
3974 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
3975 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
3980 * The routine is to initialize a port. First put the port in NotRunning
3981 * state, then enable port interrupt and clear Serror register. And under
3982 * AHCI_ATTACH case, find device signature and then try to start the port.
3985 * 1. ahci_initialize_controller
3986 * 2. ahci_intr_phyrdy_change (hotplug)
3989 ahci_initialize_port(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
3992 uint32_t port_sstatus
, port_task_file
, port_cmd_status
;
3993 uint8_t port
= addrp
->aa_port
;
3994 boolean_t resuming
= B_TRUE
; /* processing DDI_RESUME */
3997 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
3999 /* AHCI_ADDR_PORT: We've no idea of the attached device here. */
4000 ASSERT(AHCI_ADDR_IS_PORT(addrp
));
4003 * At the time being, only probe ports/devices and get the types of
4004 * attached devices during DDI_ATTACH. In fact, the device can be
4005 * changed during power state changes, but at the time being, we
4006 * don't support the situation.
4008 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_HOTPLUG
) {
4011 /* check for DDI_RESUME case */
4012 mutex_exit(&ahci_portp
->ahciport_mutex
);
4013 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
4014 if (ahci_ctlp
->ahcictl_flags
& AHCI_ATTACH
)
4016 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
4017 mutex_enter(&ahci_portp
->ahciport_mutex
);
4022 * During the resume, we need to set the PxCLB, PxCLBU, PxFB
4023 * and PxFBU registers in case these registers were cleared
4024 * during the suspend.
4026 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4027 "ahci_initialize_port: port %d "
4028 "set PxCLB, PxCLBU, PxFB and PxFBU "
4029 "during resume", port
);
4031 if (ahci_setup_port_base_addresses(ahci_ctlp
, ahci_portp
) !=
4033 return (AHCI_FAILURE
);
4036 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4037 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
4039 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
4040 "ahci_initialize_port: port %d ", port
);
4043 * Check whether the port is in NotRunning state, if not,
4044 * put the port in NotRunning state
4046 if (port_cmd_status
&
4047 (AHCI_CMD_STATUS_ST
|
4048 AHCI_CMD_STATUS_CR
|
4049 AHCI_CMD_STATUS_FRE
|
4050 AHCI_CMD_STATUS_FR
)) {
4051 (void) ahci_put_port_into_notrunning_state(ahci_ctlp
,
4055 /* Make sure the drive is spun-up */
4056 ahci_staggered_spin_up(ahci_ctlp
, port
);
4058 /* Disable interrupt */
4059 ahci_disable_port_intrs(ahci_ctlp
, port
);
4061 /* Device is unknown at first */
4062 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_UNKNOWN
);
4064 /* Disable the interface power management */
4065 ahci_disable_interface_pm(ahci_ctlp
, port
);
4067 port_sstatus
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4068 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp
, port
));
4069 port_task_file
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4070 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp
, port
));
4072 /* Check physcial link status */
4073 if (SSTATUS_GET_IPM(port_sstatus
) == SSTATUS_IPM_NODEV_NOPHYCOM
||
4074 SSTATUS_GET_DET(port_sstatus
) == SSTATUS_DET_DEVPRE_NOPHYCOM
||
4076 /* Check interface status */
4077 port_task_file
& AHCI_TFD_STS_BSY
||
4078 port_task_file
& AHCI_TFD_STS_DRQ
||
4080 /* Check whether port reset must be executed */
4081 ahci_ctlp
->ahcictl_cap
& AHCI_CAP_INIT_PORT_RESET
||
4083 /* Always reset port on RESUME */
4084 resuming
!= B_FALSE
) {
4086 /* Something went wrong, we need do some reset things */
4087 ret
= ahci_port_reset(ahci_ctlp
, ahci_portp
, addrp
);
4089 /* Does port reset succeed on HBA port? */
4090 if (ret
!= AHCI_SUCCESS
) {
4091 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ERRS
, ahci_ctlp
,
4092 "ahci_initialize_port:"
4093 "port reset failed at port %d", port
);
4094 return (AHCI_FAILURE
);
4097 /* Is port failed? */
4098 if (AHCIPORT_GET_STATE(ahci_portp
, addrp
) &
4099 SATA_PSTATE_FAILED
) {
4100 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ERRS
, ahci_ctlp
,
4101 "ahci_initialize_port: port %d state 0x%x",
4102 port
, ahci_portp
->ahciport_port_state
);
4103 return (AHCI_FAILURE
);
4107 AHCIPORT_SET_STATE(ahci_portp
, addrp
, SATA_STATE_READY
);
4108 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "port %d is ready now.", port
);
4111 * Try to get the device signature if the port is not empty.
4113 if (!resuming
&& AHCIPORT_DEV_TYPE(ahci_portp
, addrp
) !=
4115 ahci_find_dev_signature(ahci_ctlp
, ahci_portp
, addrp
);
4117 /* Return directly if no device connected */
4118 if (AHCIPORT_DEV_TYPE(ahci_portp
, addrp
) == SATA_DTYPE_NONE
) {
4119 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4120 "No device connected to port %d", port
);
4124 /* If this is a port multiplier, we need do some initialization */
4125 if (AHCIPORT_DEV_TYPE(ahci_portp
, addrp
) == SATA_DTYPE_PMULT
) {
4126 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
4127 "Port multiplier found at port %d", port
);
4128 ahci_alloc_pmult(ahci_ctlp
, ahci_portp
);
4131 /* Try to start the port */
4132 if (ahci_start_port(ahci_ctlp
, ahci_portp
, port
)
4134 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4135 "failed to start port %d", port
);
4136 return (AHCI_FAILURE
);
4139 /* Enable port interrupts */
4140 ahci_enable_port_intrs(ahci_ctlp
, port
);
4142 return (AHCI_SUCCESS
);
4146 * Handle hardware defect, and check the capabilities. For example,
4147 * power management capabilty and MSI capability.
4150 ahci_config_space_init(ahci_ctl_t
*ahci_ctlp
)
4152 ushort_t caps_ptr
, cap_count
, cap
;
4154 ushort_t pmcap
, pmcsr
;
4159 ahci_ctlp
->ahcictl_venid
=
4160 pci_config_get16(ahci_ctlp
->ahcictl_pci_conf_handle
,
4163 ahci_ctlp
->ahcictl_devid
=
4164 pci_config_get16(ahci_ctlp
->ahcictl_pci_conf_handle
,
4168 * Modify dma_attr_align of ahcictl_buffer_dma_attr. For VT8251, those
4169 * controllers with 0x00 revision id work on 4-byte aligned buffer,
4170 * which is a bug and was fixed after 0x00 revision id controllers.
4172 * Moreover, VT8251 cannot use multiple command slots in the command
4173 * list for non-queued commands because the previous register content
4174 * of PxCI can be re-written in the register write, so a flag will be
4175 * set to record this defect - AHCI_CAP_NO_MCMDLIST_NONQUEUE.
4177 * For VT8251, software reset also has the same defect as the below
4178 * AMD/ATI chipset. That is, software reset will get failed if 0xf
4179 * is filled in pmport field. Therefore, another software reset need
4180 * to be done with 0 filled in pmport field.
4182 if (ahci_ctlp
->ahcictl_venid
== VIA_VENID
) {
4183 revision
= pci_config_get8(ahci_ctlp
->ahcictl_pci_conf_handle
,
4185 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4186 "revision id = 0x%x", revision
);
4187 if (revision
== 0x00) {
4188 ahci_ctlp
->ahcictl_buffer_dma_attr
.dma_attr_align
= 0x4;
4189 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4190 "change ddi_attr_align to 0x4", NULL
);
4193 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_NO_MCMDLIST_NONQUEUE
;
4194 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4195 "VT8251 cannot use multiple command lists for "
4196 "non-queued commands", NULL
);
4198 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_SRST_NO_HOSTPORT
;
4202 * AMD/ATI SB600 (0x1002,0x4380) AHCI chipset doesn't support 64-bit
4203 * DMA addressing for communication memory descriptors though S64A bit
4204 * of CAP register declares it supports. Even though 64-bit DMA for
4205 * data buffer works on ASUS M2A-VM with newer BIOS, three other
4206 * motherboards are known not, so both AHCI_CAP_BUF_32BIT_DMA and
4207 * AHCI_CAP_COMMU_32BIT_DMA are set for this controller.
4209 * Due to certain hardware issue, the chipset must do port reset during
4210 * initialization, otherwise, when retrieving device signature,
4211 * software reset will get time out. So AHCI_CAP_INIT_PORT_RESET flag
4214 * For this chipset software reset will get failure if the pmport of
4215 * Register FIS was set with SATA_PMULT_HOSTPORT (0xf) and no port
4216 * multiplier is connected to the port. In order to fix the issue,
4217 * AHCI_CAP_SRST_NO_HOSTPORT flag need to be set, and once software
4218 * reset got failure, the driver will try to do another software reset
4221 if (ahci_ctlp
->ahcictl_venid
== 0x1002 &&
4222 ahci_ctlp
->ahcictl_devid
== 0x4380) {
4223 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_BUF_32BIT_DMA
;
4224 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_COMMU_32BIT_DMA
;
4225 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_INIT_PORT_RESET
;
4226 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_SRST_NO_HOSTPORT
;
4228 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4229 "ATI SB600 cannot do 64-bit DMA for both data buffer and "
4230 "communication memory descriptors though CAP indicates "
4231 "support, so force it to use 32-bit DMA", NULL
);
4232 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4233 "ATI SB600 need to do a port reset during initialization",
4235 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4236 "ATI SB600 will get software reset failure if pmport "
4237 "is set 0xf and no port multiplier is attached", NULL
);
4241 * AMD/ATI SB700/710/750/800 and SP5100 AHCI chipset share the same
4242 * vendor ID and device ID (0x1002,0x4391).
4244 * SB700/750 AHCI chipset on some boards doesn't support 64-bit
4245 * DMA addressing for communication memory descriptors though S64A bit
4246 * of CAP register declares the support. However, it does support
4247 * 64-bit DMA for data buffer. So only AHCI_CAP_COMMU_32BIT_DMA is
4248 * set for this controller.
4250 * SB710 has the same initialization issue as SB600, so it also need
4251 * a port reset. That is AHCI_CAP_INIT_PORT_RESET need to set for it.
4253 * SB700 also has the same issue about software reset, and thus
4254 * AHCI_CAP_SRST_NO_HOSTPORT flag also is needed.
4256 if (ahci_ctlp
->ahcictl_venid
== 0x1002 &&
4257 ahci_ctlp
->ahcictl_devid
== 0x4391) {
4258 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_COMMU_32BIT_DMA
;
4259 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_INIT_PORT_RESET
;
4260 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_SRST_NO_HOSTPORT
;
4262 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4263 "ATI SB700/750 cannot do 64-bit DMA for communication "
4264 "memory descriptors though CAP indicates support, "
4265 "so force it to use 32-bit DMA", NULL
);
4266 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4267 "ATI SB710 need to do a port reset during initialization",
4269 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4270 "ATI SB700 will get software reset failure if pmport "
4271 "is set 0xf and no port multiplier is attached", NULL
);
4275 * Check if capabilities list is supported and if so,
4276 * get initial capabilities pointer and clear bits 0,1.
4278 if (pci_config_get16(ahci_ctlp
->ahcictl_pci_conf_handle
,
4279 PCI_CONF_STAT
) & PCI_STAT_CAP
) {
4280 caps_ptr
= P2ALIGN(pci_config_get8(
4281 ahci_ctlp
->ahcictl_pci_conf_handle
,
4282 PCI_CONF_CAP_PTR
), 4);
4284 caps_ptr
= PCI_CAP_NEXT_PTR_NULL
;
4288 * Walk capabilities if supported.
4290 for (cap_count
= 0; caps_ptr
!= PCI_CAP_NEXT_PTR_NULL
; ) {
4293 * Check that we haven't exceeded the maximum number of
4294 * capabilities and that the pointer is in a valid range.
4296 if (++cap_count
> PCI_CAP_MAX_PTR
) {
4297 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
4298 "too many device capabilities", NULL
);
4299 return (AHCI_FAILURE
);
4301 if (caps_ptr
< PCI_CAP_PTR_OFF
) {
4302 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
4303 "capabilities pointer 0x%x out of range",
4305 return (AHCI_FAILURE
);
4309 * Get next capability and check that it is valid.
4310 * For now, we only support power management.
4312 cap
= pci_config_get8(ahci_ctlp
->ahcictl_pci_conf_handle
,
4317 /* power management supported */
4318 ahci_ctlp
->ahcictl_cap
|= AHCI_CAP_PM
;
4320 /* Save PMCSR offset */
4321 ahci_ctlp
->ahcictl_pmcsr_offset
= caps_ptr
+ PCI_PMCSR
;
4324 pmcap
= pci_config_get16(
4325 ahci_ctlp
->ahcictl_pci_conf_handle
,
4326 caps_ptr
+ PCI_PMCAP
);
4327 pmcsr
= pci_config_get16(
4328 ahci_ctlp
->ahcictl_pci_conf_handle
,
4329 ahci_ctlp
->ahcictl_pmcsr_offset
);
4330 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4331 "Power Management capability found PCI_PMCAP "
4332 "= 0x%x PCI_PMCSR = 0x%x", pmcap
, pmcsr
);
4333 if ((pmcap
& 0x3) == 0x3)
4334 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4335 "PCI Power Management Interface "
4336 "spec 1.2 compliant", NULL
);
4340 case PCI_CAP_ID_MSI
:
4342 msimc
= pci_config_get16(
4343 ahci_ctlp
->ahcictl_pci_conf_handle
,
4344 caps_ptr
+ PCI_MSI_CTRL
);
4345 AHCIDBG(AHCIDBG_MSI
, ahci_ctlp
,
4346 "Message Signaled Interrupt capability found "
4347 "MSICAP_MC.MMC = 0x%x", (msimc
& 0xe) >> 1);
4349 AHCIDBG(AHCIDBG_MSI
, ahci_ctlp
,
4350 "MSI capability found", NULL
);
4353 case PCI_CAP_ID_PCIX
:
4354 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4355 "PCI-X capability found", NULL
);
4358 case PCI_CAP_ID_PCI_E
:
4359 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4360 "PCI Express capability found", NULL
);
4363 case PCI_CAP_ID_MSI_X
:
4364 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4365 "MSI-X capability found", NULL
);
4368 case PCI_CAP_ID_SATA
:
4369 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4370 "SATA capability found", NULL
);
4374 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4375 "Vendor Specific capability found", NULL
);
4379 AHCIDBG(AHCIDBG_PM
, ahci_ctlp
,
4380 "unrecognized capability 0x%x", cap
);
4385 * Get next capabilities pointer and clear bits 0,1.
4387 caps_ptr
= P2ALIGN(pci_config_get8(
4388 ahci_ctlp
->ahcictl_pci_conf_handle
,
4389 (caps_ptr
+ PCI_CAP_NEXT_PTR
)), 4);
4392 return (AHCI_SUCCESS
);
4396 * Read/Write a register at port multiplier by SATA READ PORTMULT / SATA WRITE
4397 * PORTMULT command. SYNC & POLLING mode is used.
4400 ahci_rdwr_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_addr_t
*addrp
,
4401 uint8_t regn
, uint32_t *pregv
, uint8_t type
)
4403 ahci_port_t
*ahci_portp
;
4404 ahci_addr_t pmult_addr
;
4407 sata_device_t sata_device
;
4408 uint8_t port
= addrp
->aa_port
;
4409 uint8_t pmport
= addrp
->aa_pmport
;
4415 SET_PORTSTR(portstr
, addrp
);
4416 cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
4417 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
4419 ASSERT(AHCI_ADDR_IS_PMPORT(addrp
) || AHCI_ADDR_IS_PMULT(addrp
));
4420 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
4422 /* Check the existence of the port multiplier */
4423 if (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
)
4424 return (AHCI_FAILURE
);
4426 /* Request a READ/WRITE PORTMULT sata packet. */
4427 bzero(&sata_device
, sizeof (sata_device_t
));
4428 sata_device
.satadev_addr
.cport
= cport
;
4429 sata_device
.satadev_addr
.pmport
= pmport
;
4430 sata_device
.satadev_addr
.qual
= SATA_ADDR_PMULT
;
4431 sata_device
.satadev_rev
= SATA_DEVICE_REV
;
4434 * Make sure no command is outstanding here. All R/W PMULT requests
4438 * The port should be empty.
4440 * 2. ahci_tran_probe_port()
4441 * Any request from SATA framework (via ahci_tran_start) should be
4442 * rejected if R/W PMULT command is outstanding.
4444 * If we are doing mopping, do not check those flags because no
4445 * command will be actually outstanding.
4447 * If the port has been occupied by any other commands, the probe
4448 * function will return a SATA_RETRY. SATA framework will retry
4451 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
4452 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4453 "R/W PMULT failed: R/W PMULT in progress at port %d.",
4454 port
, ahci_portp
->ahciport_flags
);
4455 return (AHCI_FAILURE
);
4458 if (!(ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) && (
4459 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
) ||
4460 NCQ_CMD_IN_PROGRESS(ahci_portp
) ||
4461 NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))) {
4462 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4463 "R/W PMULT failed: port %d is occupied (flags 0x%x).",
4464 port
, ahci_portp
->ahciport_flags
);
4465 return (AHCI_FAILURE
);
4469 * The port multiplier is gone. This may happen when
4470 * 1. Cutting off the power of an enclosure. The device lose the power
4471 * before port multiplier.
4472 * 2. Disconnecting the port multiplier during hot-plugging a sub-drive.
4474 * The issued command should be aborted and the following command
4475 * should not be continued.
4477 if (!(ahci_portp
->ahciport_port_state
& SATA_STATE_READY
)) {
4478 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4479 "READ/WRITE PMULT failed: "
4480 "port-mult is removed from port %d", port
);
4481 return (AHCI_FAILURE
);
4484 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_RDWR_PMULT
;
4486 spkt
= sata_get_rdwr_pmult_pkt(ahci_ctlp
->ahcictl_dip
,
4487 &sata_device
, regn
, *pregv
, type
);
4490 * READ/WRITE PORTMULT command is intended to sent to the control port
4491 * of the port multiplier.
4493 AHCI_ADDR_SET_PMULT(&pmult_addr
, addrp
->aa_port
);
4495 ahci_portp
->ahciport_rdwr_pmult_pkt
= spkt
;
4497 /* No interrupt here. Store the interrupt enable mask. */
4498 intr_mask
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4499 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp
, port
));
4500 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4501 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp
, port
), 0);
4503 rval
= ahci_do_sync_start(ahci_ctlp
, ahci_portp
, &pmult_addr
, spkt
);
4505 if (rval
== AHCI_SUCCESS
&&
4506 spkt
->satapkt_reason
== SATA_PKT_COMPLETED
) {
4507 if (type
== SATA_RDWR_PMULT_PKT_TYPE_READ
) {
4508 scmd
= &spkt
->satapkt_cmd
;
4509 *pregv
= scmd
->satacmd_lba_high_lsb
<< 24 |
4510 scmd
->satacmd_lba_mid_lsb
<< 16 |
4511 scmd
->satacmd_lba_low_lsb
<< 8 |
4512 scmd
->satacmd_sec_count_lsb
;
4515 /* Failed or not completed. */
4516 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4517 "ahci_rdwr_pmult: cannot [%s] %s[%d] at port %s",
4518 type
== SATA_RDWR_PMULT_PKT_TYPE_READ
?"Read":"Write",
4519 AHCI_ADDR_IS_PMULT(addrp
)?"gscr":"pscr", regn
, portstr
);
4520 rval
= AHCI_FAILURE
;
4523 /* Restore the interrupt mask */
4524 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4525 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp
, port
), intr_mask
);
4527 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_RDWR_PMULT
;
4528 ahci_portp
->ahciport_rdwr_pmult_pkt
= NULL
;
4529 sata_free_rdwr_pmult_pkt(spkt
);
4534 ahci_read_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_addr_t
*addrp
,
4535 uint8_t regn
, uint32_t *pregv
)
4537 return ahci_rdwr_pmult(ahci_ctlp
, addrp
, regn
, pregv
,
4538 SATA_RDWR_PMULT_PKT_TYPE_READ
);
4542 ahci_write_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_addr_t
*addrp
,
4543 uint8_t regn
, uint32_t regv
)
4545 return ahci_rdwr_pmult(ahci_ctlp
, addrp
, regn
, ®v
,
4546 SATA_RDWR_PMULT_PKT_TYPE_WRITE
);
4549 #define READ_PMULT(addrp, r, pv, out) \
4550 if (ahci_read_pmult(ahci_ctlp, addrp, r, pv) != AHCI_SUCCESS) \
4553 #define WRITE_PMULT(addrp, r, v, out) \
4554 if (ahci_write_pmult(ahci_ctlp, addrp, r, v) != AHCI_SUCCESS) \
4558 * Update sata registers on port multiplier, including GSCR/PSCR registers.
4559 * ahci_update_pmult_gscr()
4560 * ahci_update_pmult_pscr()
4563 ahci_update_pmult_gscr(ahci_ctl_t
*ahci_ctlp
, ahci_addr_t
*addrp
,
4564 sata_pmult_gscr_t
*sg
)
4567 &ahci_ctlp
->ahcictl_ports
[addrp
->aa_port
]->ahciport_mutex
));
4569 READ_PMULT(addrp
, SATA_PMULT_GSCR0
, &sg
->gscr0
, err
);
4570 READ_PMULT(addrp
, SATA_PMULT_GSCR1
, &sg
->gscr1
, err
);
4571 READ_PMULT(addrp
, SATA_PMULT_GSCR2
, &sg
->gscr2
, err
);
4572 READ_PMULT(addrp
, SATA_PMULT_GSCR64
, &sg
->gscr64
, err
);
4574 return (AHCI_SUCCESS
);
4576 err
: /* R/W PMULT error */
4577 return (AHCI_FAILURE
);
4581 ahci_update_pmult_pscr(ahci_ctl_t
*ahci_ctlp
, ahci_addr_t
*addrp
,
4584 ASSERT(AHCI_ADDR_IS_PMPORT(addrp
));
4586 &ahci_ctlp
->ahcictl_ports
[addrp
->aa_port
]->ahciport_mutex
));
4588 READ_PMULT(addrp
, SATA_PMULT_REG_SSTS
, &sd
->satadev_scr
.sstatus
, err
);
4589 READ_PMULT(addrp
, SATA_PMULT_REG_SERR
, &sd
->satadev_scr
.serror
, err
);
4590 READ_PMULT(addrp
, SATA_PMULT_REG_SCTL
, &sd
->satadev_scr
.scontrol
, err
);
4591 READ_PMULT(addrp
, SATA_PMULT_REG_SACT
, &sd
->satadev_scr
.sactive
, err
);
4593 return (AHCI_SUCCESS
);
4595 err
: /* R/W PMULT error */
4596 return (AHCI_FAILURE
);
4600 * ahci_initialize_pmult()
4602 * Initialize a port multiplier, including
4603 * 1. Enable FEATURES register at port multiplier. (SATA Chp.16)
4604 * 2. Redefine MASK register. (SATA Chap 16.?)
4607 ahci_initialize_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
4608 ahci_addr_t
*addrp
, sata_device_t
*sd
)
4610 sata_pmult_gscr_t sg
;
4612 uint8_t port
= addrp
->aa_port
;
4614 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
4616 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
4617 "[Initialize] Port-multiplier at port %d.", port
);
4620 * Enable features of port multiplier. Currently only
4621 * Asynchronous Notification is enabled.
4623 /* Check gscr64 for supported features. */
4624 READ_PMULT(addrp
, SATA_PMULT_GSCR64
, &gscr64
, err
);
4626 if (gscr64
& SATA_PMULT_CAP_SNOTIF
) {
4627 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
4628 "port %d: Port Multiplier supports "
4629 "Asynchronous Notification.", port
);
4631 /* Write to gscr96 to enabled features */
4632 WRITE_PMULT(addrp
, SATA_PMULT_GSCR96
,
4633 SATA_PMULT_CAP_SNOTIF
, err
);
4635 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4636 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp
, port
),
4637 AHCI_SNOTIF_CLEAR_ALL
);
4638 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
4639 "port %d: PMult PxSNTF cleared.", port
);
4644 * Now we need to update gscr33 register to enable hot-plug interrupt
4645 * for sub devices behind port multiplier.
4647 WRITE_PMULT(addrp
, SATA_PMULT_GSCR33
, (0x1ffff), err
);
4648 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
4649 "port %d: gscr33 mask set to %x.", port
, (0x1ffff));
4652 * Fetch the number of device ports of the port multiplier
4654 if (ahci_update_pmult_gscr(ahci_ctlp
, addrp
, &sg
) != AHCI_SUCCESS
)
4655 return (AHCI_FAILURE
);
4657 /* Register the port multiplier to SATA Framework. */
4658 mutex_exit(&ahci_portp
->ahciport_mutex
);
4659 sata_register_pmult(ahci_ctlp
->ahcictl_dip
, sd
, &sg
);
4660 mutex_enter(&ahci_portp
->ahciport_mutex
);
4662 ahci_portp
->ahciport_pmult_info
->ahcipmi_num_dev_ports
=
4663 sd
->satadev_add_info
& SATA_PMULT_PORTNUM_MASK
;
4665 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
4666 "port %d: pmult sub-port number updated to %x.", port
,
4667 ahci_portp
->ahciport_pmult_info
->ahcipmi_num_dev_ports
);
4669 /* Till now port-mult is successfully initialized */
4670 ahci_portp
->ahciport_port_state
|= SATA_DSTATE_PMULT_INIT
;
4671 return (AHCI_SUCCESS
);
4673 err
: /* R/W PMULT error */
4674 return (AHCI_FAILURE
);
4678 * Initialize a port multiplier port. According to spec, firstly we need
4679 * issue a COMRESET, then a software reset to get its signature.
4681 * NOTE: This function should only be called in ahci_probe_pmport()
4684 ahci_initialize_pmport(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
4687 uint32_t finished_tags
= 0, reset_tags
= 0, slot_status
= 0;
4688 uint8_t port
= addrp
->aa_port
;
4689 uint8_t pmport
= addrp
->aa_pmport
;
4690 int ret
= AHCI_FAILURE
;
4692 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
4693 ASSERT(AHCI_ADDR_IS_PMPORT(addrp
));
4695 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
4696 "ahci_initialize_pmport: port %d:%d", port
, pmport
);
4698 /* Check HBA port state */
4699 if (ahci_portp
->ahciport_port_state
& SATA_PSTATE_FAILED
) {
4700 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ERRS
, ahci_ctlp
,
4701 "ahci_initialize_pmport:"
4702 "port %d:%d Port Multiplier is failed.",
4704 return (AHCI_FAILURE
);
4707 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_HOTPLUG
) {
4708 return (AHCI_FAILURE
);
4710 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_HOTPLUG
;
4712 /* Checking for outstanding commands */
4713 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
4714 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4715 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
4716 reset_tags
= slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
4717 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
4718 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4719 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
4720 reset_tags
= slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
4723 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
4724 ahci_portp
->ahciport_mop_in_progress
++;
4727 AHCIPORT_SET_STATE(ahci_portp
, addrp
, SATA_STATE_UNKNOWN
);
4729 /* Firstly assume an unknown device */
4730 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_UNKNOWN
);
4732 ahci_disable_port_intrs(ahci_ctlp
, port
);
4734 /* port reset is necessary for port multiplier port */
4735 if (ahci_pmport_reset(ahci_ctlp
, ahci_portp
, addrp
) != AHCI_SUCCESS
) {
4736 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ERRS
, ahci_ctlp
,
4737 "ahci_initialize_pmport:"
4738 "port reset failed at port %d:%d",
4743 /* Is port failed? */
4744 if (AHCIPORT_GET_STATE(ahci_portp
, addrp
) &
4745 SATA_PSTATE_FAILED
) {
4746 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
4747 "ahci_initialize_pmport: port %d:%d failed. "
4748 "state = 0x%x", port
, pmport
,
4749 ahci_portp
->ahciport_port_state
);
4753 /* Is there any device attached? */
4754 if (AHCIPORT_GET_DEV_TYPE(ahci_portp
, addrp
)
4755 == SATA_DTYPE_NONE
) {
4756 /* Do not waste time on an empty port */
4757 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
4758 "ahci_initialize_pmport: No device is found "
4759 "at port %d:%d", port
, pmport
);
4764 AHCIPORT_SET_STATE(ahci_portp
, addrp
, SATA_STATE_READY
);
4765 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
4766 "port %d:%d is ready now.", port
, pmport
);
4769 * Till now we can assure a device attached to that HBA port and work
4770 * correctly. Now try to get the device signature. This is an optional
4771 * step. If failed, unknown device is assumed, then SATA module will
4772 * continue to use IDENTIFY DEVICE to get the information of the
4775 ahci_find_dev_signature(ahci_ctlp
, ahci_portp
, addrp
);
4780 /* Next try to mop the pending commands */
4781 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
))
4782 finished_tags
= ahci_portp
->ahciport_pending_tags
&
4783 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
4784 else if (NCQ_CMD_IN_PROGRESS(ahci_portp
))
4785 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
4786 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
4787 reset_tags
&= ~finished_tags
;
4789 ahci_mop_commands(ahci_ctlp
,
4792 0, /* failed tags */
4793 0, /* timeout tags */
4794 0, /* aborted tags */
4795 reset_tags
); /* reset tags */
4797 /* Clear PxSNTF register if supported. */
4798 if (ahci_ctlp
->ahcictl_cap
& AHCI_CAP_SNTF
) {
4799 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
4800 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp
, port
),
4801 AHCI_SNOTIF_CLEAR_ALL
);
4804 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_HOTPLUG
;
4805 ahci_enable_port_intrs(ahci_ctlp
, port
);
4810 * ahci_probe_pmult()
4812 * This function will be called to probe a port multiplier, which will
4813 * handle hotplug events on port multiplier ports.
4815 * NOTE: Only called from ahci_tran_probe_port()
4818 ahci_probe_pmult(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
4821 sata_device_t sdevice
;
4822 ahci_addr_t pmport_addr
;
4823 uint32_t gscr32
, port_hotplug_tags
;
4824 uint32_t pmport_sstatus
;
4825 int dev_exists_now
= 0, dev_existed_previously
= 0;
4826 uint8_t port
= addrp
->aa_port
;
4829 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
4831 /* The bits in GSCR32 refers to the pmport that has a hot-plug event. */
4832 READ_PMULT(addrp
, SATA_PMULT_GSCR32
, &gscr32
, err
);
4833 port_hotplug_tags
= gscr32
& AHCI_PMPORT_MASK(ahci_portp
);
4836 npmport
= ddi_ffs(port_hotplug_tags
) - 1;
4838 /* no pending hot plug events. */
4839 return (AHCI_SUCCESS
);
4841 AHCIDBG(AHCIDBG_EVENT
|AHCIDBG_PMULT
, ahci_ctlp
,
4842 "hot-plug event at port %d:%d", port
, npmport
);
4844 AHCI_ADDR_SET_PMPORT(&pmport_addr
, port
, (uint8_t)npmport
);
4846 /* Check previous device at that port */
4847 if (AHCIPORT_GET_DEV_TYPE(ahci_portp
, &pmport_addr
)
4849 dev_existed_previously
= 1;
4851 /* PxSStatus tells the presence of device. */
4852 READ_PMULT(&pmport_addr
, SATA_PMULT_REG_SSTS
,
4853 &pmport_sstatus
, err
);
4855 if (SSTATUS_GET_DET(pmport_sstatus
) ==
4856 SSTATUS_DET_DEVPRE_PHYCOM
)
4860 * Clear PxSERR is critical. The transition from 0 to 1 will
4861 * emit a FIS which generates an asynchronous notification
4862 * event at controller. If we fail to clear the PxSERR, the
4863 * Async Notif events will no longer be activated on this
4866 WRITE_PMULT(&pmport_addr
, SATA_PMULT_REG_SERR
,
4867 AHCI_SERROR_CLEAR_ALL
, err
);
4869 bzero((void *)&sdevice
, sizeof (sata_device_t
));
4870 sdevice
.satadev_addr
.cport
= ahci_ctlp
->
4871 ahcictl_port_to_cport
[port
];
4872 sdevice
.satadev_addr
.qual
= SATA_ADDR_PMPORT
;
4873 sdevice
.satadev_addr
.pmport
= (uint8_t)npmport
;
4874 sdevice
.satadev_state
= SATA_PSTATE_PWRON
;
4876 AHCIDBG(AHCIDBG_EVENT
|AHCIDBG_PMULT
, ahci_ctlp
,
4877 "[Existence] %d -> %d", dev_existed_previously
,
4880 if (dev_exists_now
) {
4881 if (dev_existed_previously
) {
4882 /* Link (may) not change: Exist -> Exist * */
4883 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
4884 "ahci_probe_pmult: port %d:%d "
4885 "device link lost/established",
4888 mutex_exit(&ahci_portp
->ahciport_mutex
);
4889 sata_hba_event_notify(
4890 ahci_ctlp
->ahcictl_sata_hba_tran
->
4893 SATA_EVNT_LINK_LOST
|
4894 SATA_EVNT_LINK_ESTABLISHED
);
4895 mutex_enter(&ahci_portp
->ahciport_mutex
);
4897 /* Link change: None -> Exist */
4898 AHCIDBG(AHCIDBG_EVENT
|AHCIDBG_PMULT
, ahci_ctlp
,
4899 "ahci_probe_pmult: port %d:%d "
4900 "device link established", port
, npmport
);
4902 /* Clear port state */
4903 AHCIPORT_SET_STATE(ahci_portp
, &pmport_addr
,
4904 SATA_STATE_UNKNOWN
);
4905 AHCIDBG(AHCIDBG_EVENT
|AHCIDBG_PMULT
, ahci_ctlp
,
4906 "ahci_probe_pmult: port %d "
4907 "ahciport_port_state [Cleared].", port
);
4909 mutex_exit(&ahci_portp
->ahciport_mutex
);
4910 sata_hba_event_notify(
4911 ahci_ctlp
->ahcictl_sata_hba_tran
->
4914 SATA_EVNT_LINK_ESTABLISHED
);
4915 mutex_enter(&ahci_portp
->ahciport_mutex
);
4917 } else { /* No device exists now */
4918 if (dev_existed_previously
) {
4920 /* Link change: Exist -> None */
4921 AHCIDBG(AHCIDBG_EVENT
|AHCIDBG_PMULT
, ahci_ctlp
,
4922 "ahci_probe_pmult: port %d:%d "
4923 "device link lost", port
, npmport
);
4925 /* An existing device is lost. */
4926 AHCIPORT_SET_STATE(ahci_portp
, &pmport_addr
,
4927 SATA_STATE_UNKNOWN
);
4928 AHCIPORT_SET_DEV_TYPE(ahci_portp
, &pmport_addr
,
4931 mutex_exit(&ahci_portp
->ahciport_mutex
);
4932 sata_hba_event_notify(
4933 ahci_ctlp
->ahcictl_sata_hba_tran
->
4936 SATA_EVNT_LINK_LOST
);
4937 mutex_enter(&ahci_portp
->ahciport_mutex
);
4941 CLEAR_BIT(port_hotplug_tags
, npmport
);
4942 } while (port_hotplug_tags
!= 0);
4944 return (AHCI_SUCCESS
);
4946 err
: /* R/W PMULT error */
4947 return (AHCI_FAILURE
);
4951 * Probe and initialize a port multiplier port.
4952 * A port multiplier port could only be initilaizer here.
4955 ahci_probe_pmport(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
4956 ahci_addr_t
*addrp
, sata_device_t
*sd
)
4958 uint32_t port_state
;
4959 uint8_t port
= addrp
->aa_port
;
4960 ahci_addr_t addr_pmult
;
4962 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
4965 * Check the parent - port multiplier first.
4969 * Parent port multiplier might have been removed. This event will be
4970 * ignored and failure.
4972 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
||
4973 ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
) {
4974 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4975 "ahci_tran_probe_port: "
4976 "parent device removed, ignore event.", NULL
);
4978 return (AHCI_FAILURE
);
4981 /* The port is ready? */
4982 port_state
= ahci_portp
->ahciport_port_state
;
4983 if (!(port_state
& SATA_STATE_READY
)) {
4984 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4985 "ahci_tran_probe_port: "
4986 "parent port-mult is NOT ready.", NULL
);
4988 if (ahci_restart_port_wait_till_ready(ahci_ctlp
,
4989 ahci_portp
, port
, AHCI_PORT_RESET
, NULL
) !=
4991 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
4992 "ahci_tran_probe_port: "
4993 "restart port-mult failed.", NULL
);
4994 return (AHCI_FAILURE
);
4999 * If port-mult is restarted due to some reason, we need
5000 * re-initialized the PMult.
5002 if (!(port_state
& SATA_DSTATE_PMULT_INIT
)) {
5003 /* Initialize registers on a port multiplier */
5004 AHCI_ADDR_SET_PMULT(&addr_pmult
, addrp
->aa_port
);
5005 if (ahci_initialize_pmult(ahci_ctlp
, ahci_portp
,
5006 &addr_pmult
, sd
) != AHCI_SUCCESS
)
5007 return (AHCI_FAILURE
);
5011 * Then we check the port-mult port
5013 /* Is this pmport initialized? */
5014 port_state
= AHCIPORT_GET_STATE(ahci_portp
, addrp
);
5015 if (!(port_state
& SATA_STATE_READY
)) {
5017 /* ahci_initialize_pmport() will set READY state */
5018 if (ahci_initialize_pmport(ahci_ctlp
,
5019 ahci_portp
, addrp
) != AHCI_SUCCESS
)
5020 return (AHCI_FAILURE
);
5023 return (AHCI_SUCCESS
);
5027 * AHCI device reset ...; a single device on one of the ports is reset,
5028 * but the HBA and physical communication remain intact. This is the
5031 * When issuing a software reset sequence, there should not be other
5032 * commands in the command list, so we will first clear and then re-set
5033 * PxCMD.ST to clear PxCI. And before issuing the software reset,
5034 * the port must be idle and PxTFD.STS.BSY and PxTFD.STS.DRQ must be
5035 * cleared unless command list override (PxCMD.CLO) is supported.
5038 ahci_software_reset(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
5041 ahci_fis_h2d_register_t
*h2d_register_fisp
;
5042 ahci_cmd_table_t
*cmd_table
;
5043 ahci_cmd_header_t
*cmd_header
;
5044 uint32_t port_cmd_status
, port_cmd_issue
, port_task_file
;
5045 int slot
, loop_count
;
5046 uint8_t port
= addrp
->aa_port
;
5047 uint8_t pmport
= addrp
->aa_pmport
;
5048 int rval
= AHCI_FAILURE
;
5050 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
5052 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
5053 "port %d:%d device software resetting (FIS)", port
, pmport
);
5055 /* First clear PxCMD.ST (AHCI v1.2 10.4.1) */
5056 if (ahci_put_port_into_notrunning_state(ahci_ctlp
, ahci_portp
,
5057 port
) != AHCI_SUCCESS
) {
5058 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5059 "ahci_software_reset: cannot stop HBA port %d.", port
);
5063 /* Check PxTFD.STS.BSY and PxTFD.STS.DRQ */
5064 port_task_file
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5065 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp
, port
));
5067 if (port_task_file
& AHCI_TFD_STS_BSY
||
5068 port_task_file
& AHCI_TFD_STS_DRQ
) {
5069 if (!(ahci_ctlp
->ahcictl_cap
& AHCI_CAP_SCLO
)) {
5070 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5071 "PxTFD.STS.BSY/DRQ is set (PxTFD=0x%x), "
5072 "cannot issue a software reset.", port_task_file
);
5077 * If HBA Support CLO, as Command List Override (CAP.SCLO is
5078 * set), PxCMD.CLO bit should be set before set PxCMD.ST, in
5079 * order to clear PxTFD.STS.BSY and PxTFD.STS.DRQ.
5081 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5082 "PxTFD.STS.BSY/DRQ is set, try SCLO.", NULL
)
5084 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5085 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
5086 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5087 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
5088 port_cmd_status
|AHCI_CMD_STATUS_CLO
);
5090 /* Waiting till PxCMD.SCLO bit is cleared */
5093 /* Wait for 10 millisec */
5094 drv_usecwait(AHCI_10MS_USECS
);
5096 /* We are effectively timing out after 1 sec. */
5097 if (loop_count
++ > 100) {
5098 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5099 "SCLO time out. port %d is busy.", port
);
5104 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5105 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
5106 } while (port_cmd_status
& AHCI_CMD_STATUS_CLO
);
5109 port_task_file
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5110 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp
, port
));
5111 if (port_task_file
& AHCI_TFD_STS_BSY
||
5112 port_task_file
& AHCI_TFD_STS_DRQ
) {
5113 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5114 "SCLO cannot clear PxTFD.STS.BSY/DRQ (PxTFD=0x%x)",
5120 /* Then start port */
5121 if (ahci_start_port(ahci_ctlp
, ahci_portp
, port
)
5123 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5124 "ahci_software_reset: cannot start AHCI port %d.", port
);
5129 * When ahci_port.ahciport_mop_in_progress is set, A non-zero
5130 * ahci_port.ahciport_pending_ncq_tags may fail
5131 * ahci_claim_free_slot(). Actually according to spec, by clearing
5132 * PxCMD.ST there is no command outstanding while executing software
5133 * reseting. Hence we directly use slot 0 instead of
5134 * ahci_claim_free_slot().
5138 /* Now send the first H2D Register FIS with SRST set to 1 */
5139 cmd_table
= ahci_portp
->ahciport_cmd_tables
[slot
];
5140 bzero((void *)cmd_table
, ahci_cmd_table_size
);
5143 &(cmd_table
->ahcict_command_fis
.ahcifc_fis
.ahcifc_h2d_register
);
5145 SET_FIS_TYPE(h2d_register_fisp
, AHCI_H2D_REGISTER_FIS_TYPE
);
5146 SET_FIS_PMP(h2d_register_fisp
, pmport
);
5147 SET_FIS_DEVCTL(h2d_register_fisp
, SATA_DEVCTL_SRST
);
5149 /* Set Command Header in Command List */
5150 cmd_header
= &ahci_portp
->ahciport_cmd_list
[slot
];
5151 BZERO_DESCR_INFO(cmd_header
);
5152 BZERO_PRD_BYTE_COUNT(cmd_header
);
5153 SET_COMMAND_FIS_LENGTH(cmd_header
, 5);
5154 SET_PORT_MULTI_PORT(cmd_header
, pmport
);
5156 SET_CLEAR_BUSY_UPON_R_OK(cmd_header
, 1);
5157 SET_RESET(cmd_header
, 1);
5158 SET_WRITE(cmd_header
, 1);
5160 (void) ddi_dma_sync(ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
],
5162 ahci_cmd_table_size
,
5163 DDI_DMA_SYNC_FORDEV
);
5165 (void) ddi_dma_sync(ahci_portp
->ahciport_cmd_list_dma_handle
,
5166 slot
* sizeof (ahci_cmd_header_t
),
5167 sizeof (ahci_cmd_header_t
),
5168 DDI_DMA_SYNC_FORDEV
);
5170 /* Indicate to the HBA that a command is active. */
5171 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5172 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
),
5177 /* Loop till the first command is finished */
5179 port_cmd_issue
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5180 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
5182 /* We are effectively timing out after 1 sec. */
5183 if (loop_count
++ > AHCI_POLLRATE_PORT_SOFTRESET
) {
5184 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5185 "the first SRST FIS is timed out, "
5186 "loop_count = %d", loop_count
);
5189 /* Wait for 10 millisec */
5190 drv_usecwait(AHCI_10MS_USECS
);
5191 } while (port_cmd_issue
& AHCI_SLOT_MASK(ahci_ctlp
) & (0x1 << slot
));
5193 AHCIDBG(AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5194 "ahci_software_reset: 1st loop count: %d, "
5195 "port_cmd_issue = 0x%x, slot = 0x%x",
5196 loop_count
, port_cmd_issue
, slot
);
5198 /* According to ATA spec, we need wait at least 5 microsecs here. */
5199 drv_usecwait(AHCI_1MS_USECS
);
5201 /* Now send the second H2D Register FIS with SRST cleard to zero */
5202 cmd_table
= ahci_portp
->ahciport_cmd_tables
[slot
];
5203 bzero((void *)cmd_table
, ahci_cmd_table_size
);
5206 &(cmd_table
->ahcict_command_fis
.ahcifc_fis
.ahcifc_h2d_register
);
5208 SET_FIS_TYPE(h2d_register_fisp
, AHCI_H2D_REGISTER_FIS_TYPE
);
5209 SET_FIS_PMP(h2d_register_fisp
, pmport
);
5211 /* Set Command Header in Command List */
5212 cmd_header
= &ahci_portp
->ahciport_cmd_list
[slot
];
5213 BZERO_DESCR_INFO(cmd_header
);
5214 BZERO_PRD_BYTE_COUNT(cmd_header
);
5215 SET_COMMAND_FIS_LENGTH(cmd_header
, 5);
5216 SET_PORT_MULTI_PORT(cmd_header
, pmport
);
5218 SET_WRITE(cmd_header
, 1);
5220 (void) ddi_dma_sync(ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
],
5222 ahci_cmd_table_size
,
5223 DDI_DMA_SYNC_FORDEV
);
5225 (void) ddi_dma_sync(ahci_portp
->ahciport_cmd_list_dma_handle
,
5226 slot
* sizeof (ahci_cmd_header_t
),
5227 sizeof (ahci_cmd_header_t
),
5228 DDI_DMA_SYNC_FORDEV
);
5230 /* Indicate to the HBA that a command is active. */
5231 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5232 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
),
5237 /* Loop till the second command is finished */
5239 port_cmd_issue
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5240 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
5242 /* We are effectively timing out after 1 sec. */
5243 if (loop_count
++ > AHCI_POLLRATE_PORT_SOFTRESET
) {
5244 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5245 "the second SRST FIS is timed out, "
5246 "loop_count = %d", loop_count
);
5250 /* Wait for 10 millisec */
5251 drv_usecwait(AHCI_10MS_USECS
);
5252 } while (port_cmd_issue
& AHCI_SLOT_MASK(ahci_ctlp
) & (0x1 << slot
));
5254 AHCIDBG(AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5255 "ahci_software_reset: 2nd loop count: %d, "
5256 "port_cmd_issue = 0x%x, slot = 0x%x",
5257 loop_count
, port_cmd_issue
, slot
);
5259 if ((ahci_check_ctl_handle(ahci_ctlp
) != DDI_SUCCESS
) ||
5260 (ahci_check_port_handle(ahci_ctlp
, port
) != DDI_SUCCESS
)) {
5261 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
5262 DDI_SERVICE_UNAFFECTED
);
5266 rval
= AHCI_SUCCESS
;
5268 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5269 "ahci_software_reset: %s at port %d:%d",
5270 rval
== AHCI_SUCCESS
? "succeed" : "failed",
5277 * AHCI port reset ...; the physical communication between the HBA and device
5278 * on a port are disabled. This is more intrusive.
5280 * When an HBA or port reset occurs, Phy communication is going to
5281 * be re-established with the device through a COMRESET followed by the
5282 * normal out-of-band communication sequence defined in Serial ATA. At
5283 * the end of reset, the device, if working properly, will send a D2H
5284 * Register FIS, which contains the device signature. When the HBA receives
5285 * this FIS, it updates PxTFD.STS and PxTFD.ERR register fields, and updates
5286 * the PxSIG register with the signature.
5288 * NOTE: It is expected both PxCMD.ST and PxCMD.CR are cleared before the
5289 * function is called. If not, it is assumed the interface is in hung
5293 ahci_port_reset(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
5296 ahci_addr_t pmult_addr
;
5297 uint32_t port_cmd_status
;
5298 uint32_t port_scontrol
, port_sstatus
;
5299 uint32_t port_task_file
;
5300 uint32_t port_state
;
5301 uint8_t port
= addrp
->aa_port
;
5304 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
5306 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
5308 /* Target is a port multiplier port? */
5309 if (AHCI_ADDR_IS_PMPORT(addrp
))
5310 return (ahci_pmport_reset(ahci_ctlp
, ahci_portp
, addrp
));
5312 /* Otherwise it must be an HBA port. */
5313 ASSERT(AHCI_ADDR_IS_PORT(addrp
));
5315 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
5316 "Port %d port resetting...", port
);
5317 ahci_portp
->ahciport_port_state
= 0;
5319 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5320 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
5323 * According to the spec, SUD bit should be set here,
5324 * but JMicron JMB363 doesn't follow it, so print
5327 if (!(port_cmd_status
& AHCI_CMD_STATUS_SUD
))
5328 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5329 "ahci_port_reset: port %d SUD bit not set", port
);
5331 port_scontrol
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5332 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
));
5333 SCONTROL_SET_DET(port_scontrol
, SCONTROL_DET_COMRESET
);
5335 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5336 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
),
5339 /* Enable PxCMD.FRE to read device */
5340 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5341 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
5342 port_cmd_status
|AHCI_CMD_STATUS_FRE
);
5345 * The port enters P:StartComm state, and the HBA tells the link layer
5346 * to start communication, which involves sending COMRESET to the
5347 * device. And the HBA resets PxTFD.STS to 7Fh.
5349 * Give time for COMRESET to percolate, according to the AHCI
5350 * spec, software shall wait at least 1 millisecond before
5351 * clearing PxSCTL.DET
5353 drv_usecwait(AHCI_1MS_USECS
* 2);
5355 /* Fetch the SCONTROL again and rewrite the DET part with 0 */
5356 port_scontrol
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5357 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
));
5358 SCONTROL_SET_DET(port_scontrol
, SCONTROL_DET_NOACTION
);
5359 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5360 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
),
5364 * When a COMINIT is received from the device, then the port enters
5365 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5366 * PxSSTS.DET to 1h to indicate a device is detected but communication
5367 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5368 * a COMINIT has been received.
5371 * The DET field is valid only if IPM field indicates
5372 * that the interface is in active state.
5376 port_sstatus
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5377 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp
, port
));
5379 if (SSTATUS_GET_IPM(port_sstatus
) != SSTATUS_IPM_ACTIVE
) {
5381 * If the interface is not active, the DET field
5382 * is considered not accurate. So we want to
5385 SSTATUS_SET_DET(port_sstatus
, SSTATUS_DET_NODEV
);
5388 if (SSTATUS_GET_DET(port_sstatus
) == SSTATUS_DET_DEVPRE_PHYCOM
)
5391 if (loop_count
++ > AHCI_POLLRATE_PORT_SSTATUS
) {
5393 * We are effectively timing out after 0.1 sec.
5398 /* Wait for 10 millisec */
5399 drv_usecwait(AHCI_10MS_USECS
);
5402 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5403 "ahci_port_reset: 1st loop count: %d, "
5404 "port_sstatus = 0x%x port %d",
5405 loop_count
, port_sstatus
, port
);
5407 if (SSTATUS_GET_DET(port_sstatus
) != SSTATUS_DET_DEVPRE_PHYCOM
) {
5409 * Either the port is not active or there
5410 * is no device present.
5412 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_NONE
);
5413 return (AHCI_SUCCESS
);
5416 /* Clear port serror register for the port */
5417 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5418 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
5419 AHCI_SERROR_CLEAR_ALL
);
5422 * Devices should return a FIS contains its signature to HBA after
5423 * COMINIT signal. Check whether a D2H Register FIS is received by
5424 * polling PxTFD.STS.
5429 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5430 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp
, port
));
5432 if ((port_task_file
& (AHCI_TFD_STS_BSY
| AHCI_TFD_STS_DRQ
|
5433 AHCI_TFD_STS_ERR
)) == 0)
5436 if (loop_count
++ > AHCI_POLLRATE_PORT_TFD_ERROR
) {
5438 * We are effectively timing out after 11 sec.
5440 cmn_err(CE_WARN
, "!ahci%d: ahci_port_reset port %d "
5441 "the device hardware has been initialized and "
5442 "the power-up diagnostics failed",
5445 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_port_reset: "
5446 "port %d: some or all of BSY, DRQ and ERR in "
5447 "PxTFD.STS are not clear. We need another "
5448 "software reset.", port
);
5450 /* Clear port serror register for the port */
5451 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5452 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
5453 AHCI_SERROR_CLEAR_ALL
);
5455 AHCI_ADDR_SET_PMULT(&pmult_addr
, port
);
5457 /* Try another software reset. */
5458 if (ahci_software_reset(ahci_ctlp
, ahci_portp
,
5459 &pmult_addr
) != AHCI_SUCCESS
) {
5460 AHCIPORT_SET_STATE(ahci_portp
, addrp
,
5461 SATA_PSTATE_FAILED
);
5462 return (AHCI_FAILURE
);
5467 /* Wait for 10 millisec */
5468 drv_usecwait(AHCI_10MS_USECS
);
5471 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5472 "ahci_port_reset: 2nd loop count: %d, "
5473 "port_task_file = 0x%x port %d",
5474 loop_count
, port_task_file
, port
);
5476 /* Clear port serror register for the port */
5477 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5478 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
5479 AHCI_SERROR_CLEAR_ALL
);
5481 /* Set port as ready */
5482 port_state
= AHCIPORT_GET_STATE(ahci_portp
, addrp
);
5483 AHCIPORT_SET_STATE(ahci_portp
, addrp
, port_state
|SATA_STATE_READY
);
5485 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_ERRS
, ahci_ctlp
,
5486 "ahci_port_reset: succeed at port %d.", port
);
5487 return (AHCI_SUCCESS
);
5491 * COMRESET on a port multiplier port.
5493 * NOTE: Only called in ahci_port_reset()
5496 ahci_pmport_reset(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
5499 uint32_t port_scontrol
, port_sstatus
, port_serror
;
5500 uint32_t port_cmd_status
, port_intr_status
;
5501 uint32_t port_state
;
5502 uint8_t port
= addrp
->aa_port
;
5503 uint8_t pmport
= addrp
->aa_pmport
;
5505 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
5507 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
5508 "port %d:%d: pmport resetting", port
, pmport
);
5510 /* Initialize pmport state */
5511 AHCIPORT_SET_STATE(ahci_portp
, addrp
, 0);
5513 READ_PMULT(addrp
, SATA_PMULT_REG_SCTL
, &port_scontrol
, err
);
5514 SCONTROL_SET_DET(port_scontrol
, SCONTROL_DET_COMRESET
);
5515 WRITE_PMULT(addrp
, SATA_PMULT_REG_SCTL
, port_scontrol
, err
);
5517 /* PxCMD.FRE should be set before. */
5518 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5519 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
5520 ASSERT(port_cmd_status
& AHCI_CMD_STATUS_FRE
);
5521 if (!(port_cmd_status
& AHCI_CMD_STATUS_FRE
))
5522 return (AHCI_FAILURE
);
5525 * Give time for COMRESET to percolate, according to the AHCI
5526 * spec, software shall wait at least 1 millisecond before
5527 * clearing PxSCTL.DET
5529 drv_usecwait(AHCI_1MS_USECS
*2);
5532 * Fetch the SCONTROL again and rewrite the DET part with 0
5533 * This will generate an Asychronous Notification events.
5535 READ_PMULT(addrp
, SATA_PMULT_REG_SCTL
, &port_scontrol
, err
);
5536 SCONTROL_SET_DET(port_scontrol
, SCONTROL_DET_NOACTION
);
5537 WRITE_PMULT(addrp
, SATA_PMULT_REG_SCTL
, port_scontrol
, err
);
5540 * The port enters P:StartComm state, and HBA tells link layer to
5541 * start communication, which involves sending COMRESET to device.
5542 * And the HBA resets PxTFD.STS to 7Fh.
5544 * When a COMINIT is received from the device, then the port enters
5545 * P:ComInit state. And HBA sets PxTFD.STS to FFh or 80h. HBA sets
5546 * PxSSTS.DET to 1h to indicate a device is detected but communication
5547 * is not yet established. HBA sets PxSERR.DIAG.X to '1' to indicate
5548 * a COMINIT has been received.
5551 * The DET field is valid only if IPM field indicates
5552 * that the interface is in active state.
5556 READ_PMULT(addrp
, SATA_PMULT_REG_SSTS
, &port_sstatus
, err
);
5558 if (SSTATUS_GET_IPM(port_sstatus
) != SSTATUS_IPM_ACTIVE
) {
5560 * If the interface is not active, the DET field
5561 * is considered not accurate. So we want to
5564 SSTATUS_SET_DET(port_sstatus
, SSTATUS_DET_NODEV
);
5567 if (loop_count
++ > AHCI_POLLRATE_PORT_SSTATUS
) {
5569 * We are effectively timing out after 0.1 sec.
5574 /* Wait for 10 millisec */
5575 drv_usecwait(AHCI_10MS_USECS
);
5577 } while (SSTATUS_GET_DET(port_sstatus
) != SSTATUS_DET_DEVPRE_PHYCOM
);
5579 AHCIDBG(AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5580 "ahci_pmport_reset: 1st loop count: %d, "
5581 "port_sstatus = 0x%x port %d:%d",
5582 loop_count
, port_sstatus
, port
, pmport
);
5584 if ((SSTATUS_GET_IPM(port_sstatus
) != SSTATUS_IPM_ACTIVE
) ||
5585 (SSTATUS_GET_DET(port_sstatus
) != SSTATUS_DET_DEVPRE_PHYCOM
)) {
5587 * Either the port is not active or there
5588 * is no device present.
5590 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INFO
, ahci_ctlp
,
5591 "ahci_pmport_reset: "
5592 "no device attached to port %d:%d",
5594 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_NONE
);
5595 return (AHCI_SUCCESS
);
5598 /* Now we can make sure there is a device connected to the port */
5599 /* COMINIT signal is supposed to be received (PxSERR.DIAG.X = '1') */
5600 READ_PMULT(addrp
, SATA_PMULT_REG_SERR
, &port_serror
, err
);
5602 if (!(port_serror
& (1 << 26))) {
5603 cmn_err(CE_WARN
, "!ahci%d: ahci_pmport_reset: "
5604 "COMINIT signal from the device not received port %d:%d",
5605 instance
, port
, pmport
);
5607 AHCIPORT_SET_STATE(ahci_portp
, addrp
, SATA_PSTATE_FAILED
);
5608 return (AHCI_FAILURE
);
5612 * After clear PxSERR register, we will receive a D2H FIS.
5613 * Normally this FIS will cause a IPMS error according to AHCI spec
5614 * v1.2 because there is no command outstanding for it. So we need
5615 * to ignore this error.
5617 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_IGNORE_IPMS
;
5618 WRITE_PMULT(addrp
, SATA_PMULT_REG_SERR
, AHCI_SERROR_CLEAR_ALL
, err
);
5620 /* Now we need to check the D2H FIS by checking IPMS error. */
5623 port_intr_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5624 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp
, port
));
5626 if (loop_count
++ > AHCI_POLLRATE_PORT_TFD_ERROR
) {
5628 * No D2H FIS received. This is possible according
5631 cmn_err(CE_WARN
, "ahci_port_reset: port %d:%d "
5632 "PxIS.IPMS is not set, we need another "
5633 "software reset.", port
, pmport
);
5638 /* Wait for 10 millisec */
5639 mutex_exit(&ahci_portp
->ahciport_mutex
);
5640 delay(AHCI_10MS_TICKS
);
5641 mutex_enter(&ahci_portp
->ahciport_mutex
);
5643 } while (!(port_intr_status
& AHCI_INTR_STATUS_IPMS
));
5645 AHCIDBG(AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5646 "ahci_pmport_reset: 2st loop count: %d, "
5647 "port_sstatus = 0x%x port %d:%d",
5648 loop_count
, port_sstatus
, port
, pmport
);
5651 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5652 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp
, port
),
5653 AHCI_INTR_STATUS_IPMS
);
5654 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_IGNORE_IPMS
;
5656 /* This pmport is now ready for ahci_tran_start() */
5657 port_state
= AHCIPORT_GET_STATE(ahci_portp
, addrp
);
5658 AHCIPORT_SET_STATE(ahci_portp
, addrp
, port_state
|SATA_STATE_READY
);
5660 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_ERRS
, ahci_ctlp
,
5661 "ahci_pmport_reset: succeed at port %d:%d", port
, pmport
);
5662 return (AHCI_SUCCESS
);
5664 err
: /* R/W PMULT error */
5665 /* IPMS flags might be set before. */
5666 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_IGNORE_IPMS
;
5667 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_ERRS
, ahci_ctlp
,
5668 "ahci_pmport_reset: failed at port %d:%d", port
, pmport
);
5670 return (AHCI_FAILURE
);
5674 * AHCI HBA reset ...; the entire HBA is reset, and all ports are disabled.
5675 * This is the most intrusive.
5677 * When an HBA reset occurs, Phy communication will be re-established with
5678 * the device through a COMRESET followed by the normal out-of-band
5679 * communication sequence defined in Serial ATA. At the end of reset, the
5680 * device, if working properly, will send a D2H Register FIS, which contains
5681 * the device signature. When the HBA receives this FIS, it updates PxTFD.STS
5682 * and PxTFD.ERR register fields, and updates the PxSIG register with the
5685 * Remember to set GHC.AE to 1 before calling ahci_hba_reset.
5688 ahci_hba_reset(ahci_ctl_t
*ahci_ctlp
)
5690 ahci_port_t
*ahci_portp
;
5691 uint32_t ghc_control
;
5694 int rval
= AHCI_SUCCESS
;
5696 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
, "HBA resetting",
5699 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
5701 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5702 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
5704 /* Setting GHC.HR to 1, remember GHC.AE is already set to 1 before */
5705 ghc_control
|= AHCI_HBA_GHC_HR
;
5706 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5707 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
), ghc_control
);
5710 * Wait until HBA Reset complete or timeout
5714 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5715 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
5717 if (loop_count
++ > AHCI_POLLRATE_HBA_RESET
) {
5718 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
5719 "ahci hba reset is timing out, "
5720 "ghc_control = 0x%x", ghc_control
);
5721 /* We are effectively timing out after 1 sec. */
5725 /* Wait for 10 millisec */
5726 drv_usecwait(AHCI_10MS_USECS
);
5727 } while (ghc_control
& AHCI_HBA_GHC_HR
);
5729 AHCIDBG(AHCIDBG_POLL_LOOP
, ahci_ctlp
,
5730 "ahci_hba_reset: 1st loop count: %d, "
5731 "ghc_control = 0x%x", loop_count
, ghc_control
);
5733 if (ghc_control
& AHCI_HBA_GHC_HR
) {
5734 /* The hba is not reset for some reasons */
5735 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
5736 "hba reset failed: HBA in a hung or locked state", NULL
);
5737 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
5738 return (AHCI_FAILURE
);
5742 * HBA reset will clear (AHCI Spec v1.2 10.4.3) GHC.IE / GHC.AE
5744 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5745 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
5746 ghc_control
|= (AHCI_HBA_GHC_AE
| AHCI_HBA_GHC_IE
);
5747 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5748 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
), ghc_control
);
5750 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
5752 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
5753 /* Only check implemented ports */
5754 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
5758 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
5759 mutex_enter(&ahci_portp
->ahciport_mutex
);
5761 /* Make sure the drive is spun-up */
5762 ahci_staggered_spin_up(ahci_ctlp
, port
);
5764 if (ahci_restart_port_wait_till_ready(ahci_ctlp
, ahci_portp
,
5765 port
, AHCI_PORT_RESET
|AHCI_RESET_NO_EVENTS_UP
, NULL
) !=
5767 rval
= AHCI_FAILURE
;
5768 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5769 "ahci_hba_reset: port %d failed", port
);
5771 * Set the port state to SATA_PSTATE_FAILED if
5772 * failed to initialize it.
5774 ahci_portp
->ahciport_port_state
= SATA_PSTATE_FAILED
;
5777 mutex_exit(&ahci_portp
->ahciport_mutex
);
5784 * This routine is only called from AHCI_ATTACH or phyrdy change
5785 * case. It first calls software reset, then stop the port and try to
5786 * read PxSIG register to find the type of device attached to the port.
5788 * The caller should make sure a valid device exists on specified port and
5789 * physical communication has been established so that the signature could
5790 * be retrieved by software reset.
5792 * NOTE: The port interrupts should be disabled before the function is called.
5795 ahci_find_dev_signature(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
5798 ahci_addr_t dev_addr
;
5800 uint8_t port
= addrp
->aa_port
;
5801 uint8_t pmport
= addrp
->aa_pmport
;
5804 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
5805 ASSERT(AHCI_ADDR_IS_VALID(addrp
));
5808 * If the HBA doesn't support port multiplier, then the driver
5809 * doesn't need to bother to check port multiplier device.
5811 * The second port of ICH7 on ASUS P5W DH deluxe motherboard is
5812 * connected to Silicon Image 4723, to which the two sata drives
5813 * attached can be set with RAID1, RAID0 or Spanning mode.
5815 * We found software reset will get failure if port multiplier address
5816 * 0xf is used by software reset, so just ignore the check since
5817 * ICH7 doesn't support port multiplier device at all.
5819 if (AHCI_ADDR_IS_PORT(addrp
) &&
5820 (ahci_ctlp
->ahcictl_cap
& AHCI_CAP_PMULT_CBSS
)) {
5821 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
5822 "ahci_find_dev_signature enter: port %d", port
);
5825 * NOTE: when the ahci address is a HBA port, we do not know
5826 * it is a device or a port multiplier that attached. we need
5827 * try a software reset at port multiplier address (0xf
5830 AHCI_ADDR_SET_PMULT(&dev_addr
, addrp
->aa_port
);
5832 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
5833 "ahci_find_dev_signature enter: port %d:%d",
5838 /* Assume it is unknown. */
5839 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_UNKNOWN
);
5841 /* Issue a software reset to get the signature */
5842 rval
= ahci_software_reset(ahci_ctlp
, ahci_portp
, &dev_addr
);
5843 if (rval
!= AHCI_SUCCESS
) {
5846 * Try to do software reset again with pmport set with 0 if
5847 * the controller is set with AHCI_CAP_SRST_NO_HOSTPORT and
5848 * the original pmport is set with SATA_PMULT_HOSTPORT (0xf)
5850 if ((ahci_ctlp
->ahcictl_cap
& AHCI_CAP_SRST_NO_HOSTPORT
) &&
5851 (dev_addr
.aa_pmport
== SATA_PMULT_HOSTPORT
)) {
5852 dev_addr
.aa_pmport
= 0;
5853 rval
= ahci_software_reset(ahci_ctlp
, ahci_portp
,
5857 if (rval
!= AHCI_SUCCESS
) {
5858 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
5859 "ahci_find_dev_signature: software reset failed "
5860 "at port %d:%d, cannot get signature.",
5863 AHCIPORT_SET_STATE(ahci_portp
, addrp
,
5864 SATA_PSTATE_FAILED
);
5870 * ahci_software_reset has started the port, so we need manually stop
5873 if (AHCI_ADDR_IS_PORT(addrp
)) {
5874 if (ahci_put_port_into_notrunning_state(ahci_ctlp
,
5875 ahci_portp
, port
) != AHCI_SUCCESS
) {
5876 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
5877 "ahci_find_dev_signature: cannot stop port %d.",
5879 ahci_portp
->ahciport_port_state
= SATA_PSTATE_FAILED
;
5884 /* Now we can make sure that a valid signature is received. */
5885 signature
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5886 (uint32_t *)AHCI_PORT_PxSIG(ahci_ctlp
, port
));
5888 if (AHCI_ADDR_IS_PMPORT(addrp
)) {
5889 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
5890 "ahci_find_dev_signature: signature = 0x%x at port %d:%d",
5891 signature
, port
, pmport
);
5893 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_INFO
, ahci_ctlp
,
5894 "ahci_find_dev_signature: signature = 0x%x at port %d",
5898 /* NOTE: Only support ATAPI device at controller port. */
5899 if (signature
== AHCI_SIGNATURE_ATAPI
&& !AHCI_ADDR_IS_PORT(addrp
))
5900 signature
= SATA_DTYPE_UNKNOWN
;
5902 switch (signature
) {
5904 case AHCI_SIGNATURE_DISK
:
5905 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_ATADISK
);
5906 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
5907 "Disk is found at port: %d", port
);
5910 case AHCI_SIGNATURE_ATAPI
:
5911 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_ATAPI
);
5912 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
5913 "ATAPI device is found at port: %d", port
);
5916 case AHCI_SIGNATURE_PORT_MULTIPLIER
:
5917 /* Port Multiplier cannot recursively attached. */
5918 ASSERT(AHCI_ADDR_IS_PORT(addrp
));
5919 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_PMULT
);
5920 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
5921 "Port Multiplier is found at port: %d", port
);
5925 AHCIPORT_SET_DEV_TYPE(ahci_portp
, addrp
, SATA_DTYPE_UNKNOWN
);
5926 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
5927 "Unknown device is found at port: %d", port
);
5932 * According to the spec, to reliably detect hot plug removals, software
5933 * must disable interface power management. Software should perform the
5934 * following initialization on a port after a device is attached:
5935 * Set PxSCTL.IPM to 3h to disable interface state transitions
5936 * Set PxCMD.ALPE to '0' to disable aggressive power management
5937 * Disable device initiated interface power management by SET FEATURE
5939 * We can ignore the last item because by default the feature is disabled
5942 ahci_disable_interface_pm(ahci_ctl_t
*ahci_ctlp
, uint8_t port
)
5944 uint32_t port_scontrol
, port_cmd_status
;
5946 port_scontrol
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5947 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
));
5948 SCONTROL_SET_IPM(port_scontrol
, SCONTROL_IPM_DISABLE_BOTH
);
5949 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5950 (uint32_t *)AHCI_PORT_PxSCTL(ahci_ctlp
, port
), port_scontrol
);
5952 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5953 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
5954 port_cmd_status
&= ~AHCI_CMD_STATUS_ALPE
;
5955 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5956 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
), port_cmd_status
);
5960 * Start the port - set PxCMD.ST to 1, if PxCMD.FRE is not set
5961 * to 1, then set it firstly.
5963 * Each port contains two major DMA engines. One DMA engine walks through
5964 * the command list, and is controlled by PxCMD.ST. The second DMA engine
5965 * copies received FISes into system memory, and is controlled by PxCMD.FRE.
5967 * Software shall not set PxCMD.ST to '1' until it verifies that PxCMD.CR
5968 * is '0' and has set PxCMD.FRE is '1'. And software shall not clear
5969 * PxCMD.FRE while PxCMD.ST or PxCMD.CR is set '1'.
5971 * Software shall not set PxCMD.ST to '1' unless a functional device is
5972 * present on the port(as determined by PxTFD.STS.BSY = '0',
5973 * PxTFD.STS.DRQ = '0', and PxSSTS.DET = 3h).
5976 ahci_start_port(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
, uint8_t port
)
5978 uint32_t port_cmd_status
;
5980 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
5982 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_start_port: %d enter", port
);
5984 if (ahci_portp
->ahciport_port_state
& SATA_PSTATE_FAILED
) {
5985 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_start_port failed "
5986 "the state for port %d is 0x%x",
5987 port
, ahci_portp
->ahciport_port_state
);
5988 return (AHCI_FAILURE
);
5991 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
) {
5992 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_start_port failed "
5993 "no device is attached at port %d", port
);
5994 return (AHCI_FAILURE
);
5997 /* First to set PxCMD.FRE before setting PxCMD.ST. */
5998 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
5999 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
6001 if (!(port_cmd_status
& AHCI_CMD_STATUS_FRE
)) {
6002 port_cmd_status
|= AHCI_CMD_STATUS_FRE
;
6003 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6004 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
6008 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6009 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
6011 port_cmd_status
|= AHCI_CMD_STATUS_ST
;
6013 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6014 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
6017 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_STARTED
;
6019 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_start_port: "
6020 "PxCMD.ST set to '1' at port %d", port
);
6022 return (AHCI_SUCCESS
);
6026 * Setup PxCLB, PxCLBU, PxFB, and PxFBU for particular port. First, we need
6027 * to make sure PxCMD.ST, PxCMD.CR, PxCMD.FRE, and PxCMD.FR are all cleared.
6028 * Then set PxCLB, PxCLBU, PxFB, and PxFBU.
6031 ahci_setup_port_base_addresses(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
6033 uint8_t port
= ahci_portp
->ahciport_port_num
;
6034 uint32_t port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6035 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
6037 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6039 /* Step 1: Make sure both PxCMD.ST and PxCMD.CR are cleared. */
6040 if (port_cmd_status
& (AHCI_CMD_STATUS_ST
| AHCI_CMD_STATUS_CR
)) {
6041 if (ahci_put_port_into_notrunning_state(ahci_ctlp
, ahci_portp
,
6042 port
) != AHCI_SUCCESS
)
6043 return (AHCI_FAILURE
);
6045 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6046 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
6049 /* Step 2: Make sure both PxCMD.FRE and PxCMD.FR are cleared. */
6050 if (port_cmd_status
& (AHCI_CMD_STATUS_FRE
| AHCI_CMD_STATUS_FR
)) {
6053 /* Clear PxCMD.FRE */
6054 port_cmd_status
&= ~AHCI_CMD_STATUS_FRE
;
6055 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6056 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
),
6059 /* Wait until PxCMD.FR is cleared */
6062 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6063 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
6065 if (!(port_cmd_status
& AHCI_CMD_STATUS_FR
))
6068 if (loop_count
++ >= AHCI_POLLRATE_PORT_IDLE_FR
) {
6069 AHCIDBG(AHCIDBG_INIT
| AHCIDBG_ERRS
, ahci_ctlp
,
6070 "ahci_setup_port_base_addresses: cannot "
6071 "clear PxCMD.FR for port %d.", port
);
6074 * We are effectively timing out after 0.5 sec.
6075 * This value is specified in AHCI spec.
6077 return (AHCI_FAILURE
);
6080 /* Wait for 1 millisec */
6081 drv_usecwait(AHCI_1MS_USECS
);
6085 /* Step 3: Config Port Command List Base Address */
6086 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6087 (uint32_t *)AHCI_PORT_PxCLB(ahci_ctlp
, port
),
6088 ahci_portp
->ahciport_cmd_list_dma_cookie
.dmac_address
);
6090 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6091 (uint32_t *)AHCI_PORT_PxCLBU(ahci_ctlp
, port
),
6092 ahci_portp
->ahciport_cmd_list_dma_cookie
.dmac_notused
);
6094 /* Step 4: Config Port Received FIS Base Address */
6095 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6096 (uint32_t *)AHCI_PORT_PxFB(ahci_ctlp
, port
),
6097 ahci_portp
->ahciport_rcvd_fis_dma_cookie
.dmac_address
);
6099 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6100 (uint32_t *)AHCI_PORT_PxFBU(ahci_ctlp
, port
),
6101 ahci_portp
->ahciport_rcvd_fis_dma_cookie
.dmac_notused
);
6103 return (AHCI_SUCCESS
);
6107 * Allocate the ahci_port_t including Received FIS and Command List.
6108 * The argument - port is the physical port number, and not logical
6109 * port number seen by the SATA framework.
6112 ahci_alloc_port_state(ahci_ctl_t
*ahci_ctlp
, uint8_t port
)
6114 dev_info_t
*dip
= ahci_ctlp
->ahcictl_dip
;
6115 ahci_port_t
*ahci_portp
;
6116 char taskq_name
[64] = "event_handle_taskq";
6118 ASSERT(MUTEX_HELD(&ahci_ctlp
->ahcictl_mutex
));
6121 (ahci_port_t
*)kmem_zalloc(sizeof (ahci_port_t
), KM_SLEEP
);
6123 ahci_ctlp
->ahcictl_ports
[port
] = ahci_portp
;
6124 ahci_portp
->ahciport_port_num
= port
;
6126 /* Initialize the port condition variable */
6127 cv_init(&ahci_portp
->ahciport_cv
, NULL
, CV_DRIVER
, NULL
);
6129 /* Initialize the port mutex */
6130 mutex_init(&ahci_portp
->ahciport_mutex
, NULL
, MUTEX_DRIVER
,
6131 (void *)(uintptr_t)ahci_ctlp
->ahcictl_intr_pri
);
6133 mutex_enter(&ahci_portp
->ahciport_mutex
);
6136 * Allocate memory for received FIS structure and
6137 * command list for this port
6139 if (ahci_alloc_rcvd_fis(ahci_ctlp
, ahci_portp
) != AHCI_SUCCESS
) {
6143 if (ahci_alloc_cmd_list(ahci_ctlp
, ahci_portp
) != AHCI_SUCCESS
) {
6147 /* Setup PxCMD.CLB, PxCMD.CLBU, PxCMD.FB, and PxCMD.FBU */
6148 if (ahci_setup_port_base_addresses(ahci_ctlp
, ahci_portp
) !=
6153 (void) snprintf(taskq_name
+ strlen(taskq_name
),
6154 sizeof (taskq_name
) - strlen(taskq_name
),
6157 /* Create the taskq for the port */
6158 if ((ahci_portp
->ahciport_event_taskq
= ddi_taskq_create(dip
,
6159 taskq_name
, 2, TASKQ_DEFAULTPRI
, 0)) == NULL
) {
6160 cmn_err(CE_WARN
, "!ahci%d: ddi_taskq_create failed for event "
6161 "handle", ddi_get_instance(ahci_ctlp
->ahcictl_dip
));
6165 /* Allocate the argument for the taskq */
6166 ahci_portp
->ahciport_event_args
=
6167 kmem_zalloc(sizeof (ahci_event_arg_t
), KM_SLEEP
);
6169 ahci_portp
->ahciport_event_args
->ahciea_addrp
=
6170 kmem_zalloc(sizeof (ahci_addr_t
), KM_SLEEP
);
6172 if (ahci_portp
->ahciport_event_args
== NULL
)
6175 /* Initialize the done queue */
6176 ahci_portp
->ahciport_doneq
= NULL
;
6177 ahci_portp
->ahciport_doneqtail
= &ahci_portp
->ahciport_doneq
;
6178 ahci_portp
->ahciport_doneq_len
= 0;
6180 mutex_exit(&ahci_portp
->ahciport_mutex
);
6182 return (AHCI_SUCCESS
);
6185 ddi_taskq_destroy(ahci_portp
->ahciport_event_taskq
);
6188 ahci_dealloc_cmd_list(ahci_ctlp
, ahci_portp
);
6191 ahci_dealloc_rcvd_fis(ahci_portp
);
6194 mutex_exit(&ahci_portp
->ahciport_mutex
);
6195 mutex_destroy(&ahci_portp
->ahciport_mutex
);
6196 cv_destroy(&ahci_portp
->ahciport_cv
);
6198 kmem_free(ahci_portp
, sizeof (ahci_port_t
));
6200 return (AHCI_FAILURE
);
6204 * Reverse of ahci_alloc_port_state().
6207 ahci_dealloc_port_state(ahci_ctl_t
*ahci_ctlp
, uint8_t port
)
6209 ahci_port_t
*ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
6211 ASSERT(MUTEX_HELD(&ahci_ctlp
->ahcictl_mutex
));
6212 ASSERT(ahci_portp
!= NULL
);
6214 mutex_enter(&ahci_portp
->ahciport_mutex
);
6215 kmem_free(ahci_portp
->ahciport_event_args
->ahciea_addrp
,
6216 sizeof (ahci_addr_t
));
6217 ahci_portp
->ahciport_event_args
->ahciea_addrp
= NULL
;
6218 kmem_free(ahci_portp
->ahciport_event_args
, sizeof (ahci_event_arg_t
));
6219 ahci_portp
->ahciport_event_args
= NULL
;
6220 ddi_taskq_destroy(ahci_portp
->ahciport_event_taskq
);
6221 ahci_dealloc_cmd_list(ahci_ctlp
, ahci_portp
);
6222 ahci_dealloc_rcvd_fis(ahci_portp
);
6223 ahci_dealloc_pmult(ahci_ctlp
, ahci_portp
);
6224 mutex_exit(&ahci_portp
->ahciport_mutex
);
6226 mutex_destroy(&ahci_portp
->ahciport_mutex
);
6227 cv_destroy(&ahci_portp
->ahciport_cv
);
6229 kmem_free(ahci_portp
, sizeof (ahci_port_t
));
6231 ahci_ctlp
->ahcictl_ports
[port
] = NULL
;
6235 * Allocates memory for the Received FIS Structure
6238 ahci_alloc_rcvd_fis(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
6240 size_t rcvd_fis_size
;
6242 uint_t cookie_count
;
6244 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6246 rcvd_fis_size
= sizeof (ahci_rcvd_fis_t
);
6248 /* allocate rcvd FIS dma handle. */
6249 if (ddi_dma_alloc_handle(ahci_ctlp
->ahcictl_dip
,
6250 &ahci_ctlp
->ahcictl_rcvd_fis_dma_attr
,
6253 &ahci_portp
->ahciport_rcvd_fis_dma_handle
) !=
6255 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6256 "rcvd FIS dma handle alloc failed", NULL
);
6258 return (AHCI_FAILURE
);
6261 if (ddi_dma_mem_alloc(ahci_portp
->ahciport_rcvd_fis_dma_handle
,
6267 (caddr_t
*)&ahci_portp
->ahciport_rcvd_fis
,
6269 &ahci_portp
->ahciport_rcvd_fis_acc_handle
) != NULL
) {
6271 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6272 "rcvd FIS dma mem alloc fail", NULL
);
6273 /* error.. free the dma handle. */
6274 ddi_dma_free_handle(&ahci_portp
->ahciport_rcvd_fis_dma_handle
);
6275 return (AHCI_FAILURE
);
6278 if (ddi_dma_addr_bind_handle(ahci_portp
->ahciport_rcvd_fis_dma_handle
,
6280 (caddr_t
)ahci_portp
->ahciport_rcvd_fis
,
6282 DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
,
6285 &ahci_portp
->ahciport_rcvd_fis_dma_cookie
,
6286 &cookie_count
) != DDI_DMA_MAPPED
) {
6288 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6289 "rcvd FIS dma handle bind fail", NULL
);
6290 /* error.. free the dma handle & free the memory. */
6291 ddi_dma_mem_free(&ahci_portp
->ahciport_rcvd_fis_acc_handle
);
6292 ddi_dma_free_handle(&ahci_portp
->ahciport_rcvd_fis_dma_handle
);
6293 return (AHCI_FAILURE
);
6296 bzero((void *)ahci_portp
->ahciport_rcvd_fis
, rcvd_fis_size
);
6298 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "64-bit, dma address: 0x%llx",
6299 ahci_portp
->ahciport_rcvd_fis_dma_cookie
.dmac_laddress
);
6300 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "32-bit, dma address: 0x%x",
6301 ahci_portp
->ahciport_rcvd_fis_dma_cookie
.dmac_address
);
6303 return (AHCI_SUCCESS
);
6307 * Deallocates the Received FIS Structure
6310 ahci_dealloc_rcvd_fis(ahci_port_t
*ahci_portp
)
6312 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6314 /* Unbind the cmd list dma handle first. */
6315 (void) ddi_dma_unbind_handle(ahci_portp
->ahciport_rcvd_fis_dma_handle
);
6317 /* Then free the underlying memory. */
6318 ddi_dma_mem_free(&ahci_portp
->ahciport_rcvd_fis_acc_handle
);
6320 /* Now free the handle itself. */
6321 ddi_dma_free_handle(&ahci_portp
->ahciport_rcvd_fis_dma_handle
);
6325 * Allocates memory for the Command List, which contains up to 32 entries.
6326 * Each entry contains a command header, which is a 32-byte structure that
6327 * includes the pointer to the command table.
6330 ahci_alloc_cmd_list(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
6332 size_t cmd_list_size
;
6334 uint_t cookie_count
;
6336 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6339 ahci_ctlp
->ahcictl_num_cmd_slots
* sizeof (ahci_cmd_header_t
);
6341 /* allocate cmd list dma handle. */
6342 if (ddi_dma_alloc_handle(ahci_ctlp
->ahcictl_dip
,
6343 &ahci_ctlp
->ahcictl_cmd_list_dma_attr
,
6346 &ahci_portp
->ahciport_cmd_list_dma_handle
) != DDI_SUCCESS
) {
6348 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6349 "cmd list dma handle alloc failed", NULL
);
6350 return (AHCI_FAILURE
);
6353 if (ddi_dma_mem_alloc(ahci_portp
->ahciport_cmd_list_dma_handle
,
6359 (caddr_t
*)&ahci_portp
->ahciport_cmd_list
,
6361 &ahci_portp
->ahciport_cmd_list_acc_handle
) != NULL
) {
6363 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6364 "cmd list dma mem alloc fail", NULL
);
6365 /* error.. free the dma handle. */
6366 ddi_dma_free_handle(&ahci_portp
->ahciport_cmd_list_dma_handle
);
6367 return (AHCI_FAILURE
);
6370 if (ddi_dma_addr_bind_handle(ahci_portp
->ahciport_cmd_list_dma_handle
,
6372 (caddr_t
)ahci_portp
->ahciport_cmd_list
,
6374 DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
,
6377 &ahci_portp
->ahciport_cmd_list_dma_cookie
,
6378 &cookie_count
) != DDI_DMA_MAPPED
) {
6380 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6381 "cmd list dma handle bind fail", NULL
);
6382 /* error.. free the dma handle & free the memory. */
6383 ddi_dma_mem_free(&ahci_portp
->ahciport_cmd_list_acc_handle
);
6384 ddi_dma_free_handle(&ahci_portp
->ahciport_cmd_list_dma_handle
);
6385 return (AHCI_FAILURE
);
6388 bzero((void *)ahci_portp
->ahciport_cmd_list
, cmd_list_size
);
6390 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "64-bit, dma address: 0x%llx",
6391 ahci_portp
->ahciport_cmd_list_dma_cookie
.dmac_laddress
);
6393 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
, "32-bit, dma address: 0x%x",
6394 ahci_portp
->ahciport_cmd_list_dma_cookie
.dmac_address
);
6396 if (ahci_alloc_cmd_tables(ahci_ctlp
, ahci_portp
) != AHCI_SUCCESS
) {
6400 return (AHCI_SUCCESS
);
6403 /* Unbind the cmd list dma handle first. */
6404 (void) ddi_dma_unbind_handle(ahci_portp
->ahciport_cmd_list_dma_handle
);
6406 /* Then free the underlying memory. */
6407 ddi_dma_mem_free(&ahci_portp
->ahciport_cmd_list_acc_handle
);
6409 /* Now free the handle itself. */
6410 ddi_dma_free_handle(&ahci_portp
->ahciport_cmd_list_dma_handle
);
6412 return (AHCI_FAILURE
);
6416 * Deallocates the Command List
6419 ahci_dealloc_cmd_list(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
6421 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6423 /* First dealloc command table */
6424 ahci_dealloc_cmd_tables(ahci_ctlp
, ahci_portp
);
6426 /* Unbind the cmd list dma handle first. */
6427 (void) ddi_dma_unbind_handle(ahci_portp
->ahciport_cmd_list_dma_handle
);
6429 /* Then free the underlying memory. */
6430 ddi_dma_mem_free(&ahci_portp
->ahciport_cmd_list_acc_handle
);
6432 /* Now free the handle itself. */
6433 ddi_dma_free_handle(&ahci_portp
->ahciport_cmd_list_dma_handle
);
6437 * Allocates memory for all Command Tables, which contains Command FIS,
6438 * ATAPI Command and Physical Region Descriptor Table.
6441 ahci_alloc_cmd_tables(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
6444 ddi_dma_cookie_t cmd_table_dma_cookie
;
6445 uint_t cookie_count
;
6448 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6450 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_ENTRY
, ahci_ctlp
,
6451 "ahci_alloc_cmd_tables: port %d enter",
6452 ahci_portp
->ahciport_port_num
);
6454 for (slot
= 0; slot
< ahci_ctlp
->ahcictl_num_cmd_slots
; slot
++) {
6455 /* Allocate cmd table dma handle. */
6456 if (ddi_dma_alloc_handle(ahci_ctlp
->ahcictl_dip
,
6457 &ahci_ctlp
->ahcictl_cmd_table_dma_attr
,
6460 &ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]) !=
6463 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6464 "cmd table dma handle alloc failed", NULL
);
6469 if (ddi_dma_mem_alloc(
6470 ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
],
6471 ahci_cmd_table_size
,
6476 (caddr_t
*)&ahci_portp
->ahciport_cmd_tables
[slot
],
6478 &ahci_portp
->ahciport_cmd_tables_acc_handle
[slot
]) !=
6481 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6482 "cmd table dma mem alloc fail", NULL
);
6484 /* error.. free the dma handle. */
6485 ddi_dma_free_handle(
6486 &ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]);
6490 if (ddi_dma_addr_bind_handle(
6491 ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
],
6493 (caddr_t
)ahci_portp
->ahciport_cmd_tables
[slot
],
6494 ahci_cmd_table_size
,
6495 DDI_DMA_RDWR
| DDI_DMA_CONSISTENT
,
6498 &cmd_table_dma_cookie
,
6499 &cookie_count
) != DDI_DMA_MAPPED
) {
6501 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
6502 "cmd table dma handle bind fail", NULL
);
6503 /* error.. free the dma handle & free the memory. */
6505 &ahci_portp
->ahciport_cmd_tables_acc_handle
[slot
]);
6506 ddi_dma_free_handle(
6507 &ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]);
6511 bzero((void *)ahci_portp
->ahciport_cmd_tables
[slot
],
6512 ahci_cmd_table_size
);
6514 /* Config Port Command Table Base Address */
6515 SET_COMMAND_TABLE_BASE_ADDR(
6516 (&ahci_portp
->ahciport_cmd_list
[slot
]),
6517 cmd_table_dma_cookie
.dmac_laddress
& 0xffffffffull
);
6520 SET_COMMAND_TABLE_BASE_ADDR_UPPER(
6521 (&ahci_portp
->ahciport_cmd_list
[slot
]),
6522 cmd_table_dma_cookie
.dmac_laddress
>> 32);
6526 return (AHCI_SUCCESS
);
6529 for (slot
--; slot
>= 0; slot
--) {
6530 /* Unbind the cmd table dma handle first */
6531 (void) ddi_dma_unbind_handle(
6532 ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]);
6534 /* Then free the underlying memory */
6536 &ahci_portp
->ahciport_cmd_tables_acc_handle
[slot
]);
6538 /* Now free the handle itself */
6539 ddi_dma_free_handle(
6540 &ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]);
6543 return (AHCI_FAILURE
);
6547 * Deallocates memory for all Command Tables.
6550 ahci_dealloc_cmd_tables(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
)
6554 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
6556 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
6557 "ahci_dealloc_cmd_tables: %d enter",
6558 ahci_portp
->ahciport_port_num
);
6560 for (slot
= 0; slot
< ahci_ctlp
->ahcictl_num_cmd_slots
; slot
++) {
6561 /* Unbind the cmd table dma handle first. */
6562 (void) ddi_dma_unbind_handle(
6563 ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]);
6565 /* Then free the underlying memory. */
6567 &ahci_portp
->ahciport_cmd_tables_acc_handle
[slot
]);
6569 /* Now free the handle itself. */
6570 ddi_dma_free_handle(
6571 &ahci_portp
->ahciport_cmd_tables_dma_handle
[slot
]);
6576 * Update SATA registers at controller ports
6579 ahci_update_sata_registers(ahci_ctl_t
*ahci_ctlp
, uint8_t port
,
6582 ASSERT(MUTEX_HELD(&ahci_ctlp
->ahcictl_ports
[port
]->ahciport_mutex
));
6584 sd
->satadev_scr
.sstatus
=
6585 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6586 (uint32_t *)(AHCI_PORT_PxSSTS(ahci_ctlp
, port
)));
6587 sd
->satadev_scr
.serror
=
6588 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6589 (uint32_t *)(AHCI_PORT_PxSERR(ahci_ctlp
, port
)));
6590 sd
->satadev_scr
.scontrol
=
6591 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6592 (uint32_t *)(AHCI_PORT_PxSCTL(ahci_ctlp
, port
)));
6593 sd
->satadev_scr
.sactive
=
6594 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6595 (uint32_t *)(AHCI_PORT_PxSACT(ahci_ctlp
, port
)));
6599 * For poll mode, ahci_port_intr will be called to emulate the interrupt
6602 ahci_port_intr(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
, uint8_t port
)
6604 uint32_t port_intr_status
;
6605 uint32_t port_intr_enable
;
6607 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ENTRY
, ahci_ctlp
,
6608 "ahci_port_intr enter: port %d", port
);
6610 mutex_enter(&ahci_portp
->ahciport_mutex
);
6611 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_POLLING
) {
6612 /* For SATA_OPMODE_POLLING commands */
6614 (AHCI_INTR_STATUS_DHRS
|
6615 AHCI_INTR_STATUS_PSS
|
6616 AHCI_INTR_STATUS_SDBS
|
6617 AHCI_INTR_STATUS_UFS
|
6618 AHCI_INTR_STATUS_PCS
|
6619 AHCI_INTR_STATUS_PRCS
|
6620 AHCI_INTR_STATUS_OFS
|
6621 AHCI_INTR_STATUS_INFS
|
6622 AHCI_INTR_STATUS_IFS
|
6623 AHCI_INTR_STATUS_HBDS
|
6624 AHCI_INTR_STATUS_HBFS
|
6625 AHCI_INTR_STATUS_TFES
);
6628 * port_intr_enable indicates that the corresponding interrrupt
6629 * reporting is enabled.
6631 port_intr_enable
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6632 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp
, port
));
6635 /* IPMS error in port reset should be ignored according AHCI spec. */
6636 if (!(ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_IGNORE_IPMS
))
6637 port_intr_enable
|= AHCI_INTR_STATUS_IPMS
;
6638 mutex_exit(&ahci_portp
->ahciport_mutex
);
6641 * port_intr_stats indicates that the corresponding interrupt
6642 * condition is active.
6644 port_intr_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6645 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp
, port
));
6647 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
6648 "ahci_port_intr: port %d, port_intr_status = 0x%x, "
6649 "port_intr_enable = 0x%x",
6650 port
, port_intr_status
, port_intr_enable
);
6652 port_intr_status
&= port_intr_enable
;
6655 * Pending interrupt events are indicated by the PxIS register.
6656 * Make sure we don't miss any event.
6658 if (ahci_check_ctl_handle(ahci_ctlp
) != DDI_SUCCESS
) {
6659 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
6660 DDI_SERVICE_UNAFFECTED
);
6661 ddi_fm_acc_err_clear(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6666 /* First clear the port interrupts status */
6667 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6668 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp
, port
),
6671 /* Check the completed non-queued commands */
6672 if (port_intr_status
& (AHCI_INTR_STATUS_DHRS
|
6673 AHCI_INTR_STATUS_PSS
)) {
6674 (void) ahci_intr_cmd_cmplt(ahci_ctlp
,
6678 /* Check the completed queued commands */
6679 if (port_intr_status
& AHCI_INTR_STATUS_SDBS
) {
6680 (void) ahci_intr_set_device_bits(ahci_ctlp
,
6684 /* Check the port connect change status interrupt bit */
6685 if (port_intr_status
& AHCI_INTR_STATUS_PCS
) {
6686 (void) ahci_intr_port_connect_change(ahci_ctlp
,
6690 /* Check the device mechanical presence status interrupt bit */
6691 if (port_intr_status
& AHCI_INTR_STATUS_DMPS
) {
6692 (void) ahci_intr_device_mechanical_presence_status(
6693 ahci_ctlp
, ahci_portp
, port
);
6696 /* Check the PhyRdy change status interrupt bit */
6697 if (port_intr_status
& AHCI_INTR_STATUS_PRCS
) {
6698 (void) ahci_intr_phyrdy_change(ahci_ctlp
, ahci_portp
,
6703 * Check the non-fatal error interrupt bits, there are four
6704 * kinds of non-fatal errors at the time being:
6706 * PxIS.UFS - Unknown FIS Error
6707 * PxIS.OFS - Overflow Error
6708 * PxIS.INFS - Interface Non-Fatal Error
6709 * PxIS.IPMS - Incorrect Port Multiplier Status Error
6711 * For these non-fatal errors, the HBA can continue to operate,
6712 * so the driver just log the error messages.
6714 if (port_intr_status
& (AHCI_INTR_STATUS_UFS
|
6715 AHCI_INTR_STATUS_OFS
|
6716 AHCI_INTR_STATUS_IPMS
|
6717 AHCI_INTR_STATUS_INFS
)) {
6718 (void) ahci_intr_non_fatal_error(ahci_ctlp
, ahci_portp
,
6719 port
, port_intr_status
);
6723 * Check the fatal error interrupt bits, there are four kinds
6724 * of fatal errors for AHCI controllers:
6726 * PxIS.HBFS - Host Bus Fatal Error
6727 * PxIS.HBDS - Host Bus Data Error
6728 * PxIS.IFS - Interface Fatal Error
6729 * PxIS.TFES - Task File Error
6731 * The fatal error means the HBA can not recover from it by
6732 * itself, and it will try to abort the transfer, and the software
6733 * must intervene to restart the port.
6735 if (port_intr_status
& (AHCI_INTR_STATUS_IFS
|
6736 AHCI_INTR_STATUS_HBDS
|
6737 AHCI_INTR_STATUS_HBFS
|
6738 AHCI_INTR_STATUS_TFES
))
6739 (void) ahci_intr_fatal_error(ahci_ctlp
, ahci_portp
,
6740 port
, port_intr_status
);
6742 /* Check the cold port detect interrupt bit */
6743 if (port_intr_status
& AHCI_INTR_STATUS_CPDS
) {
6744 (void) ahci_intr_cold_port_detect(ahci_ctlp
, ahci_portp
, port
);
6747 /* Second clear the corresponding bit in IS.IPS */
6748 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6749 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp
), (0x1 << port
));
6751 /* Try to recover at the end of the interrupt handler. */
6752 if (ahci_check_acc_handle(ahci_ctlp
->ahcictl_ahci_acc_handle
) !=
6754 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
6755 DDI_SERVICE_UNAFFECTED
);
6756 ddi_fm_acc_err_clear(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6762 * Interrupt service handler
6765 ahci_intr(caddr_t arg1
, caddr_t arg2
)
6768 _NOTE(ARGUNUSED(arg2
))
6771 ahci_ctl_t
*ahci_ctlp
= (ahci_ctl_t
*)arg1
;
6772 ahci_port_t
*ahci_portp
;
6773 int32_t global_intr_status
;
6777 * global_intr_status indicates that the corresponding port has
6778 * an interrupt pending.
6780 global_intr_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6781 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp
));
6783 if (!(global_intr_status
& ahci_ctlp
->ahcictl_ports_implemented
)) {
6784 /* The interrupt is not ours */
6785 return (DDI_INTR_UNCLAIMED
);
6789 * Check the handle after reading global_intr_status - we don't want
6790 * to miss any port with pending interrupts.
6792 if (ahci_check_acc_handle(ahci_ctlp
->ahcictl_ahci_acc_handle
) !=
6794 ddi_fm_service_impact(ahci_ctlp
->ahcictl_dip
,
6795 DDI_SERVICE_UNAFFECTED
);
6796 ddi_fm_acc_err_clear(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6798 return (DDI_INTR_UNCLAIMED
);
6801 /* Loop for all the ports */
6802 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
6803 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
6806 if (!((0x1 << port
) & global_intr_status
)) {
6810 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
6812 /* Call ahci_port_intr */
6813 ahci_port_intr(ahci_ctlp
, ahci_portp
, port
);
6816 return (DDI_INTR_CLAIMED
);
6820 * For non-queued commands, when the corresponding bit in the PxCI register
6821 * is cleared, it means the command is completed successfully. And according
6822 * to the HBA state machine, there are three conditions which possibly will
6823 * try to clear the PxCI register bit.
6824 * 1. Receive one D2H Register FIS which is with 'I' bit set
6825 * 2. Update PIO Setup FIS
6826 * 3. Transmit a command and receive R_OK if CTBA.C is set (software reset)
6828 * Process completed non-queued commands when the interrupt status bit -
6829 * AHCI_INTR_STATUS_DHRS or AHCI_INTR_STATUS_PSS is set.
6831 * AHCI_INTR_STATUS_DHRS means a D2H Register FIS has been received
6832 * with the 'I' bit set. And the following commands will send thus
6833 * FIS with 'I' bit set upon the successful completion:
6834 * 1. Non-data commands
6835 * 2. DMA data-in command
6836 * 3. DMA data-out command
6837 * 4. PIO data-out command
6838 * 5. PACKET non-data commands
6839 * 6. PACKET PIO data-in command
6840 * 7. PACKET PIO data-out command
6841 * 8. PACKET DMA data-in command
6842 * 9. PACKET DMA data-out command
6844 * AHCI_INTR_STATUS_PSS means a PIO Setup FIS has been received
6845 * with the 'I' bit set. And the following commands will send this
6846 * FIS upon the successful completion:
6847 * 1. PIO data-in command
6850 ahci_intr_cmd_cmplt(ahci_ctl_t
*ahci_ctlp
,
6851 ahci_port_t
*ahci_portp
, uint8_t port
)
6853 uint32_t port_cmd_issue
= 0;
6854 uint32_t finished_tags
;
6856 sata_pkt_t
*satapkt
;
6857 ahci_fis_d2h_register_t
*rcvd_fisp
;
6859 ahci_cmd_header_t
*cmd_header
;
6860 uint32_t cmd_dmacount
;
6863 mutex_enter(&ahci_portp
->ahciport_mutex
);
6865 if (!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
) &&
6866 !RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
) &&
6867 !NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
6869 * Spurious interrupt. Nothing to be done.
6871 mutex_exit(&ahci_portp
->ahciport_mutex
);
6872 return (AHCI_SUCCESS
);
6875 port_cmd_issue
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
6876 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
6878 /* If the PxCI corrupts, don't complete the commmands. */
6879 if (ahci_check_acc_handle(ahci_ctlp
->ahcictl_ahci_acc_handle
)
6881 mutex_exit(&ahci_portp
->ahciport_mutex
);
6882 return (AHCI_FAILURE
);
6885 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
6886 /* Slot 0 is always used during error recovery */
6887 finished_tags
= 0x1 & ~port_cmd_issue
;
6888 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
6889 "ahci_intr_cmd_cmplt: port %d the sata pkt for error "
6890 "retrieval is finished, and finished_tags = 0x%x",
6891 port
, finished_tags
);
6892 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
6893 finished_tags
= 0x1 & ~port_cmd_issue
;
6894 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
,
6895 "ahci_intr_cmd_cmplt: port %d the sata pkt for r/w "
6896 "port multiplier is finished, and finished_tags = 0x%x",
6897 port
, finished_tags
);
6901 finished_tags
= ahci_portp
->ahciport_pending_tags
&
6902 ~port_cmd_issue
& AHCI_SLOT_MASK(ahci_ctlp
);
6905 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
6906 "ahci_intr_cmd_cmplt: pending_tags = 0x%x, "
6907 "port_cmd_issue = 0x%x finished_tags = 0x%x",
6908 ahci_portp
->ahciport_pending_tags
, port_cmd_issue
,
6911 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
) &&
6912 (finished_tags
== 0x1)) {
6913 satapkt
= ahci_portp
->ahciport_err_retri_pkt
;
6914 ASSERT(satapkt
!= NULL
);
6916 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
6917 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6918 "with SATA_PKT_COMPLETED", (void *)satapkt
);
6920 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_COMPLETED
);
6924 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
) &&
6925 (finished_tags
== 0x1)) {
6926 satapkt
= ahci_portp
->ahciport_rdwr_pmult_pkt
;
6927 ASSERT(satapkt
!= NULL
);
6929 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
6930 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
6931 "with SATA_PKT_COMPLETED", (void *)satapkt
);
6933 /* READ PORTMULT need copy out FIS content. */
6934 if (satapkt
->satapkt_cmd
.satacmd_flags
.sata_special_regs
) {
6935 rcvd_fisp
= &(ahci_portp
->ahciport_rcvd_fis
->
6936 ahcirf_d2h_register_fis
);
6937 satapkt
->satapkt_cmd
.satacmd_status_reg
=
6938 GET_RFIS_STATUS(rcvd_fisp
);
6939 ahci_copy_out_regs(&satapkt
->satapkt_cmd
, rcvd_fisp
);
6942 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_COMPLETED
);
6946 while (finished_tags
) {
6947 finished_slot
= ddi_ffs(finished_tags
) - 1;
6948 if (finished_slot
== -1) {
6952 satapkt
= ahci_portp
->ahciport_slot_pkts
[finished_slot
];
6953 ASSERT(satapkt
!= NULL
);
6956 * For non-native queued commands, the PRD byte count field
6957 * shall contain an accurate count of the number of bytes
6958 * transferred for the command before the PxCI bit is cleared
6959 * to '0' for the command.
6961 * The purpose of this field is to let software know how many
6962 * bytes transferred for a given operation in order to
6963 * determine if underflow occurred. When issuing native command
6964 * queuing commands, this field should not be used and is not
6965 * required to be valid since in this case underflow is always
6968 * For data reads, the HBA will update its PRD byte count with
6969 * the total number of bytes received from the last FIS, and
6970 * may be able to continue normally. For data writes, the
6971 * device will detect an error, and HBA most likely will get
6974 * Therefore, here just put code to debug part. And please
6975 * refer to the comment above ahci_intr_fatal_error for the
6976 * definition of underflow error.
6979 ahci_portp
->ahciport_prd_bytecounts
[finished_slot
];
6982 &ahci_portp
->ahciport_cmd_list
[finished_slot
];
6983 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_PRDT
, ahci_ctlp
,
6984 "ahci_intr_cmd_cmplt: port %d, "
6985 "PRD Byte Count = 0x%x, "
6986 "ahciport_prd_bytecounts = 0x%x", port
,
6987 cmd_header
->ahcich_prd_byte_count
,
6990 if (cmd_header
->ahcich_prd_byte_count
!= cmd_dmacount
) {
6991 AHCIDBG(AHCIDBG_UNDERFLOW
, ahci_ctlp
,
6992 "ahci_intr_cmd_cmplt: port %d, "
6993 "an underflow occurred", port
);
6999 * For SATAC_SMART command with SATA_SMART_RETURN_STATUS
7000 * feature, sata_special_regs flag will be set, and the
7001 * driver should copy the status and the other corresponding
7002 * register values in the D2H Register FIS received (It's
7003 * working on Non-data protocol) from the device back to
7006 * For every AHCI port, there is only one Received FIS
7007 * structure, which contains the FISes received from the
7008 * device, So we're trying to copy the content of D2H
7009 * Register FIS in the Received FIS structure back to
7012 if (satapkt
->satapkt_cmd
.satacmd_flags
.sata_special_regs
) {
7013 rcvd_fisp
= &(ahci_portp
->ahciport_rcvd_fis
->
7014 ahcirf_d2h_register_fis
);
7015 satapkt
->satapkt_cmd
.satacmd_status_reg
=
7016 GET_RFIS_STATUS(rcvd_fisp
);
7017 ahci_copy_out_regs(&satapkt
->satapkt_cmd
, rcvd_fisp
);
7020 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
7021 "ahci_intr_cmd_cmplt: sending up pkt 0x%p "
7022 "with SATA_PKT_COMPLETED", (void *)satapkt
);
7024 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, finished_slot
);
7025 CLEAR_BIT(finished_tags
, finished_slot
);
7026 ahci_portp
->ahciport_slot_pkts
[finished_slot
] = NULL
;
7028 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_COMPLETED
);
7031 AHCIDBG(AHCIDBG_PKTCOMP
, ahci_ctlp
,
7032 "ahci_intr_cmd_cmplt: pending_tags = 0x%x",
7033 ahci_portp
->ahciport_pending_tags
);
7035 ahci_flush_doneq(ahci_portp
);
7037 mutex_exit(&ahci_portp
->ahciport_mutex
);
7039 return (AHCI_SUCCESS
);
7043 * AHCI_INTR_STATUS_SDBS means a Set Device Bits FIS has been received
7044 * with the 'I' bit set and has been copied into system memory. It will
7045 * be sent under the following situations:
7047 * 1. NCQ command is completed
7049 * The completion of NCQ commands (READ/WRITE FPDMA QUEUED) is performed
7050 * via the Set Device Bits FIS. When such event is generated, the software
7051 * needs to read PxSACT register and compares the current value to the
7052 * list of commands previously issue by software. ahciport_pending_ncq_tags
7053 * keeps the tags of previously issued commands.
7055 * 2. Asynchronous Notification
7057 * Asynchronous Notification is a feature in SATA spec 2.6.
7059 * 1) ATAPI device will send a signal to the host when media is inserted or
7060 * removed and avoids polling the device for media changes. The signal
7061 * sent to the host is a Set Device Bits FIS with the 'I' and 'N' bits
7062 * set to '1'. At the moment, it's not supported yet.
7064 * 2) Port multiplier will send a signal to the host when a hot plug event
7065 * has occured on a port multiplier port. It is used when command based
7066 * switching is employed. This is handled by ahci_intr_pmult_sntf_events()
7069 ahci_intr_set_device_bits(ahci_ctl_t
*ahci_ctlp
,
7070 ahci_port_t
*ahci_portp
, uint8_t port
)
7074 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
, ahci_ctlp
,
7075 "ahci_intr_set_device_bits enter: port %d", port
);
7077 /* Initialize HBA port address */
7078 AHCI_ADDR_SET_PORT(&addr
, port
);
7080 /* NCQ plug handler */
7081 (void) ahci_intr_ncq_events(ahci_ctlp
, ahci_portp
, &addr
);
7083 /* Check port multiplier's asynchronous notification events */
7084 if (ahci_ctlp
->ahcictl_cap
& AHCI_CAP_SNTF
) {
7085 (void) ahci_intr_pmult_sntf_events(ahci_ctlp
,
7089 /* ATAPI events is not supported yet */
7091 return (AHCI_SUCCESS
);
7094 * NCQ interrupt handler. Called upon a NCQ command is completed.
7095 * Only be called from ahci_intr_set_device_bits().
7098 ahci_intr_ncq_events(ahci_ctl_t
*ahci_ctlp
,
7099 ahci_port_t
*ahci_portp
, ahci_addr_t
*addrp
)
7101 uint32_t port_sactive
;
7102 uint32_t port_cmd_issue
;
7103 uint32_t issued_tags
;
7105 uint32_t finished_tags
;
7107 uint8_t port
= addrp
->aa_port
;
7108 sata_pkt_t
*satapkt
;
7110 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
|AHCIDBG_NCQ
, ahci_ctlp
,
7111 "ahci_intr_set_device_bits enter: port %d", port
);
7113 mutex_enter(&ahci_portp
->ahciport_mutex
);
7114 if (!NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
7115 mutex_exit(&ahci_portp
->ahciport_mutex
);
7116 return (AHCI_SUCCESS
);
7120 * First the handler got which commands are finished by checking
7123 port_sactive
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7124 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
7126 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
7127 ~port_sactive
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
7129 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
, ahci_ctlp
,
7130 "ahci_intr_set_device_bits: port %d pending_ncq_tags = 0x%x "
7131 "port_sactive = 0x%x", port
,
7132 ahci_portp
->ahciport_pending_ncq_tags
, port_sactive
);
7134 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
, ahci_ctlp
,
7135 "ahci_intr_set_device_bits: finished_tags = 0x%x", finished_tags
);
7138 * For NCQ commands, the software can determine which command has
7139 * already been transmitted to the device by checking PxCI register.
7141 port_cmd_issue
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7142 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
7144 issued_tags
= ahci_portp
->ahciport_pending_tags
&
7145 ~port_cmd_issue
& AHCI_SLOT_MASK(ahci_ctlp
);
7147 /* If the PxSACT/PxCI corrupts, don't complete the NCQ commmands. */
7148 if (ahci_check_acc_handle(ahci_ctlp
->ahcictl_ahci_acc_handle
)
7150 mutex_exit(&ahci_portp
->ahciport_mutex
);
7151 return (AHCI_FAILURE
);
7154 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
, ahci_ctlp
,
7155 "ahci_intr_set_device_bits: port %d pending_tags = 0x%x "
7156 "port_cmd_issue = 0x%x", port
,
7157 ahci_portp
->ahciport_pending_tags
, port_cmd_issue
);
7159 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
, ahci_ctlp
,
7160 "ahci_intr_set_device_bits: issued_tags = 0x%x", issued_tags
);
7163 * Clear ahciport_pending_tags bit when the corresponding command
7164 * is already sent down to the device.
7166 while (issued_tags
) {
7167 issued_slot
= ddi_ffs(issued_tags
) - 1;
7168 if (issued_slot
== -1) {
7171 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, issued_slot
);
7172 CLEAR_BIT(issued_tags
, issued_slot
);
7176 while (finished_tags
) {
7177 finished_slot
= ddi_ffs(finished_tags
) - 1;
7178 if (finished_slot
== -1) {
7182 /* The command is certainly transmitted to the device */
7183 ASSERT(!(ahci_portp
->ahciport_pending_tags
&
7184 (0x1 << finished_slot
)));
7186 satapkt
= ahci_portp
->ahciport_slot_pkts
[finished_slot
];
7187 ASSERT(satapkt
!= NULL
);
7189 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
, ahci_ctlp
,
7190 "ahci_intr_set_device_bits: sending up pkt 0x%p "
7191 "with SATA_PKT_COMPLETED", (void *)satapkt
);
7193 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
, finished_slot
);
7194 CLEAR_BIT(finished_tags
, finished_slot
);
7195 ahci_portp
->ahciport_slot_pkts
[finished_slot
] = NULL
;
7197 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_COMPLETED
);
7200 AHCIDBG(AHCIDBG_PKTCOMP
|AHCIDBG_NCQ
, ahci_ctlp
,
7201 "ahci_intr_set_device_bits: port %d "
7202 "pending_ncq_tags = 0x%x pending_tags = 0x%x",
7203 port
, ahci_portp
->ahciport_pending_ncq_tags
,
7204 ahci_portp
->ahciport_pending_tags
);
7206 ahci_flush_doneq(ahci_portp
);
7208 mutex_exit(&ahci_portp
->ahciport_mutex
);
7210 return (AHCI_SUCCESS
);
7214 * Port multiplier asynchronous notification event handler. Called upon a
7215 * device is hot plugged/pulled.
7217 * The async-notification event will only be recorded by ahcipmi_snotif_tags
7218 * here and will be handled by ahci_probe_pmult().
7220 * NOTE: called only from ahci_port_intr().
7223 ahci_intr_pmult_sntf_events(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
7226 sata_device_t sdevice
;
7228 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
, ahci_ctlp
,
7229 "ahci_intr_pmult_sntf_events enter: port %d ", port
);
7231 /* no hot-plug while attaching process */
7232 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
7233 if (ahci_ctlp
->ahcictl_flags
& AHCI_ATTACH
) {
7234 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
7235 return (AHCI_SUCCESS
);
7237 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
7239 mutex_enter(&ahci_portp
->ahciport_mutex
);
7240 if (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
) {
7241 mutex_exit(&ahci_portp
->ahciport_mutex
);
7242 return (AHCI_SUCCESS
);
7245 ASSERT(ahci_portp
->ahciport_pmult_info
!= NULL
);
7247 ahci_portp
->ahciport_pmult_info
->ahcipmi_snotif_tags
=
7248 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7249 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp
, port
));
7250 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7251 (uint32_t *)AHCI_PORT_PxSNTF(ahci_ctlp
, port
),
7252 AHCI_SNOTIF_CLEAR_ALL
);
7254 if (ahci_portp
->ahciport_pmult_info
->ahcipmi_snotif_tags
== 0) {
7255 mutex_exit(&ahci_portp
->ahciport_mutex
);
7256 return (AHCI_SUCCESS
);
7259 /* Port Multiplier sub-device hot-plug handler */
7260 if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
7261 mutex_exit(&ahci_portp
->ahciport_mutex
);
7262 return (AHCI_SUCCESS
);
7265 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_PMULT_SNTF
) {
7266 /* Not allowed to re-enter. */
7267 mutex_exit(&ahci_portp
->ahciport_mutex
);
7268 return (AHCI_SUCCESS
);
7271 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_PMULT_SNTF
;
7275 * Even if Asynchronous Notification is supported (and enabled) by
7276 * both controller and the port multiplier, the content of PxSNTF
7277 * register is always set to 0x8000 by async notification event. We
7278 * need to check GSCR[32] on the port multiplier to find out the
7279 * owner of this event.
7280 * This is not accord with SATA spec 2.6 and needs further
7283 /* hot-plug will not reported while reseting. */
7284 if (ahci_portp
->ahciport_reset_in_progress
== 1) {
7285 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
7286 "port %d snotif event ignored", port
);
7287 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_PMULT_SNTF
;
7288 mutex_exit(&ahci_portp
->ahciport_mutex
);
7289 return (AHCI_SUCCESS
);
7292 AHCIDBG(AHCIDBG_INFO
|AHCIDBG_PMULT
, ahci_ctlp
,
7293 "PxSNTF is set to 0x%x by port multiplier",
7294 ahci_portp
->ahciport_pmult_info
->ahcipmi_snotif_tags
);
7297 * Now we need do some necessary operation and inform SATA framework
7298 * that link/device events has happened.
7300 bzero((void *)&sdevice
, sizeof (sata_device_t
));
7301 sdevice
.satadev_addr
.cport
= ahci_ctlp
->
7302 ahcictl_port_to_cport
[port
];
7303 sdevice
.satadev_addr
.pmport
= SATA_PMULT_HOSTPORT
;
7304 sdevice
.satadev_addr
.qual
= SATA_ADDR_PMULT
;
7305 sdevice
.satadev_state
= SATA_PSTATE_PWRON
;
7307 /* Just reject packets, do not stop that port. */
7308 ahci_reject_all_abort_pkts(ahci_ctlp
, ahci_portp
, port
);
7310 mutex_exit(&ahci_portp
->ahciport_mutex
);
7311 sata_hba_event_notify(
7312 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
7314 SATA_EVNT_PMULT_LINK_CHANGED
);
7315 mutex_enter(&ahci_portp
->ahciport_mutex
);
7317 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_PMULT_SNTF
;
7318 mutex_exit(&ahci_portp
->ahciport_mutex
);
7320 return (AHCI_SUCCESS
);
7324 * 1=Change in Current Connect Status. 0=No change in Current Connect Status.
7325 * This bit reflects the state of PxSERR.DIAG.X. This bit is only cleared
7326 * when PxSERR.DIAG.X is cleared. When PxSERR.DIAG.X is set to one, it
7327 * indicates a COMINIT signal was received.
7329 * Hot plug insertion is detected by reception of a COMINIT signal from the
7330 * device. On reception of unsolicited COMINIT, the HBA shall generate a
7331 * COMRESET. If the COMINIT is in responce to a COMRESET, then the HBA shall
7332 * begin the normal communication negotiation sequence as outlined in the
7333 * Serial ATA 1.0a specification. When a COMRESET is sent to the device the
7334 * PxSSTS.DET field shall be cleared to 0h. When a COMINIT is received, the
7335 * PxSSTS.DET field shall be set to 1h. When the communication negotiation
7336 * sequence is complete and PhyRdy is true the PxSSTS.DET field shall be set
7337 * to 3h. Therefore, at the moment the ahci driver is going to check PhyRdy
7338 * to handle hot plug insertion. In this interrupt handler, just do nothing
7339 * but print some log message and clear the bit.
7342 ahci_intr_port_connect_change(ahci_ctl_t
*ahci_ctlp
,
7343 ahci_port_t
*ahci_portp
, uint8_t port
)
7346 uint32_t port_serror
;
7349 mutex_enter(&ahci_portp
->ahciport_mutex
);
7352 port_serror
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7353 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
));
7355 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ENTRY
, ahci_ctlp
,
7356 "ahci_intr_port_connect_change: port %d, "
7357 "port_serror = 0x%x", port
, port_serror
);
7360 /* Clear PxSERR.DIAG.X to clear the interrupt bit */
7361 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7362 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
7363 SERROR_EXCHANGED_ERR
);
7365 mutex_exit(&ahci_portp
->ahciport_mutex
);
7367 return (AHCI_SUCCESS
);
7371 * Hot Plug Operation for platforms that support Mechanical Presence
7374 * When set, it indicates that a mechanical presence switch attached to this
7375 * port has been opened or closed, which may lead to a change in the connection
7376 * state of the device. This bit is only valid if both CAP.SMPS and PxCMD.MPSP
7379 * At the moment, this interrupt is not needed and disabled and we just log
7380 * the debug message.
7383 ahci_intr_device_mechanical_presence_status(ahci_ctl_t
*ahci_ctlp
,
7384 ahci_port_t
*ahci_portp
, uint8_t port
)
7386 uint32_t cap_status
, port_cmd_status
;
7388 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ENTRY
, ahci_ctlp
,
7389 "ahci_intr_device_mechanical_presence_status enter, "
7392 cap_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7393 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp
));
7395 mutex_enter(&ahci_portp
->ahciport_mutex
);
7396 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7397 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
7399 if (!(cap_status
& AHCI_HBA_CAP_SMPS
) ||
7400 !(port_cmd_status
& AHCI_CMD_STATUS_MPSP
)) {
7401 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
7402 "CAP.SMPS or PxCMD.MPSP is not set, so just ignore "
7403 "the interrupt: cap_status = 0x%x, "
7404 "port_cmd_status = 0x%x", cap_status
, port_cmd_status
);
7405 mutex_exit(&ahci_portp
->ahciport_mutex
);
7407 return (AHCI_SUCCESS
);
7411 if (port_cmd_status
& AHCI_CMD_STATUS_MPSS
) {
7412 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
7413 "The mechanical presence switch is open: "
7414 "port %d, port_cmd_status = 0x%x",
7415 port
, port_cmd_status
);
7417 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
7418 "The mechanical presence switch is close: "
7419 "port %d, port_cmd_status = 0x%x",
7420 port
, port_cmd_status
);
7424 mutex_exit(&ahci_portp
->ahciport_mutex
);
7426 return (AHCI_SUCCESS
);
7430 * Native Hot Plug Support.
7432 * When set, it indicates that the internal PHYRDY signal changed state.
7433 * This bit reflects the state of PxSERR.DIAG.N.
7435 * There are three kinds of conditions to generate this interrupt event:
7436 * 1. a device is inserted
7437 * 2. a device is disconnected
7438 * 3. when the link enters/exits a Partial or Slumber interface power
7441 * If inteface power management is enabled for a port, the PxSERR.DIAG.N
7442 * bit may be set due to the link entering the Partial or Slumber power
7443 * management state, rather than due to a hot plug insertion or removal
7444 * event. So far, the interface power management is disabled, so the
7445 * driver can reliably get removal detection notification via the
7446 * PxSERR.DIAG.N bit.
7449 ahci_intr_phyrdy_change(ahci_ctl_t
*ahci_ctlp
,
7450 ahci_port_t
*ahci_portp
, uint8_t port
)
7452 uint32_t port_sstatus
= 0; /* No dev present & PHY not established. */
7453 sata_device_t sdevice
;
7454 int dev_exists_now
= 0;
7455 int dev_existed_previously
= 0;
7456 ahci_addr_t port_addr
;
7458 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ENTRY
, ahci_ctlp
,
7459 "ahci_intr_phyrdy_change enter, port %d", port
);
7461 /* Clear PxSERR.DIAG.N to clear the interrupt bit */
7462 mutex_enter(&ahci_portp
->ahciport_mutex
);
7463 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7464 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
7465 SERROR_PHY_RDY_CHG
);
7466 mutex_exit(&ahci_portp
->ahciport_mutex
);
7468 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
7469 if ((ahci_ctlp
->ahcictl_sata_hba_tran
== NULL
) ||
7470 (ahci_portp
== NULL
)) {
7471 /* The whole controller setup is not yet done. */
7472 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
7473 return (AHCI_SUCCESS
);
7475 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
7477 mutex_enter(&ahci_portp
->ahciport_mutex
);
7479 /* SStatus tells the presence of device. */
7480 port_sstatus
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7481 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp
, port
));
7483 if (SSTATUS_GET_DET(port_sstatus
) == SSTATUS_DET_DEVPRE_PHYCOM
) {
7487 if (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_NONE
) {
7488 dev_existed_previously
= 1;
7491 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_NODEV
) {
7492 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_NODEV
;
7493 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
7494 "ahci_intr_phyrdy_change: port %d "
7495 "AHCI_PORT_FLAG_NODEV is cleared", port
);
7496 if (dev_exists_now
== 0)
7497 dev_existed_previously
= 1;
7500 bzero((void *)&sdevice
, sizeof (sata_device_t
));
7501 sdevice
.satadev_addr
.cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
7502 sdevice
.satadev_addr
.qual
= SATA_ADDR_CPORT
;
7503 sdevice
.satadev_addr
.pmport
= 0;
7504 sdevice
.satadev_state
= SATA_PSTATE_PWRON
;
7505 ahci_portp
->ahciport_port_state
= SATA_PSTATE_PWRON
;
7507 AHCI_ADDR_SET_PORT(&port_addr
, port
);
7509 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_HOTPLUG
;
7510 if (dev_exists_now
) {
7511 if (dev_existed_previously
) { /* 1 -> 1 */
7512 /* Things are fine now. The loss was temporary. */
7513 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
7514 "ahci_intr_phyrdy_change port %d "
7515 "device link lost/established", port
);
7517 mutex_exit(&ahci_portp
->ahciport_mutex
);
7518 sata_hba_event_notify(
7519 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
7521 SATA_EVNT_LINK_LOST
|SATA_EVNT_LINK_ESTABLISHED
);
7522 mutex_enter(&ahci_portp
->ahciport_mutex
);
7524 } else { /* 0 -> 1 */
7525 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
7526 "ahci_intr_phyrdy_change: port %d "
7527 "device link established", port
);
7530 * A new device has been detected. The new device
7531 * might be a port multiplier instead of a drive, so
7532 * we cannot update the signature directly.
7534 (void) ahci_initialize_port(ahci_ctlp
,
7535 ahci_portp
, &port_addr
);
7537 /* Try to start the port */
7538 if (ahci_start_port(ahci_ctlp
, ahci_portp
, port
)
7540 sdevice
.satadev_state
|= SATA_PSTATE_FAILED
;
7541 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
7542 "ahci_intr_phyrdy_change: port %d failed "
7543 "at start port", port
);
7546 /* Clear the max queue depth for inserted device */
7547 ahci_portp
->ahciport_max_ncq_tags
= 0;
7549 mutex_exit(&ahci_portp
->ahciport_mutex
);
7550 sata_hba_event_notify(
7551 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
7553 SATA_EVNT_LINK_ESTABLISHED
);
7554 mutex_enter(&ahci_portp
->ahciport_mutex
);
7557 } else { /* No device exists now */
7559 if (dev_existed_previously
) { /* 1 -> 0 */
7560 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
7561 "ahci_intr_phyrdy_change: port %d "
7562 "device link lost", port
);
7564 ahci_reject_all_abort_pkts(ahci_ctlp
, ahci_portp
, port
);
7565 (void) ahci_put_port_into_notrunning_state(ahci_ctlp
,
7568 if (ahci_portp
->ahciport_device_type
==
7570 ahci_dealloc_pmult(ahci_ctlp
, ahci_portp
);
7573 /* An existing device is lost. */
7574 ahci_portp
->ahciport_device_type
= SATA_DTYPE_NONE
;
7575 ahci_portp
->ahciport_port_state
= SATA_STATE_UNKNOWN
;
7577 mutex_exit(&ahci_portp
->ahciport_mutex
);
7578 sata_hba_event_notify(
7579 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
7581 SATA_EVNT_LINK_LOST
);
7582 mutex_enter(&ahci_portp
->ahciport_mutex
);
7585 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_HOTPLUG
;
7587 mutex_exit(&ahci_portp
->ahciport_mutex
);
7589 return (AHCI_SUCCESS
);
7593 * PxIS.UFS - Unknown FIS Error
7595 * This interrupt event means an unknown FIS was received and has been
7596 * copied into system memory. An unknown FIS is not considered an illegal
7597 * FIS, unless the length received is more than 64 bytes. If an unknown
7598 * FIS arrives with length <= 64 bytes, it is posted and the HBA continues
7599 * normal operation. If the unknown FIS is more than 64 bytes, then it
7600 * won't be posted to memory and PxSERR.ERR.P will be set, which is then
7603 * PxIS.IPMS - Incorrect Port Multiplier Status
7605 * IPMS Indicates that the HBA received a FIS from a device that did not
7606 * have a command outstanding. The IPMS bit may be set during enumeration
7607 * of devices on a Port Multiplier due to the normal Port Multiplier
7608 * enumeration process. It is recommended that IPMS only be used after
7609 * enumeration is complete on the Port Multiplier (copied from spec).
7611 * PxIS.OFS - Overflow Error
7613 * Command list overflow is defined as software building a command table
7614 * that has fewer total bytes than the transaction given to the device.
7615 * On device writes, the HBA will run out of data, and on reads, there
7616 * will be no room to put the data.
7618 * For an overflow on data read, either PIO or DMA, the HBA will set
7619 * PxIS.OFS, and the HBA will do a best effort to continue, and it's a
7620 * non-fatal error when the HBA can continues. Sometimes, it will cause
7621 * a fatal error and need the software to do something.
7623 * For an overflow on data write, setting PxIS.OFS is optional for both
7624 * DMA and PIO, and it's a fatal error, and a COMRESET is required by
7625 * software to clean up from this serious error.
7627 * PxIS.INFS - Interface Non-Fatal Error
7629 * This interrupt event indicates that the HBA encountered an error on
7630 * the Serial ATA interface but was able to continue operation. The kind
7631 * of error usually occurred during a non-Data FIS, and under this condition
7632 * the FIS will be re-transmitted by HBA automatically.
7634 * When the FMA is implemented, there should be a stat structure to
7635 * record how many every kind of error happens.
7638 ahci_intr_non_fatal_error(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
7639 uint8_t port
, uint32_t intr_status
)
7641 uint32_t port_serror
;
7643 uint32_t port_cmd_status
;
7644 uint32_t port_cmd_issue
;
7645 uint32_t port_sactive
;
7647 uint32_t current_tags
;
7648 sata_pkt_t
*satapkt
;
7649 ahci_cmd_header_t
*cmd_header
;
7650 uint32_t cmd_dmacount
;
7653 mutex_enter(&ahci_portp
->ahciport_mutex
);
7655 port_serror
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7656 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
));
7658 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ENTRY
|AHCIDBG_ERRS
, ahci_ctlp
,
7659 "ahci_intr_non_fatal_error: port %d, "
7660 "PxSERR = 0x%x, PxIS = 0x%x ", port
, port_serror
, intr_status
);
7662 ahci_log_serror_message(ahci_ctlp
, port
, port_serror
, 1);
7664 if (intr_status
& AHCI_INTR_STATUS_UFS
) {
7665 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
7666 "ahci port %d has unknown FIS error", port
);
7668 /* Clear the interrupt bit by clearing PxSERR.DIAG.F */
7669 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7670 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
7675 if (intr_status
& AHCI_INTR_STATUS_IPMS
) {
7676 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci port %d "
7677 "has Incorrect Port Multiplier Status error", port
);
7680 if (intr_status
& AHCI_INTR_STATUS_OFS
) {
7681 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7682 "ahci port %d has overflow error", port
);
7685 if (intr_status
& AHCI_INTR_STATUS_INFS
) {
7686 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7687 "ahci port %d has interface non fatal error", port
);
7691 * Record the error occurred command's slot.
7693 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
) ||
7694 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
7695 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7696 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
7698 current_slot
= (port_cmd_status
& AHCI_CMD_STATUS_CCS
) >>
7699 AHCI_CMD_STATUS_CCS_SHIFT
;
7701 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
7702 satapkt
= ahci_portp
->ahciport_err_retri_pkt
;
7703 ASSERT(satapkt
!= NULL
);
7704 ASSERT(current_slot
== 0);
7706 satapkt
= ahci_portp
->ahciport_slot_pkts
[current_slot
];
7709 if (satapkt
!= NULL
) {
7710 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7711 "ahci_intr_non_fatal_error: pending_tags = 0x%x "
7712 "cmd 0x%x", ahci_portp
->ahciport_pending_tags
,
7713 satapkt
->satapkt_cmd
.satacmd_cmd_reg
);
7715 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7716 "ahci_intr_non_fatal_error: port %d, "
7717 "satapkt 0x%p is being processed when error occurs",
7718 port
, (void *)satapkt
);
7721 * PRD Byte Count field of command header is not
7722 * required to reflect the total number of bytes
7723 * transferred when an overflow occurs, so here
7724 * just log the value.
7727 ahci_portp
->ahciport_prd_bytecounts
[current_slot
];
7729 cmd_header
= &ahci_portp
->
7730 ahciport_cmd_list
[current_slot
];
7731 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7732 "ahci_intr_non_fatal_error: port %d, "
7733 "PRD Byte Count = 0x%x, "
7734 "ahciport_prd_bytecounts = 0x%x", port
,
7735 cmd_header
->ahcich_prd_byte_count
,
7739 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
7741 * For queued command, list those command which have already
7742 * been transmitted to the device and still not completed.
7744 port_sactive
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7745 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
7747 port_cmd_issue
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7748 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
7750 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
|AHCIDBG_ERRS
, ahci_ctlp
,
7751 "ahci_intr_non_fatal_error: pending_ncq_tags = 0x%x "
7752 "port_sactive = 0x%x port_cmd_issue = 0x%x",
7753 ahci_portp
->ahciport_pending_ncq_tags
,
7754 port_sactive
, port_cmd_issue
);
7756 current_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
7757 port_sactive
& ~port_cmd_issue
&
7758 AHCI_NCQ_SLOT_MASK(ahci_portp
);
7760 while (current_tags
) {
7761 current_slot
= ddi_ffs(current_tags
) - 1;
7762 if (current_slot
== -1) {
7766 satapkt
= ahci_portp
->ahciport_slot_pkts
[current_slot
];
7767 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_NCQ
|AHCIDBG_ERRS
,
7768 ahci_ctlp
, "ahci_intr_non_fatal_error: "
7769 "port %d, satapkt 0x%p is outstanding when "
7770 "error occurs", port
, (void *)satapkt
);
7772 CLEAR_BIT(current_tags
, current_slot
);
7777 mutex_exit(&ahci_portp
->ahciport_mutex
);
7779 return (AHCI_SUCCESS
);
7783 * According to the AHCI spec, the error types include system memory
7784 * errors, interface errors, port multiplier errors, device errors,
7785 * command list overflow, command list underflow, native command
7786 * queuing tag errors and pio data transfer errors.
7788 * System memory errors such as target abort, master abort, and parity
7789 * may cause the host to stop, and they are serious errors and needed
7790 * to be recovered with software intervention. When system software
7791 * has given a pointer to the HBA that doesn't exist in physical memory,
7792 * a master/target abort error occurs, and PxIS.HBFS will be set. A
7793 * data error such as CRC or parity occurs, the HBA aborts the transfer
7794 * (if necessary) and PxIS.HBDS will be set.
7796 * Interface errors are errors that occur due to electrical issues on
7797 * the interface, or protocol miscommunication between the device and
7798 * HBA, and the respective PxSERR register bit will be set. And PxIS.IFS
7799 * (fatal) or PxIS.INFS (non-fatal) will be set. The conditions that
7800 * causes PxIS.IFS/PxIS.INFS to be set are
7801 * 1. in PxSERR.ERR, P bit is set to '1'
7802 * 2. in PxSERR.DIAG, C or H bit is set to '1'
7803 * 3. PhyRdy drop unexpectly, N bit is set to '1'
7804 * If the error occurred during a non-data FIS, the FIS must be
7805 * retransmitted, and the error is non-fatal and PxIS.INFS is set. If
7806 * the error occurred during a data FIS, the transfer will stop, so
7807 * the error is fatal and PxIS.IFS is set.
7809 * When a FIS arrives that updates the taskfile, the HBA checks to see
7810 * if PxTFD.STS.ERR is set. If yes, PxIS.TFES will be set and the HBA
7811 * stops processing any more commands.
7813 * Command list overflow is defined as software building a command table
7814 * that has fewer total bytes than the transaction given to the device.
7815 * On device writes, the HBA will run out of data, and on reads, there
7816 * will be no room to put the data. For an overflow on data read, either
7817 * PIO or DMA, the HBA will set PxIS.OFS, and it's a non-fatal error.
7818 * For an overflow on data write, setting PxIS.OFS is optional for both
7819 * DMA and PIO, and a COMRESET is required by software to clean up from
7820 * this serious error.
7822 * Command list underflow is defined as software building a command
7823 * table that has more total bytes than the transaction given to the
7824 * device. For data writes, both PIO and DMA, the device will detect
7825 * an error and end the transfer. And these errors are most likely going
7826 * to be fatal errors that will cause the port to be restarted. For
7827 * data reads, the HBA updates its PRD byte count, and may be
7828 * able to continue normally, but is not required to. And The HBA is
7829 * not required to detect underflow conditions for native command
7832 * The HBA does not actively check incoming DMA Setup FISes to ensure
7833 * that the PxSACT register bit for that slot is set. Existing error
7834 * mechanisms, such as host bus failure, or bad protocol, are used to
7835 * recover from this case.
7837 * In accordance with Serial ATA 1.0a, DATA FISes prior to the final
7838 * DATA FIS must be an integral number of Dwords. If the HBA receives
7839 * a request which is not an integral number of Dwords, the HBA
7840 * set PxSERR.ERR.P to '1', set PxIS.IFS to '1' and stop running until
7841 * software restarts the port. And the HBA ensures that the size
7842 * of the DATA FIS received during a PIO command matches the size in
7843 * the Transfer Cound field of the preceding PIO Setup FIS, if not, the
7844 * HBA sets PxSERR.ERR.P to '1', set PxIS.IFS to '1', and then
7845 * stop running until software restarts the port.
7848 * the fatal errors include PxIS.IFS, PxIS.HBDS, PxIS.HBFS and PxIS.TFES.
7850 * PxIS.IFS indicates that the hba encountered an error on the serial ata
7851 * interface which caused the transfer to stop.
7853 * PxIS.HBDS indicates that the hba encountered a data error
7854 * (uncorrectable ecc/parity) when reading from or writing to system memory.
7856 * PxIS.HBFS indicates that the hba encountered a host bus error that it
7857 * cannot recover from, such as a bad software pointer.
7859 * PxIS.TFES is set whenever the status register is updated by the device
7860 * and the error bit (bit 0) is set.
7863 ahci_intr_fatal_error(ahci_ctl_t
*ahci_ctlp
,
7864 ahci_port_t
*ahci_portp
, uint8_t port
, uint32_t intr_status
)
7866 uint32_t port_cmd_status
;
7867 uint32_t port_serror
;
7868 uint32_t task_file_status
;
7870 sata_pkt_t
*spkt
= NULL
;
7872 ahci_event_arg_t
*args
;
7873 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
7874 uint32_t failed_tags
= 0;
7875 int task_fail_flag
= 0, task_abort_flag
= 0;
7876 uint32_t slot_status
;
7878 mutex_enter(&ahci_portp
->ahciport_mutex
);
7881 * ahci_intr_phyrdy_change() may have rendered it to
7884 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
) {
7885 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
, ahci_ctlp
,
7886 "ahci_intr_fatal_error: port %d no device attached, "
7887 "and just return without doing anything", port
);
7891 if (intr_status
& AHCI_INTR_STATUS_TFES
) {
7892 task_file_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7893 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp
, port
));
7894 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7895 "ahci_intr_fatal_error: port %d "
7896 "task_file_status = 0x%x", port
, task_file_status
);
7899 err_byte
= (task_file_status
& AHCI_TFD_ERR_MASK
)
7900 >> AHCI_TFD_ERR_SHIFT
;
7901 if (err_byte
== SATA_ERROR_ABORT
)
7902 task_abort_flag
= 1;
7906 * Here we just log the fatal error info in interrupt context.
7907 * Misc recovery processing will be handled in task queue.
7909 if (task_fail_flag
== 1) {
7910 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
7912 * Read PxCMD.CCS to determine the slot that the HBA
7913 * was processing when the error occurred.
7915 port_cmd_status
= ddi_get32(
7916 ahci_ctlp
->ahcictl_ahci_acc_handle
,
7917 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
7918 failed_slot
= (port_cmd_status
& AHCI_CMD_STATUS_CCS
) >>
7919 AHCI_CMD_STATUS_CCS_SHIFT
;
7920 failed_tags
= 0x1 << failed_slot
;
7922 spkt
= ahci_portp
->ahciport_slot_pkts
[failed_slot
];
7923 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
7924 "ahci_intr_fatal_error: spkt 0x%p is being "
7925 "processed when fatal error occurred for port %d",
7929 * Won't emit the error message if it is an IDENTIFY
7930 * DEVICE command sent to an ATAPI device.
7932 if ((spkt
!= NULL
) &&
7933 (spkt
->satapkt_cmd
.satacmd_cmd_reg
==
7935 (task_abort_flag
== 1))
7939 * Won't emit the error message if it is an ATAPI PACKET
7942 if ((spkt
!= NULL
) &&
7943 (spkt
->satapkt_cmd
.satacmd_cmd_reg
== SATAC_PACKET
))
7946 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
7947 slot_status
= ddi_get32(
7948 ahci_ctlp
->ahcictl_ahci_acc_handle
,
7949 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
7950 failed_tags
= slot_status
&
7951 AHCI_NCQ_SLOT_MASK(ahci_portp
);
7955 /* print the fatal error type */
7956 ahci_log_fatal_error_message(ahci_ctlp
, port
, intr_status
);
7957 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_ERRPRINT
;
7959 port_serror
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
7960 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
));
7962 /* print PxSERR related error message */
7963 ahci_log_serror_message(ahci_ctlp
, port
, port_serror
, 0);
7965 /* print task file register value */
7966 if (task_fail_flag
== 1) {
7967 cmn_err(CE_WARN
, "!ahci%d: ahci port %d task_file_status "
7968 "= 0x%x", instance
, port
, task_file_status
);
7969 if (task_abort_flag
== 1) {
7970 cmn_err(CE_WARN
, "!ahci%d: the below command (s) on "
7971 "port %d are aborted", instance
, port
);
7972 ahci_dump_commands(ahci_ctlp
, port
, failed_tags
);
7977 /* Prepare the argument for the taskq */
7978 args
= ahci_portp
->ahciport_event_args
;
7979 args
->ahciea_ctlp
= (void *)ahci_ctlp
;
7980 args
->ahciea_portp
= (void *)ahci_portp
;
7981 args
->ahciea_event
= intr_status
;
7982 AHCI_ADDR_SET_PORT((ahci_addr_t
*)args
->ahciea_addrp
, port
);
7984 /* Start the taskq to handle error recovery */
7985 if ((ddi_taskq_dispatch(ahci_portp
->ahciport_event_taskq
,
7986 ahci_events_handler
,
7987 (void *)args
, DDI_NOSLEEP
)) != DDI_SUCCESS
) {
7988 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_ERRPRINT
;
7989 cmn_err(CE_WARN
, "!ahci%d: start taskq for error recovery "
7990 "port %d failed", instance
, port
);
7993 mutex_exit(&ahci_portp
->ahciport_mutex
);
7995 return (AHCI_SUCCESS
);
7999 * Hot Plug Operation for platforms that support Cold Presence Detect.
8001 * When set, a device status has changed as detected by the cold presence
8002 * detect logic. This bit can either be set due to a non-connected port
8003 * receiving a device, or a connected port having its device removed.
8004 * This bit is only valid if the port supports cold presence detect as
8005 * indicated by PxCMD.CPD set to '1'.
8007 * At the moment, this interrupt is not needed and disabled and we just
8008 * log the debug message.
8011 ahci_intr_cold_port_detect(ahci_ctl_t
*ahci_ctlp
,
8012 ahci_port_t
*ahci_portp
, uint8_t port
)
8014 uint32_t port_cmd_status
;
8015 sata_device_t sdevice
;
8017 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
8018 "ahci_intr_cold_port_detect enter, port %d", port
);
8020 mutex_enter(&ahci_portp
->ahciport_mutex
);
8022 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8023 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
8024 if (!(port_cmd_status
& AHCI_CMD_STATUS_CPD
)) {
8025 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
8026 "port %d does not support cold presence detect, so "
8027 "we just ignore this interrupt", port
);
8028 mutex_exit(&ahci_portp
->ahciport_mutex
);
8029 return (AHCI_SUCCESS
);
8032 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
8033 "port %d device status has changed", port
);
8035 bzero((void *)&sdevice
, sizeof (sata_device_t
));
8036 sdevice
.satadev_addr
.cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
8037 sdevice
.satadev_addr
.qual
= SATA_ADDR_CPORT
;
8038 sdevice
.satadev_addr
.pmport
= 0;
8039 sdevice
.satadev_state
= SATA_PSTATE_PWRON
;
8041 if (port_cmd_status
& AHCI_CMD_STATUS_CPS
) {
8042 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
8043 "port %d: a device is hot plugged", port
);
8044 mutex_exit(&ahci_portp
->ahciport_mutex
);
8045 sata_hba_event_notify(
8046 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
8048 SATA_EVNT_DEVICE_ATTACHED
);
8049 mutex_enter(&ahci_portp
->ahciport_mutex
);
8052 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
8053 "port %d: a device is hot unplugged", port
);
8054 mutex_exit(&ahci_portp
->ahciport_mutex
);
8055 sata_hba_event_notify(
8056 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
8058 SATA_EVNT_DEVICE_DETACHED
);
8059 mutex_enter(&ahci_portp
->ahciport_mutex
);
8062 mutex_exit(&ahci_portp
->ahciport_mutex
);
8064 return (AHCI_SUCCESS
);
8068 * Enable the interrupts for a particular port.
8071 ahci_enable_port_intrs(ahci_ctl_t
*ahci_ctlp
, uint8_t port
)
8073 ASSERT(MUTEX_HELD(&ahci_ctlp
->ahcictl_ports
[port
]->ahciport_mutex
));
8075 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
8076 "ahci_enable_port_intrs enter, port %d", port
);
8079 * Clear port interrupt status before enabling interrupt
8081 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8082 (uint32_t *)AHCI_PORT_PxIS(ahci_ctlp
, port
),
8083 AHCI_PORT_INTR_MASK
);
8086 * Clear the pending bit from IS.IPS
8088 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8089 (uint32_t *)AHCI_GLOBAL_IS(ahci_ctlp
), (1 << port
));
8092 * Enable the following interrupts:
8093 * Device to Host Register FIS Interrupt (DHRS)
8094 * PIO Setup FIS Interrupt (PSS)
8095 * Set Device Bits Interrupt (SDBS)
8096 * Unknown FIS Interrupt (UFS)
8097 * Port Connect Change Status (PCS)
8098 * PhyRdy Change Status (PRCS)
8099 * Overflow Status (OFS)
8100 * Interface Non-fatal Error Status (INFS)
8101 * Interface Fatal Error Status (IFS)
8102 * Host Bus Data Error Status (HBDS)
8103 * Host Bus Fatal Error Status (HBFS)
8104 * Task File Error Status (TFES)
8106 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8107 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp
, port
),
8108 (AHCI_INTR_STATUS_DHRS
|
8109 AHCI_INTR_STATUS_PSS
|
8110 AHCI_INTR_STATUS_SDBS
|
8111 AHCI_INTR_STATUS_UFS
|
8112 AHCI_INTR_STATUS_DPS
|
8113 AHCI_INTR_STATUS_PCS
|
8114 AHCI_INTR_STATUS_PRCS
|
8115 AHCI_INTR_STATUS_OFS
|
8116 AHCI_INTR_STATUS_INFS
|
8117 AHCI_INTR_STATUS_IFS
|
8118 AHCI_INTR_STATUS_HBDS
|
8119 AHCI_INTR_STATUS_HBFS
|
8120 AHCI_INTR_STATUS_TFES
));
8124 * Enable interrupts for all the ports.
8127 ahci_enable_all_intrs(ahci_ctl_t
*ahci_ctlp
)
8129 uint32_t ghc_control
;
8131 ASSERT(MUTEX_HELD(&ahci_ctlp
->ahcictl_mutex
));
8133 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_enable_all_intrs enter", NULL
);
8135 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8136 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
8138 ghc_control
|= AHCI_HBA_GHC_IE
;
8140 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8141 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
), ghc_control
);
8145 * Disable interrupts for a particular port.
8148 ahci_disable_port_intrs(ahci_ctl_t
*ahci_ctlp
, uint8_t port
)
8150 ASSERT(ahci_ctlp
->ahcictl_flags
& AHCI_QUIESCE
||
8151 MUTEX_HELD(&ahci_ctlp
->ahcictl_ports
[port
]->ahciport_mutex
));
8153 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
8154 "ahci_disable_port_intrs enter, port %d", port
);
8156 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8157 (uint32_t *)AHCI_PORT_PxIE(ahci_ctlp
, port
), 0);
8161 * Disable interrupts for the whole HBA.
8163 * The global bit is cleared, then all interrupt sources from all
8164 * ports are disabled.
8167 ahci_disable_all_intrs(ahci_ctl_t
*ahci_ctlp
)
8169 uint32_t ghc_control
;
8171 ASSERT(ahci_ctlp
->ahcictl_flags
& (AHCI_ATTACH
| AHCI_QUIESCE
) ||
8172 MUTEX_HELD(&ahci_ctlp
->ahcictl_mutex
));
8174 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_disable_all_intrs enter",
8177 ghc_control
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8178 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
));
8180 ghc_control
&= ~AHCI_HBA_GHC_IE
;
8182 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8183 (uint32_t *)AHCI_GLOBAL_GHC(ahci_ctlp
), ghc_control
);
8187 * Handle FIXED or MSI interrupts.
8190 * According to AHCI spec, the HBA may support several interrupt modes:
8191 * * pin based interrupts (FIXED)
8192 * * single MSI message interrupts
8193 * * multiple MSI based message interrupts
8195 * For pin based interrupts, the software interrupt handler need to check IS
8196 * register to find out which port has pending interrupts. And then check
8197 * PxIS register to find out which interrupt events happened on that port.
8199 * For single MSI message interrupts, MSICAP.MC.MSIE is set with '1', and
8200 * MSICAP.MC.MME is set with '0'. This mode is similar to pin based interrupts
8201 * in that software interrupt handler need to check IS register to determine
8202 * which port triggered the interrupts since it uses a single message for all
8205 * HBA may optionally support multiple MSI message for better performance. In
8206 * this mode, each port may have its own interrupt message, and thus generation
8207 * of interrupts is no longer controlled through the IS register. MSICAP.MC.MMC
8208 * represents a power-of-2 wrapper on the number of implemented ports, and
8209 * the mapping of ports to interrupts is done in a 1-1 relationship, up to the
8210 * maximum number of assigned interrupts. When the number of MSI messages
8211 * allocated is less than the number requested, then hardware may have two
8212 * implementation behaviors:
8213 * * assign each ports its own interrupt and then force all additional
8214 * ports to share the last interrupt message, and this condition is
8215 * indicated by clearing GHC.MRSM to '0'
8216 * * revert to single MSI mode, indicated by setting GHC.MRSM to '1'
8217 * When multiple-message MSI is enabled, hardware will still set IS register
8218 * as single message case. And this IS register may be used by software when
8219 * fewer than the requested number of messages is granted in order to determine
8220 * which port had the interrupt.
8222 * Note: The current ahci driver only supports the first two interrupt modes:
8223 * pin based interrupts and single MSI message interrupts, and the reason
8224 * is indicated in below code.
8227 ahci_add_intrs(ahci_ctl_t
*ahci_ctlp
, int intr_type
)
8229 dev_info_t
*dip
= ahci_ctlp
->ahcictl_dip
;
8230 int count
, avail
, actual
;
8233 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INIT
|AHCIDBG_INTR
, ahci_ctlp
,
8234 "ahci_add_intrs enter interrupt type 0x%x", intr_type
);
8236 /* get number of interrupts. */
8237 rc
= ddi_intr_get_nintrs(dip
, intr_type
, &count
);
8238 if ((rc
!= DDI_SUCCESS
) || (count
== 0)) {
8239 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8240 "ddi_intr_get_nintrs() failed, "
8241 "rc %d count %d\n", rc
, count
);
8242 return (DDI_FAILURE
);
8245 /* get number of available interrupts. */
8246 rc
= ddi_intr_get_navail(dip
, intr_type
, &avail
);
8247 if ((rc
!= DDI_SUCCESS
) || (avail
== 0)) {
8248 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8249 "ddi_intr_get_navail() failed, "
8250 "rc %d avail %d\n", rc
, avail
);
8251 return (DDI_FAILURE
);
8255 if (avail
< count
) {
8256 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8257 "ddi_intr_get_nintrs returned %d, navail() returned %d",
8263 * Note: So far Solaris restricts the maximum number of messages for
8264 * x86 to 2, that is avail is 2, so here we set the count with 1 to
8265 * force the driver to use single MSI message interrupt. In future if
8266 * Solaris remove the restriction, then we need to delete the below
8267 * code and try to use multiple interrupt routine to gain better
8270 if ((intr_type
== DDI_INTR_TYPE_MSI
) && (count
> 1)) {
8271 AHCIDBG(AHCIDBG_INTR
, ahci_ctlp
,
8272 "force to use one interrupt routine though the "
8273 "HBA supports %d interrupt", count
);
8277 /* Allocate an array of interrupt handles. */
8278 ahci_ctlp
->ahcictl_intr_size
= count
* sizeof (ddi_intr_handle_t
);
8279 ahci_ctlp
->ahcictl_intr_htable
=
8280 kmem_alloc(ahci_ctlp
->ahcictl_intr_size
, KM_SLEEP
);
8282 /* call ddi_intr_alloc(). */
8283 rc
= ddi_intr_alloc(dip
, ahci_ctlp
->ahcictl_intr_htable
,
8284 intr_type
, 0, count
, &actual
, DDI_INTR_ALLOC_NORMAL
);
8286 if ((rc
!= DDI_SUCCESS
) || (actual
== 0)) {
8287 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8288 "ddi_intr_alloc() failed, rc %d count %d actual %d "
8289 "avail %d\n", rc
, count
, actual
, avail
);
8290 kmem_free(ahci_ctlp
->ahcictl_intr_htable
,
8291 ahci_ctlp
->ahcictl_intr_size
);
8292 return (DDI_FAILURE
);
8295 /* use interrupt count returned */
8297 if (actual
< count
) {
8298 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8299 "Requested: %d, Received: %d", count
, actual
);
8303 ahci_ctlp
->ahcictl_intr_cnt
= actual
;
8306 * Get priority for first, assume remaining are all the same.
8308 if (ddi_intr_get_pri(ahci_ctlp
->ahcictl_intr_htable
[0],
8309 &ahci_ctlp
->ahcictl_intr_pri
) != DDI_SUCCESS
) {
8310 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8311 "ddi_intr_get_pri() failed", NULL
);
8313 /* Free already allocated intr. */
8314 for (i
= 0; i
< actual
; i
++) {
8315 (void) ddi_intr_free(ahci_ctlp
->ahcictl_intr_htable
[i
]);
8318 kmem_free(ahci_ctlp
->ahcictl_intr_htable
,
8319 ahci_ctlp
->ahcictl_intr_size
);
8320 return (DDI_FAILURE
);
8323 /* Test for high level interrupt. */
8324 if (ahci_ctlp
->ahcictl_intr_pri
>= ddi_intr_get_hilevel_pri()) {
8325 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8326 "ahci_add_intrs: Hi level intr not supported", NULL
);
8328 /* Free already allocated intr. */
8329 for (i
= 0; i
< actual
; i
++) {
8330 (void) ddi_intr_free(ahci_ctlp
->ahcictl_intr_htable
[i
]);
8333 kmem_free(ahci_ctlp
->ahcictl_intr_htable
,
8334 sizeof (ddi_intr_handle_t
));
8336 return (DDI_FAILURE
);
8339 /* Call ddi_intr_add_handler(). */
8340 for (i
= 0; i
< actual
; i
++) {
8341 if (ddi_intr_add_handler(ahci_ctlp
->ahcictl_intr_htable
[i
],
8342 ahci_intr
, (caddr_t
)ahci_ctlp
, NULL
) != DDI_SUCCESS
) {
8343 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8344 "ddi_intr_add_handler() failed", NULL
);
8346 /* Free already allocated intr. */
8347 for (i
= 0; i
< actual
; i
++) {
8348 (void) ddi_intr_free(
8349 ahci_ctlp
->ahcictl_intr_htable
[i
]);
8352 kmem_free(ahci_ctlp
->ahcictl_intr_htable
,
8353 ahci_ctlp
->ahcictl_intr_size
);
8354 return (DDI_FAILURE
);
8358 if (ddi_intr_get_cap(ahci_ctlp
->ahcictl_intr_htable
[0],
8359 &ahci_ctlp
->ahcictl_intr_cap
) != DDI_SUCCESS
) {
8360 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_INIT
, ahci_ctlp
,
8361 "ddi_intr_get_cap() failed", NULL
);
8363 /* Free already allocated intr. */
8364 for (i
= 0; i
< actual
; i
++) {
8365 (void) ddi_intr_free(
8366 ahci_ctlp
->ahcictl_intr_htable
[i
]);
8369 kmem_free(ahci_ctlp
->ahcictl_intr_htable
,
8370 ahci_ctlp
->ahcictl_intr_size
);
8371 return (DDI_FAILURE
);
8374 if (ahci_ctlp
->ahcictl_intr_cap
& DDI_INTR_FLAG_BLOCK
) {
8375 /* Call ddi_intr_block_enable() for MSI. */
8376 (void) ddi_intr_block_enable(ahci_ctlp
->ahcictl_intr_htable
,
8377 ahci_ctlp
->ahcictl_intr_cnt
);
8379 /* Call ddi_intr_enable() for FIXED or MSI non block enable. */
8380 for (i
= 0; i
< ahci_ctlp
->ahcictl_intr_cnt
; i
++) {
8381 (void) ddi_intr_enable(
8382 ahci_ctlp
->ahcictl_intr_htable
[i
]);
8386 return (DDI_SUCCESS
);
8390 * Removes the registered interrupts irrespective of whether they
8391 * were legacy or MSI.
8393 * NOTE: The controller interrupts must be disabled before calling
8397 ahci_rem_intrs(ahci_ctl_t
*ahci_ctlp
)
8401 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
, "ahci_rem_intrs entered", NULL
);
8403 /* Disable all interrupts. */
8404 if ((ahci_ctlp
->ahcictl_intr_type
== DDI_INTR_TYPE_MSI
) &&
8405 (ahci_ctlp
->ahcictl_intr_cap
& DDI_INTR_FLAG_BLOCK
)) {
8406 /* Call ddi_intr_block_disable(). */
8407 (void) ddi_intr_block_disable(ahci_ctlp
->ahcictl_intr_htable
,
8408 ahci_ctlp
->ahcictl_intr_cnt
);
8410 for (x
= 0; x
< ahci_ctlp
->ahcictl_intr_cnt
; x
++) {
8411 (void) ddi_intr_disable(
8412 ahci_ctlp
->ahcictl_intr_htable
[x
]);
8416 /* Call ddi_intr_remove_handler(). */
8417 for (x
= 0; x
< ahci_ctlp
->ahcictl_intr_cnt
; x
++) {
8418 (void) ddi_intr_remove_handler(
8419 ahci_ctlp
->ahcictl_intr_htable
[x
]);
8420 (void) ddi_intr_free(ahci_ctlp
->ahcictl_intr_htable
[x
]);
8423 kmem_free(ahci_ctlp
->ahcictl_intr_htable
, ahci_ctlp
->ahcictl_intr_size
);
8427 * This routine tries to put port into P:NotRunning state by clearing
8428 * PxCMD.ST. HBA will clear PxCI to 0h, PxSACT to 0h, PxCMD.CCS to 0h
8429 * and PxCMD.CR to '0'.
8432 ahci_put_port_into_notrunning_state(ahci_ctl_t
*ahci_ctlp
,
8433 ahci_port_t
*ahci_portp
, uint8_t port
)
8435 uint32_t port_cmd_status
;
8438 ASSERT(ahci_ctlp
->ahcictl_flags
& AHCI_QUIESCE
||
8439 MUTEX_HELD(&ahci_ctlp
->ahcictl_ports
[port
]->ahciport_mutex
));
8441 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
8442 "ahci_put_port_into_notrunning_state enter: port %d", port
);
8444 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8445 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
8447 port_cmd_status
&= ~AHCI_CMD_STATUS_ST
;
8448 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8449 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
), port_cmd_status
);
8451 /* Wait until PxCMD.CR is cleared */
8455 ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8456 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
8458 if (loop_count
++ > AHCI_POLLRATE_PORT_IDLE
) {
8459 AHCIDBG(AHCIDBG_INIT
, ahci_ctlp
,
8460 "clearing port %d CMD.CR timeout, "
8461 "port_cmd_status = 0x%x", port
,
8464 * We are effectively timing out after 0.5 sec.
8465 * This value is specified in AHCI spec.
8470 /* Wait for 10 millisec */
8471 drv_usecwait(AHCI_10MS_USECS
);
8472 } while (port_cmd_status
& AHCI_CMD_STATUS_CR
);
8474 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_STARTED
;
8476 if (port_cmd_status
& AHCI_CMD_STATUS_CR
) {
8477 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_POLL_LOOP
, ahci_ctlp
,
8478 "ahci_put_port_into_notrunning_state: failed to clear "
8479 "PxCMD.CR to '0' after loop count: %d, and "
8480 "port_cmd_status = 0x%x", loop_count
, port_cmd_status
);
8481 return (AHCI_FAILURE
);
8483 AHCIDBG(AHCIDBG_INIT
|AHCIDBG_POLL_LOOP
, ahci_ctlp
,
8484 "ahci_put_port_into_notrunning_state: succeeded to clear "
8485 "PxCMD.CR to '0' after loop count: %d, and "
8486 "port_cmd_status = 0x%x", loop_count
, port_cmd_status
);
8487 return (AHCI_SUCCESS
);
8492 * First clear PxCMD.ST, and then check PxTFD. If both PxTFD.STS.BSY
8493 * and PxTFD.STS.DRQ cleared to '0', it means the device is in a
8494 * stable state, then set PxCMD.ST to '1' to start the port directly.
8495 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue a
8496 * COMRESET to the device to put it in an idle state.
8498 * The fifth argument returns whether the port reset is involved during
8501 * The routine will be called under following scenarios:
8502 * + To reset the HBA
8503 * + To abort the packet(s)
8504 * + To reset the port
8505 * + To activate the port
8506 * + Fatal error recovery
8507 * + To abort the timeout packet(s)
8509 * NOTES!!! During this procedure, PxSERR register will be cleared, and
8510 * according to the spec, the clearance of three bits will also clear
8511 * three interrupt status bits.
8512 * 1. PxSERR.DIAG.F will clear PxIS.UFS
8513 * 2. PxSERR.DIAG.X will clear PxIS.PCS
8514 * 3. PxSERR.DIAG.N will clear PxIS.PRCS
8516 * Among these three interrupt events, the driver needs to take care of
8517 * PxIS.PRCS, which is the hot plug event. When the driver found out
8518 * a device was unplugged, it will call the interrupt handler.
8521 ahci_restart_port_wait_till_ready(ahci_ctl_t
*ahci_ctlp
,
8522 ahci_port_t
*ahci_portp
, uint8_t port
, int flag
, int *reset_flag
)
8524 uint32_t port_sstatus
;
8525 uint32_t task_file_status
;
8526 sata_device_t sdevice
;
8528 ahci_addr_t addr_port
;
8529 ahci_pmult_info_t
*pminfo
= NULL
;
8530 int dev_exists_begin
= 0;
8531 int dev_exists_end
= 0;
8532 uint32_t previous_dev_type
= ahci_portp
->ahciport_device_type
;
8534 uint8_t cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
8536 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
8538 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
8539 "ahci_restart_port_wait_till_ready: port %d enter", port
);
8541 AHCI_ADDR_SET_PORT(&addr_port
, port
);
8543 if (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_NONE
)
8544 dev_exists_begin
= 1;
8546 /* First clear PxCMD.ST */
8547 rval
= ahci_put_port_into_notrunning_state(ahci_ctlp
, ahci_portp
,
8549 if (rval
!= AHCI_SUCCESS
)
8551 * If PxCMD.CR does not clear within a reasonable time, it
8552 * may assume the interface is in a hung condition and may
8553 * continue with issuing the port reset.
8557 /* Then clear PxSERR */
8558 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8559 (uint32_t *)AHCI_PORT_PxSERR(ahci_ctlp
, port
),
8560 AHCI_SERROR_CLEAR_ALL
);
8562 /* Then get PxTFD */
8563 task_file_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8564 (uint32_t *)AHCI_PORT_PxTFD(ahci_ctlp
, port
));
8567 * Check whether the device is in a stable status, if yes,
8568 * then start the port directly. However for ahci_tran_reset_dport,
8569 * we may have to perform a port reset.
8571 if (!(task_file_status
& (AHCI_TFD_STS_BSY
| AHCI_TFD_STS_DRQ
)) &&
8572 !(flag
& AHCI_PORT_RESET
))
8577 * If PxTFD.STS.BSY or PxTFD.STS.DRQ is set to '1', then issue
8578 * a COMRESET to the device
8580 ahci_disable_port_intrs(ahci_ctlp
, port
);
8581 rval
= ahci_port_reset(ahci_ctlp
, ahci_portp
, &addr_port
);
8582 ahci_enable_port_intrs(ahci_ctlp
, port
);
8585 if (rval
!= AHCI_SUCCESS
)
8586 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
8587 "ahci_restart_port_wait_till_ready: port %d failed",
8591 if (reset_flag
!= NULL
)
8594 /* Indicate to the framework that a reset has happened. */
8595 if ((ahci_portp
->ahciport_device_type
!= SATA_DTYPE_NONE
) &&
8596 (ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
) &&
8597 !(flag
& AHCI_RESET_NO_EVENTS_UP
)) {
8598 /* Set the reset in progress flag */
8599 ahci_portp
->ahciport_reset_in_progress
= 1;
8601 bzero((void *)&sdevice
, sizeof (sata_device_t
));
8602 sdevice
.satadev_addr
.cport
=
8603 ahci_ctlp
->ahcictl_port_to_cport
[port
];
8604 sdevice
.satadev_addr
.pmport
= 0;
8605 sdevice
.satadev_addr
.qual
= SATA_ADDR_DCPORT
;
8607 sdevice
.satadev_state
= SATA_DSTATE_RESET
|
8608 SATA_DSTATE_PWR_ACTIVE
;
8609 if (ahci_ctlp
->ahcictl_sata_hba_tran
) {
8610 mutex_exit(&ahci_portp
->ahciport_mutex
);
8611 sata_hba_event_notify(
8612 ahci_ctlp
->ahcictl_sata_hba_tran
->sata_tran_hba_dip
,
8614 SATA_EVNT_DEVICE_RESET
);
8615 mutex_enter(&ahci_portp
->ahciport_mutex
);
8618 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
8619 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port
);
8621 ahci_portp
->ahciport_reset_in_progress
= 0;
8625 (void) ahci_start_port(ahci_ctlp
, ahci_portp
, port
);
8627 /* SStatus tells the presence of device. */
8628 port_sstatus
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
8629 (uint32_t *)AHCI_PORT_PxSSTS(ahci_ctlp
, port
));
8631 if (SSTATUS_GET_DET(port_sstatus
) == SSTATUS_DET_DEVPRE_PHYCOM
) {
8635 if (dev_exists_begin
== 0 && dev_exists_end
== 0) /* 0 -> 0 */
8638 /* Check whether a hot plug event happened */
8639 if (dev_exists_begin
== 1 && dev_exists_end
== 0) { /* 1 -> 0 */
8640 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
8641 "ahci_restart_port_wait_till_ready: port %d "
8642 "device is removed", port
);
8643 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_NODEV
;
8644 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
8645 "ahci_restart_port_wait_till_ready: port %d "
8646 "AHCI_PORT_FLAG_NODEV flag is set", port
);
8647 mutex_exit(&ahci_portp
->ahciport_mutex
);
8648 (void) ahci_intr_phyrdy_change(ahci_ctlp
, ahci_portp
, port
);
8649 mutex_enter(&ahci_portp
->ahciport_mutex
);
8655 /* 0/1 -> 1 : device may change */
8657 * May be called by ahci_fatal_error_recovery_handler, so
8658 * don't issue software if the previous device is ATAPI.
8660 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_ATAPI
)
8664 * The COMRESET will make port multiplier enter legacy mode.
8665 * Issue a software reset to make it work again.
8667 ahci_disable_port_intrs(ahci_ctlp
, port
);
8668 ahci_find_dev_signature(ahci_ctlp
, ahci_portp
, &addr_port
);
8669 ahci_enable_port_intrs(ahci_ctlp
, port
);
8672 * Following codes are specific for the port multiplier
8674 if (previous_dev_type
!= SATA_DTYPE_PMULT
&&
8675 ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
) {
8676 /* in case previous_dev_type is corrupt */
8677 ahci_dealloc_pmult(ahci_ctlp
, ahci_portp
);
8678 (void) ahci_start_port(ahci_ctlp
, ahci_portp
, port
);
8682 /* Device change: PMult -> Non-PMult */
8683 if (previous_dev_type
== SATA_DTYPE_PMULT
&&
8684 ahci_portp
->ahciport_device_type
!= SATA_DTYPE_PMULT
) {
8686 * This might happen because
8687 * 1. Software reset failed. Port multiplier is not correctly
8689 * 2. Another non-port-multiplier device is attached. Perhaps
8690 * the port multiplier was replaced by another device by
8691 * whatever reason, but AHCI driver missed hot-plug event.
8693 * Now that the port has been initialized, we just need to
8694 * update the port structure according new device, then report
8695 * and wait SATA framework to probe new device.
8698 /* Force to release pmult resource */
8699 ahci_dealloc_pmult(ahci_ctlp
, ahci_portp
);
8700 (void) ahci_start_port(ahci_ctlp
, ahci_portp
, port
);
8702 bzero((void *)&sdevice
, sizeof (sata_device_t
));
8703 sdevice
.satadev_addr
.cport
=
8704 ahci_ctlp
->ahcictl_port_to_cport
[port
];
8705 sdevice
.satadev_addr
.pmport
= 0;
8706 sdevice
.satadev_addr
.qual
= SATA_ADDR_DCPORT
;
8708 sdevice
.satadev_state
= SATA_DSTATE_RESET
|
8709 SATA_DSTATE_PWR_ACTIVE
;
8711 mutex_exit(&ahci_portp
->ahciport_mutex
);
8712 sata_hba_event_notify(
8713 ahci_ctlp
->ahcictl_dip
,
8715 SATA_EVNT_DEVICE_RESET
);
8716 mutex_enter(&ahci_portp
->ahciport_mutex
);
8718 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
8719 "Port multiplier is [Gone] at port %d ", port
);
8720 AHCIDBG(AHCIDBG_EVENT
, ahci_ctlp
,
8721 "port %d sending event up: SATA_EVNT_DEVICE_RESET", port
);
8723 return (AHCI_SUCCESS
);
8726 /* Device change: Non-PMult -> PMult */
8727 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_PMULT
) {
8729 /* NOTE: The PxCMD.PMA may be cleared by HBA reset. */
8730 ahci_alloc_pmult(ahci_ctlp
, ahci_portp
);
8732 (void) ahci_start_port(ahci_ctlp
, ahci_portp
, port
);
8734 pminfo
= ahci_portp
->ahciport_pmult_info
;
8735 ASSERT(pminfo
!= NULL
);
8737 /* Device (may) change: PMult -> PMult */
8739 * First initialize port multiplier. Set state to READY and wait for
8740 * probe entry point to initialize it
8742 ahci_portp
->ahciport_port_state
= SATA_STATE_READY
;
8745 * It's a little complicated while target is a port multiplier. we
8746 * need to COMRESET all pmports behind that PMult otherwise those
8747 * sub-links between the PMult and the sub-devices will be in an
8748 * inactive state (indicated by PSCR0/PxSSTS) and the following access
8749 * to those sub-devices will be rejected by Link-Fatal-Error.
8752 * The PxSNTF will be set soon after the pmult is plugged. While the
8753 * pmult itself is attaching, sata_hba_event_notfiy will fail. so we
8754 * simply mark every sub-port as 'unknown', then ahci_probe_pmport
8755 * will initialized it.
8757 for (npmport
= 0; npmport
< pminfo
->ahcipmi_num_dev_ports
; npmport
++)
8758 pminfo
->ahcipmi_port_state
[npmport
] = SATA_STATE_UNKNOWN
;
8760 /* Report reset event. */
8761 ahci_portp
->ahciport_reset_in_progress
= 1;
8763 bzero((void *)&sdevice
, sizeof (sata_device_t
));
8764 sdevice
.satadev_addr
.cport
= cport
;
8765 sdevice
.satadev_addr
.pmport
= SATA_PMULT_HOSTPORT
;
8766 sdevice
.satadev_addr
.qual
= SATA_ADDR_PMULT
;
8767 sdevice
.satadev_state
= SATA_DSTATE_RESET
| SATA_DSTATE_PWR_ACTIVE
;
8768 sata_hba_event_notify(ahci_ctlp
->ahcictl_dip
, &sdevice
,
8769 SATA_EVNT_DEVICE_RESET
);
8775 * This routine may be called under four scenarios:
8776 * a) do the recovery from fatal error
8777 * b) or we need to timeout some commands
8778 * c) or we need to abort some commands
8779 * d) or we need reset device/port/controller
8781 * In all these scenarios, we need to send any pending unfinished
8782 * commands up to sata framework.
8785 ahci_mop_commands(ahci_ctl_t
*ahci_ctlp
,
8786 ahci_port_t
*ahci_portp
,
8787 uint32_t slot_status
,
8788 uint32_t failed_tags
,
8789 uint32_t timeout_tags
,
8790 uint32_t aborted_tags
,
8791 uint32_t reset_tags
)
8793 uint32_t finished_tags
= 0;
8794 uint32_t unfinished_tags
= 0;
8796 sata_pkt_t
*satapkt
;
8797 int ncq_cmd_in_progress
= 0;
8798 int err_retri_cmd_in_progress
= 0;
8799 int rdwr_pmult_cmd_in_progress
= 0;
8801 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
8803 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_ENTRY
, ahci_ctlp
,
8804 "ahci_mop_commands entered: port: %d slot_status: 0x%x",
8805 ahci_portp
->ahciport_port_num
, slot_status
);
8807 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_ENTRY
, ahci_ctlp
,
8808 "ahci_mop_commands: failed_tags: 0x%x, "
8809 "timeout_tags: 0x%x aborted_tags: 0x%x, "
8810 "reset_tags: 0x%x", failed_tags
,
8811 timeout_tags
, aborted_tags
, reset_tags
);
8814 if (ahci_debug_flags
& AHCIDBG_ERRS
) {
8816 char msg_buf
[200] = {0, };
8817 for (i
= 0x1f; i
>= 0; i
--) {
8818 if (ahci_portp
->ahciport_slot_pkts
[i
] != NULL
)
8823 msg_buf
[0x20] = '\0';
8824 cmn_err(CE_NOTE
, "port[%d] slots: %s",
8825 ahci_portp
->ahciport_port_num
, msg_buf
);
8826 cmn_err(CE_NOTE
, "[ERR-RT] %p [RW-PM] %p ",
8827 (void *)ahci_portp
->ahciport_err_retri_pkt
,
8828 (void *)ahci_portp
->ahciport_rdwr_pmult_pkt
);
8832 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
8833 finished_tags
= ahci_portp
->ahciport_pending_tags
&
8834 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
8836 unfinished_tags
= slot_status
&
8837 AHCI_SLOT_MASK(ahci_ctlp
) &
8842 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
8843 ncq_cmd_in_progress
= 1;
8844 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
8845 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
8847 unfinished_tags
= slot_status
&
8848 AHCI_NCQ_SLOT_MASK(ahci_portp
) &
8853 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
8856 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT is
8857 * set, it means REQUEST SENSE or READ LOG EXT command doesn't
8858 * complete successfully due to one of the following three
8861 * 1. Fatal error - failed_tags includes its slot
8862 * 2. Timed out - timeout_tags includes its slot
8863 * 3. Aborted when hot unplug - aborted_tags includes its
8866 * Please note that the command is always sent down in Slot 0
8868 err_retri_cmd_in_progress
= 1;
8869 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_NCQ
, ahci_ctlp
,
8870 "ahci_mop_commands is called for port %d while "
8871 "REQUEST SENSE or READ LOG EXT for error retrieval "
8872 "is being executed slot_status = 0x%x",
8873 ahci_portp
->ahciport_port_num
, slot_status
);
8874 ASSERT(ahci_portp
->ahciport_mop_in_progress
> 1);
8875 ASSERT(slot_status
== 0x1);
8876 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
8877 rdwr_pmult_cmd_in_progress
= 1;
8878 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_PMULT
, ahci_ctlp
,
8879 "ahci_mop_commands is called for port %d while "
8880 "READ/WRITE PORTMULT command is being executed",
8881 ahci_portp
->ahciport_port_num
);
8883 ASSERT(slot_status
== 0x1);
8887 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_ENTRY
, ahci_ctlp
,
8888 "ahci_mop_commands: finished_tags: 0x%x, "
8889 "unfinished_tags 0x%x", finished_tags
, unfinished_tags
);
8892 /* Send up finished packets with SATA_PKT_COMPLETED */
8893 while (finished_tags
) {
8894 tmp_slot
= ddi_ffs(finished_tags
) - 1;
8895 if (tmp_slot
== -1) {
8899 satapkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
8900 ASSERT(satapkt
!= NULL
);
8902 AHCIDBG(AHCIDBG_INFO
, ahci_ctlp
, "ahci_mop_commands: "
8903 "sending up pkt 0x%p with SATA_PKT_COMPLETED",
8907 * Cannot fetch the return register content since the port
8908 * was restarted, so the corresponding tag will be set to
8911 if (satapkt
->satapkt_cmd
.satacmd_flags
.sata_special_regs
) {
8912 CLEAR_BIT(finished_tags
, tmp_slot
);
8913 aborted_tags
|= tmp_slot
;
8917 if (ncq_cmd_in_progress
)
8918 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
,
8920 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, tmp_slot
);
8921 CLEAR_BIT(finished_tags
, tmp_slot
);
8922 ahci_portp
->ahciport_slot_pkts
[tmp_slot
] = NULL
;
8924 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_COMPLETED
);
8927 /* Send up failed packets with SATA_PKT_DEV_ERROR. */
8928 while (failed_tags
) {
8929 if (err_retri_cmd_in_progress
) {
8930 satapkt
= ahci_portp
->ahciport_err_retri_pkt
;
8931 ASSERT(satapkt
!= NULL
);
8932 ASSERT(failed_tags
== 0x1);
8934 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
8935 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8937 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_DEV_ERROR
);
8940 if (rdwr_pmult_cmd_in_progress
) {
8941 satapkt
= ahci_portp
->ahciport_rdwr_pmult_pkt
;
8942 ASSERT(satapkt
!= NULL
);
8943 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
8944 "ahci_mop_commands: sending up "
8945 "rdwr pmult pkt 0x%p with SATA_PKT_DEV_ERROR",
8947 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_DEV_ERROR
);
8951 tmp_slot
= ddi_ffs(failed_tags
) - 1;
8952 if (tmp_slot
== -1) {
8956 satapkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
8957 ASSERT(satapkt
!= NULL
);
8959 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
8960 "sending up pkt 0x%p with SATA_PKT_DEV_ERROR",
8963 if (ncq_cmd_in_progress
)
8964 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
,
8966 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, tmp_slot
);
8967 CLEAR_BIT(failed_tags
, tmp_slot
);
8968 ahci_portp
->ahciport_slot_pkts
[tmp_slot
] = NULL
;
8970 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_DEV_ERROR
);
8973 /* Send up timeout packets with SATA_PKT_TIMEOUT. */
8974 while (timeout_tags
) {
8975 if (err_retri_cmd_in_progress
) {
8976 satapkt
= ahci_portp
->ahciport_err_retri_pkt
;
8977 ASSERT(satapkt
!= NULL
);
8978 ASSERT(timeout_tags
== 0x1);
8980 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
8981 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
8983 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_TIMEOUT
);
8986 if (rdwr_pmult_cmd_in_progress
) {
8987 satapkt
= ahci_portp
->ahciport_rdwr_pmult_pkt
;
8988 ASSERT(satapkt
!= NULL
);
8989 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
8990 "ahci_mop_commands: sending up "
8991 "rdwr pmult pkt 0x%p with SATA_PKT_TIMEOUT",
8993 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_TIMEOUT
);
8997 tmp_slot
= ddi_ffs(timeout_tags
) - 1;
8998 if (tmp_slot
== -1) {
9002 satapkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
9003 ASSERT(satapkt
!= NULL
);
9005 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
9006 "sending up pkt 0x%p with SATA_PKT_TIMEOUT",
9009 if (ncq_cmd_in_progress
)
9010 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
,
9012 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, tmp_slot
);
9013 CLEAR_BIT(timeout_tags
, tmp_slot
);
9014 ahci_portp
->ahciport_slot_pkts
[tmp_slot
] = NULL
;
9016 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_TIMEOUT
);
9019 /* Send up aborted packets with SATA_PKT_ABORTED */
9020 while (aborted_tags
) {
9021 if (err_retri_cmd_in_progress
) {
9022 satapkt
= ahci_portp
->ahciport_err_retri_pkt
;
9023 ASSERT(satapkt
!= NULL
);
9024 ASSERT(aborted_tags
== 0x1);
9026 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
9027 "sending up pkt 0x%p with SATA_PKT_ABORTED",
9029 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_ABORTED
);
9032 if (rdwr_pmult_cmd_in_progress
) {
9033 satapkt
= ahci_portp
->ahciport_rdwr_pmult_pkt
;
9034 ASSERT(satapkt
!= NULL
);
9035 ASSERT(aborted_tags
== 0x1);
9036 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9037 "ahci_mop_commands: sending up "
9038 "rdwr pmult pkt 0x%p with SATA_PKT_ABORTED",
9040 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_ABORTED
);
9044 tmp_slot
= ddi_ffs(aborted_tags
) - 1;
9045 if (tmp_slot
== -1) {
9049 satapkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
9050 ASSERT(satapkt
!= NULL
);
9052 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
9053 "sending up pkt 0x%p with SATA_PKT_ABORTED",
9056 if (ncq_cmd_in_progress
)
9057 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
,
9059 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, tmp_slot
);
9060 CLEAR_BIT(aborted_tags
, tmp_slot
);
9061 ahci_portp
->ahciport_slot_pkts
[tmp_slot
] = NULL
;
9063 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_ABORTED
);
9066 /* Send up reset packets with SATA_PKT_RESET. */
9067 while (reset_tags
) {
9068 if (rdwr_pmult_cmd_in_progress
) {
9069 satapkt
= ahci_portp
->ahciport_rdwr_pmult_pkt
;
9070 ASSERT(satapkt
!= NULL
);
9071 ASSERT(aborted_tags
== 0x1);
9072 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9073 "ahci_mop_commands: sending up "
9074 "rdwr pmult pkt 0x%p with SATA_PKT_RESET",
9076 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_RESET
);
9080 tmp_slot
= ddi_ffs(reset_tags
) - 1;
9081 if (tmp_slot
== -1) {
9085 satapkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
9086 ASSERT(satapkt
!= NULL
);
9088 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
9089 "sending up pkt 0x%p with SATA_PKT_RESET",
9092 if (ncq_cmd_in_progress
)
9093 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
,
9095 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, tmp_slot
);
9096 CLEAR_BIT(reset_tags
, tmp_slot
);
9097 ahci_portp
->ahciport_slot_pkts
[tmp_slot
] = NULL
;
9099 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_RESET
);
9102 /* Send up unfinished packets with SATA_PKT_RESET */
9103 while (unfinished_tags
) {
9104 tmp_slot
= ddi_ffs(unfinished_tags
) - 1;
9105 if (tmp_slot
== -1) {
9109 satapkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
9110 ASSERT(satapkt
!= NULL
);
9112 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, "ahci_mop_commands: "
9113 "sending up pkt 0x%p with SATA_PKT_RESET",
9116 if (ncq_cmd_in_progress
)
9117 CLEAR_BIT(ahci_portp
->ahciport_pending_ncq_tags
,
9119 CLEAR_BIT(ahci_portp
->ahciport_pending_tags
, tmp_slot
);
9120 CLEAR_BIT(unfinished_tags
, tmp_slot
);
9121 ahci_portp
->ahciport_slot_pkts
[tmp_slot
] = NULL
;
9123 ahci_add_doneq(ahci_portp
, satapkt
, SATA_PKT_RESET
);
9126 ahci_portp
->ahciport_mop_in_progress
--;
9127 ASSERT(ahci_portp
->ahciport_mop_in_progress
>= 0);
9129 if (ahci_portp
->ahciport_mop_in_progress
== 0)
9130 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_MOPPING
;
9132 ahci_flush_doneq(ahci_portp
);
9136 * This routine is going to first request a READ LOG EXT sata pkt from sata
9137 * module, and then deliver it to the HBA to get the ncq failure context.
9138 * The return value is the exactly failed tags.
9141 ahci_get_rdlogext_data(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
9144 sata_device_t sdevice
;
9145 sata_pkt_t
*rdlog_spkt
, *spkt
;
9146 ddi_dma_handle_t buf_dma_handle
;
9151 uint32_t failed_tags
= 0;
9152 struct sata_ncq_error_recovery_page
*ncq_err_page
;
9154 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_NCQ
, ahci_ctlp
,
9155 "ahci_get_rdlogext_data enter: port %d", port
);
9157 /* Prepare the sdevice data */
9158 bzero((void *)&sdevice
, sizeof (sata_device_t
));
9159 sdevice
.satadev_addr
.cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
9161 sdevice
.satadev_addr
.qual
= SATA_ADDR_DCPORT
;
9162 sdevice
.satadev_addr
.pmport
= 0;
9164 /* Translate sata_device.satadev_addr -> ahci_addr */
9165 ahci_get_ahci_addr(ahci_ctlp
, &sdevice
, &addr
);
9168 * Call the sata hba interface to get a rdlog spkt
9172 rdlog_spkt
= sata_get_error_retrieval_pkt(ahci_ctlp
->ahcictl_dip
,
9173 &sdevice
, SATA_ERR_RETR_PKT_TYPE_NCQ
);
9174 if (rdlog_spkt
== NULL
) {
9175 if (loop_count
++ < AHCI_POLLRATE_GET_SPKT
) {
9176 /* Sleep for a while */
9177 drv_usecwait(AHCI_10MS_USECS
);
9180 /* Timed out after 1s */
9181 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9182 "failed to get rdlog spkt for port %d", port
);
9183 return (failed_tags
);
9186 ASSERT(rdlog_spkt
->satapkt_op_mode
& SATA_OPMODE_SYNCH
);
9189 * This flag is used to handle the specific error recovery when the
9190 * READ LOG EXT command gets a failure (fatal error or time-out).
9192 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_RDLOGEXT
;
9195 * This start is not supposed to fail because after port is restarted,
9196 * the whole command list is empty.
9198 ahci_portp
->ahciport_err_retri_pkt
= rdlog_spkt
;
9199 (void) ahci_do_sync_start(ahci_ctlp
, ahci_portp
, &addr
, rdlog_spkt
);
9200 ahci_portp
->ahciport_err_retri_pkt
= NULL
;
9202 /* Remove the flag after READ LOG EXT command is completed */
9203 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_RDLOGEXT
;
9205 if (rdlog_spkt
->satapkt_reason
== SATA_PKT_COMPLETED
) {
9206 /* Update the request log data */
9207 buf_dma_handle
= *(ddi_dma_handle_t
*)
9208 (rdlog_spkt
->satapkt_cmd
.satacmd_err_ret_buf_handle
);
9209 rval
= ddi_dma_sync(buf_dma_handle
, 0, 0,
9210 DDI_DMA_SYNC_FORKERNEL
);
9211 if (rval
== DDI_SUCCESS
) {
9213 (struct sata_ncq_error_recovery_page
*)rdlog_spkt
->
9214 satapkt_cmd
.satacmd_bp
->b_un
.b_addr
;
9216 /* Get the failed tag */
9217 failed_slot
= ncq_err_page
->ncq_tag
;
9218 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9219 "ahci_get_rdlogext_data: port %d "
9220 "failed slot %d", port
, failed_slot
);
9221 if (failed_slot
& NQ
) {
9222 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9223 "the failed slot is not a valid tag", NULL
);
9227 failed_slot
&= NCQ_TAG_MASK
;
9228 spkt
= ahci_portp
->ahciport_slot_pkts
[failed_slot
];
9229 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9230 "ahci_get_rdlogext_data: failed spkt 0x%p",
9233 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9234 "the failed slot spkt is NULL", NULL
);
9238 failed_tags
= 0x1 << failed_slot
;
9240 /* Fill out the error context */
9241 ahci_copy_ncq_err_page(&spkt
->satapkt_cmd
,
9243 ahci_update_sata_registers(ahci_ctlp
, port
,
9244 &spkt
->satapkt_device
);
9248 sata_free_error_retrieval_pkt(rdlog_spkt
);
9250 return (failed_tags
);
9254 * This routine is going to first request a REQUEST SENSE sata pkt from sata
9255 * module, and then deliver it to the HBA to get the sense data and copy
9256 * the sense data back to the orignal failed sata pkt, and free the REQUEST
9257 * SENSE sata pkt later.
9260 ahci_get_rqsense_data(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
9261 uint8_t port
, sata_pkt_t
*spkt
)
9263 sata_device_t sdevice
;
9264 sata_pkt_t
*rs_spkt
;
9265 sata_cmd_t
*sata_cmd
;
9266 ddi_dma_handle_t buf_dma_handle
;
9270 struct scsi_extended_sense
*rqsense
;
9273 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
9274 "ahci_get_rqsense_data enter: port %d", port
);
9276 /* Prepare the sdevice data */
9277 bzero((void *)&sdevice
, sizeof (sata_device_t
));
9278 sdevice
.satadev_addr
.cport
= ahci_ctlp
->ahcictl_port_to_cport
[port
];
9280 sdevice
.satadev_addr
.qual
= SATA_ADDR_DCPORT
;
9281 sdevice
.satadev_addr
.pmport
= 0;
9283 /* Translate sata_device.satadev_addr -> ahci_addr */
9284 ahci_get_ahci_addr(ahci_ctlp
, &sdevice
, &addr
);
9286 sata_cmd
= &spkt
->satapkt_cmd
;
9289 * Call the sata hba interface to get a rs spkt
9293 rs_spkt
= sata_get_error_retrieval_pkt(ahci_ctlp
->ahcictl_dip
,
9294 &sdevice
, SATA_ERR_RETR_PKT_TYPE_ATAPI
);
9295 if (rs_spkt
== NULL
) {
9296 if (loop_count
++ < AHCI_POLLRATE_GET_SPKT
) {
9297 /* Sleep for a while */
9298 drv_usecwait(AHCI_10MS_USECS
);
9302 /* Timed out after 1s */
9303 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9304 "failed to get rs spkt for port %d", port
);
9308 ASSERT(rs_spkt
->satapkt_op_mode
& SATA_OPMODE_SYNCH
);
9311 * This flag is used to handle the specific error recovery when the
9312 * REQUEST SENSE command gets a faiure (fatal error or time-out).
9314 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_RQSENSE
;
9317 * This start is not supposed to fail because after port is restarted,
9318 * the whole command list is empty.
9320 ahci_portp
->ahciport_err_retri_pkt
= rs_spkt
;
9321 (void) ahci_do_sync_start(ahci_ctlp
, ahci_portp
, &addr
, rs_spkt
);
9322 ahci_portp
->ahciport_err_retri_pkt
= NULL
;
9324 /* Remove the flag after REQUEST SENSE command is completed */
9325 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_RQSENSE
;
9327 if (rs_spkt
->satapkt_reason
== SATA_PKT_COMPLETED
) {
9328 /* Update the request sense data */
9329 buf_dma_handle
= *(ddi_dma_handle_t
*)
9330 (rs_spkt
->satapkt_cmd
.satacmd_err_ret_buf_handle
);
9331 (void) ddi_dma_sync(buf_dma_handle
, 0, 0,
9332 DDI_DMA_SYNC_FORKERNEL
);
9333 /* Copy the request sense data */
9335 satapkt_cmd
.satacmd_bp
->b_un
.b_addr
,
9336 &sata_cmd
->satacmd_rqsense
,
9337 SATA_ATAPI_MIN_RQSENSE_LEN
);
9339 rqsense
= (struct scsi_extended_sense
*)
9340 sata_cmd
->satacmd_rqsense
;
9342 /* Dump the sense data */
9343 AHCIDBG(AHCIDBG_SENSEDATA
, ahci_ctlp
, "\n", NULL
);
9344 AHCIDBG(AHCIDBG_SENSEDATA
, ahci_ctlp
,
9345 "Sense data for satapkt %p ATAPI cmd 0x%x",
9346 spkt
, sata_cmd
->satacmd_acdb
[0]);
9347 AHCIDBG(AHCIDBG_SENSEDATA
, ahci_ctlp
,
9348 " es_code 0x%x es_class 0x%x "
9349 "es_key 0x%x es_add_code 0x%x "
9350 "es_qual_code 0x%x",
9351 rqsense
->es_code
, rqsense
->es_class
,
9352 rqsense
->es_key
, rqsense
->es_add_code
,
9353 rqsense
->es_qual_code
);
9357 sata_free_error_retrieval_pkt(rs_spkt
);
9361 * Fatal errors will cause the HBA to enter the ERR: Fatal state. To recover,
9362 * the port must be restarted. When the HBA detects thus error, it may try
9363 * to abort a transfer. And if the transfer was aborted, the device is
9364 * expected to send a D2H Register FIS with PxTFD.STS.ERR set to '1' and both
9365 * PxTFD.STS.BSY and PxTFD.STS.DRQ cleared to '0'. Then system software knows
9366 * that the device is in a stable status and transfers may be restarted without
9367 * issuing a COMRESET to the device. If PxTFD.STS.BSY or PxTFD.STS.DRQ is set,
9368 * then the software will send the COMRESET to do the port reset.
9370 * Software should perform the appropriate error recovery actions based on
9371 * whether non-queued commands were being issued or natived command queuing
9372 * commands were being issued.
9374 * And software will complete the command that had the error with error mark
9375 * to higher level software.
9377 * Fatal errors include the following:
9378 * PxIS.IFS - Interface Fatal Error Status
9379 * PxIS.HBDS - Host Bus Data Error Status
9380 * PxIS.HBFS - Host Bus Fatal Error Status
9381 * PxIS.TFES - Task File Error Status
9384 ahci_fatal_error_recovery_handler(ahci_ctl_t
*ahci_ctlp
,
9385 ahci_port_t
*ahci_portp
, ahci_addr_t
*addrp
, uint32_t intr_status
)
9387 uint32_t port_cmd_status
;
9388 uint32_t slot_status
= 0;
9389 uint32_t failed_tags
= 0;
9391 int reset_flag
= 0, flag
= 0;
9392 ahci_fis_d2h_register_t
*ahci_rcvd_fisp
;
9393 sata_cmd_t
*sata_cmd
= NULL
;
9394 sata_pkt_t
*spkt
= NULL
;
9396 ahci_cmd_header_t
*cmd_header
;
9398 uint8_t port
= addrp
->aa_port
;
9399 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
9402 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
9404 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
9405 "ahci_fatal_error_recovery_handler enter: port %d", port
);
9407 /* Port multiplier error */
9408 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_PMULT
) {
9409 /* FBS code is neither completed nor tested. */
9410 ahci_pmult_error_recovery_handler(ahci_ctlp
, ahci_portp
,
9413 /* Force a port reset */
9414 flag
= AHCI_PORT_RESET
;
9417 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
) ||
9418 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
9420 /* Read PxCI to see which commands are still outstanding */
9421 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9422 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
9425 * Read PxCMD.CCS to determine the slot that the HBA
9426 * was processing when the error occurred.
9428 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9429 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
9430 failed_slot
= (port_cmd_status
& AHCI_CMD_STATUS_CCS
) >>
9431 AHCI_CMD_STATUS_CCS_SHIFT
;
9433 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
9434 spkt
= ahci_portp
->ahciport_err_retri_pkt
;
9435 ASSERT(spkt
!= NULL
);
9437 spkt
= ahci_portp
->ahciport_slot_pkts
[failed_slot
];
9439 /* May happen when interface errors occur? */
9446 * Debugging purpose...
9448 if (ahci_portp
->ahciport_prd_bytecounts
[failed_slot
]) {
9450 &ahci_portp
->ahciport_cmd_list
[failed_slot
];
9451 AHCIDBG(AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
9452 "ahci_fatal_error_recovery_handler: port %d, "
9453 "PRD Byte Count = 0x%x, "
9454 "ahciport_prd_bytecounts = 0x%x", port
,
9455 cmd_header
->ahcich_prd_byte_count
,
9456 ahci_portp
->ahciport_prd_bytecounts
[failed_slot
]);
9460 sata_cmd
= &spkt
->satapkt_cmd
;
9462 /* Fill out the status and error registers for PxIS.TFES */
9463 if (intr_status
& AHCI_INTR_STATUS_TFES
) {
9464 ahci_rcvd_fisp
= &(ahci_portp
->ahciport_rcvd_fis
->
9465 ahcirf_d2h_register_fis
);
9467 /* Copy the error context back to the sata_cmd */
9468 ahci_copy_err_cnxt(sata_cmd
, ahci_rcvd_fisp
);
9471 /* The failed command must be one of the outstanding commands */
9472 failed_tags
= 0x1 << failed_slot
;
9473 ASSERT(failed_tags
& slot_status
);
9475 /* Update the sata registers, especially PxSERR register */
9476 ahci_update_sata_registers(ahci_ctlp
, port
,
9477 &spkt
->satapkt_device
);
9479 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9480 /* Read PxSACT to see which commands are still outstanding */
9481 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9482 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
9488 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9489 * set, it means a fatal error happened after REQUEST SENSE command
9490 * or READ LOG EXT command is delivered to the HBA during the error
9491 * recovery process. At this time, the only outstanding command is
9492 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9494 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
9495 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9496 "ahci_fatal_error_recovery_handler: port %d REQUEST SENSE "
9497 "command or READ LOG EXT command for error data retrieval "
9499 ASSERT(slot_status
== 0x1);
9500 ASSERT(failed_slot
== 0);
9501 ASSERT(spkt
->satapkt_cmd
.satacmd_acdb
[0] ==
9502 SCMD_REQUEST_SENSE
||
9503 spkt
->satapkt_cmd
.satacmd_cmd_reg
==
9504 SATAC_READ_LOG_EXT
);
9508 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
9509 ahci_portp
->ahciport_mop_in_progress
++;
9511 rval
= ahci_restart_port_wait_till_ready(ahci_ctlp
, ahci_portp
,
9512 port
, flag
, &reset_flag
);
9514 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_ERRPRINT
) {
9515 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_ERRPRINT
;
9516 if (rval
== AHCI_SUCCESS
)
9517 cmn_err(CE_WARN
, "!ahci%d: error recovery for port %d "
9518 "succeed", instance
, port
);
9520 cmn_err(CE_WARN
, "!ahci%d: error recovery for port %d "
9521 "failed", instance
, port
);
9525 * Won't retrieve error information:
9526 * 1. Port reset was involved to recover
9528 * 3. IDENTIFY DEVICE command sent to ATAPI device
9529 * 4. REQUEST SENSE or READ LOG EXT command during error recovery
9532 ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
||
9533 spkt
&& spkt
->satapkt_cmd
.satacmd_cmd_reg
== SATAC_ID_DEVICE
||
9534 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
))
9538 * Deliver READ LOG EXT to gather information about the error when
9539 * a COMRESET has not been performed as part of the error recovery
9540 * during NCQ command processing.
9542 if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9543 failed_tags
= ahci_get_rdlogext_data(ahci_ctlp
,
9549 * Deliver REQUEST SENSE for ATAPI command to gather information about
9550 * the error when a COMRESET has not been performed as part of the
9553 if (spkt
&& ahci_portp
->ahciport_device_type
== SATA_DTYPE_ATAPI
)
9554 ahci_get_rqsense_data(ahci_ctlp
, ahci_portp
, port
, spkt
);
9556 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9557 "ahci_fatal_error_recovery_handler: port %d fatal error "
9558 "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9559 "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9560 port
, slot_status
, ahci_portp
->ahciport_pending_tags
,
9561 ahci_portp
->ahciport_pending_ncq_tags
, failed_tags
);
9563 ahci_mop_commands(ahci_ctlp
,
9566 failed_tags
, /* failed tags */
9567 0, /* timeout tags */
9568 0, /* aborted tags */
9569 0); /* reset tags */
9573 * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9574 * 1. device specific.PxFBS.SDE=1
9575 * 2. Non Device specific.
9576 * Nothing will be done when Command-based switching is employed.
9578 * Currently code is neither completed nor tested.
9581 ahci_pmult_error_recovery_handler(ahci_ctl_t
*ahci_ctlp
,
9582 ahci_port_t
*ahci_portp
, uint8_t port
, uint32_t intr_status
)
9585 _NOTE(ARGUNUSED(intr_status
))
9587 uint32_t port_fbs_ctrl
;
9591 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
9593 /* Nothing will be done under Command-based switching. */
9594 if (!(ahci_ctlp
->ahcictl_cap
& AHCI_CAP_PMULT_FBSS
))
9597 port_fbs_ctrl
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9598 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp
, port
));
9600 if (!(port_fbs_ctrl
& AHCI_FBS_EN
))
9601 /* FBS is not enabled. */
9604 /* Problem's getting complicated now. */
9606 * If FIS-based switching is used, we need to check
9607 * the PxFBS to see the error type.
9609 port_fbs_ctrl
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9610 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp
, port
));
9612 /* Refer to spec(v1.2) 9.3.6.1 */
9613 if (port_fbs_ctrl
& AHCI_FBS_SDE
) {
9614 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
,
9615 "A Device Sepcific Error: port %d", port
);
9617 * Controller has paused commands for all other
9618 * sub-devices until PxFBS.DEC is set.
9620 ahci_reject_all_abort_pkts(ahci_ctlp
,
9623 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9624 (uint32_t *)AHCI_PORT_PxFBS(ahci_ctlp
, port
),
9625 port_fbs_ctrl
| AHCI_FBS_DEC
);
9628 * Wait controller clear PxFBS.DEC,
9629 * then we can continue.
9633 port_fbs_ctrl
= ddi_get32(ahci_ctlp
->
9634 ahcictl_ahci_acc_handle
, (uint32_t *)
9635 AHCI_PORT_PxFBS(ahci_ctlp
, port
));
9637 if (loop_count
++ > 1000)
9639 * Esclate the error. Follow
9640 * non-device specific error
9645 drv_usecwait(AHCI_100US_USECS
);
9646 } while (port_fbs_ctrl
& AHCI_FBS_DEC
);
9649 * Issue a software reset to ensure drive is in
9652 (void) ahci_software_reset(ahci_ctlp
,
9657 /* Process Non-Device Specific Error. */
9658 /* This will be handled later on. */
9659 cmn_err(CE_NOTE
, "!FBS is not supported now.");
9663 * Handle events - fatal error recovery
9666 ahci_events_handler(void *args
)
9668 ahci_event_arg_t
*ahci_event_arg
;
9669 ahci_ctl_t
*ahci_ctlp
;
9670 ahci_port_t
*ahci_portp
;
9675 ahci_event_arg
= (ahci_event_arg_t
*)args
;
9677 ahci_ctlp
= ahci_event_arg
->ahciea_ctlp
;
9678 ahci_portp
= ahci_event_arg
->ahciea_portp
;
9679 addrp
= ahci_event_arg
->ahciea_addrp
;
9680 event
= ahci_event_arg
->ahciea_event
;
9681 instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
9683 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
|AHCIDBG_ERRS
, ahci_ctlp
,
9684 "ahci_events_handler enter: port %d intr_status = 0x%x",
9685 ahci_portp
->ahciport_port_num
, event
);
9687 mutex_enter(&ahci_portp
->ahciport_mutex
);
9690 * ahci_intr_phyrdy_change() may have rendered it to
9693 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
) {
9694 AHCIDBG(AHCIDBG_ENTRY
|AHCIDBG_INTR
, ahci_ctlp
,
9695 "ahci_events_handler: port %d no device attached, "
9696 "and just return without doing anything",
9697 ahci_portp
->ahciport_port_num
);
9699 if (ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_ERRPRINT
) {
9700 ahci_portp
->ahciport_flags
&= ~AHCI_PORT_FLAG_ERRPRINT
;
9701 cmn_err(CE_WARN
, "!ahci%d: error recovery for port %d "
9702 "succeed", instance
, ahci_portp
->ahciport_port_num
);
9708 if (event
& (AHCI_INTR_STATUS_IFS
|
9709 AHCI_INTR_STATUS_HBDS
|
9710 AHCI_INTR_STATUS_HBFS
|
9711 AHCI_INTR_STATUS_TFES
))
9712 ahci_fatal_error_recovery_handler(ahci_ctlp
, ahci_portp
,
9716 mutex_exit(&ahci_portp
->ahciport_mutex
);
9720 * ahci_watchdog_handler() and ahci_do_sync_start will call us if they
9721 * detect there are some commands which are timed out.
9724 ahci_timeout_pkts(ahci_ctl_t
*ahci_ctlp
, ahci_port_t
*ahci_portp
,
9725 uint8_t port
, uint32_t tmp_timeout_tags
)
9727 uint32_t slot_status
= 0;
9728 uint32_t finished_tags
= 0;
9729 uint32_t timeout_tags
= 0;
9731 AHCIDBG(AHCIDBG_TIMEOUT
|AHCIDBG_ENTRY
, ahci_ctlp
,
9732 "ahci_timeout_pkts enter: port %d", port
);
9734 mutex_enter(&ahci_portp
->ahciport_mutex
);
9736 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
) ||
9737 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
) ||
9738 ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
9739 /* Read PxCI to see which commands are still outstanding */
9740 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9741 (uint32_t *)AHCI_PORT_PxCI(ahci_ctlp
, port
));
9742 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9743 /* Read PxSACT to see which commands are still outstanding */
9744 slot_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9745 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
9750 * When AHCI_PORT_FLAG_RQSENSE or AHCI_PORT_FLAG_RDLOGEXT flag is
9751 * set, it means a fatal error happened after REQUEST SENSE command
9752 * or READ LOG EXT command is delivered to the HBA during the error
9753 * recovery process. At this time, the only outstanding command is
9754 * supposed to be REQUEST SENSE command or READ LOG EXT command.
9756 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
)) {
9757 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_TIMEOUT
, ahci_ctlp
,
9758 "ahci_timeout_pkts called while REQUEST SENSE "
9759 "command or READ LOG EXT command for error recovery "
9760 "timed out timeout_tags = 0x%x, slot_status = 0x%x, "
9761 "pending_tags = 0x%x, pending_ncq_tags = 0x%x",
9762 tmp_timeout_tags
, slot_status
,
9763 ahci_portp
->ahciport_pending_tags
,
9764 ahci_portp
->ahciport_pending_ncq_tags
);
9765 ASSERT(slot_status
== 0x1);
9766 } else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
9767 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_TIMEOUT
, ahci_ctlp
,
9768 "ahci_timeout_pkts called while executing R/W PMULT "
9769 "command timeout_tags = 0x%x, slot_status = 0x%x",
9770 tmp_timeout_tags
, slot_status
);
9771 ASSERT(slot_status
== 0x1);
9775 ahci_portp
->ahciport_flags
|= AHCI_PORT_FLAG_MOPPING
;
9776 ahci_portp
->ahciport_mop_in_progress
++;
9778 (void) ahci_restart_port_wait_till_ready(ahci_ctlp
, ahci_portp
,
9779 port
, AHCI_PORT_RESET
, NULL
);
9782 * Re-identify timeout tags because some previously checked commands
9783 * could already complete.
9785 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9786 finished_tags
= ahci_portp
->ahciport_pending_tags
&
9787 ~slot_status
& AHCI_SLOT_MASK(ahci_ctlp
);
9788 timeout_tags
= tmp_timeout_tags
& ~finished_tags
;
9790 AHCIDBG(AHCIDBG_TIMEOUT
, ahci_ctlp
,
9791 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9792 "timeout_tags = 0x%x, port_cmd_issue = 0x%x, "
9793 "pending_tags = 0x%x ",
9794 port
, finished_tags
, timeout_tags
,
9795 slot_status
, ahci_portp
->ahciport_pending_tags
);
9796 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9797 finished_tags
= ahci_portp
->ahciport_pending_ncq_tags
&
9798 ~slot_status
& AHCI_NCQ_SLOT_MASK(ahci_portp
);
9799 timeout_tags
= tmp_timeout_tags
& ~finished_tags
;
9801 AHCIDBG(AHCIDBG_TIMEOUT
|AHCIDBG_NCQ
, ahci_ctlp
,
9802 "ahci_timeout_pkts: port %d, finished_tags = 0x%x, "
9803 "timeout_tags = 0x%x, port_sactive = 0x%x, "
9804 "pending_ncq_tags = 0x%x ",
9805 port
, finished_tags
, timeout_tags
,
9806 slot_status
, ahci_portp
->ahciport_pending_ncq_tags
);
9807 } else if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
) ||
9808 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
9809 timeout_tags
= tmp_timeout_tags
;
9812 ahci_mop_commands(ahci_ctlp
,
9815 0, /* failed tags */
9816 timeout_tags
, /* timeout tags */
9817 0, /* aborted tags */
9818 0); /* reset tags */
9820 mutex_exit(&ahci_portp
->ahciport_mutex
);
9824 * Watchdog handler kicks in every 5 seconds to timeout any commands pending
9828 ahci_watchdog_handler(ahci_ctl_t
*ahci_ctlp
)
9830 ahci_port_t
*ahci_portp
;
9832 uint32_t pending_tags
;
9833 uint32_t timeout_tags
;
9834 uint32_t port_cmd_status
;
9835 uint32_t port_sactive
;
9839 uint32_t current_tags
;
9840 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
9842 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
9844 AHCIDBG(AHCIDBG_ENTRY
, ahci_ctlp
,
9845 "ahci_watchdog_handler entered", NULL
);
9847 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
9848 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
9852 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
9854 mutex_enter(&ahci_portp
->ahciport_mutex
);
9855 if (ahci_portp
->ahciport_device_type
== SATA_DTYPE_NONE
) {
9856 mutex_exit(&ahci_portp
->ahciport_mutex
);
9860 /* Skip the check for those ports in error recovery */
9861 if ((ahci_portp
->ahciport_flags
& AHCI_PORT_FLAG_MOPPING
) &&
9862 !(ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
))) {
9863 mutex_exit(&ahci_portp
->ahciport_mutex
);
9868 port_cmd_status
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
9869 (uint32_t *)AHCI_PORT_PxCMD(ahci_ctlp
, port
));
9871 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
) ||
9872 RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
)) {
9875 } else if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9877 (port_cmd_status
& AHCI_CMD_STATUS_CCS
) >>
9878 AHCI_CMD_STATUS_CCS_SHIFT
;
9879 pending_tags
= ahci_portp
->ahciport_pending_tags
;
9880 } else if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9881 port_sactive
= ddi_get32(
9882 ahci_ctlp
->ahcictl_ahci_acc_handle
,
9883 (uint32_t *)AHCI_PORT_PxSACT(ahci_ctlp
, port
));
9884 current_tags
= port_sactive
&
9886 AHCI_NCQ_SLOT_MASK(ahci_portp
);
9887 pending_tags
= ahci_portp
->ahciport_pending_ncq_tags
;
9891 while (pending_tags
) {
9892 tmp_slot
= ddi_ffs(pending_tags
) - 1;
9893 if (tmp_slot
== -1) {
9897 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp
))
9898 spkt
= ahci_portp
->ahciport_err_retri_pkt
;
9899 else if (RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp
))
9900 spkt
= ahci_portp
->ahciport_rdwr_pmult_pkt
;
9902 spkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
9904 if ((spkt
!= NULL
) && spkt
->satapkt_time
&&
9905 !(spkt
->satapkt_op_mode
& SATA_OPMODE_POLLING
)) {
9907 * If a packet has survived for more than it's
9908 * max life cycles, it is a candidate for time
9911 ahci_portp
->ahciport_slot_timeout
[tmp_slot
] -=
9912 ahci_watchdog_timeout
;
9914 if (ahci_portp
->ahciport_slot_timeout
[tmp_slot
]
9919 if (NCQ_CMD_IN_PROGRESS(ahci_portp
)) {
9920 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_TIMEOUT
,
9921 ahci_ctlp
, "watchdog: the current "
9922 "tags is 0x%x", current_tags
);
9924 AHCIDBG(AHCIDBG_ERRS
|AHCIDBG_TIMEOUT
,
9925 ahci_ctlp
, "watchdog: the current "
9926 "slot is %d", current_slot
);
9931 * We need to check whether the HBA has
9932 * begun to execute the command, if not,
9933 * then re-set the timer of the command.
9935 if (NON_NCQ_CMD_IN_PROGRESS(ahci_portp
) &&
9936 (tmp_slot
!= current_slot
) ||
9937 NCQ_CMD_IN_PROGRESS(ahci_portp
) &&
9938 ((0x1 << tmp_slot
) & current_tags
)) {
9939 ahci_portp
->ahciport_slot_timeout \
9940 [tmp_slot
] = spkt
->satapkt_time
;
9942 timeout_tags
|= (0x1 << tmp_slot
);
9943 cmn_err(CE_WARN
, "!ahci%d: watchdog "
9944 "port %d satapkt 0x%p timed out\n",
9945 instance
, port
, (void *)spkt
);
9949 CLEAR_BIT(pending_tags
, tmp_slot
);
9953 mutex_exit(&ahci_portp
->ahciport_mutex
);
9954 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
9955 ahci_timeout_pkts(ahci_ctlp
, ahci_portp
,
9956 port
, timeout_tags
);
9957 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
9958 mutex_enter(&ahci_portp
->ahciport_mutex
);
9961 mutex_exit(&ahci_portp
->ahciport_mutex
);
9964 /* Re-install the watchdog timeout handler */
9965 if (ahci_ctlp
->ahcictl_timeout_id
!= 0) {
9966 ahci_ctlp
->ahcictl_timeout_id
=
9967 timeout((void (*)(void *))ahci_watchdog_handler
,
9968 (caddr_t
)ahci_ctlp
, ahci_watchdog_tick
);
9971 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
9975 * Fill the error context into sata_cmd for non-queued command error.
9978 ahci_copy_err_cnxt(sata_cmd_t
*scmd
, ahci_fis_d2h_register_t
*rfisp
)
9980 scmd
->satacmd_status_reg
= GET_RFIS_STATUS(rfisp
);
9981 scmd
->satacmd_error_reg
= GET_RFIS_ERROR(rfisp
);
9982 scmd
->satacmd_sec_count_lsb
= GET_RFIS_SECTOR_COUNT(rfisp
);
9983 scmd
->satacmd_lba_low_lsb
= GET_RFIS_CYL_LOW(rfisp
);
9984 scmd
->satacmd_lba_mid_lsb
= GET_RFIS_CYL_MID(rfisp
);
9985 scmd
->satacmd_lba_high_lsb
= GET_RFIS_CYL_HI(rfisp
);
9986 scmd
->satacmd_device_reg
= GET_RFIS_DEV_HEAD(rfisp
);
9988 if (scmd
->satacmd_addr_type
== ATA_ADDR_LBA48
) {
9989 scmd
->satacmd_sec_count_msb
= GET_RFIS_SECTOR_COUNT_EXP(rfisp
);
9990 scmd
->satacmd_lba_low_msb
= GET_RFIS_CYL_LOW_EXP(rfisp
);
9991 scmd
->satacmd_lba_mid_msb
= GET_RFIS_CYL_MID_EXP(rfisp
);
9992 scmd
->satacmd_lba_high_msb
= GET_RFIS_CYL_HI_EXP(rfisp
);
9997 * Fill the ncq error page into sata_cmd for queued command error.
10000 ahci_copy_ncq_err_page(sata_cmd_t
*scmd
,
10001 struct sata_ncq_error_recovery_page
*ncq_err_page
)
10003 scmd
->satacmd_sec_count_msb
= ncq_err_page
->ncq_sector_count_ext
;
10004 scmd
->satacmd_sec_count_lsb
= ncq_err_page
->ncq_sector_count
;
10005 scmd
->satacmd_lba_low_msb
= ncq_err_page
->ncq_sector_number_ext
;
10006 scmd
->satacmd_lba_low_lsb
= ncq_err_page
->ncq_sector_number
;
10007 scmd
->satacmd_lba_mid_msb
= ncq_err_page
->ncq_cyl_low_ext
;
10008 scmd
->satacmd_lba_mid_lsb
= ncq_err_page
->ncq_cyl_low
;
10009 scmd
->satacmd_lba_high_msb
= ncq_err_page
->ncq_cyl_high_ext
;
10010 scmd
->satacmd_lba_high_lsb
= ncq_err_page
->ncq_cyl_high
;
10011 scmd
->satacmd_device_reg
= ncq_err_page
->ncq_dev_head
;
10012 scmd
->satacmd_status_reg
= ncq_err_page
->ncq_status
;
10013 scmd
->satacmd_error_reg
= ncq_err_page
->ncq_error
;
10017 * Put the respective register value to sata_cmd_t for satacmd_flags.
10020 ahci_copy_out_regs(sata_cmd_t
*scmd
, ahci_fis_d2h_register_t
*rfisp
)
10022 if (scmd
->satacmd_flags
.sata_copy_out_sec_count_msb
)
10023 scmd
->satacmd_sec_count_msb
= GET_RFIS_SECTOR_COUNT_EXP(rfisp
);
10024 if (scmd
->satacmd_flags
.sata_copy_out_lba_low_msb
)
10025 scmd
->satacmd_lba_low_msb
= GET_RFIS_CYL_LOW_EXP(rfisp
);
10026 if (scmd
->satacmd_flags
.sata_copy_out_lba_mid_msb
)
10027 scmd
->satacmd_lba_mid_msb
= GET_RFIS_CYL_MID_EXP(rfisp
);
10028 if (scmd
->satacmd_flags
.sata_copy_out_lba_high_msb
)
10029 scmd
->satacmd_lba_high_msb
= GET_RFIS_CYL_HI_EXP(rfisp
);
10030 if (scmd
->satacmd_flags
.sata_copy_out_sec_count_lsb
)
10031 scmd
->satacmd_sec_count_lsb
= GET_RFIS_SECTOR_COUNT(rfisp
);
10032 if (scmd
->satacmd_flags
.sata_copy_out_lba_low_lsb
)
10033 scmd
->satacmd_lba_low_lsb
= GET_RFIS_CYL_LOW(rfisp
);
10034 if (scmd
->satacmd_flags
.sata_copy_out_lba_mid_lsb
)
10035 scmd
->satacmd_lba_mid_lsb
= GET_RFIS_CYL_MID(rfisp
);
10036 if (scmd
->satacmd_flags
.sata_copy_out_lba_high_lsb
)
10037 scmd
->satacmd_lba_high_lsb
= GET_RFIS_CYL_HI(rfisp
);
10038 if (scmd
->satacmd_flags
.sata_copy_out_device_reg
)
10039 scmd
->satacmd_device_reg
= GET_RFIS_DEV_HEAD(rfisp
);
10040 if (scmd
->satacmd_flags
.sata_copy_out_error_reg
)
10041 scmd
->satacmd_error_reg
= GET_RFIS_ERROR(rfisp
);
10045 ahci_log_fatal_error_message(ahci_ctl_t
*ahci_ctlp
, uint8_t port
,
10046 uint32_t intr_status
)
10048 int instance
= ddi_get_instance(ahci_ctlp
->ahcictl_dip
);
10050 if (intr_status
& AHCI_INTR_STATUS_IFS
)
10051 cmn_err(CE_WARN
, "!ahci%d: ahci port %d has interface fatal "
10052 "error", instance
, port
);
10054 if (intr_status
& AHCI_INTR_STATUS_HBDS
)
10055 cmn_err(CE_WARN
, "!ahci%d: ahci port %d has bus data error",
10058 if (intr_status
& AHCI_INTR_STATUS_HBFS
)
10059 cmn_err(CE_WARN
, "!ahci%d: ahci port %d has bus fatal error",
10062 if (intr_status
& AHCI_INTR_STATUS_TFES
)
10063 cmn_err(CE_WARN
, "!ahci%d: ahci port %d has task file error",
10066 cmn_err(CE_WARN
, "!ahci%d: ahci port %d is trying to do error "
10067 "recovery", instance
, port
);
10071 ahci_dump_commands(ahci_ctl_t
*ahci_ctlp
, uint8_t port
,
10072 uint32_t slot_tags
)
10074 ahci_port_t
*ahci_portp
;
10079 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
10080 ASSERT(ahci_portp
!= NULL
);
10082 while (slot_tags
) {
10083 tmp_slot
= ddi_ffs(slot_tags
) - 1;
10084 if (tmp_slot
== -1) {
10088 spkt
= ahci_portp
->ahciport_slot_pkts
[tmp_slot
];
10089 if (spkt
!= NULL
) {
10090 cmd
= spkt
->satapkt_cmd
;
10092 cmn_err(CE_WARN
, "!satapkt 0x%p: cmd_reg = 0x%x "
10093 "features_reg = 0x%x sec_count_msb = 0x%x "
10094 "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
10095 "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
10096 "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
10097 "lba_high_lsb = 0x%x device_reg = 0x%x "
10098 "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt
,
10099 cmd
.satacmd_cmd_reg
, cmd
.satacmd_features_reg
,
10100 cmd
.satacmd_sec_count_msb
, cmd
.satacmd_lba_low_msb
,
10101 cmd
.satacmd_lba_mid_msb
, cmd
.satacmd_lba_high_msb
,
10102 cmd
.satacmd_sec_count_lsb
, cmd
.satacmd_lba_low_lsb
,
10103 cmd
.satacmd_lba_mid_lsb
, cmd
.satacmd_lba_high_lsb
,
10104 cmd
.satacmd_device_reg
, cmd
.satacmd_addr_type
,
10105 *((uint32_t *)&(cmd
.satacmd_flags
)));
10108 CLEAR_BIT(slot_tags
, tmp_slot
);
10113 * Dump the serror message to the log.
10116 ahci_log_serror_message(ahci_ctl_t
*ahci_ctlp
, uint8_t port
,
10117 uint32_t port_serror
, int debug_only
)
10119 static char err_buf
[512];
10120 static char err_msg_header
[16];
10121 char *err_msg
= err_buf
;
10124 *err_msg_header
= '\0';
10126 if (port_serror
& SERROR_DATA_ERR_FIXED
) {
10127 err_msg
= strcat(err_msg
,
10128 "\tRecovered Data Integrity Error (I)\n");
10131 if (port_serror
& SERROR_COMM_ERR_FIXED
) {
10132 err_msg
= strcat(err_msg
,
10133 "\tRecovered Communication Error (M)\n");
10136 if (port_serror
& SERROR_DATA_ERR
) {
10137 err_msg
= strcat(err_msg
,
10138 "\tTransient Data Integrity Error (T)\n");
10141 if (port_serror
& SERROR_PERSISTENT_ERR
) {
10142 err_msg
= strcat(err_msg
,
10143 "\tPersistent Communication or Data Integrity Error (C)\n");
10146 if (port_serror
& SERROR_PROTOCOL_ERR
) {
10147 err_msg
= strcat(err_msg
, "\tProtocol Error (P)\n");
10150 if (port_serror
& SERROR_INT_ERR
) {
10151 err_msg
= strcat(err_msg
, "\tInternal Error (E)\n");
10154 if (port_serror
& SERROR_PHY_RDY_CHG
) {
10155 err_msg
= strcat(err_msg
, "\tPhyRdy Change (N)\n");
10158 if (port_serror
& SERROR_PHY_INT_ERR
) {
10159 err_msg
= strcat(err_msg
, "\tPhy Internal Error (I)\n");
10162 if (port_serror
& SERROR_COMM_WAKE
) {
10163 err_msg
= strcat(err_msg
, "\tComm Wake (W)\n");
10166 if (port_serror
& SERROR_10B_TO_8B_ERR
) {
10167 err_msg
= strcat(err_msg
, "\t10B to 8B Decode Error (B)\n");
10170 if (port_serror
& SERROR_DISPARITY_ERR
) {
10171 err_msg
= strcat(err_msg
, "\tDisparity Error (D)\n");
10174 if (port_serror
& SERROR_CRC_ERR
) {
10175 err_msg
= strcat(err_msg
, "\tCRC Error (C)\n");
10178 if (port_serror
& SERROR_HANDSHAKE_ERR
) {
10179 err_msg
= strcat(err_msg
, "\tHandshake Error (H)\n");
10182 if (port_serror
& SERROR_LINK_SEQ_ERR
) {
10183 err_msg
= strcat(err_msg
, "\tLink Sequence Error (S)\n");
10186 if (port_serror
& SERROR_TRANS_ERR
) {
10187 err_msg
= strcat(err_msg
,
10188 "\tTransport state transition error (T)\n");
10191 if (port_serror
& SERROR_FIS_TYPE
) {
10192 err_msg
= strcat(err_msg
, "\tUnknown FIS Type (F)\n");
10195 if (port_serror
& SERROR_EXCHANGED_ERR
) {
10196 err_msg
= strcat(err_msg
, "\tExchanged (X)\n");
10199 if (*err_msg
== '\0')
10203 (void) sprintf(err_msg_header
, "port %d", port
);
10204 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, err_msg_header
, NULL
);
10205 AHCIDBG(AHCIDBG_ERRS
, ahci_ctlp
, err_msg
, NULL
);
10206 } else if (ahci_ctlp
) {
10207 cmn_err(CE_WARN
, "!ahci%d: %s %s",
10208 ddi_get_instance(ahci_ctlp
->ahcictl_dip
),
10209 err_msg_header
, err_msg
);
10211 /* sata trace debug */
10212 sata_trace_debug(ahci_ctlp
->ahcictl_dip
,
10213 "ahci%d: %s %s", ddi_get_instance(ahci_ctlp
->ahcictl_dip
),
10214 err_msg_header
, err_msg
);
10216 cmn_err(CE_WARN
, "!ahci: %s %s", err_msg_header
, err_msg
);
10218 /* sata trace debug */
10219 sata_trace_debug(NULL
, "ahci: %s %s", err_msg_header
, err_msg
);
10224 * Translate the sata_address_t type into the ahci_addr_t type.
10225 * sata_device.satadev_addr structure is used as source.
10228 ahci_get_ahci_addr(ahci_ctl_t
*ahci_ctlp
, sata_device_t
*sd
,
10229 ahci_addr_t
*ahci_addrp
)
10231 sata_address_t
*sata_addrp
= &sd
->satadev_addr
;
10232 ahci_addrp
->aa_port
=
10233 ahci_ctlp
->ahcictl_cport_to_port
[sata_addrp
->cport
];
10234 ahci_addrp
->aa_pmport
= sata_addrp
->pmport
;
10236 switch (sata_addrp
->qual
) {
10237 case SATA_ADDR_DCPORT
:
10238 case SATA_ADDR_CPORT
:
10239 ahci_addrp
->aa_qual
= AHCI_ADDR_PORT
;
10241 case SATA_ADDR_PMULT
:
10242 case SATA_ADDR_PMULT_SPEC
:
10243 ahci_addrp
->aa_qual
= AHCI_ADDR_PMULT
;
10245 case SATA_ADDR_DPMPORT
:
10246 case SATA_ADDR_PMPORT
:
10247 ahci_addrp
->aa_qual
= AHCI_ADDR_PMPORT
;
10249 case SATA_ADDR_NULL
:
10251 /* something went wrong */
10252 ahci_addrp
->aa_qual
= AHCI_ADDR_NULL
;
10258 * This routine is to calculate the total number of ports implemented
10262 ahci_get_num_implemented_ports(uint32_t ports_implemented
)
10267 for (i
= 0; i
< AHCI_MAX_PORTS
; i
++) {
10268 if (((uint32_t)0x1 << i
) & ports_implemented
)
10277 ahci_log(ahci_ctl_t
*ahci_ctlp
, uint_t level
, char *fmt
, ...)
10279 static char name
[16];
10282 mutex_enter(&ahci_log_mutex
);
10286 (void) sprintf(name
, "ahci%d: ",
10287 ddi_get_instance(ahci_ctlp
->ahcictl_dip
));
10289 (void) sprintf(name
, "ahci: ");
10292 (void) vsprintf(ahci_log_buf
, fmt
, ap
);
10295 cmn_err(level
, "%s%s", name
, ahci_log_buf
);
10297 mutex_exit(&ahci_log_mutex
);
10302 * quiesce(9E) entry point.
10304 * This function is called when the system is single-threaded at high
10305 * PIL with preemption disabled. Therefore, this function must not be
10306 * blocked. Because no taskqs are running, there is no need for us to
10307 * take any action for enclosure services which are running in the
10308 * taskq context, especially as no interrupts are generated by it nor
10309 * are any messages expected to come in.
10311 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10312 * DDI_FAILURE indicates an error condition and should almost never happen.
10315 ahci_quiesce(dev_info_t
*dip
)
10317 ahci_ctl_t
*ahci_ctlp
;
10318 ahci_port_t
*ahci_portp
;
10319 int instance
, port
;
10321 instance
= ddi_get_instance(dip
);
10322 ahci_ctlp
= ddi_get_soft_state(ahci_statep
, instance
);
10324 if (ahci_ctlp
== NULL
)
10325 return (DDI_FAILURE
);
10328 ahci_debug_flags
= 0;
10331 ahci_ctlp
->ahcictl_flags
|= AHCI_QUIESCE
;
10333 /* disable all the interrupts. */
10334 ahci_disable_all_intrs(ahci_ctlp
);
10336 for (port
= 0; port
< ahci_ctlp
->ahcictl_num_ports
; port
++) {
10337 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, port
)) {
10341 ahci_portp
= ahci_ctlp
->ahcictl_ports
[port
];
10344 * Stop the port by clearing PxCMD.ST
10346 * Here we must disable the port interrupt because
10347 * ahci_disable_all_intrs only clear GHC.IE, and IS
10348 * register will be still set if PxIE is enabled.
10349 * When ahci shares one IRQ with other drivers, the
10350 * intr handler may claim the intr mistakenly.
10352 ahci_disable_port_intrs(ahci_ctlp
, port
);
10353 (void) ahci_put_port_into_notrunning_state(ahci_ctlp
,
10357 ahci_ctlp
->ahcictl_flags
&= ~AHCI_QUIESCE
;
10359 return (DDI_SUCCESS
);
10363 * The function will add a sata packet to the done queue.
10366 ahci_add_doneq(ahci_port_t
*ahci_portp
, sata_pkt_t
*satapkt
, int reason
)
10368 ASSERT(satapkt
!= NULL
);
10369 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
10371 /* set the reason for all packets */
10372 satapkt
->satapkt_reason
= reason
;
10373 satapkt
->satapkt_hba_driver_private
= NULL
;
10375 if (! (satapkt
->satapkt_op_mode
& SATA_OPMODE_SYNCH
) &&
10376 satapkt
->satapkt_comp
) {
10378 * only add to queue when mode is not synch and there is
10379 * completion callback
10381 *ahci_portp
->ahciport_doneqtail
= satapkt
;
10382 ahci_portp
->ahciport_doneqtail
=
10383 (sata_pkt_t
**)&(satapkt
->satapkt_hba_driver_private
);
10384 ahci_portp
->ahciport_doneq_len
++;
10386 } else if ((satapkt
->satapkt_op_mode
& SATA_OPMODE_SYNCH
) &&
10387 ! (satapkt
->satapkt_op_mode
& SATA_OPMODE_POLLING
))
10389 * for sync/non-poll mode, just call cv_broadcast
10391 cv_broadcast(&ahci_portp
->ahciport_cv
);
10395 * The function will call completion callback of sata packet on the
10399 ahci_flush_doneq(ahci_port_t
*ahci_portp
)
10401 sata_pkt_t
*satapkt
, *next
;
10403 ASSERT(MUTEX_HELD(&ahci_portp
->ahciport_mutex
));
10405 if (ahci_portp
->ahciport_doneq
) {
10406 satapkt
= ahci_portp
->ahciport_doneq
;
10408 ahci_portp
->ahciport_doneq
= NULL
;
10409 ahci_portp
->ahciport_doneqtail
= &ahci_portp
->ahciport_doneq
;
10410 ahci_portp
->ahciport_doneq_len
= 0;
10412 mutex_exit(&ahci_portp
->ahciport_mutex
);
10414 while (satapkt
!= NULL
) {
10415 next
= satapkt
->satapkt_hba_driver_private
;
10416 satapkt
->satapkt_hba_driver_private
= NULL
;
10418 /* Call the callback */
10419 (*satapkt
->satapkt_comp
)(satapkt
);
10424 mutex_enter(&ahci_portp
->ahciport_mutex
);
10429 * Sets the state for the specified port on the controller to desired state.
10430 * This must be run in the context of the enclosure taskq which ensures that
10431 * only one event is outstanding at any time.
10434 ahci_em_set_led(ahci_ctl_t
*ahci_ctlp
, uint8_t port
, ahci_em_led_state_t desire
)
10436 ahci_em_led_msg_t msg
;
10437 ahci_em_msg_hdr_t hdr
;
10438 uint32_t msgval
, hdrval
;
10439 uint_t i
, max_delay
= ahci_em_tx_delay_count
;
10441 msg
.alm_hba
= port
;
10442 msg
.alm_pminfo
= 0;
10445 if (desire
& AHCI_EM_LED_IDENT_ENABLE
) {
10446 msg
.alm_value
|= AHCI_LED_ON
<< AHCI_LED_IDENT_OFF
;
10449 if (desire
& AHCI_EM_LED_FAULT_ENABLE
) {
10450 msg
.alm_value
|= AHCI_LED_ON
<< AHCI_LED_FAULT_OFF
;
10453 if ((ahci_ctlp
->ahcictl_em_ctl
& AHCI_HBA_EM_CTL_ATTR_ALHD
) == 0 &&
10454 (desire
& AHCI_EM_LED_ACTIVITY_DISABLE
) == 0) {
10455 msg
.alm_value
|= AHCI_LED_ON
<< AHCI_LED_ACTIVITY_OFF
;
10459 hdr
.aemh_mlen
= sizeof (ahci_em_led_msg_t
);
10461 hdr
.aemh_mtype
= AHCI_EM_MSG_TYPE_LED
;
10463 bcopy(&msg
, &msgval
, sizeof (msgval
));
10464 bcopy(&hdr
, &hdrval
, sizeof (hdrval
));
10467 * First, make sure we can transmit. We should not have been placed in a
10468 * situation where an outstanding transmission is going on.
10470 for (i
= 0; i
< max_delay
; i
++) {
10473 val
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10474 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp
));
10475 if ((val
& AHCI_HBA_EM_CTL_CTL_TM
) == 0)
10478 delay(drv_usectohz(ahci_em_tx_delay_ms
* 1000));
10481 if (i
== max_delay
)
10484 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10485 (uint32_t *)ahci_ctlp
->ahcictl_em_tx_off
, hdrval
);
10486 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10487 (uint32_t *)(ahci_ctlp
->ahcictl_em_tx_off
+ 4), msgval
);
10488 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10489 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp
), AHCI_HBA_EM_CTL_CTL_TM
);
10491 for (i
= 0; i
< max_delay
; i
++) {
10494 val
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10495 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp
));
10496 if ((val
& AHCI_HBA_EM_CTL_CTL_TM
) == 0)
10499 delay(drv_usectohz(ahci_em_tx_delay_ms
* 1000));
10502 if (i
== max_delay
)
10508 typedef struct ahci_em_led_task_arg
{
10509 ahci_ctl_t
*aelta_ctl
;
10510 uint8_t aelta_port
;
10512 ahci_em_led_state_t aelta_state
;
10514 kcondvar_t aelta_cv
;
10516 } ahci_em_led_task_arg_t
;
10519 ahci_em_led_task_free(ahci_em_led_task_arg_t
*task
)
10521 ASSERT3U(task
->aelta_ref
, ==, 0);
10522 cv_destroy(&task
->aelta_cv
);
10523 kmem_free(task
, sizeof (*task
));
10527 ahci_em_led_task(void *arg
)
10529 boolean_t ret
, cleanup
= B_FALSE
;
10530 ahci_em_led_task_arg_t
*led
= arg
;
10531 ahci_em_led_state_t state
;
10533 mutex_enter(&led
->aelta_ctl
->ahcictl_mutex
);
10534 if (led
->aelta_ctl
->ahcictl_em_flags
!= AHCI_EM_USABLE
) {
10535 led
->aelta_ret
= EIO
;
10536 mutex_exit(&led
->aelta_ctl
->ahcictl_mutex
);
10540 state
= led
->aelta_ctl
->ahcictl_em_state
[led
->aelta_port
];
10541 mutex_exit(&led
->aelta_ctl
->ahcictl_mutex
);
10543 switch (led
->aelta_op
) {
10544 case AHCI_EM_IOC_SET_OP_ADD
:
10545 state
|= led
->aelta_state
;
10547 case AHCI_EM_IOC_SET_OP_REM
:
10548 state
&= ~led
->aelta_state
;
10550 case AHCI_EM_IOC_SET_OP_SET
:
10551 state
= led
->aelta_state
;
10554 led
->aelta_ret
= ENOTSUP
;
10558 ret
= ahci_em_set_led(led
->aelta_ctl
, led
->aelta_port
, state
);
10560 mutex_enter(&led
->aelta_ctl
->ahcictl_mutex
);
10562 led
->aelta_ctl
->ahcictl_em_state
[led
->aelta_port
] =
10564 led
->aelta_ret
= 0;
10566 led
->aelta_ret
= EIO
;
10567 led
->aelta_ctl
->ahcictl_em_flags
|= AHCI_EM_TIMEOUT
;
10570 if (led
->aelta_ref
> 0) {
10571 cv_signal(&led
->aelta_cv
);
10575 mutex_exit(&led
->aelta_ctl
->ahcictl_mutex
);
10578 ahci_em_led_task_free(led
);
10583 ahci_em_reset(void *arg
)
10585 uint_t i
, max_delay
= ahci_em_reset_delay_count
;
10586 ahci_ctl_t
*ahci_ctlp
= arg
;
10589 * We've been asked to reset the device. The caller should have set the
10590 * resetting flag. Make sure that we don't have a request to quiesce.
10592 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10593 ASSERT(ahci_ctlp
->ahcictl_em_flags
& AHCI_EM_RESETTING
);
10594 if (ahci_ctlp
->ahcictl_em_flags
& AHCI_EM_QUIESCE
) {
10595 ahci_ctlp
->ahcictl_em_flags
&= ~AHCI_EM_RESETTING
;
10596 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10599 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10601 ddi_put32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10602 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp
), AHCI_HBA_EM_CTL_CTL_RST
);
10603 for (i
= 0; i
< max_delay
; i
++) {
10606 val
= ddi_get32(ahci_ctlp
->ahcictl_ahci_acc_handle
,
10607 (uint32_t *)AHCI_GLOBAL_EM_CTL(ahci_ctlp
));
10608 if ((val
& AHCI_HBA_EM_CTL_CTL_RST
) == 0)
10611 delay(drv_usectohz(ahci_em_reset_delay_ms
* 1000));
10614 if (i
== max_delay
) {
10615 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10616 ahci_ctlp
->ahcictl_em_flags
&= ~AHCI_EM_RESETTING
;
10617 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_TIMEOUT
;
10618 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10619 cmn_err(CE_WARN
, "!ahci%d: enclosure timed out resetting",
10620 ddi_get_instance(ahci_ctlp
->ahcictl_dip
));
10624 for (i
= 0; i
< ahci_ctlp
->ahcictl_num_ports
; i
++) {
10626 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, i
))
10630 * Try to flush all the LEDs as part of reset. If it fails,
10633 if (!ahci_em_set_led(ahci_ctlp
, i
,
10634 ahci_ctlp
->ahcictl_em_state
[i
])) {
10635 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10636 ahci_ctlp
->ahcictl_em_flags
&= ~AHCI_EM_RESETTING
;
10637 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_TIMEOUT
;
10638 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10639 cmn_err(CE_WARN
, "!ahci%d: enclosure timed out "
10641 ddi_get_instance(ahci_ctlp
->ahcictl_dip
), i
);
10646 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10647 ahci_ctlp
->ahcictl_em_flags
&= ~AHCI_EM_RESETTING
;
10648 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_READY
;
10649 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10653 ahci_em_init(ahci_ctl_t
*ahci_ctlp
)
10658 * First make sure we actually have enclosure services and if so, that
10659 * we have the hardware support that we care about for this.
10661 if (ahci_ctlp
->ahcictl_em_loc
== 0 ||
10662 (ahci_ctlp
->ahcictl_em_ctl
& AHCI_HBA_EM_CTL_SUPP_LED
) == 0)
10666 * Next, make sure that the buffer is large enough for us. We need two
10667 * dwords or 8 bytes. The location register is stored in dwords.
10669 if ((ahci_ctlp
->ahcictl_em_loc
& AHCI_HBA_EM_LOC_SZ_MASK
) <
10670 AHCI_EM_BUFFER_MIN
) {
10674 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_PRESENT
;
10676 ahci_ctlp
->ahcictl_em_tx_off
= ((ahci_ctlp
->ahcictl_em_loc
&
10677 AHCI_HBA_EM_LOC_OFST_MASK
) >> AHCI_HBA_EM_LOC_OFST_SHIFT
) * 4;
10678 ahci_ctlp
->ahcictl_em_tx_off
+= ahci_ctlp
->ahcictl_ahci_addr
;
10680 bzero(ahci_ctlp
->ahcictl_em_state
,
10681 sizeof (ahci_ctlp
->ahcictl_em_state
));
10683 (void) snprintf(name
, sizeof (name
), "ahcti_em_taskq%d",
10684 ddi_get_instance(ahci_ctlp
->ahcictl_dip
));
10685 if ((ahci_ctlp
->ahcictl_em_taskq
=
10686 ddi_taskq_create(ahci_ctlp
->ahcictl_dip
, name
, 1,
10687 TASKQ_DEFAULTPRI
, 0)) == NULL
) {
10688 cmn_err(CE_WARN
, "!ahci%d: ddi_tasq_create failed for em "
10689 "services", ddi_get_instance(ahci_ctlp
->ahcictl_dip
));
10693 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10694 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_RESETTING
;
10695 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10696 (void) ddi_taskq_dispatch(ahci_ctlp
->ahcictl_em_taskq
, ahci_em_reset
,
10697 ahci_ctlp
, DDI_SLEEP
);
10703 ahci_em_ioctl_get(ahci_ctl_t
*ahci_ctlp
, intptr_t arg
)
10706 ahci_ioc_em_get_t get
;
10708 bzero(&get
, sizeof (get
));
10709 get
.aiemg_nports
= ahci_ctlp
->ahcictl_ports_implemented
;
10710 if ((ahci_ctlp
->ahcictl_em_ctl
& AHCI_HBA_EM_CTL_ATTR_ALHD
) == 0) {
10711 get
.aiemg_flags
|= AHCI_EM_FLAG_CONTROL_ACTIVITY
;
10714 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10715 for (i
= 0; i
< ahci_ctlp
->ahcictl_num_ports
; i
++) {
10716 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, i
)) {
10719 get
.aiemg_status
[i
] = ahci_ctlp
->ahcictl_em_state
[i
];
10721 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10723 if (ddi_copyout(&get
, (void *)arg
, sizeof (get
), 0) != 0)
10730 ahci_em_ioctl_set(ahci_ctl_t
*ahci_ctlp
, intptr_t arg
)
10733 ahci_ioc_em_set_t set
;
10734 ahci_em_led_task_arg_t
*task
;
10735 boolean_t signal
, cleanup
;
10737 if (ddi_copyin((void *)arg
, &set
, sizeof (set
), 0) != 0)
10740 if (set
.aiems_port
> ahci_ctlp
->ahcictl_num_ports
)
10743 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp
, set
.aiems_port
)) {
10747 if ((set
.aiems_leds
& ~(AHCI_EM_LED_IDENT_ENABLE
|
10748 AHCI_EM_LED_FAULT_ENABLE
|
10749 AHCI_EM_LED_ACTIVITY_DISABLE
)) != 0) {
10753 switch (set
.aiems_op
) {
10754 case AHCI_EM_IOC_SET_OP_ADD
:
10755 case AHCI_EM_IOC_SET_OP_REM
:
10756 case AHCI_EM_IOC_SET_OP_SET
:
10762 if ((set
.aiems_leds
& AHCI_EM_LED_ACTIVITY_DISABLE
) != 0 &&
10763 ((ahci_ctlp
->ahcictl_em_ctl
& AHCI_HBA_EM_CTL_ATTR_ALHD
) != 0)) {
10767 task
= kmem_alloc(sizeof (*task
), KM_NOSLEEP
| KM_NORMALPRI
);
10768 if (task
== NULL
) {
10772 task
->aelta_ctl
= ahci_ctlp
;
10773 task
->aelta_port
= (uint8_t)set
.aiems_port
;
10774 task
->aelta_op
= set
.aiems_op
;
10775 task
->aelta_state
= set
.aiems_leds
;
10777 cv_init(&task
->aelta_cv
, NULL
, CV_DRIVER
, NULL
);
10780 * Initialize the reference count to two. One for us and one for the
10781 * taskq. This will be used in case we get canceled.
10783 task
->aelta_ref
= 2;
10786 * Once dispatched, the task state is protected by our global mutex.
10788 (void) ddi_taskq_dispatch(ahci_ctlp
->ahcictl_em_taskq
,
10789 ahci_em_led_task
, task
, DDI_SLEEP
);
10792 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10793 while (task
->aelta_ref
> 1) {
10794 if (cv_wait_sig(&task
->aelta_cv
, &ahci_ctlp
->ahcictl_mutex
) ==
10802 * Remove our reference count. If we were woken up because of a signal
10803 * then the taskq may still be dispatched. In which case we shouldn't
10804 * free this memory until it is done. In that case, the taskq will take
10808 cleanup
= (task
->aelta_ref
== 0);
10812 ret
= task
->aelta_ret
;
10814 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10817 ahci_em_led_task_free(task
);
10824 ahci_em_ioctl(dev_info_t
*dip
, int cmd
, intptr_t arg
)
10827 ahci_ctl_t
*ahci_ctlp
;
10829 inst
= ddi_get_instance(dip
);
10830 if ((ahci_ctlp
= ddi_get_soft_state(ahci_statep
, inst
)) == NULL
) {
10835 case AHCI_EM_IOC_GET
:
10836 return (ahci_em_ioctl_get(ahci_ctlp
, arg
));
10837 case AHCI_EM_IOC_SET
:
10838 return (ahci_em_ioctl_set(ahci_ctlp
, arg
));
10846 ahci_em_quiesce(ahci_ctl_t
*ahci_ctlp
)
10848 ASSERT(ahci_ctlp
->ahcictl_em_flags
& AHCI_EM_PRESENT
);
10850 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10851 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_QUIESCE
;
10852 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10854 ddi_taskq_wait(ahci_ctlp
->ahcictl_em_taskq
);
10858 ahci_em_suspend(ahci_ctl_t
*ahci_ctlp
)
10860 ahci_em_quiesce(ahci_ctlp
);
10862 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10863 ahci_ctlp
->ahcictl_em_flags
&= ~AHCI_EM_READY
;
10864 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10868 ahci_em_resume(ahci_ctl_t
*ahci_ctlp
)
10870 mutex_enter(&ahci_ctlp
->ahcictl_mutex
);
10871 ahci_ctlp
->ahcictl_em_flags
|= AHCI_EM_RESETTING
;
10872 mutex_exit(&ahci_ctlp
->ahcictl_mutex
);
10874 (void) ddi_taskq_dispatch(ahci_ctlp
->ahcictl_em_taskq
, ahci_em_reset
,
10875 ahci_ctlp
, DDI_SLEEP
);
10879 ahci_em_fini(ahci_ctl_t
*ahci_ctlp
)
10881 if ((ahci_ctlp
->ahcictl_em_flags
& AHCI_EM_PRESENT
) == 0) {
10885 ahci_em_quiesce(ahci_ctlp
);
10886 ddi_taskq_destroy(ahci_ctlp
->ahcictl_em_taskq
);
10887 ahci_ctlp
->ahcictl_em_taskq
= NULL
;