Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is provided under a dual BSD/GPLv2 license.  When using or
0003  * redistributing this file, you may do so under either license.
0004  *
0005  * GPL LICENSE SUMMARY
0006  *
0007  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
0008  *
0009  * This program is free software; you can redistribute it and/or modify
0010  * it under the terms of version 2 of the GNU General Public License as
0011  * published by the Free Software Foundation.
0012  *
0013  * This program is distributed in the hope that it will be useful, but
0014  * WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU General Public License
0019  * along with this program; if not, write to the Free Software
0020  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
0021  * The full GNU General Public License is included in this distribution
0022  * in the file called LICENSE.GPL.
0023  *
0024  * BSD LICENSE
0025  *
0026  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
0027  * All rights reserved.
0028  *
0029  * Redistribution and use in source and binary forms, with or without
0030  * modification, are permitted provided that the following conditions
0031  * are met:
0032  *
0033  *   * Redistributions of source code must retain the above copyright
0034  *     notice, this list of conditions and the following disclaimer.
0035  *   * Redistributions in binary form must reproduce the above copyright
0036  *     notice, this list of conditions and the following disclaimer in
0037  *     the documentation and/or other materials provided with the
0038  *     distribution.
0039  *   * Neither the name of Intel Corporation nor the names of its
0040  *     contributors may be used to endorse or promote products derived
0041  *     from this software without specific prior written permission.
0042  *
0043  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0044  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0045  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0046  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0047  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0048  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0049  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0050  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0051  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0052  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0053  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0054  */
0055 #include <scsi/sas_ata.h>
0056 #include "host.h"
0057 #include "isci.h"
0058 #include "remote_device.h"
0059 #include "remote_node_context.h"
0060 #include "scu_event_codes.h"
0061 #include "scu_task_context.h"
0062 
0063 #undef C
0064 #define C(a) (#a)
0065 const char *rnc_state_name(enum scis_sds_remote_node_context_states state)
0066 {
0067     static const char * const strings[] = RNC_STATES;
0068 
0069     if (state >= ARRAY_SIZE(strings))
0070         return "UNKNOWN";
0071 
0072     return strings[state];
0073 }
0074 #undef C
0075 
0076 /**
0077  * sci_remote_node_context_is_ready()
0078  * @sci_rnc: The state of the remote node context object to check.
0079  *
0080  * This method will return true if the remote node context is in a READY state
0081  * otherwise it will return false bool true if the remote node context is in
0082  * the ready state. false if the remote node context is not in the ready state.
0083  */
0084 bool sci_remote_node_context_is_ready(
0085     struct sci_remote_node_context *sci_rnc)
0086 {
0087     u32 current_state = sci_rnc->sm.current_state_id;
0088 
0089     if (current_state == SCI_RNC_READY) {
0090         return true;
0091     }
0092 
0093     return false;
0094 }
0095 
0096 bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc)
0097 {
0098     u32 current_state = sci_rnc->sm.current_state_id;
0099 
0100     if (current_state == SCI_RNC_TX_RX_SUSPENDED)
0101         return true;
0102     return false;
0103 }
0104 
0105 static union scu_remote_node_context *sci_rnc_by_id(struct isci_host *ihost, u16 id)
0106 {
0107     if (id < ihost->remote_node_entries &&
0108         ihost->device_table[id])
0109         return &ihost->remote_node_context_table[id];
0110 
0111     return NULL;
0112 }
0113 
0114 static void sci_remote_node_context_construct_buffer(struct sci_remote_node_context *sci_rnc)
0115 {
0116     struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0117     struct domain_device *dev = idev->domain_dev;
0118     int rni = sci_rnc->remote_node_index;
0119     union scu_remote_node_context *rnc;
0120     struct isci_host *ihost;
0121     __le64 sas_addr;
0122 
0123     ihost = idev->owning_port->owning_controller;
0124     rnc = sci_rnc_by_id(ihost, rni);
0125 
0126     memset(rnc, 0, sizeof(union scu_remote_node_context)
0127         * sci_remote_device_node_count(idev));
0128 
0129     rnc->ssp.remote_node_index = rni;
0130     rnc->ssp.remote_node_port_width = idev->device_port_width;
0131     rnc->ssp.logical_port_index = idev->owning_port->physical_port_index;
0132 
0133     /* sas address is __be64, context ram format is __le64 */
0134     sas_addr = cpu_to_le64(SAS_ADDR(dev->sas_addr));
0135     rnc->ssp.remote_sas_address_hi = upper_32_bits(sas_addr);
0136     rnc->ssp.remote_sas_address_lo = lower_32_bits(sas_addr);
0137 
0138     rnc->ssp.nexus_loss_timer_enable = true;
0139     rnc->ssp.check_bit               = false;
0140     rnc->ssp.is_valid                = false;
0141     rnc->ssp.is_remote_node_context  = true;
0142     rnc->ssp.function_number         = 0;
0143 
0144     rnc->ssp.arbitration_wait_time = 0;
0145 
0146     if (dev_is_sata(dev)) {
0147         rnc->ssp.connection_occupancy_timeout =
0148             ihost->user_parameters.stp_max_occupancy_timeout;
0149         rnc->ssp.connection_inactivity_timeout =
0150             ihost->user_parameters.stp_inactivity_timeout;
0151     } else {
0152         rnc->ssp.connection_occupancy_timeout  =
0153             ihost->user_parameters.ssp_max_occupancy_timeout;
0154         rnc->ssp.connection_inactivity_timeout =
0155             ihost->user_parameters.ssp_inactivity_timeout;
0156     }
0157 
0158     rnc->ssp.initial_arbitration_wait_time = 0;
0159 
0160     /* Open Address Frame Parameters */
0161     rnc->ssp.oaf_connection_rate = idev->connection_rate;
0162     rnc->ssp.oaf_features = 0;
0163     rnc->ssp.oaf_source_zone_group = 0;
0164     rnc->ssp.oaf_more_compatibility_features = 0;
0165 }
0166 /*
0167  * This method will setup the remote node context object so it will transition
0168  * to its ready state.  If the remote node context is already setup to
0169  * transition to its final state then this function does nothing. none
0170  */
0171 static void sci_remote_node_context_setup_to_resume(
0172     struct sci_remote_node_context *sci_rnc,
0173     scics_sds_remote_node_context_callback callback,
0174     void *callback_parameter,
0175     enum sci_remote_node_context_destination_state dest_param)
0176 {
0177     if (sci_rnc->destination_state != RNC_DEST_FINAL) {
0178         sci_rnc->destination_state = dest_param;
0179         if (callback != NULL) {
0180             sci_rnc->user_callback = callback;
0181             sci_rnc->user_cookie   = callback_parameter;
0182         }
0183     }
0184 }
0185 
0186 static void sci_remote_node_context_setup_to_destroy(
0187     struct sci_remote_node_context *sci_rnc,
0188     scics_sds_remote_node_context_callback callback,
0189     void *callback_parameter)
0190 {
0191     struct isci_host *ihost = idev_to_ihost(rnc_to_dev(sci_rnc));
0192 
0193     sci_rnc->destination_state = RNC_DEST_FINAL;
0194     sci_rnc->user_callback     = callback;
0195     sci_rnc->user_cookie       = callback_parameter;
0196 
0197     wake_up(&ihost->eventq);
0198 }
0199 
0200 /*
0201  * This method just calls the user callback function and then resets the
0202  * callback.
0203  */
0204 static void sci_remote_node_context_notify_user(
0205     struct sci_remote_node_context *rnc)
0206 {
0207     if (rnc->user_callback != NULL) {
0208         (*rnc->user_callback)(rnc->user_cookie);
0209 
0210         rnc->user_callback = NULL;
0211         rnc->user_cookie = NULL;
0212     }
0213 }
0214 
0215 static void sci_remote_node_context_continue_state_transitions(struct sci_remote_node_context *rnc)
0216 {
0217     switch (rnc->destination_state) {
0218     case RNC_DEST_READY:
0219     case RNC_DEST_SUSPENDED_RESUME:
0220         rnc->destination_state = RNC_DEST_READY;
0221         fallthrough;
0222     case RNC_DEST_FINAL:
0223         sci_remote_node_context_resume(rnc, rnc->user_callback,
0224                            rnc->user_cookie);
0225         break;
0226     default:
0227         rnc->destination_state = RNC_DEST_UNSPECIFIED;
0228         break;
0229     }
0230 }
0231 
0232 static void sci_remote_node_context_validate_context_buffer(struct sci_remote_node_context *sci_rnc)
0233 {
0234     union scu_remote_node_context *rnc_buffer;
0235     struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0236     struct domain_device *dev = idev->domain_dev;
0237     struct isci_host *ihost = idev->owning_port->owning_controller;
0238 
0239     rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index);
0240 
0241     rnc_buffer->ssp.is_valid = true;
0242 
0243     if (dev_is_sata(dev) && dev->parent) {
0244         sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_96);
0245     } else {
0246         sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_32);
0247 
0248         if (!dev->parent)
0249             sci_port_setup_transports(idev->owning_port,
0250                           sci_rnc->remote_node_index);
0251     }
0252 }
0253 
0254 static void sci_remote_node_context_invalidate_context_buffer(struct sci_remote_node_context *sci_rnc)
0255 {
0256     union scu_remote_node_context *rnc_buffer;
0257     struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0258     struct isci_host *ihost = idev->owning_port->owning_controller;
0259 
0260     rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index);
0261 
0262     rnc_buffer->ssp.is_valid = false;
0263 
0264     sci_remote_device_post_request(rnc_to_dev(sci_rnc),
0265                        SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE);
0266 }
0267 
0268 static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm)
0269 {
0270     struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0271     struct isci_remote_device *idev = rnc_to_dev(rnc);
0272     struct isci_host *ihost = idev->owning_port->owning_controller;
0273 
0274     /* Check to see if we have gotten back to the initial state because
0275      * someone requested to destroy the remote node context object.
0276      */
0277     if (sm->previous_state_id == SCI_RNC_INVALIDATING) {
0278         rnc->destination_state = RNC_DEST_UNSPECIFIED;
0279         sci_remote_node_context_notify_user(rnc);
0280 
0281         smp_wmb();
0282         wake_up(&ihost->eventq);
0283     }
0284 }
0285 
0286 static void sci_remote_node_context_posting_state_enter(struct sci_base_state_machine *sm)
0287 {
0288     struct sci_remote_node_context *sci_rnc = container_of(sm, typeof(*sci_rnc), sm);
0289 
0290     sci_remote_node_context_validate_context_buffer(sci_rnc);
0291 }
0292 
0293 static void sci_remote_node_context_invalidating_state_enter(struct sci_base_state_machine *sm)
0294 {
0295     struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0296 
0297     /* Terminate all outstanding requests. */
0298     sci_remote_device_terminate_requests(rnc_to_dev(rnc));
0299     sci_remote_node_context_invalidate_context_buffer(rnc);
0300 }
0301 
0302 static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_machine *sm)
0303 {
0304     struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0305     struct isci_remote_device *idev;
0306     struct domain_device *dev;
0307 
0308     idev = rnc_to_dev(rnc);
0309     dev = idev->domain_dev;
0310 
0311     /*
0312      * For direct attached SATA devices we need to clear the TLCR
0313      * NCQ to TCi tag mapping on the phy and in cases where we
0314      * resume because of a target reset we also need to update
0315      * the STPTLDARNI register with the RNi of the device
0316      */
0317     if (dev_is_sata(dev) && !dev->parent)
0318         sci_port_setup_transports(idev->owning_port, rnc->remote_node_index);
0319 
0320     sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_RESUME);
0321 }
0322 
0323 static void sci_remote_node_context_ready_state_enter(struct sci_base_state_machine *sm)
0324 {
0325     struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0326     enum sci_remote_node_context_destination_state dest_select;
0327     int tell_user = 1;
0328 
0329     dest_select = rnc->destination_state;
0330     rnc->destination_state = RNC_DEST_UNSPECIFIED;
0331 
0332     if ((dest_select == RNC_DEST_SUSPENDED) ||
0333         (dest_select == RNC_DEST_SUSPENDED_RESUME)) {
0334         sci_remote_node_context_suspend(
0335             rnc, rnc->suspend_reason,
0336             SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT);
0337 
0338         if (dest_select == RNC_DEST_SUSPENDED_RESUME)
0339             tell_user = 0;  /* Wait until ready again. */
0340     }
0341     if (tell_user)
0342         sci_remote_node_context_notify_user(rnc);
0343 }
0344 
0345 static void sci_remote_node_context_tx_suspended_state_enter(struct sci_base_state_machine *sm)
0346 {
0347     struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0348 
0349     sci_remote_node_context_continue_state_transitions(rnc);
0350 }
0351 
0352 static void sci_remote_node_context_tx_rx_suspended_state_enter(struct sci_base_state_machine *sm)
0353 {
0354     struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0355     struct isci_remote_device *idev = rnc_to_dev(rnc);
0356     struct isci_host *ihost = idev->owning_port->owning_controller;
0357     u32 new_count = rnc->suspend_count + 1;
0358 
0359     if (new_count == 0)
0360         rnc->suspend_count = 1;
0361     else
0362         rnc->suspend_count = new_count;
0363     smp_wmb();
0364 
0365     /* Terminate outstanding requests pending abort. */
0366     sci_remote_device_abort_requests_pending_abort(idev);
0367 
0368     wake_up(&ihost->eventq);
0369     sci_remote_node_context_continue_state_transitions(rnc);
0370 }
0371 
0372 static void sci_remote_node_context_await_suspend_state_exit(
0373     struct sci_base_state_machine *sm)
0374 {
0375     struct sci_remote_node_context *rnc
0376         = container_of(sm, typeof(*rnc), sm);
0377     struct isci_remote_device *idev = rnc_to_dev(rnc);
0378 
0379     if (dev_is_sata(idev->domain_dev))
0380         isci_dev_set_hang_detection_timeout(idev, 0);
0381 }
0382 
0383 static const struct sci_base_state sci_remote_node_context_state_table[] = {
0384     [SCI_RNC_INITIAL] = {
0385         .enter_state = sci_remote_node_context_initial_state_enter,
0386     },
0387     [SCI_RNC_POSTING] = {
0388         .enter_state = sci_remote_node_context_posting_state_enter,
0389     },
0390     [SCI_RNC_INVALIDATING] = {
0391         .enter_state = sci_remote_node_context_invalidating_state_enter,
0392     },
0393     [SCI_RNC_RESUMING] = {
0394         .enter_state = sci_remote_node_context_resuming_state_enter,
0395     },
0396     [SCI_RNC_READY] = {
0397         .enter_state = sci_remote_node_context_ready_state_enter,
0398     },
0399     [SCI_RNC_TX_SUSPENDED] = {
0400         .enter_state = sci_remote_node_context_tx_suspended_state_enter,
0401     },
0402     [SCI_RNC_TX_RX_SUSPENDED] = {
0403         .enter_state = sci_remote_node_context_tx_rx_suspended_state_enter,
0404     },
0405     [SCI_RNC_AWAIT_SUSPENSION] = {
0406         .exit_state = sci_remote_node_context_await_suspend_state_exit,
0407     },
0408 };
0409 
0410 void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
0411                         u16 remote_node_index)
0412 {
0413     memset(rnc, 0, sizeof(struct sci_remote_node_context));
0414 
0415     rnc->remote_node_index = remote_node_index;
0416     rnc->destination_state = RNC_DEST_UNSPECIFIED;
0417 
0418     sci_init_sm(&rnc->sm, sci_remote_node_context_state_table, SCI_RNC_INITIAL);
0419 }
0420 
0421 enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc,
0422                                u32 event_code)
0423 {
0424     enum scis_sds_remote_node_context_states state;
0425     u32 next_state;
0426 
0427     state = sci_rnc->sm.current_state_id;
0428     switch (state) {
0429     case SCI_RNC_POSTING:
0430         switch (scu_get_event_code(event_code)) {
0431         case SCU_EVENT_POST_RNC_COMPLETE:
0432             sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
0433             break;
0434         default:
0435             goto out;
0436         }
0437         break;
0438     case SCI_RNC_INVALIDATING:
0439         if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) {
0440             if (sci_rnc->destination_state == RNC_DEST_FINAL)
0441                 next_state = SCI_RNC_INITIAL;
0442             else
0443                 next_state = SCI_RNC_POSTING;
0444             sci_change_state(&sci_rnc->sm, next_state);
0445         } else {
0446             switch (scu_get_event_type(event_code)) {
0447             case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
0448             case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
0449                 /* We really dont care if the hardware is going to suspend
0450                  * the device since it's being invalidated anyway */
0451                 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0452                     "%s: SCIC Remote Node Context 0x%p was "
0453                     "suspended by hardware while being "
0454                     "invalidated.\n", __func__, sci_rnc);
0455                 break;
0456             default:
0457                 goto out;
0458             }
0459         }
0460         break;
0461     case SCI_RNC_RESUMING:
0462         if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) {
0463             sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
0464         } else {
0465             switch (scu_get_event_type(event_code)) {
0466             case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
0467             case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
0468                 /* We really dont care if the hardware is going to suspend
0469                  * the device since it's being resumed anyway */
0470                 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0471                     "%s: SCIC Remote Node Context 0x%p was "
0472                     "suspended by hardware while being resumed.\n",
0473                     __func__, sci_rnc);
0474                 break;
0475             default:
0476                 goto out;
0477             }
0478         }
0479         break;
0480     case SCI_RNC_READY:
0481         switch (scu_get_event_type(event_code)) {
0482         case SCU_EVENT_TL_RNC_SUSPEND_TX:
0483             sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED);
0484             sci_rnc->suspend_type = scu_get_event_type(event_code);
0485             break;
0486         case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
0487             sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED);
0488             sci_rnc->suspend_type = scu_get_event_type(event_code);
0489             break;
0490         default:
0491             goto out;
0492         }
0493         break;
0494     case SCI_RNC_AWAIT_SUSPENSION:
0495         switch (scu_get_event_type(event_code)) {
0496         case SCU_EVENT_TL_RNC_SUSPEND_TX:
0497             next_state = SCI_RNC_TX_SUSPENDED;
0498             break;
0499         case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
0500             next_state = SCI_RNC_TX_RX_SUSPENDED;
0501             break;
0502         default:
0503             goto out;
0504         }
0505         if (sci_rnc->suspend_type == scu_get_event_type(event_code))
0506             sci_change_state(&sci_rnc->sm, next_state);
0507         break;
0508     default:
0509         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0510              "%s: invalid state: %s\n", __func__,
0511              rnc_state_name(state));
0512         return SCI_FAILURE_INVALID_STATE;
0513     }
0514     return SCI_SUCCESS;
0515 
0516  out:
0517     dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0518          "%s: code: %#x state: %s\n", __func__, event_code,
0519          rnc_state_name(state));
0520     return SCI_FAILURE;
0521 
0522 }
0523 
0524 enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc,
0525                               scics_sds_remote_node_context_callback cb_fn,
0526                               void *cb_p)
0527 {
0528     enum scis_sds_remote_node_context_states state;
0529 
0530     state = sci_rnc->sm.current_state_id;
0531     switch (state) {
0532     case SCI_RNC_INVALIDATING:
0533         sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
0534         return SCI_SUCCESS;
0535     case SCI_RNC_POSTING:
0536     case SCI_RNC_RESUMING:
0537     case SCI_RNC_READY:
0538     case SCI_RNC_TX_SUSPENDED:
0539     case SCI_RNC_TX_RX_SUSPENDED:
0540         sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
0541         sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
0542         return SCI_SUCCESS;
0543     case SCI_RNC_AWAIT_SUSPENSION:
0544         sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
0545         return SCI_SUCCESS;
0546     case SCI_RNC_INITIAL:
0547         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0548              "%s: invalid state: %s\n", __func__,
0549              rnc_state_name(state));
0550         /* We have decided that the destruct request on the remote node context
0551          * can not fail since it is either in the initial/destroyed state or is
0552          * can be destroyed.
0553          */
0554         return SCI_SUCCESS;
0555     default:
0556         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0557              "%s: invalid state %s\n", __func__,
0558              rnc_state_name(state));
0559         return SCI_FAILURE_INVALID_STATE;
0560     }
0561 }
0562 
0563 enum sci_status sci_remote_node_context_suspend(
0564             struct sci_remote_node_context *sci_rnc,
0565             enum sci_remote_node_suspension_reasons suspend_reason,
0566             u32 suspend_type)
0567 {
0568     enum scis_sds_remote_node_context_states state
0569         = sci_rnc->sm.current_state_id;
0570     struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0571     enum sci_status status = SCI_FAILURE_INVALID_STATE;
0572     enum sci_remote_node_context_destination_state dest_param =
0573         RNC_DEST_UNSPECIFIED;
0574 
0575     dev_dbg(scirdev_to_dev(idev),
0576         "%s: current state %s, current suspend_type %x dest state %d,"
0577             " arg suspend_reason %d, arg suspend_type %x",
0578         __func__, rnc_state_name(state), sci_rnc->suspend_type,
0579         sci_rnc->destination_state, suspend_reason,
0580         suspend_type);
0581 
0582     /* Disable automatic state continuations if explicitly suspending. */
0583     if ((suspend_reason == SCI_HW_SUSPEND) ||
0584         (sci_rnc->destination_state == RNC_DEST_FINAL))
0585         dest_param = sci_rnc->destination_state;
0586 
0587     switch (state) {
0588     case SCI_RNC_READY:
0589         break;
0590     case SCI_RNC_INVALIDATING:
0591         if (sci_rnc->destination_state == RNC_DEST_FINAL) {
0592             dev_warn(scirdev_to_dev(idev),
0593                  "%s: already destroying %p\n",
0594                  __func__, sci_rnc);
0595             return SCI_FAILURE_INVALID_STATE;
0596         }
0597         fallthrough;    /* and handle like SCI_RNC_POSTING */
0598     case SCI_RNC_RESUMING:
0599         fallthrough;    /* and handle like SCI_RNC_POSTING */
0600     case SCI_RNC_POSTING:
0601         /* Set the destination state to AWAIT - this signals the
0602          * entry into the SCI_RNC_READY state that a suspension
0603          * needs to be done immediately.
0604          */
0605         if (sci_rnc->destination_state != RNC_DEST_FINAL)
0606             sci_rnc->destination_state = RNC_DEST_SUSPENDED;
0607         sci_rnc->suspend_type = suspend_type;
0608         sci_rnc->suspend_reason = suspend_reason;
0609         return SCI_SUCCESS;
0610 
0611     case SCI_RNC_TX_SUSPENDED:
0612         if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX)
0613             status = SCI_SUCCESS;
0614         break;
0615     case SCI_RNC_TX_RX_SUSPENDED:
0616         if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX)
0617             status = SCI_SUCCESS;
0618         break;
0619     case SCI_RNC_AWAIT_SUSPENSION:
0620         if ((sci_rnc->suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX)
0621             || (suspend_type == sci_rnc->suspend_type))
0622             return SCI_SUCCESS;
0623         break;
0624     default:
0625         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0626              "%s: invalid state %s\n", __func__,
0627              rnc_state_name(state));
0628         return SCI_FAILURE_INVALID_STATE;
0629     }
0630     sci_rnc->destination_state = dest_param;
0631     sci_rnc->suspend_type = suspend_type;
0632     sci_rnc->suspend_reason = suspend_reason;
0633 
0634     if (status == SCI_SUCCESS) { /* Already in the destination state? */
0635         struct isci_host *ihost = idev->owning_port->owning_controller;
0636 
0637         wake_up_all(&ihost->eventq); /* Let observers look. */
0638         return SCI_SUCCESS;
0639     }
0640     if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) ||
0641         (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) {
0642 
0643         if (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)
0644             isci_dev_set_hang_detection_timeout(idev, 0x00000001);
0645 
0646         sci_remote_device_post_request(
0647             idev, SCI_SOFTWARE_SUSPEND_CMD);
0648     }
0649     if (state != SCI_RNC_AWAIT_SUSPENSION)
0650         sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION);
0651 
0652     return SCI_SUCCESS;
0653 }
0654 
0655 enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
0656                             scics_sds_remote_node_context_callback cb_fn,
0657                             void *cb_p)
0658 {
0659     enum scis_sds_remote_node_context_states state;
0660     struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0661 
0662     state = sci_rnc->sm.current_state_id;
0663     dev_dbg(scirdev_to_dev(idev),
0664         "%s: state %s, cb_fn = %p, cb_p = %p; dest_state = %d; "
0665             "dev resume path %s\n",
0666         __func__, rnc_state_name(state), cb_fn, cb_p,
0667         sci_rnc->destination_state,
0668         test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)
0669             ? "<abort active>" : "<normal>");
0670 
0671     switch (state) {
0672     case SCI_RNC_INITIAL:
0673         if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
0674             return SCI_FAILURE_INVALID_STATE;
0675 
0676         sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
0677                             RNC_DEST_READY);
0678         if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
0679             sci_remote_node_context_construct_buffer(sci_rnc);
0680             sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
0681         }
0682         return SCI_SUCCESS;
0683 
0684     case SCI_RNC_POSTING:
0685     case SCI_RNC_INVALIDATING:
0686     case SCI_RNC_RESUMING:
0687         /* We are still waiting to post when a resume was
0688          * requested.
0689          */
0690         switch (sci_rnc->destination_state) {
0691         case RNC_DEST_SUSPENDED:
0692         case RNC_DEST_SUSPENDED_RESUME:
0693             /* Previously waiting to suspend after posting.
0694              * Now continue onto resumption.
0695              */
0696             sci_remote_node_context_setup_to_resume(
0697                 sci_rnc, cb_fn, cb_p,
0698                 RNC_DEST_SUSPENDED_RESUME);
0699             break;
0700         default:
0701             sci_remote_node_context_setup_to_resume(
0702                 sci_rnc, cb_fn, cb_p,
0703                 RNC_DEST_READY);
0704             break;
0705         }
0706         return SCI_SUCCESS;
0707 
0708     case SCI_RNC_TX_SUSPENDED:
0709     case SCI_RNC_TX_RX_SUSPENDED:
0710         {
0711             struct domain_device *dev = idev->domain_dev;
0712             /* If this is an expander attached SATA device we must
0713              * invalidate and repost the RNC since this is the only
0714              * way to clear the TCi to NCQ tag mapping table for
0715              * the RNi. All other device types we can just resume.
0716              */
0717             sci_remote_node_context_setup_to_resume(
0718                 sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
0719 
0720             if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
0721                 if ((dev_is_sata(dev) && dev->parent) ||
0722                     (sci_rnc->destination_state == RNC_DEST_FINAL))
0723                     sci_change_state(&sci_rnc->sm,
0724                              SCI_RNC_INVALIDATING);
0725                 else
0726                     sci_change_state(&sci_rnc->sm,
0727                              SCI_RNC_RESUMING);
0728             }
0729         }
0730         return SCI_SUCCESS;
0731 
0732     case SCI_RNC_AWAIT_SUSPENSION:
0733         sci_remote_node_context_setup_to_resume(
0734             sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME);
0735         return SCI_SUCCESS;
0736     default:
0737         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0738              "%s: invalid state %s\n", __func__,
0739              rnc_state_name(state));
0740         return SCI_FAILURE_INVALID_STATE;
0741     }
0742 }
0743 
0744 enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc,
0745                                  struct isci_request *ireq)
0746 {
0747     enum scis_sds_remote_node_context_states state;
0748 
0749     state = sci_rnc->sm.current_state_id;
0750 
0751     switch (state) {
0752     case SCI_RNC_READY:
0753         return SCI_SUCCESS;
0754     case SCI_RNC_TX_SUSPENDED:
0755     case SCI_RNC_TX_RX_SUSPENDED:
0756     case SCI_RNC_AWAIT_SUSPENSION:
0757         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0758              "%s: invalid state %s\n", __func__,
0759              rnc_state_name(state));
0760         return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
0761     default:
0762         dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0763             "%s: invalid state %s\n", __func__,
0764             rnc_state_name(state));
0765         return SCI_FAILURE_INVALID_STATE;
0766     }
0767 }
0768 
0769 enum sci_status sci_remote_node_context_start_task(
0770     struct sci_remote_node_context *sci_rnc,
0771     struct isci_request *ireq,
0772     scics_sds_remote_node_context_callback cb_fn,
0773     void *cb_p)
0774 {
0775     enum sci_status status = sci_remote_node_context_resume(sci_rnc,
0776                                 cb_fn, cb_p);
0777     if (status != SCI_SUCCESS)
0778         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0779             "%s: resume failed: %d\n", __func__, status);
0780     return status;
0781 }
0782 
0783 int sci_remote_node_context_is_safe_to_abort(
0784     struct sci_remote_node_context *sci_rnc)
0785 {
0786     enum scis_sds_remote_node_context_states state;
0787 
0788     state = sci_rnc->sm.current_state_id;
0789     switch (state) {
0790     case SCI_RNC_INVALIDATING:
0791     case SCI_RNC_TX_RX_SUSPENDED:
0792         return 1;
0793     case SCI_RNC_POSTING:
0794     case SCI_RNC_RESUMING:
0795     case SCI_RNC_READY:
0796     case SCI_RNC_TX_SUSPENDED:
0797     case SCI_RNC_AWAIT_SUSPENSION:
0798     case SCI_RNC_INITIAL:
0799         return 0;
0800     default:
0801         dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0802              "%s: invalid state %d\n", __func__, state);
0803         return 0;
0804     }
0805 }