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$");
55
56/**
57 * @file
58 *
59 * @brief This file contains all of the method implementations pertaining
60 *        to the framework io request state handler methods.
61 */
62
63#include <dev/isci/scil/scic_controller.h>
64#include <dev/isci/scil/scif_sas_logger.h>
65#include <dev/isci/scil/scif_sas_io_request.h>
66#include <dev/isci/scil/scif_sas_remote_device.h>
67#include <dev/isci/scil/scif_sas_domain.h>
68#include <dev/isci/scil/scif_sas_controller.h>
69
70//******************************************************************************
71//* C O N S T R U C T E D   H A N D L E R S
72//******************************************************************************
73
74/**
75 * @brief This method provides CONSTRUCTED state specific handling for
76 *        when the user attempts to start the supplied IO request.
77 *
78 * @param[in] io_request This parameter specifies the IO request object
79 *            to be started.
80 *
81 * @return This method returns a value indicating if the IO request was
82 *         successfully started or not.
83 * @retval SCI_SUCCESS This return value indicates successful starting
84 *         of the IO request.
85 */
86SCI_STATUS scif_sas_io_request_constructed_start_handler(
87   SCI_BASE_REQUEST_T * io_request
88)
89{
90   return SCI_SUCCESS;
91}
92
93/**
94 * @brief This method provides CONSTRUCTED state specific handling for
95 *        when the user attempts to abort the supplied IO request.
96 *
97 * @param[in] io_request This parameter specifies the IO request object
98 *            to be aborted.
99 *
100 * @return This method returns a value indicating if the IO request was
101 *         successfully aborted or not.
102 * @retval SCI_SUCCESS This return value indicates successful aborting
103 *         of the IO request.
104 */
105SCI_STATUS scif_sas_io_request_constructed_abort_handler(
106   SCI_BASE_REQUEST_T * io_request
107)
108{
109   sci_base_state_machine_change_state(
110      &io_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
111   );
112
113   return SCI_SUCCESS;
114}
115
116//******************************************************************************
117//* S T A R T E D   H A N D L E R S
118//******************************************************************************
119
120/**
121 * @brief This method provides STARTED state specific handling for
122 *        when the user attempts to abort the supplied IO request.
123 *
124 * @param[in] io_request This parameter specifies the IO request object
125 *            to be aborted.
126 *
127 * @return This method returns a value indicating if the aborting the
128 *         IO request was successfully started.
129 * @retval SCI_SUCCESS This return value indicates that the abort process
130 *         began successfully.
131 */
132static
133SCI_STATUS scif_sas_io_request_started_abort_handler(
134   SCI_BASE_REQUEST_T * io_request
135)
136{
137   SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T *) io_request;
138
139   sci_base_state_machine_change_state(
140      &io_request->state_machine, SCI_BASE_REQUEST_STATE_ABORTING
141   );
142
143   return fw_request->status;
144}
145
146/**
147 * @brief This method provides STARTED state specific handling for
148 *        when the user attempts to complete the supplied IO request.
149 *
150 * @param[in] io_request This parameter specifies the IO request object
151 *            to be completed.
152 *
153 * @return This method returns a value indicating if the completion of the
154 *         IO request was successful.
155 * @retval SCI_SUCCESS This return value indicates that the completion process
156 *         was successful.
157 */
158static
159SCI_STATUS scif_sas_io_request_started_complete_handler(
160   SCI_BASE_REQUEST_T * io_request
161)
162{
163   sci_base_state_machine_change_state(
164      &io_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
165   );
166
167   return SCI_SUCCESS;
168}
169
170//******************************************************************************
171//* C O M P L E T E D   H A N D L E R S
172//******************************************************************************
173
174/**
175 * @brief This method provides COMPLETED state specific handling for
176 *        when the user attempts to destruct the supplied IO request.
177 *
178 * @param[in] io_request This parameter specifies the IO request object
179 *            to be destructed.
180 *
181 * @return This method returns a value indicating if the destruct
182 *         operation was successful.
183 * @retval SCI_SUCCESS This return value indicates that the destruct
184 *         was successful.
185 */
186static
187SCI_STATUS scif_sas_io_request_completed_destruct_handler(
188   SCI_BASE_REQUEST_T * io_request
189)
190{
191   sci_base_state_machine_change_state(
192      &io_request->state_machine, SCI_BASE_REQUEST_STATE_FINAL
193   );
194
195   sci_base_state_machine_logger_deinitialize(
196      &io_request->state_machine_logger,
197      &io_request->state_machine
198   );
199
200   return SCI_SUCCESS;
201}
202
203//******************************************************************************
204//* A B O R T I N G   H A N D L E R S
205//******************************************************************************
206
207/**
208 * @brief This method provides ABORTING state specific handlering for when the
209 *        user attempts to abort the supplied IO request.
210 *
211 * @param[in] io_request This parameter specifies the IO request object
212 *            to be completed.
213 *
214 * @return This method returns a value indicating if the completion
215 *         operation was successful.
216 * @retval SCI_SUCCESS This return value indicates that the abort operation
217 *         was successful.
218 */
219static
220SCI_STATUS scif_sas_io_request_aborting_abort_handler(
221   SCI_BASE_REQUEST_T * io_request
222)
223{
224   SCIF_SAS_IO_REQUEST_T * fw_request = (SCIF_SAS_IO_REQUEST_T *) io_request;
225
226   return scic_controller_terminate_request(
227             fw_request->parent.device->domain->controller->core_object,
228             fw_request->parent.device->core_object,
229             fw_request->parent.core_object
230          );
231}
232
233/**
234 * @brief This method provides ABORTING state specific handling for
235 *        when the user attempts to complete the supplied IO request.
236 *
237 * @param[in] io_request This parameter specifies the IO request object
238 *            to be completed.
239 *
240 * @return This method returns a value indicating if the completion
241 *         operation was successful.
242 * @retval SCI_SUCCESS This return value indicates that the completion
243 *         was successful.
244 */
245static
246SCI_STATUS scif_sas_io_request_aborting_complete_handler(
247   SCI_BASE_REQUEST_T * io_request
248)
249{
250   sci_base_state_machine_change_state(
251      &io_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
252   );
253
254   return SCI_SUCCESS;
255}
256
257//******************************************************************************
258//* D E F A U L T   H A N D L E R S
259//******************************************************************************
260
261/**
262 * @brief This method provides DEFAULT handling for when the user
263 *        attempts to start the supplied IO request.
264 *
265 * @param[in] io_request This parameter specifies the IO request object
266 *            to be started.
267 *
268 * @return This method returns an indication that the start operation is
269 *         not allowed.
270 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
271 */
272static
273SCI_STATUS scif_sas_io_request_default_start_handler(
274   SCI_BASE_REQUEST_T * io_request
275)
276{
277   SCIF_LOG_ERROR((
278      sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
279      SCIF_LOG_OBJECT_IO_REQUEST,
280      "IoRequest:0x%x State:0x%x invalid state to start\n",
281      io_request,
282      sci_base_state_machine_get_state(
283         &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
284   ));
285
286   return SCI_FAILURE_INVALID_STATE;
287}
288
289/**
290 * @brief This method provides DEFAULT handling for when the user
291 *        attempts to abort the supplied IO request.
292 *
293 * @param[in] io_request This parameter specifies the IO request object
294 *            to be aborted.
295 *
296 * @return This method returns an indication that the abort operation is
297 *         not allowed.
298 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
299 */
300static
301SCI_STATUS scif_sas_io_request_default_abort_handler(
302   SCI_BASE_REQUEST_T * io_request
303)
304{
305   SCIF_LOG_ERROR((
306      sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
307      SCIF_LOG_OBJECT_IO_REQUEST,
308      "IoRequest:0x%x State:0x%x invalid state to abort\n",
309      io_request,
310      sci_base_state_machine_get_state(
311         &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
312   ));
313
314   return SCI_FAILURE_INVALID_STATE;
315}
316
317/**
318 * @brief This method provides DEFAULT handling for when the user
319 *        attempts to complete the supplied IO request.
320 *
321 * @param[in] io_request This parameter specifies the IO request object
322 *            to be completed.
323 *
324 * @return This method returns an indication that complete operation is
325 *         not allowed.
326 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
327 */
328SCI_STATUS scif_sas_io_request_default_complete_handler(
329   SCI_BASE_REQUEST_T * io_request
330)
331{
332   SCIF_LOG_ERROR((
333      sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
334      SCIF_LOG_OBJECT_IO_REQUEST,
335      "IoRequest:0x%x State:0x%x invalid state to complete\n",
336      io_request,
337      sci_base_state_machine_get_state(
338         &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
339   ));
340
341   return SCI_FAILURE_INVALID_STATE;
342}
343
344/**
345 * @brief This method provides DEFAULT handling for when the user
346 *        attempts to destruct the supplied IO request.
347 *
348 * @param[in] io_request This parameter specifies the IO request object
349 *            to be destructed.
350 *
351 * @return This method returns an indication that destruct operation is
352 *         not allowed.
353 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
354 */
355SCI_STATUS scif_sas_io_request_default_destruct_handler(
356   SCI_BASE_REQUEST_T * io_request
357)
358{
359   SCIF_LOG_ERROR((
360      sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
361      SCIF_LOG_OBJECT_IO_REQUEST,
362      "IoRequest:0x%x State:0x%x invalid state to destruct.\n",
363      io_request,
364      sci_base_state_machine_get_state(
365         &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
366   ));
367
368   return SCI_FAILURE_INVALID_STATE;
369}
370
371
372SCI_BASE_REQUEST_STATE_HANDLER_T scif_sas_io_request_state_handler_table[] =
373{
374   // SCI_BASE_REQUEST_STATE_INITIAL
375   {
376      scif_sas_io_request_default_start_handler,
377      scif_sas_io_request_default_abort_handler,
378      scif_sas_io_request_default_complete_handler,
379      scif_sas_io_request_default_destruct_handler
380   },
381   // SCI_BASE_REQUEST_STATE_CONSTRUCTED
382   {
383      scif_sas_io_request_constructed_start_handler,
384      scif_sas_io_request_constructed_abort_handler,
385      scif_sas_io_request_default_complete_handler,
386      scif_sas_io_request_default_destruct_handler
387   },
388   // SCI_BASE_REQUEST_STATE_STARTED
389   {
390      scif_sas_io_request_default_start_handler,
391      scif_sas_io_request_started_abort_handler,
392      scif_sas_io_request_started_complete_handler,
393      scif_sas_io_request_default_destruct_handler
394   },
395   // SCI_BASE_REQUEST_STATE_COMPLETED
396   {
397      scif_sas_io_request_default_start_handler,
398      scif_sas_io_request_default_abort_handler,
399      scif_sas_io_request_default_complete_handler,
400      scif_sas_io_request_completed_destruct_handler
401   },
402   // SCI_BASE_REQUEST_STATE_ABORTING
403   {
404      scif_sas_io_request_default_start_handler,
405      scif_sas_io_request_aborting_abort_handler,
406      scif_sas_io_request_aborting_complete_handler,
407      scif_sas_io_request_default_destruct_handler
408   },
409   // SCI_BASE_REQUEST_STATE_FINAL
410   {
411      scif_sas_io_request_default_start_handler,
412      scif_sas_io_request_default_abort_handler,
413      scif_sas_io_request_default_complete_handler,
414      scif_sas_io_request_default_destruct_handler
415   },
416};
417
418