4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * AHCI (Advanced Host Controller Interface) SATA HBA Driver
29 *
30 * Power Management Support
31 * ------------------------
32 *
33 * At the moment, the ahci driver only implements suspend/resume to
34 * support Suspend to RAM on X86 feature. Device power management isn't
35 * implemented, link power management is disabled, and hot plug isn't
36 * allowed during the period from suspend to resume.
37 *
38 * For s/r support, the ahci driver only need to implement DDI_SUSPEND
39 * and DDI_RESUME entries, and don't need to take care of new requests
40 * sent down after suspend because the target driver (sd) has already
41 * handled these conditions, and blocked these requests. For the detailed
42 * information, please check with sdopen, sdclose and sdioctl routines.
43 *
44 */
45
46 #include <sys/note.h>
47 #include <sys/scsi/scsi.h>
48 #include <sys/pci.h>
49 #include <sys/disp.h>
50 #include <sys/sata/sata_hba.h>
51 #include <sys/sata/adapters/ahci/ahcireg.h>
52 #include <sys/sata/adapters/ahci/ahcivar.h>
53
54 /*
55 * FMA header files
56 */
57 #include <sys/ddifm.h>
58 #include <sys/fm/protocol.h>
59 #include <sys/fm/util.h>
60 #include <sys/fm/io/ddi.h>
61
62 /*
63 * This is the string displayed by modinfo, etc.
64 */
65 static char ahci_ident[] = "ahci driver";
66
67 /*
68 * Function prototypes for driver entry points
69 */
70 static int ahci_attach(dev_info_t *, ddi_attach_cmd_t);
71 static int ahci_detach(dev_info_t *, ddi_detach_cmd_t);
72 static int ahci_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
73 static int ahci_quiesce(dev_info_t *);
74
75 /*
76 * Function prototypes for SATA Framework interfaces
77 */
78 static int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
79 static int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
80
81 static int ahci_tran_probe_port(dev_info_t *, sata_device_t *);
82 static int ahci_tran_start(dev_info_t *, sata_pkt_t *spkt);
204 static int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
205 static int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
206 static int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
207 ahci_port_t *, uint8_t);
208 static int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
209 static int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
210 uint8_t, uint32_t);
211 static int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
212 uint8_t, uint32_t);
213 static int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
214
215 static void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
216 static int ahci_get_num_implemented_ports(uint32_t);
217 static void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
218 static void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
219 static void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
220 #if AHCI_DEBUG
221 static void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
222 #endif
223
224
225 /*
226 * DMA attributes for the data buffer
227 *
228 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
229 * does not support 64-bit addressing
230 */
231 static ddi_dma_attr_t buffer_dma_attr = {
232 DMA_ATTR_V0, /* dma_attr_version */
233 0x0ull, /* dma_attr_addr_lo: lowest bus address */
234 0xffffffffffffffffull, /* dma_attr_addr_hi: highest bus address */
235 0x3fffffull, /* dma_attr_count_max i.e. for one cookie */
236 0x2ull, /* dma_attr_align: word aligned */
237 1, /* dma_attr_burstsizes */
238 1, /* dma_attr_minxfer */
239 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
240 0xffffffffull, /* dma_attr_seg */
241 AHCI_PRDT_NUMBER, /* dma_attr_sgllen */
242 512, /* dma_attr_granular */
243 0, /* dma_attr_flags */
244 };
298 0xffffffffull, /* dma_attr_count_max i.e. for one cookie */
299 0x80ull, /* dma_attr_align: 128-byte aligned */
300 1, /* dma_attr_burstsizes */
301 1, /* dma_attr_minxfer */
302 0xffffffffull, /* dma_attr_maxxfer i.e. includes all cookies */
303 0xffffffffull, /* dma_attr_seg */
304 1, /* dma_attr_sgllen */
305 1, /* dma_attr_granular */
306 0, /* dma_attr_flags */
307 };
308
309
310 /* Device access attributes */
311 static ddi_device_acc_attr_t accattr = {
312 DDI_DEVICE_ATTR_V1,
313 DDI_STRUCTURE_LE_ACC,
314 DDI_STRICTORDER_ACC,
315 DDI_DEFAULT_ACC
316 };
317
318
319 static struct dev_ops ahcictl_dev_ops = {
320 DEVO_REV, /* devo_rev */
321 0, /* refcnt */
322 ahci_getinfo, /* info */
323 nulldev, /* identify */
324 nulldev, /* probe */
325 ahci_attach, /* attach */
326 ahci_detach, /* detach */
327 nodev, /* no reset */
328 (struct cb_ops *)0, /* driver operations */
329 NULL, /* bus operations */
330 NULL, /* power */
331 ahci_quiesce, /* quiesce */
332 };
333
334 static sata_tran_hotplug_ops_t ahci_tran_hotplug_ops = {
335 SATA_TRAN_HOTPLUG_OPS_REV_1,
336 ahci_tran_hotplug_port_activate,
337 ahci_tran_hotplug_port_deactivate
338 };
339
340 extern struct mod_ops mod_driverops;
341
342 static struct modldrv modldrv = {
343 &mod_driverops, /* driverops */
344 ahci_ident, /* short description */
345 &ahcictl_dev_ops, /* driver ops */
346 };
347
348 static struct modlinkage modlinkage = {
393 * PxCLBU (upper 32-bits for the command list base physical address)
394 * PxFBU (upper 32-bits for the received FIS base physical address)
395 * CTBAU (upper 32-bits of command table base)
396 */
397 boolean_t ahci_commu_64bit_dma = B_TRUE;
398
399 /*
400 * By default, 64-bit dma for data buffer will be disabled for AMD/ATI SB600
401 * chipset. If the users want to have a try with 64-bit dma, please change
402 * the below variable value to enable it.
403 */
404 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
405
406 /*
407 * By default, 64-bit dma for command buffer will be disabled for AMD/ATI
408 * SB600/700/710/750/800. If the users want to have a try with 64-bit dma,
409 * please change the below value to enable it.
410 */
411 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
412
413
414 /*
415 * End of global tunable variable definition
416 */
417
418 #if AHCI_DEBUG
419 uint32_t ahci_debug_flags = 0;
420 #else
421 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
422 #endif
423
424
425 #if AHCI_DEBUG
426 /* The following is needed for ahci_log() */
427 static kmutex_t ahci_log_mutex;
428 static char ahci_log_buf[512];
429 #endif
430
431 /* Opaque state pointer initialized by ddi_soft_state_init() */
432 static void *ahci_statep = NULL;
433
563 ahci_ctlp->ahcictl_timeout_id = timeout(
564 (void (*)(void *))ahci_watchdog_handler,
565 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
566
567 mutex_exit(&ahci_ctlp->ahcictl_mutex);
568
569 /*
570 * Re-initialize the controller and enable the interrupts and
571 * restart all the ports.
572 *
573 * Note that so far we don't support hot-plug during
574 * suspend/resume.
575 */
576 if (ahci_initialize_controller(ahci_ctlp) != AHCI_SUCCESS) {
577 AHCIDBG(AHCIDBG_ERRS|AHCIDBG_PM, ahci_ctlp,
578 "Failed to initialize the controller "
579 "during DDI_RESUME", NULL);
580 return (DDI_FAILURE);
581 }
582
583 mutex_enter(&ahci_ctlp->ahcictl_mutex);
584 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
585 mutex_exit(&ahci_ctlp->ahcictl_mutex);
586
587 return (DDI_SUCCESS);
588
589 default:
590 return (DDI_FAILURE);
591 }
592
593 attach_state = AHCI_ATTACH_STATE_NONE;
594
595 /* Allocate soft state */
596 status = ddi_soft_state_zalloc(ahci_statep, instance);
597 if (status != DDI_SUCCESS) {
598 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
599 instance);
600 goto err_out;
601 }
602
697
698 /* Get the HBA capabilities information */
699 cap_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
700 (uint32_t *)AHCI_GLOBAL_CAP(ahci_ctlp));
701
702 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
703 cap_status);
704
705 /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
706 if (ahci_version >= 0x00010200) {
707 uint32_t cap2_status;
708
709 /* Get the HBA capabilities extended information */
710 cap2_status = ddi_get32(ahci_ctlp->ahcictl_ahci_acc_handle,
711 (uint32_t *)AHCI_GLOBAL_CAP2(ahci_ctlp));
712
713 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
714 "hba capabilities extended = 0x%x", cap2_status);
715 }
716
717 #if AHCI_DEBUG
718 /* Get the interface speed supported by the HBA */
719 speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
720 if (speed == 0x01) {
721 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
722 "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
723 } else if (speed == 0x10) {
724 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
725 "hba interface speed support: Gen 2 (3 Gbps)", NULL);
726 } else if (speed == 0x11) {
727 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
728 "hba interface speed support: Gen 3 (6 Gbps)", NULL);
729 }
730 #endif
731
732 /* Get the number of command slots supported by the HBA */
733 ahci_ctlp->ahcictl_num_cmd_slots =
734 ((cap_status & AHCI_HBA_CAP_NCS) >>
735 AHCI_HBA_CAP_NCS_SHIFT) + 1;
736
948
949 /*
950 * Initialize the controller and ports.
951 */
952 status = ahci_initialize_controller(ahci_ctlp);
953 if (status != AHCI_SUCCESS) {
954 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
955 instance);
956 goto err_out;
957 }
958
959 attach_state |= AHCI_ATTACH_STATE_HW_INIT;
960
961 /* Start one thread to check packet timeouts */
962 ahci_ctlp->ahcictl_timeout_id = timeout(
963 (void (*)(void *))ahci_watchdog_handler,
964 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
965
966 attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
967
968 if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
969 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
970 instance);
971 goto err_out;
972 }
973
974 /* Check all handles at the end of the attach operation. */
975 if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
976 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
977 instance);
978 goto err_out;
979 }
980
981 ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
982
983 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
984
985 return (DDI_SUCCESS);
986
987 err_out:
988 /* FMA message */
989 ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
990 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
991
992 if (attach_state & AHCI_ATTACH_STATE_TIMEOUT_ENABLED) {
993 mutex_enter(&ahci_ctlp->ahcictl_mutex);
994 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
995 ahci_ctlp->ahcictl_timeout_id = 0;
996 mutex_exit(&ahci_ctlp->ahcictl_mutex);
997 }
998
999 if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1000 ahci_uninitialize_controller(ahci_ctlp);
1001 }
1002
1003 if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1004 ahci_dealloc_ports_state(ahci_ctlp);
1005 }
1006
1007 if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1008 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1009 }
1010
1011 if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {
1046
1047 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1048
1049 switch (cmd) {
1050 case DDI_DETACH:
1051
1052 /* disable the interrupts for an uninterrupted detach */
1053 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1054 ahci_disable_all_intrs(ahci_ctlp);
1055 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1056
1057 /* unregister from the sata framework. */
1058 ret = ahci_unregister_sata_hba_tran(ahci_ctlp);
1059 if (ret != AHCI_SUCCESS) {
1060 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1061 ahci_enable_all_intrs(ahci_ctlp);
1062 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1063 return (DDI_FAILURE);
1064 }
1065
1066 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1067
1068 /* stop the watchdog handler */
1069 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1070 ahci_ctlp->ahcictl_timeout_id = 0;
1071
1072 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1073
1074 /* uninitialize the controller */
1075 ahci_uninitialize_controller(ahci_ctlp);
1076
1077 /* remove the interrupts */
1078 ahci_rem_intrs(ahci_ctlp);
1079
1080 /* deallocate the ports structures */
1081 ahci_dealloc_ports_state(ahci_ctlp);
1082
1083 /* destroy mutex */
1084 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1085
1095 /* free the soft state. */
1096 ddi_soft_state_free(ahci_statep, instance);
1097
1098 return (DDI_SUCCESS);
1099
1100 case DDI_SUSPEND:
1101
1102 /*
1103 * The steps associated with suspension must include putting
1104 * the underlying device into a quiescent state so that it
1105 * will not generate interrupts or modify or access memory.
1106 */
1107 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1108 if (ahci_ctlp->ahcictl_flags & AHCI_SUSPEND) {
1109 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1110 return (DDI_SUCCESS);
1111 }
1112
1113 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1114
1115 /* stop the watchdog handler */
1116 if (ahci_ctlp->ahcictl_timeout_id) {
1117 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1118 ahci_ctlp->ahcictl_timeout_id = 0;
1119 }
1120
1121 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1122
1123 /*
1124 * drain the taskq
1125 */
1126 ahci_drain_ports_taskq(ahci_ctlp);
1127
1128 /*
1129 * Disable the interrupts and stop all the ports.
1130 */
1131 ahci_uninitialize_controller(ahci_ctlp);
1132
1133 return (DDI_SUCCESS);
1134
1245 SATA_CTLF_PMULT_FBS;
1246 }
1247 }
1248
1249 /* Report the number of command slots */
1250 sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1251
1252 sata_hba_tran->sata_tran_probe_port = ahci_tran_probe_port;
1253 sata_hba_tran->sata_tran_start = ahci_tran_start;
1254 sata_hba_tran->sata_tran_abort = ahci_tran_abort;
1255 sata_hba_tran->sata_tran_reset_dport = ahci_tran_reset_dport;
1256 sata_hba_tran->sata_tran_hotplug_ops = &ahci_tran_hotplug_ops;
1257 #ifdef __lock_lint
1258 sata_hba_tran->sata_tran_selftest = ahci_selftest;
1259 #endif
1260 /*
1261 * When SATA framework adds support for pwrmgt the
1262 * pwrmgt_ops needs to be updated
1263 */
1264 sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1265 sata_hba_tran->sata_tran_ioctl = NULL;
1266
1267 ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1268
1269 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1270
1271 /* Attach it to SATA framework */
1272 if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1273 != DDI_SUCCESS) {
1274 kmem_free((void *)sata_hba_tran, sizeof (sata_hba_tran_t));
1275 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1276 ahci_ctlp->ahcictl_sata_hba_tran = NULL;
1277 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1278 return (AHCI_FAILURE);
1279 }
1280
1281 return (AHCI_SUCCESS);
1282 }
1283
1284 /*
1285 * Unregisters the ahci with sata framework.
1798 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1799 uint8_t port = addrp->aa_port;
1800
1801 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1802
1803 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1804 "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1805
1806 if (spkt->satapkt_op_mode & SATA_OPMODE_POLLING) {
1807 ahci_portp->ahciport_flags |= AHCI_PORT_FLAG_POLLING;
1808 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1809 addrp, spkt)) == AHCI_FAILURE) {
1810 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1811 return (rval);
1812 }
1813
1814 pkt_timeout_ticks =
1815 drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1816
1817 while (spkt->satapkt_reason == SATA_PKT_BUSY) {
1818 mutex_exit(&ahci_portp->ahciport_mutex);
1819
1820 /* Simulate the interrupt */
1821 ahci_port_intr(ahci_ctlp, ahci_portp, port);
1822
1823 drv_usecwait(AHCI_10MS_USECS);
1824
1825 mutex_enter(&ahci_portp->ahciport_mutex);
1826 pkt_timeout_ticks -= AHCI_10MS_TICKS;
1827 if (pkt_timeout_ticks < 0) {
1828 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1829 "port %d satapkt 0x%p timed out\n",
1830 instance, port, (void *)spkt);
1831 timeout_tags = (0x1 << rval);
1832 mutex_exit(&ahci_portp->ahciport_mutex);
1833 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1834 port, timeout_tags);
1835 mutex_enter(&ahci_portp->ahciport_mutex);
1836 }
1837 }
1838 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1839 return (AHCI_SUCCESS);
1840
1841 } else {
1842 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1843 addrp, spkt)) == AHCI_FAILURE)
1844 return (rval);
1845
1846 #if AHCI_DEBUG
1847 /*
1848 * Note that the driver always uses the slot 0 to deliver
1849 * REQUEST SENSE or READ LOG EXT command
1850 */
1851 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1852 ASSERT(rval == 0);
1853 #endif
1854
1855 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1856 cv_wait(&ahci_portp->ahciport_cv,
1857 &ahci_portp->ahciport_mutex);
9457 out:
9458 AHCIDBG(AHCIDBG_ERRS, ahci_ctlp,
9459 "ahci_fatal_error_recovery_handler: port %d fatal error "
9460 "occurred slot_status = 0x%x, pending_tags = 0x%x, "
9461 "pending_ncq_tags = 0x%x failed_tags = 0x%x",
9462 port, slot_status, ahci_portp->ahciport_pending_tags,
9463 ahci_portp->ahciport_pending_ncq_tags, failed_tags);
9464
9465 ahci_mop_commands(ahci_ctlp,
9466 ahci_portp,
9467 slot_status,
9468 failed_tags, /* failed tags */
9469 0, /* timeout tags */
9470 0, /* aborted tags */
9471 0); /* reset tags */
9472 }
9473
9474 /*
9475 * Used to recovery a PMULT pmport fatal error under FIS-based switching.
9476 * 1. device specific.PxFBS.SDE=1
9477 * 2. Non-Deivce specific.
9478 * Nothing will be done when Command-based switching is employed.
9479 *
9480 * Currently code is neither completed nor tested.
9481 */
9482 static void
9483 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9484 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9485 {
9486 #ifndef __lock_lint
9487 _NOTE(ARGUNUSED(intr_status))
9488 #endif
9489 uint32_t port_fbs_ctrl;
9490 int loop_count = 0;
9491 ahci_addr_t addr;
9492
9493 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9494
9495 /* Nothing will be done under Command-based switching. */
9496 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9497 return;
9971
9972 static void
9973 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
9974 uint32_t slot_tags)
9975 {
9976 ahci_port_t *ahci_portp;
9977 int tmp_slot;
9978 sata_pkt_t *spkt;
9979 sata_cmd_t cmd;
9980
9981 ahci_portp = ahci_ctlp->ahcictl_ports[port];
9982 ASSERT(ahci_portp != NULL);
9983
9984 while (slot_tags) {
9985 tmp_slot = ddi_ffs(slot_tags) - 1;
9986 if (tmp_slot == -1) {
9987 break;
9988 }
9989
9990 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
9991 ASSERT(spkt != NULL);
9992 cmd = spkt->satapkt_cmd;
9993
9994 cmn_err(CE_WARN, "!satapkt 0x%p: cmd_reg = 0x%x "
9995 "features_reg = 0x%x sec_count_msb = 0x%x "
9996 "lba_low_msb = 0x%x lba_mid_msb = 0x%x "
9997 "lba_high_msb = 0x%x sec_count_lsb = 0x%x "
9998 "lba_low_lsb = 0x%x lba_mid_lsb = 0x%x "
9999 "lba_high_lsb = 0x%x device_reg = 0x%x "
10000 "addr_type = 0x%x cmd_flags = 0x%x", (void *)spkt,
10001 cmd.satacmd_cmd_reg, cmd.satacmd_features_reg,
10002 cmd.satacmd_sec_count_msb, cmd.satacmd_lba_low_msb,
10003 cmd.satacmd_lba_mid_msb, cmd.satacmd_lba_high_msb,
10004 cmd.satacmd_sec_count_lsb, cmd.satacmd_lba_low_lsb,
10005 cmd.satacmd_lba_mid_lsb, cmd.satacmd_lba_high_lsb,
10006 cmd.satacmd_device_reg, cmd.satacmd_addr_type,
10007 *((uint32_t *)&(cmd.satacmd_flags)));
10008
10009 CLEAR_BIT(slot_tags, tmp_slot);
10010 }
10011 }
10012
10013 /*
10014 * Dump the serror message to the log.
10015 */
10016 static void
10017 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10018 uint32_t port_serror, int debug_only)
10019 {
10020 static char err_buf[512];
10021 static char err_msg_header[16];
10022 char *err_msg = err_buf;
10023
10024 *err_buf = '\0';
10025 *err_msg_header = '\0';
10026
10027 if (port_serror & SERROR_DATA_ERR_FIXED) {
10187 (void) sprintf(name, "ahci%d: ",
10188 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10189 } else {
10190 (void) sprintf(name, "ahci: ");
10191 }
10192
10193 (void) vsprintf(ahci_log_buf, fmt, ap);
10194 va_end(ap);
10195
10196 cmn_err(level, "%s%s", name, ahci_log_buf);
10197
10198 mutex_exit(&ahci_log_mutex);
10199 }
10200 #endif
10201
10202 /*
10203 * quiesce(9E) entry point.
10204 *
10205 * This function is called when the system is single-threaded at high
10206 * PIL with preemption disabled. Therefore, this function must not be
10207 * blocked.
10208 *
10209 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
10210 * DDI_FAILURE indicates an error condition and should almost never happen.
10211 */
10212 static int
10213 ahci_quiesce(dev_info_t *dip)
10214 {
10215 ahci_ctl_t *ahci_ctlp;
10216 ahci_port_t *ahci_portp;
10217 int instance, port;
10218
10219 instance = ddi_get_instance(dip);
10220 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10221
10222 if (ahci_ctlp == NULL)
10223 return (DDI_FAILURE);
10224
10225 #if AHCI_DEBUG
10226 ahci_debug_flags = 0;
10227 #endif
10304 satapkt = ahci_portp->ahciport_doneq;
10305
10306 ahci_portp->ahciport_doneq = NULL;
10307 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10308 ahci_portp->ahciport_doneq_len = 0;
10309
10310 mutex_exit(&ahci_portp->ahciport_mutex);
10311
10312 while (satapkt != NULL) {
10313 next = satapkt->satapkt_hba_driver_private;
10314 satapkt->satapkt_hba_driver_private = NULL;
10315
10316 /* Call the callback */
10317 (*satapkt->satapkt_comp)(satapkt);
10318
10319 satapkt = next;
10320 }
10321
10322 mutex_enter(&ahci_portp->ahciport_mutex);
10323 }
10324 }
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (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.
27 */
28
29 /*
30 * AHCI (Advanced Host Controller Interface) SATA HBA Driver
31 *
32 * Power Management Support
33 * ------------------------
34 *
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.
39 *
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.
45 *
46 *
47 * Enclosure Management Support
48 * ----------------------------
49 *
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.
59 *
60 * This has some drawbacks. It means that we cannot know whether or not it has
61 * succeeded. This means we cannot ask hardware what it thinks the LEDs are
62 * set to. There's also the added unfortunate reality that firmware on the
63 * microcontroller driving this will often not show the LEDs if no drive is
64 * present and that actions taken may potentially cause this to get out of sync
65 * with what we expect it to be. For example, the specification does not
66 * describe what should happen if a drive is removed from the enclosure while
67 * this is set and what should happen when it returns. We can only infer that it
68 * should be the same.
69 *
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.
75 *
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.
82 */
83
84 #include <sys/note.h>
85 #include <sys/scsi/scsi.h>
86 #include <sys/pci.h>
87 #include <sys/disp.h>
88 #include <sys/sata/sata_hba.h>
89 #include <sys/sata/adapters/ahci/ahcireg.h>
90 #include <sys/sata/adapters/ahci/ahcivar.h>
91
92 /*
93 * FMA header files
94 */
95 #include <sys/ddifm.h>
96 #include <sys/fm/protocol.h>
97 #include <sys/fm/util.h>
98 #include <sys/fm/io/ddi.h>
99
100 /*
101 * EM Control header files
102 */
103 #include <sys/types.h>
104 #include <sys/file.h>
105 #include <sys/errno.h>
106 #include <sys/open.h>
107 #include <sys/cred.h>
108 #include <sys/ddi.h>
109 #include <sys/sunddi.h>
110
111 /*
112 * This is the string displayed by modinfo, etc.
113 */
114 static char ahci_ident[] = "ahci driver";
115
116 /*
117 * Function prototypes for driver entry points
118 */
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 *);
123
124 /*
125 * Function prototypes for SATA Framework interfaces
126 */
127 static int ahci_register_sata_hba_tran(ahci_ctl_t *, uint32_t);
128 static int ahci_unregister_sata_hba_tran(ahci_ctl_t *);
129
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);
253 static int ahci_intr_pmult_sntf_events(ahci_ctl_t *, ahci_port_t *, uint8_t);
254 static int ahci_intr_port_connect_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
255 static int ahci_intr_device_mechanical_presence_status(ahci_ctl_t *,
256 ahci_port_t *, uint8_t);
257 static int ahci_intr_phyrdy_change(ahci_ctl_t *, ahci_port_t *, uint8_t);
258 static int ahci_intr_non_fatal_error(ahci_ctl_t *, ahci_port_t *,
259 uint8_t, uint32_t);
260 static int ahci_intr_fatal_error(ahci_ctl_t *, ahci_port_t *,
261 uint8_t, uint32_t);
262 static int ahci_intr_cold_port_detect(ahci_ctl_t *, ahci_port_t *, uint8_t);
263
264 static void ahci_get_ahci_addr(ahci_ctl_t *, sata_device_t *, ahci_addr_t *);
265 static int ahci_get_num_implemented_ports(uint32_t);
266 static void ahci_log_fatal_error_message(ahci_ctl_t *, uint8_t, uint32_t);
267 static void ahci_dump_commands(ahci_ctl_t *, uint8_t, uint32_t);
268 static void ahci_log_serror_message(ahci_ctl_t *, uint8_t, uint32_t, int);
269 #if AHCI_DEBUG
270 static void ahci_log(ahci_ctl_t *, uint_t, char *, ...);
271 #endif
272
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);
278
279
280 /*
281 * DMA attributes for the data buffer
282 *
283 * dma_attr_addr_hi will be changed to 0xffffffffull if the HBA
284 * does not support 64-bit addressing
285 */
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 */
299 };
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 */
362 };
363
364
365 /* Device access attributes */
366 static ddi_device_acc_attr_t accattr = {
367 DDI_DEVICE_ATTR_V1,
368 DDI_STRUCTURE_LE_ACC,
369 DDI_STRICTORDER_ACC,
370 DDI_DEFAULT_ACC
371 };
372
373 static struct dev_ops ahcictl_dev_ops = {
374 DEVO_REV, /* devo_rev */
375 0, /* refcnt */
376 ahci_getinfo, /* info */
377 nulldev, /* identify */
378 nulldev, /* probe */
379 ahci_attach, /* attach */
380 ahci_detach, /* detach */
381 nodev, /* no reset */
382 NULL, /* driver operations */
383 NULL, /* bus operations */
384 NULL, /* power */
385 ahci_quiesce, /* quiesce */
386 };
387
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
392 };
393
394 extern struct mod_ops mod_driverops;
395
396 static struct modldrv modldrv = {
397 &mod_driverops, /* driverops */
398 ahci_ident, /* short description */
399 &ahcictl_dev_ops, /* driver ops */
400 };
401
402 static struct modlinkage modlinkage = {
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)
450 */
451 boolean_t ahci_commu_64bit_dma = B_TRUE;
452
453 /*
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.
457 */
458 boolean_t sb600_buf_64bit_dma_disable = B_TRUE;
459
460 /*
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.
464 */
465 boolean_t sbxxx_commu_64bit_dma_disable = B_TRUE;
466
467 /*
468 * These values control the default delay and default number of times to wait
469 * for an enclosure message to complete.
470 */
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;
475
476
477 /*
478 * End of global tunable variable definition
479 */
480
481 #if AHCI_DEBUG
482 uint32_t ahci_debug_flags = 0;
483 #else
484 uint32_t ahci_debug_flags = (AHCIDBG_ERRS|AHCIDBG_TIMEOUT);
485 #endif
486
487
488 #if AHCI_DEBUG
489 /* The following is needed for ahci_log() */
490 static kmutex_t ahci_log_mutex;
491 static char ahci_log_buf[512];
492 #endif
493
494 /* Opaque state pointer initialized by ddi_soft_state_init() */
495 static void *ahci_statep = NULL;
496
626 ahci_ctlp->ahcictl_timeout_id = timeout(
627 (void (*)(void *))ahci_watchdog_handler,
628 (caddr_t)ahci_ctlp, ahci_watchdog_tick);
629
630 mutex_exit(&ahci_ctlp->ahcictl_mutex);
631
632 /*
633 * Re-initialize the controller and enable the interrupts and
634 * restart all the ports.
635 *
636 * Note that so far we don't support hot-plug during
637 * suspend/resume.
638 */
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);
644 }
645
646 /*
647 * Reset the enclosure services.
648 */
649 ahci_em_resume(ahci_ctlp);
650
651 mutex_enter(&ahci_ctlp->ahcictl_mutex);
652 ahci_ctlp->ahcictl_flags &= ~AHCI_SUSPEND;
653 mutex_exit(&ahci_ctlp->ahcictl_mutex);
654
655 return (DDI_SUCCESS);
656
657 default:
658 return (DDI_FAILURE);
659 }
660
661 attach_state = AHCI_ATTACH_STATE_NONE;
662
663 /* Allocate soft state */
664 status = ddi_soft_state_zalloc(ahci_statep, instance);
665 if (status != DDI_SUCCESS) {
666 cmn_err(CE_WARN, "!ahci%d: Cannot allocate soft state",
667 instance);
668 goto err_out;
669 }
670
765
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));
769
770 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "hba capabilities = 0x%x",
771 cap_status);
772
773 /* CAP2 (HBA Capabilities Extended) is available since AHCI spec 1.2 */
774 if (ahci_version >= 0x00010200) {
775 uint32_t cap2_status;
776
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));
780
781 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
782 "hba capabilities extended = 0x%x", cap2_status);
783 }
784
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));
793 }
794
795 #if AHCI_DEBUG
796 /* Get the interface speed supported by the HBA */
797 speed = (cap_status & AHCI_HBA_CAP_ISS) >> AHCI_HBA_CAP_ISS_SHIFT;
798 if (speed == 0x01) {
799 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
800 "hba interface speed support: Gen 1 (1.5Gbps)", NULL);
801 } else if (speed == 0x10) {
802 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
803 "hba interface speed support: Gen 2 (3 Gbps)", NULL);
804 } else if (speed == 0x11) {
805 AHCIDBG(AHCIDBG_INIT, ahci_ctlp,
806 "hba interface speed support: Gen 3 (6 Gbps)", NULL);
807 }
808 #endif
809
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;
814
1026
1027 /*
1028 * Initialize the controller and ports.
1029 */
1030 status = ahci_initialize_controller(ahci_ctlp);
1031 if (status != AHCI_SUCCESS) {
1032 cmn_err(CE_WARN, "!ahci%d: HBA initialization failed",
1033 instance);
1034 goto err_out;
1035 }
1036
1037 attach_state |= AHCI_ATTACH_STATE_HW_INIT;
1038
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);
1043
1044 attach_state |= AHCI_ATTACH_STATE_TIMEOUT_ENABLED;
1045
1046 if (!ahci_em_init(ahci_ctlp)) {
1047 cmn_err(CE_WARN, "!ahci%d: failed to initialize enclosure "
1048 "services", instance);
1049 goto err_out;
1050 }
1051 attach_state |= AHCI_ATTACH_STATE_ENCLOSURE;
1052
1053 if (ahci_register_sata_hba_tran(ahci_ctlp, cap_status)) {
1054 cmn_err(CE_WARN, "!ahci%d: sata hba tran registration failed",
1055 instance);
1056 goto err_out;
1057 }
1058
1059 /* Check all handles at the end of the attach operation. */
1060 if (ahci_check_all_handle(ahci_ctlp) != DDI_SUCCESS) {
1061 cmn_err(CE_WARN, "!ahci%d: invalid dma/acc handles",
1062 instance);
1063 goto err_out;
1064 }
1065
1066 ahci_ctlp->ahcictl_flags &= ~AHCI_ATTACH;
1067
1068 AHCIDBG(AHCIDBG_INIT, ahci_ctlp, "ahci_attach success!", NULL);
1069
1070 return (DDI_SUCCESS);
1071
1072 err_out:
1073 /* FMA message */
1074 ahci_fm_ereport(ahci_ctlp, DDI_FM_DEVICE_NO_RESPONSE);
1075 ddi_fm_service_impact(ahci_ctlp->ahcictl_dip, DDI_SERVICE_LOST);
1076
1077 if (attach_state & AHCI_ATTACH_STATE_ENCLOSURE) {
1078 ahci_em_fini(ahci_ctlp);
1079 }
1080
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);
1086 }
1087
1088 if (attach_state & AHCI_ATTACH_STATE_HW_INIT) {
1089 ahci_uninitialize_controller(ahci_ctlp);
1090 }
1091
1092 if (attach_state & AHCI_ATTACH_STATE_PORT_ALLOC) {
1093 ahci_dealloc_ports_state(ahci_ctlp);
1094 }
1095
1096 if (attach_state & AHCI_ATTACH_STATE_MUTEX_INIT) {
1097 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1098 }
1099
1100 if (attach_state & AHCI_ATTACH_STATE_INTR_ADDED) {
1135
1136 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_detach enter", NULL);
1137
1138 switch (cmd) {
1139 case DDI_DETACH:
1140
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);
1145
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);
1153 }
1154
1155 ahci_em_fini(ahci_ctlp);
1156
1157 mutex_enter(&ahci_ctlp->ahcictl_mutex);
1158
1159 /* stop the watchdog handler */
1160 (void) untimeout(ahci_ctlp->ahcictl_timeout_id);
1161 ahci_ctlp->ahcictl_timeout_id = 0;
1162
1163 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1164
1165 /* uninitialize the controller */
1166 ahci_uninitialize_controller(ahci_ctlp);
1167
1168 /* remove the interrupts */
1169 ahci_rem_intrs(ahci_ctlp);
1170
1171 /* deallocate the ports structures */
1172 ahci_dealloc_ports_state(ahci_ctlp);
1173
1174 /* destroy mutex */
1175 mutex_destroy(&ahci_ctlp->ahcictl_mutex);
1176
1186 /* free the soft state. */
1187 ddi_soft_state_free(ahci_statep, instance);
1188
1189 return (DDI_SUCCESS);
1190
1191 case DDI_SUSPEND:
1192
1193 /*
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.
1197 */
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);
1202 }
1203
1204 ahci_ctlp->ahcictl_flags |= AHCI_SUSPEND;
1205
1206 ahci_em_suspend(ahci_ctlp);
1207
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;
1212 }
1213
1214 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1215
1216 /*
1217 * drain the taskq
1218 */
1219 ahci_drain_ports_taskq(ahci_ctlp);
1220
1221 /*
1222 * Disable the interrupts and stop all the ports.
1223 */
1224 ahci_uninitialize_controller(ahci_ctlp);
1225
1226 return (DDI_SUCCESS);
1227
1338 SATA_CTLF_PMULT_FBS;
1339 }
1340 }
1341
1342 /* Report the number of command slots */
1343 sata_hba_tran->sata_tran_hba_qdepth = ahci_ctlp->ahcictl_num_cmd_slots;
1344
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;
1350 #ifdef __lock_lint
1351 sata_hba_tran->sata_tran_selftest = ahci_selftest;
1352 #endif
1353 /*
1354 * When SATA framework adds support for pwrmgt the
1355 * pwrmgt_ops needs to be updated
1356 */
1357 sata_hba_tran->sata_tran_pwrmgt_ops = NULL;
1358 sata_hba_tran->sata_tran_ioctl = ahci_em_ioctl;
1359
1360 ahci_ctlp->ahcictl_sata_hba_tran = sata_hba_tran;
1361
1362 mutex_exit(&ahci_ctlp->ahcictl_mutex);
1363
1364 /* Attach it to SATA framework */
1365 if (sata_hba_attach(ahci_ctlp->ahcictl_dip, sata_hba_tran, DDI_ATTACH)
1366 != DDI_SUCCESS) {
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);
1372 }
1373
1374 return (AHCI_SUCCESS);
1375 }
1376
1377 /*
1378 * Unregisters the ahci with sata framework.
1891 int instance = ddi_get_instance(ahci_ctlp->ahcictl_dip);
1892 uint8_t port = addrp->aa_port;
1893
1894 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
1895
1896 AHCIDBG(AHCIDBG_ENTRY, ahci_ctlp, "ahci_do_sync_start enter: "
1897 "port %d:%d spkt 0x%p", port, addrp->aa_pmport, spkt);
1898
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;
1904 return (rval);
1905 }
1906
1907 pkt_timeout_ticks =
1908 drv_usectohz((clock_t)spkt->satapkt_time * 1000000);
1909
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);
1915
1916 if (spkt->satapkt_reason != SATA_PKT_BUSY)
1917 break;
1918
1919 mutex_exit(&ahci_portp->ahciport_mutex);
1920 drv_usecwait(AHCI_1MS_USECS);
1921 mutex_enter(&ahci_portp->ahciport_mutex);
1922
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);
1933 }
1934 }
1935
1936 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1937 return (AHCI_SUCCESS);
1938
1939 } else {
1940 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1941 addrp, spkt)) == AHCI_FAILURE)
1942 return (rval);
1943
1944 #if AHCI_DEBUG
1945 /*
1946 * Note that the driver always uses the slot 0 to deliver
1947 * REQUEST SENSE or READ LOG EXT command
1948 */
1949 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1950 ASSERT(rval == 0);
1951 #endif
1952
1953 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1954 cv_wait(&ahci_portp->ahciport_cv,
1955 &ahci_portp->ahciport_mutex);
9555 out:
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);
9562
9563 ahci_mop_commands(ahci_ctlp,
9564 ahci_portp,
9565 slot_status,
9566 failed_tags, /* failed tags */
9567 0, /* timeout tags */
9568 0, /* aborted tags */
9569 0); /* reset tags */
9570 }
9571
9572 /*
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.
9577 *
9578 * Currently code is neither completed nor tested.
9579 */
9580 static void
9581 ahci_pmult_error_recovery_handler(ahci_ctl_t *ahci_ctlp,
9582 ahci_port_t *ahci_portp, uint8_t port, uint32_t intr_status)
9583 {
9584 #ifndef __lock_lint
9585 _NOTE(ARGUNUSED(intr_status))
9586 #endif
9587 uint32_t port_fbs_ctrl;
9588 int loop_count = 0;
9589 ahci_addr_t addr;
9590
9591 ASSERT(MUTEX_HELD(&ahci_portp->ahciport_mutex));
9592
9593 /* Nothing will be done under Command-based switching. */
9594 if (!(ahci_ctlp->ahcictl_cap & AHCI_CAP_PMULT_FBSS))
9595 return;
10069
10070 static void
10071 ahci_dump_commands(ahci_ctl_t *ahci_ctlp, uint8_t port,
10072 uint32_t slot_tags)
10073 {
10074 ahci_port_t *ahci_portp;
10075 int tmp_slot;
10076 sata_pkt_t *spkt;
10077 sata_cmd_t cmd;
10078
10079 ahci_portp = ahci_ctlp->ahcictl_ports[port];
10080 ASSERT(ahci_portp != NULL);
10081
10082 while (slot_tags) {
10083 tmp_slot = ddi_ffs(slot_tags) - 1;
10084 if (tmp_slot == -1) {
10085 break;
10086 }
10087
10088 spkt = ahci_portp->ahciport_slot_pkts[tmp_slot];
10089 if (spkt != NULL) {
10090 cmd = spkt->satapkt_cmd;
10091
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)));
10106 }
10107
10108 CLEAR_BIT(slot_tags, tmp_slot);
10109 }
10110 }
10111
10112 /*
10113 * Dump the serror message to the log.
10114 */
10115 static void
10116 ahci_log_serror_message(ahci_ctl_t *ahci_ctlp, uint8_t port,
10117 uint32_t port_serror, int debug_only)
10118 {
10119 static char err_buf[512];
10120 static char err_msg_header[16];
10121 char *err_msg = err_buf;
10122
10123 *err_buf = '\0';
10124 *err_msg_header = '\0';
10125
10126 if (port_serror & SERROR_DATA_ERR_FIXED) {
10286 (void) sprintf(name, "ahci%d: ",
10287 ddi_get_instance(ahci_ctlp->ahcictl_dip));
10288 } else {
10289 (void) sprintf(name, "ahci: ");
10290 }
10291
10292 (void) vsprintf(ahci_log_buf, fmt, ap);
10293 va_end(ap);
10294
10295 cmn_err(level, "%s%s", name, ahci_log_buf);
10296
10297 mutex_exit(&ahci_log_mutex);
10298 }
10299 #endif
10300
10301 /*
10302 * quiesce(9E) entry point.
10303 *
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.
10310 *
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.
10313 */
10314 static int
10315 ahci_quiesce(dev_info_t *dip)
10316 {
10317 ahci_ctl_t *ahci_ctlp;
10318 ahci_port_t *ahci_portp;
10319 int instance, port;
10320
10321 instance = ddi_get_instance(dip);
10322 ahci_ctlp = ddi_get_soft_state(ahci_statep, instance);
10323
10324 if (ahci_ctlp == NULL)
10325 return (DDI_FAILURE);
10326
10327 #if AHCI_DEBUG
10328 ahci_debug_flags = 0;
10329 #endif
10406 satapkt = ahci_portp->ahciport_doneq;
10407
10408 ahci_portp->ahciport_doneq = NULL;
10409 ahci_portp->ahciport_doneqtail = &ahci_portp->ahciport_doneq;
10410 ahci_portp->ahciport_doneq_len = 0;
10411
10412 mutex_exit(&ahci_portp->ahciport_mutex);
10413
10414 while (satapkt != NULL) {
10415 next = satapkt->satapkt_hba_driver_private;
10416 satapkt->satapkt_hba_driver_private = NULL;
10417
10418 /* Call the callback */
10419 (*satapkt->satapkt_comp)(satapkt);
10420
10421 satapkt = next;
10422 }
10423
10424 mutex_enter(&ahci_portp->ahciport_mutex);
10425 }
10426 }
10427
10428 /*
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.
10432 */
10433 static boolean_t
10434 ahci_em_set_led(ahci_ctl_t *ahci_ctlp, uint8_t port, ahci_em_led_state_t desire)
10435 {
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;
10440
10441 msg.alm_hba = port;
10442 msg.alm_pminfo = 0;
10443 msg.alm_value = 0;
10444
10445 if (desire & AHCI_EM_LED_IDENT_ENABLE) {
10446 msg.alm_value |= AHCI_LED_ON << AHCI_LED_IDENT_OFF;
10447 }
10448
10449 if (desire & AHCI_EM_LED_FAULT_ENABLE) {
10450 msg.alm_value |= AHCI_LED_ON << AHCI_LED_FAULT_OFF;
10451 }
10452
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;
10456 }
10457
10458 hdr.aemh_rsvd = 0;
10459 hdr.aemh_mlen = sizeof (ahci_em_led_msg_t);
10460 hdr.aemh_dlen = 0;
10461 hdr.aemh_mtype = AHCI_EM_MSG_TYPE_LED;
10462
10463 bcopy(&msg, &msgval, sizeof (msgval));
10464 bcopy(&hdr, &hdrval, sizeof (hdrval));
10465
10466 /*
10467 * First, make sure we can transmit. We should not have been placed in a
10468 * situation where an outstanding transmission is going on.
10469 */
10470 for (i = 0; i < max_delay; i++) {
10471 uint32_t val;
10472
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)
10476 break;
10477
10478 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10479 }
10480
10481 if (i == max_delay)
10482 return (B_FALSE);
10483
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);
10490
10491 for (i = 0; i < max_delay; i++) {
10492 uint32_t val;
10493
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)
10497 break;
10498
10499 delay(drv_usectohz(ahci_em_tx_delay_ms * 1000));
10500 }
10501
10502 if (i == max_delay)
10503 return (B_FALSE);
10504
10505 return (B_TRUE);
10506 }
10507
10508 typedef struct ahci_em_led_task_arg {
10509 ahci_ctl_t *aelta_ctl;
10510 uint8_t aelta_port;
10511 uint_t aelta_op;
10512 ahci_em_led_state_t aelta_state;
10513 uint_t aelta_ret;
10514 kcondvar_t aelta_cv;
10515 uint_t aelta_ref;
10516 } ahci_em_led_task_arg_t;
10517
10518 static void
10519 ahci_em_led_task_free(ahci_em_led_task_arg_t *task)
10520 {
10521 ASSERT3U(task->aelta_ref, ==, 0);
10522 cv_destroy(&task->aelta_cv);
10523 kmem_free(task, sizeof (*task));
10524 }
10525
10526 static void
10527 ahci_em_led_task(void *arg)
10528 {
10529 boolean_t ret, cleanup = B_FALSE;
10530 ahci_em_led_task_arg_t *led = arg;
10531 ahci_em_led_state_t state;
10532
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);
10537 return;
10538 }
10539
10540 state = led->aelta_ctl->ahcictl_em_state[led->aelta_port];
10541 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10542
10543 switch (led->aelta_op) {
10544 case AHCI_EM_IOC_SET_OP_ADD:
10545 state |= led->aelta_state;
10546 break;
10547 case AHCI_EM_IOC_SET_OP_REM:
10548 state &= ~led->aelta_state;
10549 break;
10550 case AHCI_EM_IOC_SET_OP_SET:
10551 state = led->aelta_state;
10552 break;
10553 default:
10554 led->aelta_ret = ENOTSUP;
10555 return;
10556 }
10557
10558 ret = ahci_em_set_led(led->aelta_ctl, led->aelta_port, state);
10559
10560 mutex_enter(&led->aelta_ctl->ahcictl_mutex);
10561 if (ret) {
10562 led->aelta_ctl->ahcictl_em_state[led->aelta_port] =
10563 led->aelta_state;
10564 led->aelta_ret = 0;
10565 } else {
10566 led->aelta_ret = EIO;
10567 led->aelta_ctl->ahcictl_em_flags |= AHCI_EM_TIMEOUT;
10568 }
10569 led->aelta_ref--;
10570 if (led->aelta_ref > 0) {
10571 cv_signal(&led->aelta_cv);
10572 } else {
10573 cleanup = B_TRUE;
10574 }
10575 mutex_exit(&led->aelta_ctl->ahcictl_mutex);
10576
10577 if (cleanup) {
10578 ahci_em_led_task_free(led);
10579 }
10580 }
10581
10582 static void
10583 ahci_em_reset(void *arg)
10584 {
10585 uint_t i, max_delay = ahci_em_reset_delay_count;
10586 ahci_ctl_t *ahci_ctlp = arg;
10587
10588 /*
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.
10591 */
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);
10597 return;
10598 }
10599 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10600
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++) {
10604 uint32_t val;
10605
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)
10609 break;
10610
10611 delay(drv_usectohz(ahci_em_reset_delay_ms * 1000));
10612 }
10613
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));
10621 return;
10622 }
10623
10624 for (i = 0; i < ahci_ctlp->ahcictl_num_ports; i++) {
10625
10626 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, i))
10627 continue;
10628
10629 /*
10630 * Try to flush all the LEDs as part of reset. If it fails,
10631 * drive on.
10632 */
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 "
10640 "setting port %u",
10641 ddi_get_instance(ahci_ctlp->ahcictl_dip), i);
10642 return;
10643 }
10644 }
10645
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);
10650 }
10651
10652 static boolean_t
10653 ahci_em_init(ahci_ctl_t *ahci_ctlp)
10654 {
10655 char name[128];
10656
10657 /*
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.
10660 */
10661 if (ahci_ctlp->ahcictl_em_loc == 0 ||
10662 (ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_SUPP_LED) == 0)
10663 return (B_TRUE);
10664
10665 /*
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.
10668 */
10669 if ((ahci_ctlp->ahcictl_em_loc & AHCI_HBA_EM_LOC_SZ_MASK) <
10670 AHCI_EM_BUFFER_MIN) {
10671 return (B_TRUE);
10672 }
10673
10674 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_PRESENT;
10675
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;
10679
10680 bzero(ahci_ctlp->ahcictl_em_state,
10681 sizeof (ahci_ctlp->ahcictl_em_state));
10682
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));
10690 return (B_FALSE);
10691 }
10692
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);
10698
10699 return (B_TRUE);
10700 }
10701
10702 static int
10703 ahci_em_ioctl_get(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10704 {
10705 int i;
10706 ahci_ioc_em_get_t get;
10707
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;
10712 }
10713
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)) {
10717 continue;
10718 }
10719 get.aiemg_status[i] = ahci_ctlp->ahcictl_em_state[i];
10720 }
10721 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10722
10723 if (ddi_copyout(&get, (void *)arg, sizeof (get), 0) != 0)
10724 return (EFAULT);
10725
10726 return (0);
10727 }
10728
10729 static int
10730 ahci_em_ioctl_set(ahci_ctl_t *ahci_ctlp, intptr_t arg)
10731 {
10732 int ret;
10733 ahci_ioc_em_set_t set;
10734 ahci_em_led_task_arg_t *task;
10735 boolean_t signal, cleanup;
10736
10737 if (ddi_copyin((void *)arg, &set, sizeof (set), 0) != 0)
10738 return (EFAULT);
10739
10740 if (set.aiems_port > ahci_ctlp->ahcictl_num_ports)
10741 return (EINVAL);
10742
10743 if (!AHCI_PORT_IMPLEMENTED(ahci_ctlp, set.aiems_port)) {
10744 return (EINVAL);
10745 }
10746
10747 if ((set.aiems_leds & ~(AHCI_EM_LED_IDENT_ENABLE |
10748 AHCI_EM_LED_FAULT_ENABLE |
10749 AHCI_EM_LED_ACTIVITY_DISABLE)) != 0) {
10750 return (EINVAL);
10751 }
10752
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:
10757 break;
10758 default:
10759 return (EINVAL);
10760 }
10761
10762 if ((set.aiems_leds & AHCI_EM_LED_ACTIVITY_DISABLE) != 0 &&
10763 ((ahci_ctlp->ahcictl_em_ctl & AHCI_HBA_EM_CTL_ATTR_ALHD) != 0)) {
10764 return (ENOTSUP);
10765 }
10766
10767 task = kmem_alloc(sizeof (*task), KM_NOSLEEP | KM_NORMALPRI);
10768 if (task == NULL) {
10769 return (ENOMEM);
10770 }
10771
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;
10776
10777 cv_init(&task->aelta_cv, NULL, CV_DRIVER, NULL);
10778
10779 /*
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.
10782 */
10783 task->aelta_ref = 2;
10784
10785 /*
10786 * Once dispatched, the task state is protected by our global mutex.
10787 */
10788 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq,
10789 ahci_em_led_task, task, DDI_SLEEP);
10790
10791 signal = B_FALSE;
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) ==
10795 0) {
10796 signal = B_TRUE;
10797 break;
10798 }
10799 }
10800
10801 /*
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
10805 * care of it.
10806 */
10807 task->aelta_ref--;
10808 cleanup = (task->aelta_ref == 0);
10809 if (signal) {
10810 ret = EINTR;
10811 } else {
10812 ret = task->aelta_ret;
10813 }
10814 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10815
10816 if (cleanup) {
10817 ahci_em_led_task_free(task);
10818 }
10819
10820 return (ret);
10821 }
10822
10823 static int
10824 ahci_em_ioctl(dev_info_t *dip, int cmd, intptr_t arg)
10825 {
10826 int inst;
10827 ahci_ctl_t *ahci_ctlp;
10828
10829 inst = ddi_get_instance(dip);
10830 if ((ahci_ctlp = ddi_get_soft_state(ahci_statep, inst)) == NULL) {
10831 return (ENXIO);
10832 }
10833
10834 switch (cmd) {
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));
10839 default:
10840 return (ENOTTY);
10841 }
10842
10843 }
10844
10845 static void
10846 ahci_em_quiesce(ahci_ctl_t *ahci_ctlp)
10847 {
10848 ASSERT(ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT);
10849
10850 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10851 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_QUIESCE;
10852 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10853
10854 ddi_taskq_wait(ahci_ctlp->ahcictl_em_taskq);
10855 }
10856
10857 static void
10858 ahci_em_suspend(ahci_ctl_t *ahci_ctlp)
10859 {
10860 ahci_em_quiesce(ahci_ctlp);
10861
10862 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10863 ahci_ctlp->ahcictl_em_flags &= ~AHCI_EM_READY;
10864 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10865 }
10866
10867 static void
10868 ahci_em_resume(ahci_ctl_t *ahci_ctlp)
10869 {
10870 mutex_enter(&ahci_ctlp->ahcictl_mutex);
10871 ahci_ctlp->ahcictl_em_flags |= AHCI_EM_RESETTING;
10872 mutex_exit(&ahci_ctlp->ahcictl_mutex);
10873
10874 (void) ddi_taskq_dispatch(ahci_ctlp->ahcictl_em_taskq, ahci_em_reset,
10875 ahci_ctlp, DDI_SLEEP);
10876 }
10877
10878 static void
10879 ahci_em_fini(ahci_ctl_t *ahci_ctlp)
10880 {
10881 if ((ahci_ctlp->ahcictl_em_flags & AHCI_EM_PRESENT) == 0) {
10882 return;
10883 }
10884
10885 ahci_em_quiesce(ahci_ctlp);
10886 ddi_taskq_destroy(ahci_ctlp->ahcictl_em_taskq);
10887 ahci_ctlp->ahcictl_em_taskq = NULL;
10888 }
|