scif_sas_remote_device_ready_substates.c revision 331722
1/*-
2 * This file is provided under a dual BSD/GPLv2 license.  When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 *   * Redistributions of source code must retain the above copyright
34 *     notice, this list of conditions and the following disclaimer.
35 *   * Redistributions in binary form must reproduce the above copyright
36 *     notice, this list of conditions and the following disclaimer in
37 *     the documentation and/or other materials provided with the
38 *     distribution.
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 */
52
53#include <sys/cdefs.h>
54__FBSDID("$FreeBSD: stable/11/sys/dev/isci/scil/scif_sas_remote_device_ready_substates.c 331722 2018-03-29 02:50:57Z eadler $");
55
56/**
57 * @file
58 *
59 * @brief This file contains the entrance and exit methods for the ready
60 *        sub-state machine states (OPERATIONAL, TASK_MGMT).
61 */
62
63#include <dev/isci/scil/scif_sas_remote_device.h>
64#include <dev/isci/scil/scif_sas_domain.h>
65#include <dev/isci/scil/scif_sas_logger.h>
66#include <dev/isci/scil/scif_sas_internal_io_request.h>
67#include <dev/isci/scil/scif_sas_controller.h>
68#include <dev/isci/scil/sci_controller.h>
69
70//******************************************************************************
71//* P R O T E C T E D   M E T H O D S
72//******************************************************************************
73
74/**
75 * @brief This method implements the actions taken when entering the
76 *        READY OPERATIONAL substate.  This includes setting the state
77 *        handler methods and issuing a scif_cb_remote_device_ready()
78 *        notification to the user.
79 *
80 * @param[in]  object This parameter specifies the base object for which
81 *             the state transition is occurring.  This is cast into a
82 *             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
83 *
84 * @return none
85 */
86static
87void scif_sas_remote_device_ready_operational_substate_enter(
88   SCI_BASE_OBJECT_T *object
89)
90{
91   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
92
93   SET_STATE_HANDLER(
94      fw_device,
95      scif_sas_remote_device_ready_substate_handler_table,
96      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
97   );
98
99   SCIF_LOG_INFO((
100      sci_base_object_get_logger(fw_device),
101      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
102      "Domain:0x%x Device:0x%x device ready\n",
103      fw_device->domain, fw_device
104   ));
105
106   // Notify the user that the device has become ready.
107   scif_cb_remote_device_ready(
108      fw_device->domain->controller, fw_device->domain, fw_device
109   );
110}
111
112/**
113 * @brief This method implements the actions taken when exiting the
114 *        READY OPERATIONAL substate.  This method issues a
115 *        scif_cb_remote_device_not_ready() notification to the framework
116 *        user.
117 *
118 * @param[in]  object This parameter specifies the base object for which
119 *             the state transition is occurring.  This is cast into a
120 *             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
121 *
122 * @return none
123 */
124static
125void scif_sas_remote_device_ready_operational_substate_exit(
126   SCI_BASE_OBJECT_T *object
127)
128{
129   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
130
131   // Notify the user that the device has become ready.
132   scif_cb_remote_device_not_ready(
133      fw_device->domain->controller, fw_device->domain, fw_device
134   );
135}
136
137/**
138 * @brief This method implements the actions taken when entering the
139 *        READY SUSPENDED substate.  This includes setting the state
140 *        handler methods.
141 *
142 * @param[in]  object This parameter specifies the base object for which
143 *             the state transition is occurring.  This is cast into a
144 *             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
145 *
146 * @return none
147 */
148static
149void scif_sas_remote_device_ready_suspended_substate_enter(
150   SCI_BASE_OBJECT_T *object
151)
152{
153   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
154
155   SET_STATE_HANDLER(
156      fw_device,
157      scif_sas_remote_device_ready_substate_handler_table,
158      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED
159   );
160}
161
162/**
163 * @brief This method implements the actions taken when entering the
164 *        READY TASK MGMT substate.  This includes setting the state
165 *        handler methods.
166 *
167 * @param[in]  object This parameter specifies the base object for which
168 *             the state transition is occurring.  This is cast into a
169 *             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
170 *
171 * @return none
172 */
173static
174void scif_sas_remote_device_ready_taskmgmt_substate_enter(
175   SCI_BASE_OBJECT_T *object
176)
177{
178   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
179
180   SET_STATE_HANDLER(
181      fw_device,
182      scif_sas_remote_device_ready_substate_handler_table,
183      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT
184   );
185}
186
187/**
188* @brief This method implements the actions taken when entering the
189*        READY NCQ ERROR substate.  This includes setting the state
190*        handler methods.
191*
192* @param[in]  object This parameter specifies the base object for which
193*             the state transition is occurring.  This is cast into a
194*             SCIF_SAS_REMOTE_DEVICE object in the method implementation.
195*
196* @return none
197*/
198static
199void scif_sas_remote_device_ready_ncq_error_substate_enter(
200   SCI_BASE_OBJECT_T *object
201)
202{
203   SCIF_SAS_REMOTE_DEVICE_T         * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
204   SCI_STATUS                         status = SCI_SUCCESS;
205   SCI_TASK_REQUEST_HANDLE_T          handle;
206   SCIF_SAS_CONTROLLER_T            * fw_controller = fw_device->domain->controller;
207   SCIF_SAS_TASK_REQUEST_T          * fw_task_request;
208   SCIF_SAS_REQUEST_T               * fw_request;
209   void                             * internal_task_memory;
210   SCIF_SAS_DOMAIN_T                * fw_domain = fw_device->domain;
211   SCI_FAST_LIST_ELEMENT_T          * pending_request_element;
212   SCIF_SAS_REQUEST_T               * pending_request = NULL;
213
214   SET_STATE_HANDLER(
215      fw_device,
216      scif_sas_remote_device_ready_substate_handler_table,
217      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
218   );
219
220   internal_task_memory = scif_sas_controller_allocate_internal_request(fw_controller);
221   ASSERT(internal_task_memory != NULL);
222
223   fw_task_request = (SCIF_SAS_TASK_REQUEST_T*)internal_task_memory;
224
225   fw_request = &fw_task_request->parent;
226
227   //construct the scif io request
228   status = scif_sas_internal_task_request_construct(
229      fw_controller,
230      fw_device,
231      SCI_CONTROLLER_INVALID_IO_TAG,
232      (void *)fw_task_request,
233      &handle,
234      SCI_SAS_ABORT_TASK_SET
235   );
236
237   pending_request_element = fw_domain->request_list.list_head;
238
239   // Cycle through the fast list of IO requests.  Mark each request
240   //  pending to this remote device so that they are not completed
241   //  to the operating system when the request is terminated, but
242   //  rather when the abort task set completes.
243   while (pending_request_element != NULL)
244   {
245      pending_request =
246         (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(pending_request_element);
247
248      // The current element may be deleted from the list because of
249      // IO completion so advance to the next element early
250      pending_request_element = sci_fast_list_get_next(pending_request_element);
251
252      if (pending_request->device == fw_device)
253      {
254         pending_request->is_waiting_for_abort_task_set = TRUE;
255      }
256   }
257
258   scif_controller_start_task(
259      fw_controller,
260      fw_device,
261      fw_request,
262      SCI_CONTROLLER_INVALID_IO_TAG
263   );
264}
265
266SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table
267[SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES] =
268{
269   {
270      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL,
271      scif_sas_remote_device_ready_operational_substate_enter,
272      scif_sas_remote_device_ready_operational_substate_exit
273   },
274   {
275      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED,
276      scif_sas_remote_device_ready_suspended_substate_enter,
277      NULL
278   },
279   {
280      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT,
281      scif_sas_remote_device_ready_taskmgmt_substate_enter,
282      NULL
283   },
284   {
285      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
286      scif_sas_remote_device_ready_ncq_error_substate_enter,
287      NULL
288   }
289};
290
291