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 /**
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 */
93 static
scif_sas_remote_device_start_task_request(SCIF_SAS_REMOTE_DEVICE_T * fw_device,SCIF_SAS_TASK_REQUEST_T * fw_task)94 SCI_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 */
129 static
scif_sas_remote_device_ready_operational_not_ready_handler(SCIF_SAS_REMOTE_DEVICE_T * fw_device,U32 reason_code)130 void 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 */
163 static
scif_sas_remote_device_ready_task_management_not_ready_handler(SCIF_SAS_REMOTE_DEVICE_T * fw_device,U32 reason_code)164 void 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 */
182 static
scif_sas_remote_device_ready_operational_stop_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device)183 SCI_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 */
209 static
scif_sas_remote_device_ready_operational_destruct_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device)210 SCI_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 */
232 static
scif_sas_remote_device_ready_operational_fail_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device)233 SCI_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 */
269 static
scif_sas_remote_device_ready_operational_start_io_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)270 SCI_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 */
scif_sas_remote_device_ready_operational_complete_io_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)304 SCI_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 */
330 static
scif_sas_remote_device_ready_operational_complete_high_priority_io_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,void * response_data,SCI_IO_STATUS completion_status)331 SCI_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 */
365 static
scif_sas_remote_device_ready_operational_continue_io_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)366 SCI_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 */
391 static
scif_sas_remote_device_ready_operational_start_task_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)392 SCI_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 */
scif_sas_remote_device_ready_operational_complete_task_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)486 SCI_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 */
513 static
scif_sas_remote_device_ready_operational_start_high_priority_io_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)514 SCI_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 */
scif_sas_remote_device_ready_task_management_complete_task_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)560 SCI_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 */
601 static
scif_sas_remote_device_ready_suspended_ready_handler(SCIF_SAS_REMOTE_DEVICE_T * fw_device)602 void 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 */
625 SCI_STATUS
scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,void * response_data,SCI_IO_STATUS completion_status)626 scif_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
687 SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
688 scif_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