scif_sas_remote_device_ready_substate_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_ready_substate_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 READY sub-state handler methods.
61 */
62
63#include <dev/isci/scil/scic_remote_device.h>
64#include <dev/isci/scil/scic_io_request.h>
65
66#include <dev/isci/scil/scif_sas_logger.h>
67#include <dev/isci/scil/scif_sas_remote_device.h>
68#include <dev/isci/scil/scif_sas_domain.h>
69#include <dev/isci/scil/scif_sas_task_request.h>
70#include <dev/isci/scil/scif_sas_io_request.h>
71#include <dev/isci/scil/scif_sas_internal_io_request.h>
72#include <dev/isci/scil/scif_sas_controller.h>
73#include <dev/isci/scil/sci_abstract_list.h>
74#include <dev/isci/scil/intel_sat.h>
75#include <dev/isci/scil/sci_controller.h>
76
77//******************************************************************************
78//* P R I V A T E   M E T H O D S
79//******************************************************************************
80
81/**
82 * @brief This method implements the behavior common to starting a task mgmt
83 *        request.  It will change the ready substate to task management.
84 *
85 * @param[in]  fw_device This parameter specifies the remote device for
86 *             which to complete a request.
87 * @param[in]  fw_task This parameter specifies the task management
88 *             request being started.
89 *
90 * @return This method returns a value indicating the status of the
91 *         start operation.
92 */
93static
94SCI_STATUS scif_sas_remote_device_start_task_request(
95   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
96   SCIF_SAS_TASK_REQUEST_T  * fw_task
97)
98{
99   // Transition into the TASK MGMT substate if not already in it.
100   if (fw_device->ready_substate_machine.current_state_id
101       != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT)
102   {
103      sci_base_state_machine_change_state(
104         &fw_device->ready_substate_machine,
105         SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT
106      );
107   }
108
109   fw_device->request_count++;
110   fw_device->task_request_count++;
111
112   return SCI_SUCCESS;
113}
114
115//******************************************************************************
116//* R E A D Y   O P E R A T I O N A L   H A N D L E R S
117//******************************************************************************
118
119/**
120 * @brief This method provides OPERATIONAL sub-state specific handling for
121 *        when the core remote device object issues a device not ready
122 *        notification.
123 *
124 * @param[in]  remote_device This parameter specifies the remote device
125 *             object for which the notification occurred.
126 *
127 * @return none.
128 */
129static
130void scif_sas_remote_device_ready_operational_not_ready_handler(
131   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
132   U32                        reason_code
133)
134{
135   if (reason_code == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
136   {
137      sci_base_state_machine_change_state(
138         &fw_device->ready_substate_machine,
139         SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
140      );
141   }
142   else
143   {
144      // Even though we are in the OPERATIONAL state, the core remote device is not
145      // ready.  As a result, we process user requests/events as if we were
146      // stopping the framework remote device.
147      sci_base_state_machine_change_state(
148         &fw_device->ready_substate_machine,
149         SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED
150      );
151   }
152}
153
154/**
155 * @brief This method provides TASK MGMT sub-state specific handling for when
156 *        the core remote device object issues a device not ready notification.
157 *
158 * @param[in]  remote_device This parameter specifies the remote device
159 *             object for which the notification occurred.
160 *
161 * @return none.
162 */
163static
164void scif_sas_remote_device_ready_task_management_not_ready_handler(
165   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
166   U32                        reason_code
167)
168{
169   //do nothing. Don't need to go to suspended substate.
170}
171
172/**
173 * @brief This method provides OPERATIONAL sub-state specific handling for
174 *        when the remote device is being stopped by the framework.
175 *
176 * @param[in]  remote_device This parameter specifies the remote device
177 *             object for which the stop operation is being requested.
178 *
179 * @return This method returns an indication as to whether the failure
180 *         operation completed successfully.
181 */
182static
183SCI_STATUS scif_sas_remote_device_ready_operational_stop_handler(
184   SCI_BASE_REMOTE_DEVICE_T * remote_device
185)
186{
187   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
188                                          remote_device;
189
190   sci_base_state_machine_change_state(
191      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
192   );
193
194   return fw_device->operation_status;
195}
196
197/**
198 * @brief This method provides OPERATIONAL sub-state specific handling for
199 *        when the user attempts to destruct the remote device.  In
200 *        the READY state the framework must first stop the device
201 *        before destructing it.
202 *
203 * @param[in]  remote_device This parameter specifies the remote device
204 *             object for which the framework is attempting to start.
205 *
206 * @return This method returns an indication as to whether the destruct
207 *         operation completed successfully.
208 */
209static
210SCI_STATUS scif_sas_remote_device_ready_operational_destruct_handler(
211   SCI_BASE_REMOTE_DEVICE_T * remote_device
212)
213{
214   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
215                                          remote_device;
216
217   fw_device->destruct_when_stopped = TRUE;
218
219   return (fw_device->state_handlers->parent.stop_handler(&fw_device->parent));
220}
221
222/**
223 * @brief This method provides OPERATIONAL sub-state specific handling for
224 *        when the remote device undergoes a failure condition.
225 *
226 * @param[in]  remote_device This parameter specifies the remote device
227 *             object for which the failure condition occurred.
228 *
229 * @return This method returns an indication as to whether the failure
230 *         operation completed successfully.
231 */
232static
233SCI_STATUS scif_sas_remote_device_ready_operational_fail_handler(
234   SCI_BASE_REMOTE_DEVICE_T * remote_device
235)
236{
237   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
238                                          remote_device;
239
240   SCIF_LOG_WARNING((
241      sci_base_object_get_logger(fw_device),
242      SCIF_LOG_OBJECT_REMOTE_DEVICE,
243      "RemoteDevice:0x%x ready device failed\n",
244      fw_device
245   ));
246
247   sci_base_state_machine_change_state(
248      &fw_device->parent.state_machine, SCI_BASE_REMOTE_DEVICE_STATE_FAILED
249   );
250
251   /// @todo Fix the return code handling.
252   return SCI_FAILURE;
253}
254
255/**
256 * @brief This method provides OPERATIONAL sub-state specific handling for
257 *        when a user attempts to start an IO request on a remote
258 *        device.
259 *
260 * @param[in]  remote_device This parameter specifies the remote device
261 *             object on which the user is attempting to perform a start
262 *             IO operation.
263 * @param[in]  io_request This parameter specifies the IO request to be
264 *             started.
265 *
266 * @return This method returns an indication as to whether the IO request
267 *         started successfully.
268 */
269static
270SCI_STATUS scif_sas_remote_device_ready_operational_start_io_handler(
271   SCI_BASE_REMOTE_DEVICE_T * remote_device,
272   SCI_BASE_REQUEST_T       * io_request
273)
274{
275   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
276                                          remote_device;
277   SCIF_SAS_IO_REQUEST_T    * fw_io     = (SCIF_SAS_IO_REQUEST_T*) io_request;
278   SCI_STATUS                 status;
279
280   status = fw_io->parent.state_handlers->start_handler(&fw_io->parent.parent);
281
282   if (status == SCI_SUCCESS)
283   {
284      fw_device->request_count++;
285   }
286
287   return status;
288}
289
290/**
291 * @brief This method provides OPERATIONAL sub-state specific handling for
292 *        when a user attempts to start an IO request on a remote
293 *        device.
294 *
295 * @param[in]  remote_device This parameter specifies the remote device
296 *             object on which the user is attempting to perform a complete
297 *             IO operation.
298 * @param[in]  io_request This parameter specifies the IO request to
299 *             be completed.
300 *
301 * @return This method returns an indication as to whether the IO request
302 *         completed successfully.
303 */
304SCI_STATUS scif_sas_remote_device_ready_operational_complete_io_handler(
305   SCI_BASE_REMOTE_DEVICE_T * remote_device,
306   SCI_BASE_REQUEST_T       * io_request
307)
308{
309   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
310                                          remote_device;
311   fw_device->request_count--;
312   return SCI_SUCCESS;
313}
314
315
316/**
317 * @brief This method provides OPERATIONAL sub-state specific handling for
318 *        when a user attempts to start an IO request on a remote
319 *        device.
320 *
321 * @param[in]  remote_device This parameter specifies the remote device
322 *             object on which the user is attempting to perform a complete
323 *             IO operation.
324 * @param[in]  io_request This parameter specifies the IO request to
325 *             be completed.
326 *
327 * @return This method returns an indication as to whether the IO request
328 *         completed successfully.
329 */
330static
331SCI_STATUS scif_sas_remote_device_ready_operational_complete_high_priority_io_handler(
332   SCI_BASE_REMOTE_DEVICE_T * remote_device,
333   SCI_BASE_REQUEST_T       * io_request,
334   void                     * response_data,
335   SCI_IO_STATUS              completion_status
336)
337{
338   SCIF_LOG_WARNING((
339      sci_base_object_get_logger((SCIF_SAS_REMOTE_DEVICE_T *)remote_device),
340      SCIF_LOG_OBJECT_REMOTE_DEVICE,
341      "RemoteDevice:0x%x State:0x%x invalid state to complete high priority IO\n",
342      remote_device,
343      sci_base_state_machine_get_state(
344         &((SCIF_SAS_REMOTE_DEVICE_T *)remote_device)->parent.state_machine)
345   ));
346
347   return SCI_FAILURE_INVALID_STATE;
348}
349
350
351/**
352 * @brief This method provides OPERATIONAL sub-state specific handling for when
353 *        the framework attempts to continue an IO request on a remote
354 *        device.
355 *
356 * @param[in]  remote_device This parameter specifies the remote device
357 *             object on which the user is attempting to perform a continue
358 *             IO operation.
359 * @param[in]  io_request This parameter specifies the IO request to
360 *             be continued.
361 *
362 * @return This method returns an indication as to whether the IO request
363 *         completed successfully.
364 */
365static
366SCI_STATUS scif_sas_remote_device_ready_operational_continue_io_handler(
367   SCI_BASE_REMOTE_DEVICE_T * remote_device,
368   SCI_BASE_REQUEST_T       * io_request
369)
370{
371   /// @todo Fix the return code handling.
372   return SCI_FAILURE;
373}
374
375/**
376 * @brief This method provides OPERATIONAL sub-state specific handling for
377 *        when a user attempts to start a task management request on
378 *        a remote device.  This includes terminating all of the affected
379 *        ongoing IO requests (i.e. aborting them in the silicon) and then
380 *        issuing the task management request to the silicon.
381 *
382 * @param[in]  remote_device This parameter specifies the remote device
383 *             object on which the user is attempting to perform a start
384 *             task operation.
385 * @param[in]  task_request This parameter specifies the task management
386 *             request to be started.
387 *
388 * @return This method returns an indication as to whether the task
389 *         management request started successfully.
390 */
391static
392SCI_STATUS scif_sas_remote_device_ready_operational_start_task_handler(
393   SCI_BASE_REMOTE_DEVICE_T * remote_device,
394   SCI_BASE_REQUEST_T       * task_request
395)
396{
397   SCI_STATUS                 status     = SCI_FAILURE;
398   SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
399                                           remote_device;
400   SCIF_SAS_TASK_REQUEST_T  * fw_task    = (SCIF_SAS_TASK_REQUEST_T*)
401                                           task_request;
402   U8 task_function =
403         scif_sas_task_request_get_function(fw_task);
404
405   SMP_DISCOVER_RESPONSE_PROTOCOLS_T  dev_protocols;
406
407   scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
408   if (   dev_protocols.u.bits.attached_ssp_target
409       || dev_protocols.u.bits.attached_stp_target)
410   {
411      // //NOTE: For STP/SATA targets we currently terminate all requests for
412      //       any type of task management.
413      if (  (task_function == SCI_SAS_ABORT_TASK_SET)
414         || (task_function == SCI_SAS_CLEAR_TASK_SET)
415         || (task_function == SCI_SAS_LOGICAL_UNIT_RESET)
416         || (task_function == SCI_SAS_I_T_NEXUS_RESET)
417         || (task_function == SCI_SAS_HARD_RESET) )
418      {
419         // Terminate all of the requests in the silicon for this device.
420         scif_sas_domain_terminate_requests(
421            fw_device->domain, fw_device, NULL, fw_task
422         );
423
424         status = scif_sas_remote_device_start_task_request(fw_device, fw_task);
425      }
426      else if (  (task_function == SCI_SAS_CLEAR_ACA)
427              || (task_function == SCI_SAS_QUERY_TASK)
428              || (task_function == SCI_SAS_QUERY_TASK_SET)
429              || (task_function == SCI_SAS_QUERY_ASYNCHRONOUS_EVENT) )
430      {
431       ASSERT(!dev_protocols.u.bits.attached_stp_target);
432         status = scif_sas_remote_device_start_task_request(fw_device, fw_task);
433      }
434      else if (task_function == SCI_SAS_ABORT_TASK)
435      {
436         SCIF_SAS_REQUEST_T * fw_request
437            = scif_sas_domain_get_request_by_io_tag(
438                 fw_device->domain, fw_task->io_tag_to_manage
439              );
440
441         // Determine if the request being aborted was found.
442         if (fw_request != NULL)
443         {
444            scif_sas_domain_terminate_requests(
445               fw_device->domain, fw_device, fw_request, fw_task
446            );
447
448            status = scif_sas_remote_device_start_task_request(
449                        fw_device, fw_task
450                     );
451         }
452         else
453            status = SCI_FAILURE_INVALID_IO_TAG;
454      }
455   }
456   else
457      status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
458
459   if (status != SCI_SUCCESS)
460   {
461      SCIF_LOG_ERROR((
462         sci_base_object_get_logger(fw_device),
463         SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
464         "Controller:0x%x TaskRequest:0x%x Status:0x%x start task failure\n",
465         fw_device, fw_task, status
466      ));
467   }
468
469   return status;
470}
471
472/**
473 * @brief This method provides OPERATIONAL sub-state specific handling for
474 *        when a user attempts to complete a task management request on
475 *        a remote device.
476 *
477 * @param[in]  remote_device This parameter specifies the remote device object
478 *             on which the user is attempting to perform a complete task
479 *             operation.
480 * @param[in]  task_request This parameter specifies the task management
481 *             request to be completed.
482 *
483 * @return This method returns an indication as to whether the task
484 *         management request succeeded.
485 */
486SCI_STATUS scif_sas_remote_device_ready_operational_complete_task_handler(
487   SCI_BASE_REMOTE_DEVICE_T * remote_device,
488   SCI_BASE_REQUEST_T       * task_request
489)
490{
491   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
492                                          remote_device;
493   fw_device->request_count--;
494   fw_device->task_request_count--;
495
496   return SCI_SUCCESS;
497}
498
499/**
500 * @brief This method provides OPERATIONAL sub-state specific handling for
501 *        when a user attempts to start a high priority IO request on a remote
502 *        device.
503 *
504 * @param[in]  remote_device This parameter specifies the remote device
505 *             object on which the user is attempting to perform a start
506 *             IO operation.
507 * @param[in]  io_request This parameter specifies the IO request to be
508 *             started.
509 *
510 * @return This method returns an indication as to whether the IO request
511 *         started successfully.
512 */
513static
514SCI_STATUS scif_sas_remote_device_ready_operational_start_high_priority_io_handler(
515   SCI_BASE_REMOTE_DEVICE_T * remote_device,
516   SCI_BASE_REQUEST_T       * io_request
517)
518{
519   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
520                                          remote_device;
521   SCIF_SAS_IO_REQUEST_T    * fw_io     = (SCIF_SAS_IO_REQUEST_T*) io_request;
522
523   SMP_DISCOVER_RESPONSE_PROTOCOLS_T  dev_protocols;
524
525   scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
526
527   if (dev_protocols.u.bits.attached_smp_target)
528   {
529      //transit to task management state for smp request phase.
530      if (fw_device->ready_substate_machine.current_state_id
531       != SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT)
532      {
533         sci_base_state_machine_change_state(
534            &fw_device->ready_substate_machine,
535            SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT
536         );
537      }
538   }
539
540   fw_device->request_count++;
541
542   return fw_io->parent.state_handlers->start_handler(&fw_io->parent.parent);
543}
544
545
546/**
547 * @brief This method provides TASK MANAGEMENT sub-state specific handling for
548 *        when a user attempts to complete a task management request on
549 *        a remote device.
550 *
551 * @param[in]  remote_device This parameter specifies the remote device object
552 *             on which the user is attempting to perform a complete task
553 *             operation.
554 * @param[in]  task_request This parameter specifies the task management
555 *             request to be completed.
556 *
557 * @return This method returns an indication as to whether the task
558 *         management request succeeded.
559 */
560SCI_STATUS scif_sas_remote_device_ready_task_management_complete_task_handler(
561   SCI_BASE_REMOTE_DEVICE_T * remote_device,
562   SCI_BASE_REQUEST_T       * task_request
563)
564{
565   SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
566                                          remote_device;
567
568   SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)
569                                       task_request;
570
571   fw_device->request_count--;
572   fw_device->task_request_count--;
573
574   // All existing task management requests and all of the IO requests
575   // affectected by the task management request must complete before
576   // the remote device can transition back into the READY / OPERATIONAL
577   // state.
578   if (  (fw_device->task_request_count == 0)
579      && (fw_task->affected_request_count == 0) )
580   {
581      sci_base_state_machine_change_state(
582         &fw_device->ready_substate_machine,
583         SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
584      );
585   }
586
587   return SCI_SUCCESS;
588}
589
590/**
591 * @brief This method provides SUSPENDED sub-state specific handling for
592 *        when the core remote device object issues a device ready
593 *        notification.  This effectively causes the framework remote
594 *        device to transition back into the OPERATIONAL state.
595 *
596 * @param[in]  remote_device This parameter specifies the remote device
597 *             object for which the notification occurred.
598 *
599 * @return none.
600 */
601static
602void scif_sas_remote_device_ready_suspended_ready_handler(
603   SCIF_SAS_REMOTE_DEVICE_T * fw_device
604)
605{
606   sci_base_state_machine_change_state(
607      &fw_device->ready_substate_machine,
608      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
609   );
610}
611
612
613/**
614 * @brief This handler is currently solely used by smp remote device for
615 *        discovering.
616 *
617 * @param[in]  remote_device This parameter specifies the remote device
618 *             object on which the user is attempting to perform a complete high
619 *             priority IO operation.
620 * @param[in]  io_request This parameter specifies the high priority IO request
621 *             to be completed.
622 *
623 * @return SCI_STATUS indicate whether the io complete successfully.
624 */
625SCI_STATUS
626scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(
627   SCI_BASE_REMOTE_DEVICE_T * remote_device,
628   SCI_BASE_REQUEST_T       * io_request,
629   void                     * response_data,
630   SCI_IO_STATUS              completion_status
631)
632{
633   SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
634                                           remote_device;
635   SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
636   SCI_STATUS                 status     = SCI_SUCCESS;
637   SCIC_TRANSPORT_PROTOCOL    protocol;
638
639   SCIF_LOG_TRACE((
640      sci_base_object_get_logger(remote_device),
641      SCIF_LOG_OBJECT_REMOTE_DEVICE | SCIF_LOG_OBJECT_IO_REQUEST,
642      "scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
643      remote_device, io_request, response_data, completion_status
644   ));
645
646   fw_device->request_count--;
647
648   // we are back to ready operational sub state here.
649   sci_base_state_machine_change_state(
650      &fw_device->ready_substate_machine,
651      SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
652   );
653
654   protocol = scic_io_request_get_protocol(fw_request->core_object);
655
656   // If this request was an SMP initiator request we created, then
657   // decode the response.
658   if (protocol == SCIC_SMP_PROTOCOL)
659   {
660      if (completion_status != SCI_IO_FAILURE_TERMINATED)
661      {
662         status = scif_sas_smp_remote_device_decode_smp_response(
663                     fw_device, fw_request, response_data, completion_status
664                  );
665      }
666      else
667         scif_sas_smp_remote_device_terminated_request_handler(fw_device, fw_request);
668   }
669   else
670   {
671      // Currently, there are only internal SMP requests.  So, default work
672      // is simply to clean up the internal request.
673      if (fw_request->is_internal == TRUE)
674      {
675         scif_sas_internal_io_request_complete(
676            fw_device->domain->controller,
677            (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_request,
678            SCI_SUCCESS
679         );
680      }
681   }
682
683   return status;
684}
685
686
687SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
688scif_sas_remote_device_ready_substate_handler_table[] =
689{
690   // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL
691   {
692      {
693         scif_sas_remote_device_default_start_handler,
694         scif_sas_remote_device_ready_operational_stop_handler,
695         scif_sas_remote_device_ready_operational_fail_handler,
696         scif_sas_remote_device_ready_operational_destruct_handler,
697         scif_sas_remote_device_default_reset_handler,
698         scif_sas_remote_device_default_reset_complete_handler,
699         scif_sas_remote_device_ready_operational_start_io_handler,
700         scif_sas_remote_device_ready_operational_complete_io_handler,
701         scif_sas_remote_device_ready_operational_continue_io_handler,
702         scif_sas_remote_device_ready_operational_start_task_handler,
703         scif_sas_remote_device_ready_operational_complete_task_handler
704      },
705      scif_sas_remote_device_default_start_complete_handler,
706      scif_sas_remote_device_default_stop_complete_handler,
707      scif_sas_remote_device_default_ready_handler,
708      scif_sas_remote_device_ready_operational_not_ready_handler,
709      scif_sas_remote_device_ready_operational_start_high_priority_io_handler,  //
710      scif_sas_remote_device_ready_operational_complete_high_priority_io_handler
711   },
712   // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED
713   {
714      {
715         scif_sas_remote_device_default_start_handler,
716         scif_sas_remote_device_ready_operational_stop_handler,
717         scif_sas_remote_device_ready_operational_fail_handler,
718         scif_sas_remote_device_ready_operational_destruct_handler,
719         scif_sas_remote_device_default_reset_handler,
720         scif_sas_remote_device_default_reset_complete_handler,
721         scif_sas_remote_device_default_start_io_handler,
722         scif_sas_remote_device_ready_operational_complete_io_handler,
723         scif_sas_remote_device_default_continue_io_handler,
724         scif_sas_remote_device_ready_operational_start_task_handler,
725         scif_sas_remote_device_ready_operational_complete_task_handler
726      },
727      scif_sas_remote_device_default_start_complete_handler,
728      scif_sas_remote_device_default_stop_complete_handler,
729      scif_sas_remote_device_ready_suspended_ready_handler,
730      scif_sas_remote_device_default_not_ready_handler,
731      scif_sas_remote_device_default_start_io_handler,
732      scif_sas_remote_device_ready_operational_complete_high_priority_io_handler
733   },
734   // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT
735   {
736      {
737         scif_sas_remote_device_default_start_handler,
738         scif_sas_remote_device_ready_operational_stop_handler,
739         scif_sas_remote_device_ready_operational_fail_handler,
740         scif_sas_remote_device_ready_operational_destruct_handler,
741         scif_sas_remote_device_default_reset_handler,
742         scif_sas_remote_device_default_reset_complete_handler,
743         scif_sas_remote_device_default_start_io_handler,
744         scif_sas_remote_device_ready_operational_complete_io_handler,
745         scif_sas_remote_device_ready_operational_continue_io_handler,
746         scif_sas_remote_device_ready_operational_start_task_handler,
747         scif_sas_remote_device_ready_task_management_complete_task_handler
748      },
749      scif_sas_remote_device_default_start_complete_handler,
750      scif_sas_remote_device_default_stop_complete_handler,
751      scif_sas_remote_device_default_ready_handler,
752      scif_sas_remote_device_ready_task_management_not_ready_handler,
753      scif_sas_remote_device_ready_operational_start_high_priority_io_handler,
754      scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler
755   },
756   // SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR
757   {
758      {
759         scif_sas_remote_device_default_start_handler,
760         scif_sas_remote_device_ready_operational_stop_handler,
761         scif_sas_remote_device_ready_operational_fail_handler,
762         scif_sas_remote_device_ready_operational_destruct_handler,
763         scif_sas_remote_device_default_reset_handler,
764         scif_sas_remote_device_default_reset_complete_handler,
765         scif_sas_remote_device_default_start_io_handler,
766         scif_sas_remote_device_ready_operational_complete_io_handler,
767         scif_sas_remote_device_default_continue_io_handler,
768         scif_sas_remote_device_ready_operational_start_task_handler,
769         scif_sas_remote_device_ready_operational_complete_task_handler
770      },
771      scif_sas_remote_device_default_start_complete_handler,
772      scif_sas_remote_device_default_stop_complete_handler,
773      scif_sas_remote_device_ready_suspended_ready_handler,
774      scif_sas_remote_device_default_not_ready_handler,
775      scif_sas_remote_device_default_start_io_handler,
776      scif_sas_remote_device_ready_operational_complete_high_priority_io_handler
777   },
778};
779
780