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 
0056 #ifndef _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
0057 #define _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
0058 
0059 /**
0060  * This file contains the structures, constants, and prototypes associated with
0061  *    the remote node context in the silicon.  It exists to model and manage
0062  *    the remote node context in the silicon.
0063  *
0064  *
0065  */
0066 
0067 #include "isci.h"
0068 
0069 /**
0070  *
0071  *
0072  * This constant represents an invalid remote device id, it is used to program
0073  * the STPDARNI register so the driver knows when it has received a SIGNATURE
0074  * FIS from the SCU.
0075  */
0076 #define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX    0x0FFF
0077 
0078 enum sci_remote_node_suspension_reasons {
0079     SCI_HW_SUSPEND,
0080     SCI_SW_SUSPEND_NORMAL,
0081     SCI_SW_SUSPEND_LINKHANG_DETECT
0082 };
0083 #define SCI_SOFTWARE_SUSPEND_CMD SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX
0084 #define SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT SCU_EVENT_TL_RNC_SUSPEND_TX_RX
0085 
0086 struct isci_request;
0087 struct isci_remote_device;
0088 struct sci_remote_node_context;
0089 
0090 typedef void (*scics_sds_remote_node_context_callback)(void *);
0091 
0092 /**
0093  * enum sci_remote_node_context_states
0094  * @SCI_RNC_INITIAL initial state for a remote node context.  On a resume
0095  * request the remote node context will transition to the posting state.
0096  *
0097  * @SCI_RNC_POSTING: transition state that posts the RNi to the hardware. Once
0098  * the RNC is posted the remote node context will be made ready.
0099  *
0100  * @SCI_RNC_INVALIDATING: transition state that will post an RNC invalidate to
0101  * the hardware.  Once the invalidate is complete the remote node context will
0102  * transition to the posting state.
0103  *
0104  * @SCI_RNC_RESUMING: transition state that will post an RNC resume to the
0105  * hardare.  Once the event notification of resume complete is received the
0106  * remote node context will transition to the ready state.
0107  *
0108  * @SCI_RNC_READY: state that the remote node context must be in to accept io
0109  * request operations.
0110  *
0111  * @SCI_RNC_TX_SUSPENDED: state that the remote node context transitions to when
0112  * it gets a TX suspend notification from the hardware.
0113  *
0114  * @SCI_RNC_TX_RX_SUSPENDED: state that the remote node context transitions to
0115  * when it gets a TX RX suspend notification from the hardware.
0116  *
0117  * @SCI_RNC_AWAIT_SUSPENSION: wait state for the remote node context that waits
0118  * for a suspend notification from the hardware.  This state is entered when
0119  * either there is a request to supend the remote node context or when there is
0120  * a TC completion where the remote node will be suspended by the hardware.
0121  */
0122 #define RNC_STATES {\
0123     C(RNC_INITIAL),\
0124     C(RNC_POSTING),\
0125     C(RNC_INVALIDATING),\
0126     C(RNC_RESUMING),\
0127     C(RNC_READY),\
0128     C(RNC_TX_SUSPENDED),\
0129     C(RNC_TX_RX_SUSPENDED),\
0130     C(RNC_AWAIT_SUSPENSION),\
0131     }
0132 #undef C
0133 #define C(a) SCI_##a
0134 enum scis_sds_remote_node_context_states RNC_STATES;
0135 #undef C
0136 const char *rnc_state_name(enum scis_sds_remote_node_context_states state);
0137 
0138 /**
0139  *
0140  *
0141  * This enumeration is used to define the end destination state for the remote
0142  * node context.
0143  */
0144 enum sci_remote_node_context_destination_state {
0145     RNC_DEST_UNSPECIFIED,
0146     RNC_DEST_READY,
0147     RNC_DEST_FINAL,
0148     RNC_DEST_SUSPENDED,       /* Set when suspend during post/invalidate */
0149     RNC_DEST_SUSPENDED_RESUME /* Set when a resume was done during posting
0150                    * or invalidating and already suspending.
0151                    */
0152 };
0153 
0154 /**
0155  * struct sci_remote_node_context - This structure contains the data
0156  *    associated with the remote node context object.  The remote node context
0157  *    (RNC) object models the the remote device information necessary to manage
0158  *    the silicon RNC.
0159  */
0160 struct sci_remote_node_context {
0161     /**
0162      * This field indicates the remote node index (RNI) associated with
0163      * this RNC.
0164      */
0165     u16 remote_node_index;
0166 
0167     /**
0168      * This field is the recored suspension type of the remote node
0169      * context suspension.
0170      */
0171     u32 suspend_type;
0172     enum sci_remote_node_suspension_reasons suspend_reason;
0173     u32 suspend_count;
0174 
0175     /**
0176      * This field is true if the remote node context is resuming from its current
0177      * state.  This can cause an automatic resume on receiving a suspension
0178      * notification.
0179      */
0180     enum sci_remote_node_context_destination_state destination_state;
0181 
0182     /**
0183      * This field contains the callback function that the user requested to be
0184      * called when the requested state transition is complete.
0185      */
0186     scics_sds_remote_node_context_callback user_callback;
0187 
0188     /**
0189      * This field contains the parameter that is called when the user requested
0190      * state transition is completed.
0191      */
0192     void *user_cookie;
0193 
0194     /**
0195      * This field contains the data for the object's state machine.
0196      */
0197     struct sci_base_state_machine sm;
0198 };
0199 
0200 void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
0201                         u16 remote_node_index);
0202 
0203 
0204 bool sci_remote_node_context_is_ready(
0205     struct sci_remote_node_context *sci_rnc);
0206 
0207 bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc);
0208 
0209 enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc,
0210                                u32 event_code);
0211 enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc,
0212                               scics_sds_remote_node_context_callback callback,
0213                               void *callback_parameter);
0214 enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc,
0215                              enum sci_remote_node_suspension_reasons reason,
0216                              u32 suspension_code);
0217 enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
0218                             scics_sds_remote_node_context_callback cb_fn,
0219                             void *cb_p);
0220 enum sci_status sci_remote_node_context_start_task(struct sci_remote_node_context *sci_rnc,
0221                            struct isci_request *ireq,
0222                            scics_sds_remote_node_context_callback cb_fn,
0223                            void *cb_p);
0224 enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc,
0225                               struct isci_request *ireq);
0226 int sci_remote_node_context_is_safe_to_abort(
0227     struct sci_remote_node_context *sci_rnc);
0228 
0229 static inline bool sci_remote_node_context_is_being_destroyed(
0230     struct sci_remote_node_context *sci_rnc)
0231 {
0232     return (sci_rnc->destination_state == RNC_DEST_FINAL)
0233         || ((sci_rnc->sm.current_state_id == SCI_RNC_INITIAL)
0234             && (sci_rnc->destination_state == RNC_DEST_UNSPECIFIED));
0235 }
0236 #endif  /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */