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 */
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);
|
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 */
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 */
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 /* Simulate the interrupt */
1819 mutex_exit(&ahci_portp->ahciport_mutex);
1820 ahci_port_intr(ahci_ctlp, ahci_portp, port);
1821 mutex_enter(&ahci_portp->ahciport_mutex);
1822
1823 if (spkt->satapkt_reason != SATA_PKT_BUSY)
1824 break;
1825
1826 mutex_exit(&ahci_portp->ahciport_mutex);
1827 drv_usecwait(AHCI_1MS_USECS);
1828 mutex_enter(&ahci_portp->ahciport_mutex);
1829
1830 pkt_timeout_ticks -= AHCI_1MS_TICKS;
1831 if (pkt_timeout_ticks < 0) {
1832 cmn_err(CE_WARN, "!ahci%d: ahci_do_sync_start "
1833 "port %d satapkt 0x%p timed out\n",
1834 instance, port, (void *)spkt);
1835 timeout_tags = (0x1 << rval);
1836 mutex_exit(&ahci_portp->ahciport_mutex);
1837 ahci_timeout_pkts(ahci_ctlp, ahci_portp,
1838 port, timeout_tags);
1839 mutex_enter(&ahci_portp->ahciport_mutex);
1840 }
1841 }
1842
1843 ahci_portp->ahciport_flags &= ~AHCI_PORT_FLAG_POLLING;
1844 return (AHCI_SUCCESS);
1845
1846 } else {
1847 if ((rval = ahci_deliver_satapkt(ahci_ctlp, ahci_portp,
1848 addrp, spkt)) == AHCI_FAILURE)
1849 return (rval);
1850
1851 #if AHCI_DEBUG
1852 /*
1853 * Note that the driver always uses the slot 0 to deliver
1854 * REQUEST SENSE or READ LOG EXT command
1855 */
1856 if (ERR_RETRI_CMD_IN_PROGRESS(ahci_portp))
1857 ASSERT(rval == 0);
1858 #endif
1859
1860 while (spkt->satapkt_reason == SATA_PKT_BUSY)
1861 cv_wait(&ahci_portp->ahciport_cv,
1862 &ahci_portp->ahciport_mutex);
|