scif_sas_remote_device_state_handlers.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_state_handlers.c 331722 2018-03-29 02:50:57Z eadler $");
55
56/**
57 * @file
58 *
59 * @brief This file contains all of the method implementations pertaining
60 *        to the framework remote device state handler methods.
61 */
62
63#include <dev/isci/scil/scic_remote_device.h>
64
65#include <dev/isci/scil/scif_sas_logger.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_task_request.h>
69#include <dev/isci/scil/scif_sas_internal_io_request.h>
70
71//******************************************************************************
72//* S T O P P E D   H A N D L E R S
73//******************************************************************************
74
75/**
76 * @brief This method provides STOPPED state specific handling for
77 *        when the framework attempts to start the remote device.  This
78 *        method attempts to transition the state machine into the
79 *        STARTING state.  If this is unsuccessful, then there is a direct
80 *        transition into the FAILED state.
81 *
82 * @param[in]  remote_device This parameter specifies the remote device
83 *             object for which the framework is attempting to start.
84 *
85 * @return This method returns an indication as to whether the start
86 *         operating began successfully.
87 */
88static
89SCI_STATUS scif_sas_remote_device_stopped_start_handler(
90   SCI_BASE_REMOTE_DEVICE_T * remote_device
91)
92{
93   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
94                                          remote_device;
95
96   sci_base_state_machine_change_state(
97      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STARTING
98   );
99
100   // Check to see if the state transition occurred without issue.
101   if (sci_base_state_machine_get_state(&fw_device->parent.state_machine)
102       == SCI_BASE_REMOTE_DEVICE_STATE_FAILED)
103   {
104      SCIF_LOG_WARNING((
105         sci_base_object_get_logger(fw_device),
106         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
107         "Domain:0x%x Device:0x%x Status:0x%x failed to start\n",
108         fw_device->domain, fw_device, fw_device->operation_status
109      ));
110   }
111
112   return fw_device->operation_status;
113}
114
115/**
116 * @brief This method provides STOPPED state specific handling for
117 *        when the user attempts to destruct the remote device.
118 *
119 * @param[in]  remote_device This parameter specifies the remote device
120 *             object for which the framework is attempting to start.
121 *
122 * @return This method returns an indication as to whether the destruct
123 *         operation completed successfully.
124 */
125static
126SCI_STATUS scif_sas_remote_device_stopped_destruct_handler(
127   SCI_BASE_REMOTE_DEVICE_T * remote_device
128)
129{
130   SCI_STATUS                 status;
131   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
132                                          remote_device;
133
134   SMP_DISCOVER_RESPONSE_PROTOCOLS_T  dev_protocols;
135   scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
136
137   //For smp device, need to clear its smp phy list first.
138   if(dev_protocols.u.bits.attached_smp_target)
139      scif_sas_smp_remote_device_removed(fw_device);
140
141   status = scic_remote_device_destruct(fw_device->core_object);
142   if (status == SCI_SUCCESS)
143   {
144      sci_base_state_machine_change_state(
145         &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FINAL
146      );
147
148      scif_sas_remote_device_deinitialize_state_logging(fw_device);
149   }
150   else
151   {
152      SCIF_LOG_ERROR((
153         sci_base_object_get_logger(fw_device),
154         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
155         "Device:0x%x Status:0x%x failed to destruct core device\n",
156         fw_device
157      ));
158   }
159
160   return status;
161}
162
163//******************************************************************************
164//* S T O P P I N G   H A N D L E R S
165//******************************************************************************
166
167/**
168 * @brief This method provides STOPPING state specific handling for
169 *        when the core remote device object issues a stop completion
170 *        notification.
171 *
172 * @note There is no need to ensure all IO/Task requests are complete
173 *       before transitioning to the STOPPED state.  The SCI Core will
174 *       ensure this is accomplished.
175 *
176 * @param[in]  remote_device This parameter specifies the remote device
177 *             object for which the completion occurred.
178 * @param[in]  completion_status This parameter specifies the status
179 *             of the completion operation.
180 *
181 * @return none.
182 */
183static
184void scif_sas_remote_device_stopping_stop_complete_handler(
185   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
186   SCI_STATUS                 completion_status
187)
188{
189   // Transition directly to the STOPPED state since the core ensures
190   // all IO/Tasks are complete.
191   sci_base_state_machine_change_state(
192      &fw_device->parent.state_machine,
193      SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
194   );
195
196   if (completion_status != SCI_SUCCESS)
197   {
198      SCIF_LOG_ERROR((
199         sci_base_object_get_logger(fw_device),
200         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
201         "Device:0x%x Status:0x%x failed to stop core device\n",
202         fw_device, completion_status
203      ));
204
205      // Something is seriously wrong.  Stopping the core remote device
206      // shouldn't fail in anyway.
207      scif_cb_controller_error(fw_device->domain->controller,
208              SCI_CONTROLLER_REMOTE_DEVICE_ERROR);
209   }
210}
211
212/**
213 * @brief This method provides STOPPING state handling for high priority
214 *        IO requests, when the framework attempts to complete a high
215 *        priority request.
216 *
217 * @param[in]  remote_device This parameter specifies the remote device
218 *             object for which to complete the high priority IO.
219 * @param[in]  io_request This parameter specifies the IO request to be
220 *             completed.
221 * @param[in]  response_data This parameter is ignored, since the device
222 *             is in the stopping state.
223 *
224 * @return This method always returns success.
225 */
226static
227SCI_STATUS scif_sas_remote_device_stopping_complete_high_priority_io_handler(
228   SCI_BASE_REMOTE_DEVICE_T * remote_device,
229   SCI_BASE_REQUEST_T       * io_request,
230   void                     * response_data,
231   SCI_IO_STATUS              completion_status
232)
233{
234   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
235                                          remote_device;
236   SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T *) io_request;
237
238   SCIF_LOG_TRACE((
239      sci_base_object_get_logger(remote_device),
240      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
241      "scif_sas_remote_device_stopping_complete_high_priority_io_handler(0x%x,0x%x,0x%x) enter\n",
242      remote_device, io_request, response_data
243   ));
244
245   fw_device->request_count--;
246
247   if (fw_request->is_internal == TRUE)
248   {
249      scif_sas_internal_io_request_complete(
250         fw_device->domain->controller,
251         (SCIF_SAS_INTERNAL_IO_REQUEST_T *) io_request,
252         SCI_SUCCESS
253      );
254   }
255
256   return SCI_SUCCESS;
257}
258
259//******************************************************************************
260//* F A I L E D   H A N D L E R S
261//******************************************************************************
262
263/**
264 * @brief This method provides FAILED state specific handling for
265 *        when the remote device is being stopped by the framework.
266 *
267 * @param[in]  remote_device This parameter specifies the remote device
268 *             object for which the stop operation is being requested.
269 *
270 * @return This method returns an indication as to whether the failure
271 *         operation completed successfully.
272 */
273static
274SCI_STATUS scif_sas_remote_device_failed_stop_handler(
275   SCI_BASE_REMOTE_DEVICE_T * remote_device
276)
277{
278   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
279                                          remote_device;
280
281   SCIF_LOG_WARNING((
282      sci_base_object_get_logger(fw_device),
283      SCIF_LOG_OBJECT_REMOTE_DEVICE,
284      "RemoteDevice:0x%x stopping failed device\n",
285      fw_device
286   ));
287
288   sci_base_state_machine_change_state(
289      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
290   );
291
292   /// @todo Fix the return code handling.
293   return SCI_FAILURE;
294}
295
296//******************************************************************************
297//* D E F A U L T   H A N D L E R S
298//******************************************************************************
299
300/**
301 * @brief This method provides default handling (i.e. returns an error);
302 *        when a user attempts to start a remote device and a start operation
303 *        is not allowed.
304 *
305 * @param[in]  remote_device This parameter specifies the remote device object
306 *             on which the user is attempting to perform a start operation.
307 *
308 * @return This method returns an indication that start operations are not
309 *         allowed.
310 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
311 */
312SCI_STATUS scif_sas_remote_device_default_start_handler(
313   SCI_BASE_REMOTE_DEVICE_T * remote_device
314)
315{
316   SCIF_LOG_WARNING((
317      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
318      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_REMOTE_DEVICE_CONFIG,
319      "RemoteDevice:0x%x State:0x%x invalid state to start\n",
320      remote_device,
321      sci_base_state_machine_get_state(
322         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
323   ));
324
325   return SCI_FAILURE_INVALID_STATE;
326}
327
328/**
329 * @brief This method provides default handling (i.e. returns an error);
330 *        when a user attempts to stop a remote device and a stop operation
331 *        is not allowed.
332 *
333 * @param[in]  remote_device This parameter specifies the remote device object
334 *             on which the user is attempting to perform a stop operation.
335 *
336 * @return This method returns an indication that stop operations are not
337 *         allowed.
338 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
339 */
340SCI_STATUS scif_sas_remote_device_default_stop_handler(
341   SCI_BASE_REMOTE_DEVICE_T * remote_device
342)
343{
344   SCIF_LOG_WARNING((
345      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
346      SCIF_LOG_OBJECT_REMOTE_DEVICE,
347      "RemoteDevice:0x%x State:0x%x invalid state to stop\n",
348      remote_device,
349      sci_base_state_machine_get_state(
350         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
351   ));
352
353   return SCI_FAILURE_INVALID_STATE;
354}
355
356/**
357 * @brief This method provides default handling (i.e. returns an error);
358 *        when there is an attempt to fail a remote device from an invalid
359 *        state.
360 *
361 * @param[in]  remote_device This parameter specifies the remote device
362 *             object on which there is an attempt to fail the device.
363 *
364 * @return This method returns an indication that the fail transition is not
365 *         allowed.
366 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
367 */
368static
369SCI_STATUS scif_sas_remote_device_default_fail_handler(
370   SCI_BASE_REMOTE_DEVICE_T * remote_device
371)
372{
373   SCIF_LOG_WARNING((
374      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
375      SCIF_LOG_OBJECT_REMOTE_DEVICE,
376      "RemoteDevice:0x%x State:0x%x invalid state to fail device\n",
377      remote_device,
378      sci_base_state_machine_get_state(
379         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
380   ));
381
382   return SCI_FAILURE_INVALID_STATE;
383}
384
385/**
386 * @brief This method provides default handling (i.e. returns an error);
387 *        when there is an attempt to destruct a remote device from an
388 *        invalid state.
389 *
390 * @param[in]  remote_device This parameter specifies the remote device
391 *             object on which there is an attempt to fail the device.
392 *
393 * @return This method returns an indication that the fail transition is not
394 *         allowed.
395 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
396 */
397SCI_STATUS scif_sas_remote_device_default_destruct_handler(
398   SCI_BASE_REMOTE_DEVICE_T * remote_device
399)
400{
401   SCIF_LOG_WARNING((
402      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
403      SCIF_LOG_OBJECT_REMOTE_DEVICE,
404      "RemoteDevice:0x%x State:0x%x invalid state to destruct.\n",
405      remote_device,
406      sci_base_state_machine_get_state(
407         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
408   ));
409
410   return SCI_FAILURE_INVALID_STATE;
411}
412
413/**
414 * @brief This method provides default handling (i.e. returns an error);
415 *        when there is an attempt to reset a remote device from an invalid
416 *        state.
417 *
418 * @param[in]  remote_device This parameter specifies the remote device
419 *             object on which there is an attempt to fail the device.
420 *
421 * @return This method returns an indication that the fail transition is not
422 *         allowed.
423 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
424 */
425SCI_STATUS scif_sas_remote_device_default_reset_handler(
426   SCI_BASE_REMOTE_DEVICE_T * remote_device
427)
428{
429   SCIF_LOG_WARNING((
430      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
431      SCIF_LOG_OBJECT_REMOTE_DEVICE,
432      "RemoteDevice:0x%x State:0x%x invalid state to reset.\n",
433      remote_device,
434      sci_base_state_machine_get_state(
435         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
436   ));
437
438   return SCI_FAILURE_INVALID_STATE;
439}
440
441/**
442 * @brief This method provides default handling (i.e. returns an error);
443 *        when there is an attempt to complete a reset to the remote device
444 *        from an invalid state.
445 *
446 * @param[in]  remote_device This parameter specifies the remote device
447 *             object on which there is an attempt to fail the device.
448 *
449 * @return This method returns an indication that the fail transition is not
450 *         allowed.
451 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
452 */
453SCI_STATUS scif_sas_remote_device_default_reset_complete_handler(
454   SCI_BASE_REMOTE_DEVICE_T * remote_device
455)
456{
457   SCIF_LOG_WARNING((
458      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
459      SCIF_LOG_OBJECT_REMOTE_DEVICE,
460      "RemoteDevice:0x%x State:0x%x invalid state to complete reset.\n",
461      remote_device,
462      sci_base_state_machine_get_state(
463         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
464   ));
465
466   return SCI_FAILURE_INVALID_STATE;
467}
468
469/**
470 * @brief This method provides default handling (i.e. returns an error);
471 *        when a user attempts to start an IO on a remote device and a start
472 *        IO operation is not allowed.
473 *
474 * @param[in]  remote_device This parameter specifies the remote device
475 *             object on which the user is attempting to perform a start IO
476 *             operation.
477 * @param[in]  io_request This parameter specifies the IO request to be
478 *             started.
479 *
480 * @return This method returns an indication that start IO operations
481 *         are not allowed.
482 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
483 */
484SCI_STATUS scif_sas_remote_device_default_start_io_handler(
485   SCI_BASE_REMOTE_DEVICE_T * remote_device,
486   SCI_BASE_REQUEST_T       * io_request
487)
488{
489   SCIF_LOG_WARNING((
490      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
491      SCIF_LOG_OBJECT_REMOTE_DEVICE,
492      "RemoteDevice:0x%x State:0x%x invalid state to start IO.\n",
493      remote_device,
494      sci_base_state_machine_get_state(
495         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
496   ));
497
498   return SCI_FAILURE_INVALID_STATE;
499}
500
501/**
502 * @brief This method provides default handling (i.e. returns an error);
503 *        when a user attempts to complete an IO on a remote device and a
504 *        complete IO operation is not allowed.
505 *
506 * @param[in]  remote_device This parameter specifies the remote device
507 *             object on which the user is attempting to perform a complete
508 *             IO operation.
509 * @param[in]  io_request This parameter specifies the IO request to be
510 *             completed.
511 *
512 * @return This method returns an indication that complete IO operations
513 *         are not allowed.
514 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
515 */
516SCI_STATUS scif_sas_remote_device_default_complete_io_handler(
517   SCI_BASE_REMOTE_DEVICE_T * remote_device,
518   SCI_BASE_REQUEST_T       * io_request
519)
520{
521   SCIF_LOG_WARNING((
522      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
523      SCIF_LOG_OBJECT_REMOTE_DEVICE,
524      "RemoteDevice:0x%x State:0x%x invalid state to complete IO\n",
525      remote_device,
526      sci_base_state_machine_get_state(
527         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
528   ));
529
530   return SCI_FAILURE_INVALID_STATE;
531}
532
533
534/**
535 * @brief This method provides default handling (i.e. returns an error);
536 *        when a user attempts to complete an IO on a remote device and a
537 *        complete IO operation is not allowed.
538 *
539 * @param[in]  remote_device This parameter specifies the remote device
540 *             object on which the user is attempting to perform a start IO
541 *             operation.
542 * @param[in]  io_request This parameter specifies the IO request to be
543 *             started.
544 *
545 * @return This method returns an indication that complete IO operations
546 *         are not allowed.
547 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
548 */
549SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler(
550   SCI_BASE_REMOTE_DEVICE_T * remote_device,
551   SCI_BASE_REQUEST_T       * io_request,
552   void                     * response_data,
553   SCI_IO_STATUS              completion_status
554)
555{
556   SCIF_LOG_WARNING((
557      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
558      SCIF_LOG_OBJECT_REMOTE_DEVICE,
559      "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n",
560      remote_device,
561      sci_base_state_machine_get_state(
562         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
563   ));
564
565   return SCI_FAILURE_INVALID_STATE;
566}
567
568
569/**
570 * @brief This method provides default handling (i.e. returns an error);
571 *        when a user attempts to continue an IO on a remote device and a
572 *        continue IO operation is not allowed.
573 *
574 * @param[in]  remote_device This parameter specifies the remote device
575 *             object on which the user is attempting to perform a start IO
576 *             operation.
577 * @param[in]  io_request This parameter specifies the IO request to be
578 *             started.
579 *
580 * @return This method returns an indication that continue IO operations
581 *         are not allowed.
582 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
583 */
584SCI_STATUS scif_sas_remote_device_default_continue_io_handler(
585   SCI_BASE_REMOTE_DEVICE_T * remote_device,
586   SCI_BASE_REQUEST_T       * io_request
587)
588{
589   SCIF_LOG_WARNING((
590      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
591      SCIF_LOG_OBJECT_REMOTE_DEVICE,
592      "RemoteDevice:0x%x State:0x%x invalid state to continue IO\n",
593      remote_device,
594      sci_base_state_machine_get_state(
595         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
596   ));
597
598   return SCI_FAILURE_INVALID_STATE;
599}
600
601/**
602 * @brief This method provides default handling (i.e. returns an error);
603 *        when a user attempts to start a task on a remote device and a
604 *        start task operation is not allowed.
605 *
606 * @param[in]  remote_device This parameter specifies the remote device
607 *             object on which the user is attempting to perform a start
608 *             task operation.
609 * @param[in]  task_request This parameter specifies the task management
610 *             request to be started.
611 *
612 * @return This method returns an indication that start task operations
613 *         are not allowed.
614 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
615 */
616SCI_STATUS scif_sas_remote_device_default_start_task_handler(
617   SCI_BASE_REMOTE_DEVICE_T * remote_device,
618   SCI_BASE_REQUEST_T       * task_request
619)
620{
621   SCIF_LOG_WARNING((
622      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
623      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
624      "RemoteDevice:0x%x State:0x%x invalid state to start task\n",
625      remote_device,
626      sci_base_state_machine_get_state(
627         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
628   ));
629
630   return SCI_FAILURE_INVALID_STATE;
631}
632
633/**
634 * @brief This method provides default handling (i.e. returns an error);
635 *        when a user attempts to complete a task on a remote device and a
636 *        complete task operation is not allowed.
637 *
638 * @param[in]  remote_device This parameter specifies the remote device object
639 *             on which the user is attempting to perform a complete task
640 *             operation.
641 * @param[in]  task_request This parameter specifies the task management
642 *             request to be completed.
643 *
644 * @return This method returns an indication that complete task operations
645 *         are not allowed.
646 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
647 */
648SCI_STATUS scif_sas_remote_device_default_complete_task_handler(
649   SCI_BASE_REMOTE_DEVICE_T * remote_device,
650   SCI_BASE_REQUEST_T       * task_request
651)
652{
653   SCIF_LOG_WARNING((
654      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
655      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
656      "RemoteDevice:0x%x State:0x%x invalid state to complete task\n",
657      remote_device,
658      sci_base_state_machine_get_state(
659         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
660   ));
661
662   return SCI_FAILURE_INVALID_STATE;
663}
664
665/**
666 * @brief This method provides default handling (i.e. returns an error);
667 *        for when the core issues a start completion notification and
668 *        such a notification isn't supported.
669 *
670 * @param[in]  remote_device This parameter specifies the remote device object
671 *             for which the completion notification has occurred.
672 * @param[in]  completion_status This parameter specifies the status
673 *             of the completion operation.
674 *
675 * @return none.
676 */
677void scif_sas_remote_device_default_start_complete_handler(
678   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
679   SCI_STATUS                 completion_status
680)
681{
682   SCIF_LOG_WARNING((
683      sci_base_object_get_logger(fw_device),
684      SCIF_LOG_OBJECT_REMOTE_DEVICE,
685      "RemoteDevice:0x%x State:0x%x invalid state to start complete\n",
686      fw_device,
687      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
688   ));
689}
690
691/**
692 * @brief This method provides default handling (i.e. returns an error);
693 *        for when the core issues a stop completion notification and
694 *        such a notification isn't supported.
695 *
696 * @param[in]  remote_device This parameter specifies the remote device object
697 *             for which the completion notification has occurred.
698 * @param[in]  completion_status This parameter specifies the status
699 *             of the completion operation.
700 *
701 * @return none.
702 */
703void scif_sas_remote_device_default_stop_complete_handler(
704   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
705   SCI_STATUS                 completion_status
706)
707{
708   SCIF_LOG_WARNING((
709      sci_base_object_get_logger(fw_device),
710      SCIF_LOG_OBJECT_REMOTE_DEVICE,
711      "RemoteDevice:0x%x State:0x%x invalid state to stop complete\n",
712      fw_device,
713      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
714   ));
715}
716
717/**
718 * @brief This method provides default handling (i.e. returns an error);
719 *        for when the core issues a ready notification and such a
720 *        notification isn't supported.
721 *
722 * @param[in]  remote_device This parameter specifies the remote device object
723 *             for which the notification has occurred.
724 *
725 * @return none.
726 */
727void scif_sas_remote_device_default_ready_handler(
728   SCIF_SAS_REMOTE_DEVICE_T * fw_device
729)
730{
731   SCIF_LOG_WARNING((
732      sci_base_object_get_logger(fw_device),
733      SCIF_LOG_OBJECT_REMOTE_DEVICE,
734      "RemoteDevice:0x%x State:0x%x invalid state to handle ready\n",
735      fw_device,
736      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
737   ));
738}
739
740/**
741 * @brief This method provides default handling (i.e. returns an error);
742 *        for when the core issues a not ready notification and such a
743 *        notification isn't supported.
744 *
745 * @param[in]  remote_device This parameter specifies the remote device object
746 *             for which the notification has occurred.
747 *
748 * @return none.
749 */
750void scif_sas_remote_device_default_not_ready_handler(
751   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
752   U32                        reason_code
753)
754{
755   SCIF_LOG_WARNING((
756      sci_base_object_get_logger(fw_device),
757      SCIF_LOG_OBJECT_REMOTE_DEVICE,
758      "RemoteDevice:0x%x State:0x%x invalid state to handle not ready\n",
759      fw_device,
760      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
761   ));
762}
763
764#if !defined(DISABLE_WIDE_PORTED_TARGETS)
765/**
766 * @brief This method provides handling of device start complete duing
767 *        UPDATING_PORT_WIDTH state.
768 *
769 * @param[in]  remote_device This parameter specifies the remote device object
770 *             which is start complete.
771 *
772 * @return none.
773 */
774static
775SCI_STATUS scif_sas_remote_device_updating_port_width_state_complete_io_handler(
776   SCI_BASE_REMOTE_DEVICE_T * remote_device,
777   SCI_BASE_REQUEST_T       * io_request
778)
779{
780   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
781                                          remote_device;
782   fw_device->request_count--;
783
784   //If the request count is zero, go ahead to update the RNC.
785   if (fw_device->request_count == 0 )
786   {
787      if (fw_device->destination_state == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING)
788      {
789         //if the destination state of this device change to STOPPING, no matter
790         //whether we need to update the port width, just make the device
791         //go to the STOPPING state, the device will be removed anyway.
792         sci_base_state_machine_change_state(
793            &fw_device->parent.state_machine,
794            SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
795         );
796      }
797      else
798      {
799         //stop the device, upon the stop complete callback, start the device again
800         //with the updated port width.
801         scic_remote_device_stop(
802            fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
803      }
804   }
805
806   return SCI_SUCCESS;
807}
808
809
810/**
811 * @brief This method provides handling of device start complete duing
812 *        UPDATING_PORT_WIDTH state.
813 *
814 * @param[in]  remote_device This parameter specifies the remote device object
815 *             which is start complete.
816 *
817 * @return none.
818 */
819static
820void scif_sas_remote_device_updating_port_width_state_start_complete_handler(
821   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
822   SCI_STATUS                 completion_status
823)
824{
825   SCIF_LOG_INFO((
826      sci_base_object_get_logger(fw_device),
827      SCIF_LOG_OBJECT_REMOTE_DEVICE,
828      "RemoteDevice:0x%x updating port width state start complete handler\n",
829      fw_device,
830      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
831   ));
832
833   if ( fw_device->destination_state
834           == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
835   {
836      //if the destination state of this device change to STOPPING, no matter
837      //whether we need to update the port width again, just make the device
838      //go to the STOPPING state.
839      sci_base_state_machine_change_state(
840         &fw_device->parent.state_machine,
841         SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
842      );
843   }
844   else if ( scic_remote_device_get_port_width(fw_device->core_object)
845                != fw_device->device_port_width
846            && fw_device->device_port_width != 0)
847   {
848      scic_remote_device_stop(
849         fw_device->core_object,
850         SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT
851      );
852   }
853   else
854   {
855      //Port width updating succeeds. Transfer to destination state.
856      sci_base_state_machine_change_state(
857         &fw_device->parent.state_machine,
858         SCI_BASE_REMOTE_DEVICE_STATE_READY
859      );
860   }
861}
862
863/**
864 * @brief This method provides handling of device stop complete duing
865 *        UPDATING_PORT_WIDTH state.
866 *
867 * @param[in]  remote_device This parameter specifies the remote device object
868 *             which is stop complete.
869 *
870 * @return none.
871 */
872static
873void scif_sas_remote_device_updating_port_width_state_stop_complete_handler(
874   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
875   SCI_STATUS                 completion_status
876)
877{
878   SCIF_LOG_INFO((
879      sci_base_object_get_logger(fw_device),
880      SCIF_LOG_OBJECT_REMOTE_DEVICE,
881      "RemoteDevice:0x%x updating port width state stop complete handler\n",
882      fw_device,
883      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
884   ));
885
886   if ( fw_device->destination_state
887           == SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING )
888   {
889      //Device directly transits to STOPPED STATE from UPDATING_PORT_WIDTH state,
890      fw_device->domain->device_start_count--;
891
892      //if the destination state of this device change to STOPPING, no matter
893      //whether we need to update the port width again, just make the device
894      //go to the STOPPED state.
895      sci_base_state_machine_change_state(
896         &fw_device->parent.state_machine,
897         SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
898      );
899   }
900   else
901   {
902      scic_remote_device_set_port_width(
903         fw_device->core_object,
904         fw_device->device_port_width
905      );
906
907      //Device stop complete, means the RNC has been destructed. Now we need to
908      //start core device so the RNC with updated port width will be posted.
909      scic_remote_device_start(
910         fw_device->core_object, SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT);
911   }
912}
913
914/**
915 * @brief This method provides handling (i.e. returns an error);
916 *        when a user attempts to stop a remote device during the updating
917 *        port width state, it will record the destination state for this
918 *        device to be STOPPING, instead of usually READY state.
919 *
920 * @param[in]  remote_device This parameter specifies the remote device object
921 *             on which the user is attempting to perform a stop operation.
922 *
923 * @return This method always return SCI_SUCCESS.
924 */
925static
926SCI_STATUS scif_sas_remote_device_updating_port_width_state_stop_handler(
927   SCI_BASE_REMOTE_DEVICE_T * remote_device
928)
929{
930   SCIF_SAS_REMOTE_DEVICE_T * fw_device =
931      (SCIF_SAS_REMOTE_DEVICE_T *)remote_device;
932
933   SCIF_LOG_INFO((
934      sci_base_object_get_logger(fw_device),
935      SCIF_LOG_OBJECT_REMOTE_DEVICE,
936      "RemoteDevice:0x%x updating port width state stop handler\n",
937      fw_device,
938      sci_base_state_machine_get_state(&fw_device->parent.state_machine)
939   ));
940
941   //Can't stop the device right now. Remember the pending stopping request.
942   //When exit the UPDATING_PORT_WIDTH state, we will check this variable
943   //to decide which state to go.
944   fw_device->destination_state =
945      SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING;
946
947   return SCI_SUCCESS;
948}
949
950#endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
951
952#define scif_sas_remote_device_stopping_complete_io_handler   \
953        scif_sas_remote_device_ready_operational_complete_io_handler
954#define scif_sas_remote_device_stopping_complete_task_handler \
955        scif_sas_remote_device_ready_operational_complete_task_handler
956
957SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
958scif_sas_remote_device_state_handler_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] =
959{
960   // SCI_BASE_REMOTE_DEVICE_STATE_INITIAL
961   {
962      {
963         scif_sas_remote_device_default_start_handler,
964         scif_sas_remote_device_default_stop_handler,
965         scif_sas_remote_device_default_fail_handler,
966         scif_sas_remote_device_default_destruct_handler,
967         scif_sas_remote_device_default_reset_handler,
968         scif_sas_remote_device_default_reset_complete_handler,
969         scif_sas_remote_device_default_start_io_handler,
970         scif_sas_remote_device_default_complete_io_handler,
971         scif_sas_remote_device_default_continue_io_handler,
972         scif_sas_remote_device_default_start_task_handler,
973         scif_sas_remote_device_default_complete_task_handler
974      },
975      scif_sas_remote_device_default_start_complete_handler,
976      scif_sas_remote_device_default_stop_complete_handler,
977      scif_sas_remote_device_default_ready_handler,
978      scif_sas_remote_device_default_not_ready_handler,
979      scif_sas_remote_device_default_start_io_handler,
980      scif_sas_remote_device_default_complete_high_priority_io_handler
981   },
982   // SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
983   {
984      {
985         scif_sas_remote_device_stopped_start_handler,
986         scif_sas_remote_device_default_stop_handler,
987         scif_sas_remote_device_default_fail_handler,
988         scif_sas_remote_device_stopped_destruct_handler,
989         scif_sas_remote_device_default_reset_handler,
990         scif_sas_remote_device_default_reset_complete_handler,
991         scif_sas_remote_device_default_start_io_handler,
992         scif_sas_remote_device_default_complete_io_handler,
993         scif_sas_remote_device_default_continue_io_handler,
994         scif_sas_remote_device_default_start_task_handler,
995         scif_sas_remote_device_default_complete_task_handler
996      },
997      scif_sas_remote_device_default_start_complete_handler,
998      scif_sas_remote_device_default_stop_complete_handler,
999      scif_sas_remote_device_default_ready_handler,
1000      scif_sas_remote_device_default_not_ready_handler,
1001      scif_sas_remote_device_default_start_io_handler,
1002      scif_sas_remote_device_default_complete_high_priority_io_handler
1003   },
1004   // SCI_BASE_REMOTE_DEVICE_STATE_STARTING
1005   {
1006      {
1007         scif_sas_remote_device_default_start_handler,
1008         scif_sas_remote_device_default_stop_handler,
1009         scif_sas_remote_device_default_fail_handler,
1010         scif_sas_remote_device_default_destruct_handler,
1011         scif_sas_remote_device_default_reset_handler,
1012         scif_sas_remote_device_default_reset_complete_handler,
1013         scif_sas_remote_device_default_start_io_handler,
1014         scif_sas_remote_device_default_complete_io_handler,
1015         scif_sas_remote_device_default_continue_io_handler,
1016         scif_sas_remote_device_default_start_task_handler,
1017         scif_sas_remote_device_default_complete_task_handler
1018      },
1019      scif_sas_remote_device_default_start_complete_handler,
1020      scif_sas_remote_device_default_stop_complete_handler,
1021      scif_sas_remote_device_default_ready_handler,
1022      scif_sas_remote_device_default_not_ready_handler,
1023      scif_sas_remote_device_default_start_io_handler,
1024      scif_sas_remote_device_default_complete_high_priority_io_handler
1025   },
1026   // SCI_BASE_REMOTE_DEVICE_STATE_READY - see substate handlers
1027   {
1028      {
1029         scif_sas_remote_device_default_start_handler,
1030         scif_sas_remote_device_default_stop_handler,
1031         scif_sas_remote_device_default_fail_handler,
1032         scif_sas_remote_device_default_destruct_handler,
1033         scif_sas_remote_device_default_reset_handler,
1034         scif_sas_remote_device_default_reset_complete_handler,
1035         scif_sas_remote_device_default_start_io_handler,
1036         scif_sas_remote_device_default_complete_io_handler,
1037         scif_sas_remote_device_default_continue_io_handler,
1038         scif_sas_remote_device_default_start_task_handler,
1039         scif_sas_remote_device_default_complete_task_handler
1040      },
1041      scif_sas_remote_device_default_start_complete_handler,
1042      scif_sas_remote_device_default_stop_complete_handler,
1043      scif_sas_remote_device_default_ready_handler,
1044      scif_sas_remote_device_default_not_ready_handler,
1045      scif_sas_remote_device_default_start_io_handler,
1046      scif_sas_remote_device_default_complete_high_priority_io_handler
1047   },
1048   // SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
1049   {
1050      {
1051         scif_sas_remote_device_default_start_handler,
1052         scif_sas_remote_device_default_stop_handler,
1053         scif_sas_remote_device_default_fail_handler,
1054         scif_sas_remote_device_default_destruct_handler,
1055         scif_sas_remote_device_default_reset_handler,
1056         scif_sas_remote_device_default_reset_complete_handler,
1057         scif_sas_remote_device_default_start_io_handler,
1058         scif_sas_remote_device_stopping_complete_io_handler,
1059         scif_sas_remote_device_default_continue_io_handler,
1060         scif_sas_remote_device_default_start_task_handler,
1061         scif_sas_remote_device_stopping_complete_task_handler
1062      },
1063      scif_sas_remote_device_default_start_complete_handler,
1064      scif_sas_remote_device_stopping_stop_complete_handler,
1065      scif_sas_remote_device_default_ready_handler,
1066      scif_sas_remote_device_default_not_ready_handler,
1067      scif_sas_remote_device_default_start_io_handler,
1068      scif_sas_remote_device_stopping_complete_high_priority_io_handler
1069   },
1070   // SCI_BASE_REMOTE_DEVICE_STATE_FAILED
1071   {
1072      {
1073         scif_sas_remote_device_default_start_handler,
1074         scif_sas_remote_device_failed_stop_handler,
1075         scif_sas_remote_device_default_fail_handler,
1076         scif_sas_remote_device_default_destruct_handler,
1077         scif_sas_remote_device_default_reset_handler,
1078         scif_sas_remote_device_default_reset_complete_handler,
1079         scif_sas_remote_device_default_start_io_handler,
1080         scif_sas_remote_device_default_complete_io_handler,
1081         scif_sas_remote_device_default_continue_io_handler,
1082         scif_sas_remote_device_default_start_task_handler,
1083         scif_sas_remote_device_default_complete_task_handler
1084      },
1085      scif_sas_remote_device_default_start_complete_handler,
1086      scif_sas_remote_device_default_stop_complete_handler,
1087      scif_sas_remote_device_default_ready_handler,
1088      scif_sas_remote_device_default_not_ready_handler,
1089      scif_sas_remote_device_default_start_io_handler,
1090      scif_sas_remote_device_default_complete_high_priority_io_handler
1091   },
1092   // SCI_BASE_REMOTE_DEVICE_STATE_RESETTING - is unused by framework
1093   {
1094      {
1095         scif_sas_remote_device_default_start_handler,
1096         scif_sas_remote_device_default_stop_handler,
1097         scif_sas_remote_device_default_fail_handler,
1098         scif_sas_remote_device_default_destruct_handler,
1099         scif_sas_remote_device_default_reset_handler,
1100         scif_sas_remote_device_default_reset_complete_handler,
1101         scif_sas_remote_device_default_start_io_handler,
1102         scif_sas_remote_device_default_complete_io_handler,
1103         scif_sas_remote_device_default_continue_io_handler,
1104         scif_sas_remote_device_default_start_task_handler,
1105         scif_sas_remote_device_default_complete_task_handler
1106      },
1107      scif_sas_remote_device_default_start_complete_handler,
1108      scif_sas_remote_device_default_stop_complete_handler,
1109      scif_sas_remote_device_default_ready_handler,
1110      scif_sas_remote_device_default_not_ready_handler,
1111      scif_sas_remote_device_default_start_io_handler,
1112      scif_sas_remote_device_default_complete_high_priority_io_handler
1113   },
1114#if !defined(DISABLE_WIDE_PORTED_TARGETS)
1115   // SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH
1116   {
1117      {
1118         scif_sas_remote_device_default_start_handler,
1119         scif_sas_remote_device_updating_port_width_state_stop_handler,
1120         scif_sas_remote_device_default_fail_handler,
1121         scif_sas_remote_device_default_destruct_handler,
1122         scif_sas_remote_device_default_reset_handler,
1123         scif_sas_remote_device_default_reset_complete_handler,
1124         scif_sas_remote_device_default_start_io_handler,
1125         scif_sas_remote_device_updating_port_width_state_complete_io_handler,
1126         scif_sas_remote_device_default_continue_io_handler,
1127         scif_sas_remote_device_default_start_task_handler,
1128         scif_sas_remote_device_default_complete_task_handler
1129      },
1130      scif_sas_remote_device_updating_port_width_state_start_complete_handler,
1131      scif_sas_remote_device_updating_port_width_state_stop_complete_handler,
1132      scif_sas_remote_device_default_ready_handler,
1133      scif_sas_remote_device_default_not_ready_handler,
1134      scif_sas_remote_device_default_start_io_handler,
1135      scif_sas_remote_device_default_complete_high_priority_io_handler
1136   },
1137#endif
1138   // SCI_BASE_REMOTE_DEVICE_STATE_FINAL
1139   {
1140      {
1141         scif_sas_remote_device_default_start_handler,
1142         scif_sas_remote_device_default_stop_handler,
1143         scif_sas_remote_device_default_fail_handler,
1144         scif_sas_remote_device_default_destruct_handler,
1145         scif_sas_remote_device_default_reset_handler,
1146         scif_sas_remote_device_default_reset_complete_handler,
1147         scif_sas_remote_device_default_start_io_handler,
1148         scif_sas_remote_device_default_complete_io_handler,
1149         scif_sas_remote_device_default_continue_io_handler,
1150         scif_sas_remote_device_default_start_task_handler,
1151         scif_sas_remote_device_default_complete_task_handler
1152      },
1153      scif_sas_remote_device_default_start_complete_handler,
1154      scif_sas_remote_device_default_stop_complete_handler,
1155      scif_sas_remote_device_default_ready_handler,
1156      scif_sas_remote_device_default_not_ready_handler,
1157      scif_sas_remote_device_default_start_io_handler,
1158      scif_sas_remote_device_default_complete_high_priority_io_handler
1159   }
1160};
1161
1162