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