^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is provided under a dual BSD/GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * GPL LICENSE SUMMARY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * it under the terms of version 2 of the GNU General Public License as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed in the hope that it will be useful, but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * The full GNU General Public License is included in this distribution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * in the file called LICENSE.GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * BSD LICENSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * * Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * * Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * notice, this list of conditions and the following disclaimer in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * the documentation and/or other materials provided with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * * Neither the name of Intel Corporation nor the names of its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * contributors may be used to endorse or promote products derived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * from this software without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <scsi/sas.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "isci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include "port.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include "remote_device.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include "request.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include "remote_node_context.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include "scu_event_codes.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "task.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define C(a) (#a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const char *dev_state_name(enum sci_remote_device_states state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static const char * const strings[] = REMOTE_DEV_STATES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return strings[state];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #undef C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) enum sci_remote_node_suspension_reasons reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return sci_remote_node_context_suspend(&idev->rnc, reason,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * isci_remote_device_ready() - This function is called by the ihost when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * remote device is ready. We mark the isci device as ready and signal the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * waiting proccess.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * @ihost: our valid isci_host
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * @idev: remote device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) "%s: idev = %p\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) clear_bit(IDEV_IO_NCQERROR, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) set_bit(IDEV_IO_READY, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) wake_up(&ihost->eventq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static enum sci_status sci_remote_device_terminate_req(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int check_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!test_bit(IREQ_ACTIVE, &ireq->flags) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) (ireq->target_device != idev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) (check_abort && !test_bit(IREQ_PENDING_ABORT, &ireq->flags)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) "%s: idev=%p; flags=%lx; req=%p; req target=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) __func__, idev, idev->flags, ireq, ireq->target_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) set_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return sci_controller_terminate_request(ihost, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static enum sci_status sci_remote_device_terminate_reqs_checkabort(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int chk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) enum sci_status status = SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct isci_request *ireq = ihost->reqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) enum sci_status s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) s = sci_remote_device_terminate_req(ihost, idev, chk, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (s != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) status = s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static bool isci_compare_suspendcount(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u32 localcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Check for a change in the suspend count, or the RNC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * being destroyed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return (localcount != idev->rnc.suspend_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) || sci_remote_node_context_is_being_destroyed(&idev->rnc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static bool isci_check_reqterm(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct isci_request *ireq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u32 localcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) bool res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) res = isci_compare_suspendcount(idev, localcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) && !test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static bool isci_check_devempty(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u32 localcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) bool res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) res = isci_compare_suspendcount(idev, localcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) && idev->started_request_count == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) enum sci_status isci_remote_device_terminate_requests(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) enum sci_status status = SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) u32 rnc_suspend_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (isci_get_device(idev) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev_dbg(&ihost->pdev->dev, "%s: failed isci_get_device(idev=%p)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) status = SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* If already suspended, don't wait for another suspension. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) rnc_suspend_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) = sci_remote_node_context_is_suspended(&idev->rnc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ? 0 : idev->rnc.suspend_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) "%s: idev=%p, ireq=%p; started_request_count=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) "rnc_suspend_count=%d, rnc.suspend_count=%d"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) "about to wait\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) __func__, idev, ireq, idev->started_request_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) rnc_suspend_count, idev->rnc.suspend_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define MAX_SUSPEND_MSECS 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (ireq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /* Terminate a specific TC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) set_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) sci_remote_device_terminate_req(ihost, idev, 0, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (!wait_event_timeout(ihost->eventq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) isci_check_reqterm(ihost, idev, ireq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) rnc_suspend_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) msecs_to_jiffies(MAX_SUSPEND_MSECS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_warn(&ihost->pdev->dev, "%s host%d timeout single\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) __func__, ihost->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) "%s: ******* Timeout waiting for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) "suspend; idev=%p, current state %s; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) "started_request_count=%d, flags=%lx\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) "rnc_suspend_count=%d, rnc.suspend_count=%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) "RNC: current state %s, current "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "suspend_type %x dest state %d;\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) "ireq=%p, ireq->flags = %lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) __func__, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dev_state_name(idev->sm.current_state_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) idev->started_request_count, idev->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) rnc_suspend_count, idev->rnc.suspend_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) rnc_state_name(idev->rnc.sm.current_state_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) idev->rnc.suspend_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) idev->rnc.destination_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ireq, ireq->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) clear_bit(IREQ_NO_AUTO_FREE_TAG, &ireq->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!test_bit(IREQ_ABORT_PATH_ACTIVE, &ireq->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) isci_free_tag(ihost, ireq->io_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Terminate all TCs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) sci_remote_device_terminate_requests(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!wait_event_timeout(ihost->eventq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) isci_check_devempty(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) rnc_suspend_count),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) msecs_to_jiffies(MAX_SUSPEND_MSECS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) dev_warn(&ihost->pdev->dev, "%s host%d timeout all\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) __func__, ihost->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) "%s: ******* Timeout waiting for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) "suspend; idev=%p, current state %s; "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) "started_request_count=%d, flags=%lx\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) "rnc_suspend_count=%d, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) "RNC: current state %s, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) "rnc.suspend_count=%d, current "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) "suspend_type %x dest state %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) __func__, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) dev_state_name(idev->sm.current_state_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) idev->started_request_count, idev->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) rnc_suspend_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) rnc_state_name(idev->rnc.sm.current_state_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) idev->rnc.suspend_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) idev->rnc.suspend_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) idev->rnc.destination_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) dev_dbg(&ihost->pdev->dev, "%s: idev=%p, wait done\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) isci_put_device(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * isci_remote_device_not_ready() - This function is called by the ihost when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * the remote device is not ready. We mark the isci device as ready (not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * "ready_for_io") and signal the waiting proccess.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * @isci_host: This parameter specifies the isci host object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @isci_device: This parameter specifies the remote device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * sci_lock is held on entrance to this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void isci_remote_device_not_ready(struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) "%s: isci_device = %p; reason = %d\n", __func__, idev, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) switch (reason) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) set_bit(IDEV_IO_NCQERROR, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Suspend the remote device so the I/O can be terminated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Kill all outstanding requests for the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) sci_remote_device_terminate_requests(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) fallthrough; /* into the default case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) clear_bit(IDEV_IO_READY, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) /* called once the remote node context is ready to be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * The remote device can now report that its stop operation is complete. none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static void rnc_destruct_done(void *_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct isci_remote_device *idev = _dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) BUG_ON(idev->started_request_count != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) sci_change_state(&idev->sm, SCI_DEV_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) enum sci_status sci_remote_device_terminate_requests(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return sci_remote_device_terminate_reqs_checkabort(idev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) case SCI_DEV_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case SCI_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) case SCI_DEV_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case SCI_DEV_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) case SCI_DEV_STARTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) /* device not started so there had better be no requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) BUG_ON(idev->started_request_count != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) sci_remote_node_context_destruct(&idev->rnc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) rnc_destruct_done, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* Transition to the stopping state and wait for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * remote node to complete being posted and invalidated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) sci_change_state(sm, SCI_DEV_STOPPING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case SCI_STP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case SCI_STP_DEV_NCQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) sci_change_state(sm, SCI_DEV_STOPPING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (idev->started_request_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) sci_remote_node_context_destruct(&idev->rnc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) rnc_destruct_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) sci_remote_device_suspend(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) idev, SCI_SW_SUSPEND_LINKHANG_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) sci_remote_device_terminate_requests(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case SCI_DEV_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* All requests should have been terminated, but if there is an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * attempt to stop a device already in the stopping state, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * try again to terminate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return sci_remote_device_terminate_requests(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) case SCI_DEV_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) sci_change_state(sm, SCI_DEV_STOPPING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) enum sci_status sci_remote_device_reset(struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) case SCI_DEV_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) case SCI_DEV_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case SCI_DEV_STARTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) case SCI_DEV_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) case SCI_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) case SCI_DEV_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) case SCI_DEV_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) case SCI_STP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case SCI_STP_DEV_NCQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) sci_change_state(sm, SCI_DEV_RESETTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) enum sci_status sci_remote_device_reset_complete(struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (state != SCI_DEV_RESETTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sci_change_state(sm, SCI_DEV_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) enum sci_status sci_remote_device_frame_handler(struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) u32 frame_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) case SCI_DEV_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) case SCI_DEV_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) case SCI_DEV_STARTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) case SCI_STP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) case SCI_DEV_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* Return the frame back to the controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) sci_controller_release_frame(ihost, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) case SCI_DEV_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) case SCI_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) case SCI_DEV_RESETTING: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct isci_request *ireq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct ssp_frame_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) void *frame_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ssize_t word_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) frame_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) &frame_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) word_cnt = sizeof(hdr) / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) sci_swab32_cpy(&hdr, frame_header, word_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ireq = sci_request_by_tag(ihost, be16_to_cpu(hdr.tag));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (ireq && ireq->target_device == idev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* The IO request is now in charge of releasing the frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) status = sci_io_request_frame_handler(ireq, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* We could not map this tag to a valid IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) * request Just toss the frame and continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) sci_controller_release_frame(ihost, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) case SCI_STP_DEV_NCQ: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct dev_to_host_fis *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) frame_index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) (void **)&hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (hdr->fis_type == FIS_SETDEVBITS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) (hdr->status & ATA_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) idev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* TODO Check sactive and complete associated IO if any. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) sci_change_state(sm, SCI_STP_DEV_NCQ_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } else if (hdr->fis_type == FIS_REGD2H &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) (hdr->status & ATA_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * Some devices return D2H FIS when an NCQ error is detected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * Treat this like an SDB error FIS ready reason.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) idev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) sci_change_state(&idev->sm, SCI_STP_DEV_NCQ_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) status = SCI_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) sci_controller_release_frame(ihost, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* The device does not process any UF received from the hardware while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * in this state. All unsolicited frames are forwarded to the io request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) status = sci_io_request_frame_handler(idev->working_request, frame_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static bool is_remote_device_ready(struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) case SCI_STP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) case SCI_STP_DEV_NCQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * called once the remote node context has transisitioned to a ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) * state (after suspending RX and/or TX due to early D2H fis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static void atapi_remote_device_resume_done(void *_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct isci_remote_device *idev = _dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct isci_request *ireq = idev->working_request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u32 event_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) switch (scu_get_event_type(event_code)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) case SCU_EVENT_TYPE_RNC_OPS_MISC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) status = sci_remote_node_context_event_handler(&idev->rnc, event_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) status = SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) /* Suspend the associated RNC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) sci_remote_device_suspend(idev, SCI_SW_SUSPEND_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) dev_dbg(scirdev_to_dev(idev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) "%s: device: %p event code: %x: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) __func__, idev, event_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) is_remote_device_ready(idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ? "I_T_Nexus_Timeout event"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) : "I_T_Nexus_Timeout event in wrong state");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) fallthrough; /* and treat as unhandled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev_dbg(scirdev_to_dev(idev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) "%s: device: %p event code: %x: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __func__, idev, event_code,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) is_remote_device_ready(idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) ? "unexpected event"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) : "unexpected event in wrong state");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) status = SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* Decode device-specific states that may require an RNC resume during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * normal operation. When the abort path is active, these resumes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * managed when the abort path exits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (state == SCI_STP_DEV_ATAPI_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* For ATAPI error state resume the RNC right away. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return sci_remote_node_context_resume(&idev->rnc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) atapi_remote_device_resume_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) if (state == SCI_STP_DEV_IDLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* We pick up suspension events to handle specifically to this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * state. We resume the RNC right away.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) status = sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) static void sci_remote_device_start_request(struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct isci_request *ireq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) enum sci_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct isci_port *iport = idev->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) /* cleanup requests that failed after starting on the port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) sci_port_complete_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) kref_get(&idev->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) idev->started_request_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) enum sci_status sci_remote_device_start_io(struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct isci_port *iport = idev->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case SCI_DEV_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case SCI_DEV_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case SCI_DEV_STARTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) case SCI_DEV_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) case SCI_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) case SCI_DEV_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case SCI_DEV_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* attempt to start an io request for this device object. The remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * device object will issue the start request for the io and if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * successful it will start the request for the port object then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * increment its own request count.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) status = sci_port_start_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) status = sci_remote_node_context_start_io(&idev->rnc, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) status = sci_request_start(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case SCI_STP_DEV_IDLE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* handle the start io operation for a sata device that is in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * the command idle state. - Evalute the type of IO request to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * be started - If its an NCQ request change to NCQ substate -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * If its any other command change to the CMD substate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * If this is a softreset we may want to have a different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * substate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) enum sci_remote_device_states new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct sas_task *task = isci_request_access_task(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) status = sci_port_start_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) status = sci_remote_node_context_start_io(&idev->rnc, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) status = sci_request_start(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (task->ata_task.use_ncq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) new_state = SCI_STP_DEV_NCQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) idev->working_request = ireq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) new_state = SCI_STP_DEV_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) sci_change_state(sm, new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case SCI_STP_DEV_NCQ: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct sas_task *task = isci_request_access_task(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (task->ata_task.use_ncq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) status = sci_port_start_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) status = sci_remote_node_context_start_io(&idev->rnc, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) status = sci_request_start(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) status = sci_port_start_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) status = sci_remote_node_context_start_io(&idev->rnc, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) status = sci_request_start(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) idev->working_request = ireq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) sci_change_state(&idev->sm, SCI_SMP_DEV_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) /* device is already handling a command it can not accept new commands
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) * until this one is complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) sci_remote_device_start_request(idev, ireq, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static enum sci_status common_complete_io(struct isci_port *iport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) status = sci_request_complete(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) status = sci_port_complete_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) sci_remote_device_decrement_request_count(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) enum sci_status sci_remote_device_complete_io(struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct isci_port *iport = idev->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) case SCI_DEV_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case SCI_DEV_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case SCI_DEV_STARTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) case SCI_STP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) case SCI_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) case SCI_DEV_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case SCI_DEV_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) status = common_complete_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) case SCI_STP_DEV_NCQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case SCI_STP_DEV_ATAPI_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) status = common_complete_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (ireq->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* This request causes hardware error, device needs to be Lun Reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) * So here we force the state machine to IDLE state so the rest IOs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * can reach RNC state handler, these IOs will be completed by RNC with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) sci_change_state(sm, SCI_STP_DEV_AWAIT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) } else if (idev->started_request_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) sci_change_state(sm, SCI_STP_DEV_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) status = common_complete_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) sci_change_state(sm, SCI_SMP_DEV_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case SCI_DEV_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) status = common_complete_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (idev->started_request_count == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) sci_remote_node_context_destruct(&idev->rnc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) rnc_destruct_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dev_err(scirdev_to_dev(idev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) "%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) "could not complete\n", __func__, iport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) idev, ireq, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) isci_put_device(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static void sci_remote_device_continue_request(void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) struct isci_remote_device *idev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) /* we need to check if this request is still valid to continue. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (idev->working_request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) sci_controller_continue_io(idev->working_request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct isci_port *iport = idev->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case SCI_DEV_INITIAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) case SCI_DEV_STOPPED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) case SCI_DEV_STARTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) case SCI_SMP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) case SCI_SMP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) case SCI_DEV_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) case SCI_DEV_FAILED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case SCI_DEV_RESETTING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case SCI_DEV_FINAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case SCI_STP_DEV_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case SCI_STP_DEV_CMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) case SCI_STP_DEV_NCQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) case SCI_STP_DEV_NCQ_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) case SCI_STP_DEV_AWAIT_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) status = sci_port_start_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) status = sci_request_start(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Note: If the remote device state is not IDLE this will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) * replace the request that probably resulted in the task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) * management request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) idev->working_request = ireq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) sci_change_state(sm, SCI_STP_DEV_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* The remote node context must cleanup the TCi to NCQ mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * table. The only way to do this correctly is to either write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * to the TLCR register or to invalidate and repost the RNC. In
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * either case the remote node context state machine will take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * the correct action when the remote node context is suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * and later resumed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) sci_remote_device_suspend(idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) SCI_SW_SUSPEND_LINKHANG_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) status = sci_remote_node_context_start_task(&idev->rnc, ireq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) sci_remote_device_continue_request, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) sci_remote_device_start_request(idev, ireq, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* We need to let the controller start request handler know that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * it can't post TC yet. We will provide a callback function to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) * post TC when RNC gets resumed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) case SCI_DEV_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) status = sci_port_start_io(iport, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) /* Resume the RNC as needed: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) status = sci_remote_node_context_start_task(&idev->rnc, ireq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) status = sci_request_start(ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) sci_remote_device_start_request(idev, ireq, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) void sci_remote_device_post_request(struct isci_remote_device *idev, u32 request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) struct isci_port *iport = idev->owning_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) u32 context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) context = request |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) (iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) idev->rnc.remote_node_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) sci_controller_post_request(iport->owning_controller, context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) /* called once the remote node context has transisitioned to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * ready state. This is the indication that the remote device object can also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * transition to ready.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) static void remote_device_resume_done(void *_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct isci_remote_device *idev = _dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (is_remote_device_ready(idev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* go 'ready' if we are not already in a ready state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) sci_change_state(&idev->sm, SCI_DEV_READY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) static void sci_stp_remote_device_ready_idle_substate_resume_complete_handler(void *_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct isci_remote_device *idev = _dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) /* For NCQ operation we do not issue a isci_remote_device_not_ready().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * As a result, avoid sending the ready notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (idev->sm.previous_state_id != SCI_STP_DEV_NCQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) isci_remote_device_ready(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) static void sci_remote_device_initial_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) /* Initial state is a transitional state to the stopped state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) sci_change_state(&idev->sm, SCI_DEV_STOPPED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) * sci_remote_device_destruct() - free remote node context and destruct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * @remote_device: This parameter specifies the remote device to be destructed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * Remote device objects are a limited resource. As such, they must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * protected. Thus calls to construct and destruct are mutually exclusive and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * non-reentrant. The return value shall indicate if the device was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * successfully destructed or if some failure occurred. enum sci_status This value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) * is returned if the device is successfully destructed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * SCI_FAILURE_INVALID_REMOTE_DEVICE This value is returned if the supplied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * device isn't valid (e.g. it's already been destoryed, the handle isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * valid, etc.).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static enum sci_status sci_remote_device_destruct(struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct isci_host *ihost;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (state != SCI_DEV_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) sci_controller_free_remote_node_context(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) idev->rnc.remote_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) idev->rnc.remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) sci_change_state(sm, SCI_DEV_FINAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) * isci_remote_device_deconstruct() - This function frees an isci_remote_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) * @ihost: This parameter specifies the isci host object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * @idev: This parameter specifies the remote device to be freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) static void isci_remote_device_deconstruct(struct isci_host *ihost, struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) "%s: isci_device = %p\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* There should not be any outstanding io's. All paths to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * here should go through isci_remote_device_nuke_requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * If we hit this condition, we will need a way to complete
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * io requests in process */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) BUG_ON(idev->started_request_count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) sci_remote_device_destruct(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) list_del_init(&idev->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) isci_put_device(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static void sci_remote_device_stopped_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) u32 prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* If we are entering from the stopping state let the SCI User know that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * the stop operation has completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) prev_state = idev->sm.previous_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) if (prev_state == SCI_DEV_STOPPING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) isci_remote_device_deconstruct(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) sci_controller_remote_device_stopped(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static void sci_remote_device_starting_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) isci_remote_device_not_ready(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static void sci_remote_device_ready_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) struct domain_device *dev = idev->domain_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (dev->dev_type == SAS_SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) sci_change_state(&idev->sm, SCI_STP_DEV_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) } else if (dev_is_expander(dev->dev_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) sci_change_state(&idev->sm, SCI_SMP_DEV_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) isci_remote_device_ready(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) static void sci_remote_device_ready_state_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct domain_device *dev = idev->domain_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (dev->dev_type == SAS_END_DEVICE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) isci_remote_device_not_ready(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void sci_remote_device_resetting_state_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) "%s: isci_device = %p\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) "%s: isci_device = %p\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static void sci_stp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) idev->working_request = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (sci_remote_node_context_is_ready(&idev->rnc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) * Since the RNC is ready, it's alright to finish completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * processing (e.g. signal the remote device is ready). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) sci_stp_remote_device_ready_idle_substate_resume_complete_handler(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) sci_remote_node_context_resume(&idev->rnc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) sci_stp_remote_device_ready_idle_substate_resume_complete_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) static void sci_stp_remote_device_ready_cmd_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) BUG_ON(idev->working_request == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) isci_remote_device_not_ready(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static void sci_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (idev->not_ready_reason == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) isci_remote_device_not_ready(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) idev->not_ready_reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) isci_remote_device_ready(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static void sci_smp_remote_device_ready_cmd_substate_enter(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) BUG_ON(idev->working_request == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) isci_remote_device_not_ready(ihost, idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static void sci_smp_remote_device_ready_cmd_substate_exit(struct sci_base_state_machine *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) idev->working_request = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static const struct sci_base_state sci_remote_device_state_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) [SCI_DEV_INITIAL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) .enter_state = sci_remote_device_initial_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) [SCI_DEV_STOPPED] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) .enter_state = sci_remote_device_stopped_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) [SCI_DEV_STARTING] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) .enter_state = sci_remote_device_starting_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) [SCI_DEV_READY] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) .enter_state = sci_remote_device_ready_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) .exit_state = sci_remote_device_ready_state_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) [SCI_STP_DEV_IDLE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .enter_state = sci_stp_remote_device_ready_idle_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) [SCI_STP_DEV_CMD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .enter_state = sci_stp_remote_device_ready_cmd_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) [SCI_STP_DEV_NCQ] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) [SCI_STP_DEV_NCQ_ERROR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) .enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) [SCI_STP_DEV_ATAPI_ERROR] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) [SCI_STP_DEV_AWAIT_RESET] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) [SCI_SMP_DEV_IDLE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) .enter_state = sci_smp_remote_device_ready_idle_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) [SCI_SMP_DEV_CMD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) .enter_state = sci_smp_remote_device_ready_cmd_substate_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .exit_state = sci_smp_remote_device_ready_cmd_substate_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) [SCI_DEV_STOPPING] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) [SCI_DEV_FAILED] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) [SCI_DEV_RESETTING] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) .enter_state = sci_remote_device_resetting_state_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) .exit_state = sci_remote_device_resetting_state_exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) [SCI_DEV_FINAL] = { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * sci_remote_device_construct() - common construction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) * @sci_port: SAS/SATA port through which this device is accessed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * @sci_dev: remote device to construct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * This routine just performs benign initialization and does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * allocate the remote_node_context which is left to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * sci_remote_device_[de]a_construct(). sci_remote_device_destruct()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * frees the remote_node_context(s) for the device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static void sci_remote_device_construct(struct isci_port *iport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) idev->owning_port = iport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) idev->started_request_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) sci_init_sm(&idev->sm, sci_remote_device_state_table, SCI_DEV_INITIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) sci_remote_node_context_construct(&idev->rnc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) * sci_remote_device_da_construct() - construct direct attached device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) * The information (e.g. IAF, Signature FIS, etc.) necessary to build
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) * the device is known to the SCI Core since it is contained in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) * sci_phy object. Remote node context(s) is/are a global resource
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * allocated by this routine, freed by sci_remote_device_destruct().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * sata-only controller instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static enum sci_status sci_remote_device_da_construct(struct isci_port *iport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct sci_port_properties properties;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) sci_remote_device_construct(iport, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) sci_port_get_properties(iport, &properties);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) /* Get accurate port width from port's phy mask for a DA device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) idev->device_port_width = hweight32(properties.phy_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) status = sci_controller_allocate_remote_node_context(iport->owning_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) &idev->rnc.remote_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) idev->connection_rate = sci_port_get_max_allowed_speed(iport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * sci_remote_device_ea_construct() - construct expander attached device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * Remote node context(s) is/are a global resource allocated by this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) * routine, freed by sci_remote_device_destruct().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) * Returns:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) * sata-only controller instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static enum sci_status sci_remote_device_ea_construct(struct isci_port *iport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct domain_device *dev = idev->domain_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) sci_remote_device_construct(iport, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) status = sci_controller_allocate_remote_node_context(iport->owning_controller,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) &idev->rnc.remote_node_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /* For SAS-2 the physical link rate is actually a logical link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * rate that incorporates multiplexing. The SCU doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * incorporate multiplexing and for the purposes of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * connection the logical link rate is that same as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * one another, so this code works for both situations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) idev->connection_rate = min_t(u16, sci_port_get_max_allowed_speed(iport),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dev->linkrate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /* / @todo Should I assign the port width by reading all of the phys on the port? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) idev->device_port_width = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) enum sci_status sci_remote_device_resume(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) scics_sds_remote_node_context_callback cb_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) void *cb_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) status = sci_remote_node_context_resume(&idev->rnc, cb_fn, cb_p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) dev_dbg(scirdev_to_dev(idev), "%s: failed to resume: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static void isci_remote_device_resume_from_abort_complete(void *cbparam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) struct isci_remote_device *idev = cbparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct isci_host *ihost = idev->owning_port->owning_controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) scics_sds_remote_node_context_callback abort_resume_cb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) idev->abort_resume_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) dev_dbg(scirdev_to_dev(idev), "%s: passing-along resume: %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) __func__, abort_resume_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (abort_resume_cb != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) idev->abort_resume_cb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) abort_resume_cb(idev->abort_resume_cbparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) wake_up(&ihost->eventq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static bool isci_remote_device_test_resume_done(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) bool done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) done = !test_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) || test_bit(IDEV_STOP_PENDING, &idev->flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) || sci_remote_node_context_is_being_destroyed(&idev->rnc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) void isci_remote_device_wait_for_resume_from_abort(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) dev_dbg(&ihost->pdev->dev, "%s: starting resume wait: %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) #define MAX_RESUME_MSECS 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (!wait_event_timeout(ihost->eventq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) isci_remote_device_test_resume_done(ihost, idev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) msecs_to_jiffies(MAX_RESUME_MSECS))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) dev_warn(&ihost->pdev->dev, "%s: #### Timeout waiting for "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) "resume: %p\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) dev_dbg(&ihost->pdev->dev, "%s: resume wait done: %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) enum sci_status isci_remote_device_resume_from_abort(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) enum sci_status status = SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) int destroyed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) /* Preserve any current resume callbacks, for instance from other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) * resumptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) idev->abort_resume_cb = idev->rnc.user_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) idev->abort_resume_cbparam = idev->rnc.user_cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) set_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) clear_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) destroyed = sci_remote_node_context_is_being_destroyed(&idev->rnc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (!destroyed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) status = sci_remote_device_resume(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) idev, isci_remote_device_resume_from_abort_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (!destroyed && (status == SCI_SUCCESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) isci_remote_device_wait_for_resume_from_abort(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) clear_bit(IDEV_ABORT_PATH_RESUME_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * sci_remote_device_start() - This method will start the supplied remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) * device. This method enables normal IO requests to flow through to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * remote device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) * @remote_device: This parameter specifies the device to be started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) * @timeout: This parameter specifies the number of milliseconds in which the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) * start operation should complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) * An indication of whether the device was successfully started. SCI_SUCCESS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * This value is returned if the device was successfully started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * SCI_FAILURE_INVALID_PHY This value is returned if the user attempts to start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * the device when there have been no phys added to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) static enum sci_status sci_remote_device_start(struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) struct sci_base_state_machine *sm = &idev->sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) enum sci_remote_device_states state = sm->current_state_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) if (state != SCI_DEV_STOPPED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) __func__, dev_state_name(state));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) return SCI_FAILURE_INVALID_STATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) status = sci_remote_device_resume(idev, remote_device_resume_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) sci_change_state(sm, SCI_DEV_STARTING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) return SCI_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) static enum sci_status isci_remote_device_construct(struct isci_port *iport,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) struct isci_host *ihost = iport->isci_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) struct domain_device *dev = idev->domain_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (dev->parent && dev_is_expander(dev->parent->dev_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) status = sci_remote_device_ea_construct(iport, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) status = sci_remote_device_da_construct(iport, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (status != SCI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) dev_dbg(&ihost->pdev->dev, "%s: construct failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) __func__, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /* start the device. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) status = sci_remote_device_start(idev, ISCI_REMOTE_DEVICE_START_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) dev_warn(&ihost->pdev->dev, "remote device start failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) * This function builds the isci_remote_device when a libsas dev_found message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) * is received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) * @isci_host: This parameter specifies the isci host object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) * @port: This parameter specifies the isci_port connected to this device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) * pointer to new isci_remote_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static struct isci_remote_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) isci_remote_device_alloc(struct isci_host *ihost, struct isci_port *iport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) struct isci_remote_device *idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) idev = &ihost->devices[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (!test_and_set_bit(IDEV_ALLOCATED, &idev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (i >= SCI_MAX_REMOTE_DEVICES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) dev_warn(&ihost->pdev->dev, "%s: failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (WARN_ONCE(!list_empty(&idev->node), "found non-idle remote device\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) return idev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) void isci_remote_device_release(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) struct isci_remote_device *idev = container_of(kref, typeof(*idev), kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) struct isci_host *ihost = idev->isci_port->isci_host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) idev->domain_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) idev->isci_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) clear_bit(IDEV_START_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) clear_bit(IDEV_STOP_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) clear_bit(IDEV_IO_READY, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) clear_bit(IDEV_GONE, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) smp_mb__before_atomic();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) clear_bit(IDEV_ALLOCATED, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) wake_up(&ihost->eventq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) * isci_remote_device_stop() - This function is called internally to stop the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) * remote device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) * @isci_host: This parameter specifies the isci host object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) * @isci_device: This parameter specifies the remote device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) * The status of the ihost request to stop.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) "%s: isci_device = %p\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) idev->domain_dev->lldd_dev = NULL; /* disable new lookups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) set_bit(IDEV_GONE, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) set_bit(IDEV_STOP_PENDING, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) status = sci_remote_device_stop(idev, 50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) /* Wait for the stop complete callback. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (WARN_ONCE(status != SCI_SUCCESS, "failed to stop device\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) /* nothing to wait for */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) wait_for_device_stop(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) "%s: isci_device = %p, waiting done.\n", __func__, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) * isci_remote_device_gone() - This function is called by libsas when a domain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) * device is removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) * @domain_device: This parameter specifies the libsas domain device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) void isci_remote_device_gone(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) struct isci_host *ihost = dev_to_ihost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) struct isci_remote_device *idev = dev->lldd_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) "%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) __func__, dev, idev, idev->isci_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) isci_remote_device_stop(ihost, idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) * isci_remote_device_found() - This function is called by libsas when a remote
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) * device is discovered. A remote device object is created and started. the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) * function then sleeps until the sci core device started message is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) * received.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) * @domain_device: This parameter specifies the libsas domain device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) * status, zero indicates success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) int isci_remote_device_found(struct domain_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) struct isci_host *isci_host = dev_to_ihost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) struct isci_port *isci_port = dev->port->lldd_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) struct isci_remote_device *isci_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) dev_dbg(&isci_host->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) "%s: domain_device = %p\n", __func__, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (!isci_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) isci_device = isci_remote_device_alloc(isci_host, isci_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (!isci_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) kref_init(&isci_device->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) INIT_LIST_HEAD(&isci_device->node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) spin_lock_irq(&isci_host->scic_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) isci_device->domain_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) isci_device->isci_port = isci_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) set_bit(IDEV_START_PENDING, &isci_device->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) status = isci_remote_device_construct(isci_port, isci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) dev_dbg(&isci_host->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) "%s: isci_device = %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) __func__, isci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (status == SCI_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* device came up, advertise it to the world */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) dev->lldd_dev = isci_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) isci_put_device(isci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) spin_unlock_irq(&isci_host->scic_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) /* wait for the device ready callback. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) wait_for_device_start(isci_host, isci_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) return status == SCI_SUCCESS ? 0 : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) enum sci_status isci_remote_device_suspend_terminate(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct isci_request *ireq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* Put the device into suspension. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) set_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) sci_remote_device_suspend(idev, SCI_SW_SUSPEND_LINKHANG_DETECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) /* Terminate and wait for the completions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) status = isci_remote_device_terminate_requests(ihost, idev, ireq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) if (status != SCI_SUCCESS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) dev_dbg(&ihost->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) "%s: isci_remote_device_terminate_requests(%p) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) "returned %d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) __func__, idev, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /* NOTE: RNC resumption is left to the caller! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) int isci_remote_device_is_safe_to_abort(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) return sci_remote_node_context_is_safe_to_abort(&idev->rnc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) enum sci_status sci_remote_device_abort_requests_pending_abort(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) return sci_remote_device_terminate_reqs_checkabort(idev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) enum sci_status isci_remote_device_reset_complete(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) struct isci_host *ihost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct isci_remote_device *idev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) enum sci_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) spin_lock_irqsave(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) status = sci_remote_device_reset_complete(idev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) spin_unlock_irqrestore(&ihost->scic_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) void isci_dev_set_hang_detection_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) struct isci_remote_device *idev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) u32 timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) if (dev_is_sata(idev->domain_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (test_and_set_bit(IDEV_RNC_LLHANG_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) &idev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) return; /* Already enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) } else if (!test_and_clear_bit(IDEV_RNC_LLHANG_ENABLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) &idev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) return; /* Not enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) sci_port_set_hang_detection_timeout(idev->owning_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }