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.
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
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
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.
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
59 * @brief This file contains the entrance and exit methods for the ready
60 * sub-state machine states (OPERATIONAL, TASK_MGMT).
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>
70 //******************************************************************************
71 //* P R O T E C T E D M E T H O D S
72 //******************************************************************************
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.
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.
87 void scif_sas_remote_device_ready_operational_substate_enter(
88 SCI_BASE_OBJECT_T *object
91 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
95 scif_sas_remote_device_ready_substate_handler_table,
96 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
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
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
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
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.
125 void scif_sas_remote_device_ready_operational_substate_exit(
126 SCI_BASE_OBJECT_T *object
129 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
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
138 * @brief This method implements the actions taken when entering the
139 * READY SUSPENDED substate. This includes setting the state
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.
149 void scif_sas_remote_device_ready_suspended_substate_enter(
150 SCI_BASE_OBJECT_T *object
153 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
157 scif_sas_remote_device_ready_substate_handler_table,
158 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED
163 * @brief This method implements the actions taken when entering the
164 * READY TASK MGMT substate. This includes setting the state
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.
174 void scif_sas_remote_device_ready_taskmgmt_substate_enter(
175 SCI_BASE_OBJECT_T *object
178 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)object;
182 scif_sas_remote_device_ready_substate_handler_table,
183 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT
188 * @brief This method implements the actions taken when entering the
189 * READY NCQ ERROR substate. This includes setting the state
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.
199 void scif_sas_remote_device_ready_ncq_error_substate_enter(
200 SCI_BASE_OBJECT_T *object
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;
216 scif_sas_remote_device_ready_substate_handler_table,
217 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
220 internal_task_memory = scif_sas_controller_allocate_internal_request(fw_controller);
221 ASSERT(internal_task_memory != NULL);
223 fw_task_request = (SCIF_SAS_TASK_REQUEST_T*)internal_task_memory;
225 fw_request = &fw_task_request->parent;
227 //construct the scif io request
228 status = scif_sas_internal_task_request_construct(
231 SCI_CONTROLLER_INVALID_IO_TAG,
232 (void *)fw_task_request,
234 SCI_SAS_ABORT_TASK_SET
237 pending_request_element = fw_domain->request_list.list_head;
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)
246 (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(pending_request_element);
248 // The current element may be deleted from the list becasue of
249 // IO completion so advance to the next element early
250 pending_request_element = sci_fast_list_get_next(pending_request_element);
252 if (pending_request->device == fw_device)
254 pending_request->is_waiting_for_abort_task_set = TRUE;
258 scif_controller_start_task(
262 SCI_CONTROLLER_INVALID_IO_TAG
266 SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table
267 [SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES] =
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
275 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED,
276 scif_sas_remote_device_ready_suspended_substate_enter,
280 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT,
281 scif_sas_remote_device_ready_taskmgmt_substate_enter,
285 SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
286 scif_sas_remote_device_ready_ncq_error_substate_enter,