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