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 state handler routines for each
60 * of the domain states defined by the SCI_BASE_DOMAIN state
61 * machine.
62 * @note
63 * - The discover method must be synchronized with the
64 * controller's completion handler. The OS specific driver
65 * component is responsible for ensuring this occurs. If the
66 * discovery method is called from within the call
67 * tree of the completion routine, then no action is necessary.
68 */
69
70
71 #include <dev/isci/scil/scic_port.h>
72 #include <dev/isci/scil/scic_io_request.h>
73 #include <dev/isci/scil/scif_sas_logger.h>
74 #include <dev/isci/scil/scif_sas_domain.h>
75
76 //******************************************************************************
77 //* P R O T E C T E D M E T H O D S
78 //******************************************************************************
79
80 //******************************************************************************
81 //* S T A R T I N G H A N D L E R S
82 //******************************************************************************
83
84 static
scif_sas_domain_starting_port_ready_handler(SCI_BASE_DOMAIN_T * domain)85 SCI_STATUS scif_sas_domain_starting_port_ready_handler(
86 SCI_BASE_DOMAIN_T * domain
87 )
88 {
89 SCIF_LOG_TRACE((
90 sci_base_object_get_logger(domain),
91 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
92 "scif_sas_domain_starting_port_ready_handler(0x%x) enter\n",
93 domain
94 ));
95
96 // The domain was previously completely stopped. Now that the port is
97 // ready we can transition the domain to the ready state.
98 sci_base_state_machine_change_state(
99 &domain->state_machine, SCI_BASE_DOMAIN_STATE_READY
100 );
101
102 return SCI_SUCCESS;
103 }
104
105 //******************************************************************************
106 //* R E A D Y H A N D L E R S
107 //******************************************************************************
108
109 /**
110 * @brief This method provides READY state specific handling for
111 * when a user attempts to discover a domain.
112 *
113 * @param[in] domain This parameter specifies the domain object
114 * on which the user is attempting to perform a discover
115 * operation.
116 *
117 * @return This method returns an indication of whether the discover operation
118 * succeeded.
119 * @retval SCI_SUCCESS This value is returned when the discover operation
120 * begins successfully.
121 */
122 static
scif_sas_domain_ready_discover_handler(SCI_BASE_DOMAIN_T * domain,U32 op_timeout,U32 device_timeout)123 SCI_STATUS scif_sas_domain_ready_discover_handler(
124 SCI_BASE_DOMAIN_T * domain,
125 U32 op_timeout,
126 U32 device_timeout
127 )
128 {
129 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain;
130
131 SCIF_LOG_TRACE((
132 sci_base_object_get_logger(domain),
133 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
134 "scif_sas_domain_ready_discover_handler(0x%x, 0x%x, 0x%x) enter\n",
135 domain, op_timeout, device_timeout
136 ));
137
138 fw_domain->operation.timeout = op_timeout;
139 fw_domain->operation.device_timeout = device_timeout;
140 fw_domain->operation.status = SCI_SUCCESS;
141
142 scif_cb_timer_start(
143 fw_domain->controller,
144 fw_domain->operation.timer,
145 fw_domain->operation.timeout
146 );
147
148 scif_sas_domain_transition_to_discovering_state(fw_domain);
149
150 return fw_domain->operation.status;
151 }
152
153 /**
154 * @brief This method provides READY state processing for reception of a
155 * port NOT ready notification from the core.
156 *
157 * @param[in] domain This parameter specifies the domain object
158 * on which the core port has just come ready.
159 *
160 * @return
161 */
162 static
scif_sas_domain_ready_port_not_ready_handler(SCI_BASE_DOMAIN_T * domain,U32 reason_code)163 SCI_STATUS scif_sas_domain_ready_port_not_ready_handler(
164 SCI_BASE_DOMAIN_T * domain,
165 U32 reason_code
166 )
167 {
168 SCIF_LOG_TRACE((
169 sci_base_object_get_logger(domain),
170 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
171 "scif_sas_domain_ready_port_not_ready_handler(0x%x, 0x%x) enter\n",
172 domain,
173 reason_code
174 ));
175
176 if (reason_code != SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED)
177 {
178 // Change to the STOPPING state to cause existing request
179 // completions to be terminated and devices removed.
180 sci_base_state_machine_change_state(
181 &domain->state_machine, SCI_BASE_DOMAIN_STATE_STOPPING
182 );
183 }
184
185 return SCI_SUCCESS;
186 }
187
188 /**
189 * @brief This method provides READY state specific handling for
190 * when a user attempts to start an IO request.
191 *
192 * @param[in] domain This parameter specifies the domain object
193 * on which the user is attempting to perform a start IO
194 * operation.
195 * @param[in] remote_device This parameter specifies the remote device
196 * object on which the user is attempting to perform a start IO
197 * operation.
198 * @param[in] io_request This parameter specifies the io request that is
199 * being started.
200 *
201 * @return This method returns an indication of whether the start IO
202 * operation succeeded.
203 * @retval SCI_SUCCESS This value is returned when the start IO operation
204 * begins successfully.
205 */
206 static
scif_sas_domain_ready_start_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)207 SCI_STATUS scif_sas_domain_ready_start_io_handler(
208 SCI_BASE_DOMAIN_T * domain,
209 SCI_BASE_REMOTE_DEVICE_T * remote_device,
210 SCI_BASE_REQUEST_T * io_request
211 )
212 {
213 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
214 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
215 remote_device;
216 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
217 SCI_STATUS status;
218
219 SCIF_LOG_TRACE((
220 sci_base_object_get_logger(domain),
221 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
222 "scif_sas_domain_ready_start_io_handler(0x%x, 0x%x, 0x%x) enter\n",
223 domain, remote_device, io_request
224 ));
225
226 status = fw_device->state_handlers->parent.start_io_handler(
227 &fw_device->parent, &fw_request->parent
228 );
229
230 if (status == SCI_SUCCESS)
231 {
232 // Add the IO to the list of outstanding requests on the domain.
233 sci_fast_list_insert_tail(
234 &fw_domain->request_list, &fw_request->list_element
235 );
236 }
237
238 return status;
239 }
240
241 /**
242 * @brief This method provides READY state specific handling for
243 * when a user attempts to complete an IO request.
244 *
245 * @param[in] domain This parameter specifies the domain object
246 * on which the user is attempting to perform a complete IO
247 * operation.
248 * @param[in] remote_device This parameter specifies the remote device
249 * object on which the user is attempting to perform a complete
250 * IO operation.
251 * @param[in] io_request This parameter specifies the io request that is
252 * being completed.
253 *
254 * @return This method returns an indication of whether the complete IO
255 * operation succeeded.
256 * @retval SCI_SUCCESS This value is returned when the complete IO operation
257 * is successful.
258 */
259 static
scif_sas_domain_ready_complete_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)260 SCI_STATUS scif_sas_domain_ready_complete_io_handler(
261 SCI_BASE_DOMAIN_T * domain,
262 SCI_BASE_REMOTE_DEVICE_T * remote_device,
263 SCI_BASE_REQUEST_T * io_request
264 )
265 {
266 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
267 remote_device;
268 SCIF_SAS_REQUEST_T * fw_request= (SCIF_SAS_REQUEST_T*) io_request;
269
270 SCIF_LOG_TRACE((
271 sci_base_object_get_logger(domain),
272 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
273 "scif_sas_domain_ready_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
274 domain, remote_device, io_request
275 ));
276
277 // Remove the IO from the list of outstanding requests on the domain.
278 sci_fast_list_remove_element(&fw_request->list_element);
279
280 return fw_device->state_handlers->parent.complete_io_handler(
281 &fw_device->parent, &fw_request->parent
282 );
283 }
284
285 /**
286 * @brief This method provides READY state specific handling for
287 * when a user attempts to continue an IO request.
288 *
289 * @param[in] domain This parameter specifies the domain object
290 * on which the user is attempting to perform a continue IO
291 * operation.
292 * @param[in] remote_device This parameter specifies the remote device
293 * object on which the user is attempting to perform a start IO
294 * operation.
295 * @param[in] io_request This parameter specifies the io request that is
296 * being started.
297 *
298 * @return This method returns an indication of whether the continue IO
299 * operation succeeded.
300 * @retval SCI_SUCCESS This value is returned when the continue IO operation
301 * begins successfully.
302 */
303 static
scif_sas_domain_ready_continue_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)304 SCI_STATUS scif_sas_domain_ready_continue_io_handler(
305 SCI_BASE_DOMAIN_T * domain,
306 SCI_BASE_REMOTE_DEVICE_T * remote_device,
307 SCI_BASE_REQUEST_T * io_request
308 )
309 {
310 SCIF_LOG_TRACE((
311 sci_base_object_get_logger(domain),
312 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
313 "scif_sas_domain_ready_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n",
314 domain, remote_device, io_request
315 ));
316
317 /// @todo fix return code handling.
318 return SCI_FAILURE;
319 }
320
321 /**
322 * @brief This method provides READY state specific handling for
323 * when a user attempts to start a task request.
324 *
325 * @param[in] domain This parameter specifies the domain object
326 * on which the user is attempting to perform a start task
327 * operation.
328 * @param[in] remote_device This parameter specifies the remote device
329 * object on which the user is attempting to perform a start IO
330 * operation.
331 * @param[in] task_request This parameter specifies the task request that
332 * is being started.
333 *
334 * @return This method returns an indication of whether the start task
335 * operation succeeded.
336 * @retval SCI_SUCCESS This value is returned when the start task operation
337 * begins successfully.
338 */
339 static
scif_sas_domain_ready_start_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)340 SCI_STATUS scif_sas_domain_ready_start_task_handler(
341 SCI_BASE_DOMAIN_T * domain,
342 SCI_BASE_REMOTE_DEVICE_T * remote_device,
343 SCI_BASE_REQUEST_T * task_request
344 )
345 {
346 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
347 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
348 remote_device;
349 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) task_request;
350 SCI_STATUS status;
351
352 SCIF_LOG_TRACE((
353 sci_base_object_get_logger(domain),
354 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
355 "scif_sas_domain_ready_start_task_handler(0x%x, 0x%x, 0x%x) enter\n",
356 domain, remote_device, task_request
357 ));
358
359 status = fw_device->state_handlers->parent.start_task_handler(
360 &fw_device->parent, &fw_request->parent
361 );
362
363 if (status == SCI_SUCCESS)
364 {
365 // Add the task to the list of outstanding requests on the domain.
366 sci_fast_list_insert_tail(
367 &fw_domain->request_list, &fw_request->list_element
368 );
369 }
370
371 return status;
372 }
373
374 /**
375 * @brief This method provides READY state specific handling for
376 * when a user attempts to complete a task request.
377 *
378 * @param[in] domain This parameter specifies the domain object
379 * on which the user is attempting to perform a complete task
380 * operation.
381 * @param[in] remote_device This parameter specifies the remote device
382 * object on which the user is attempting to perform a start IO
383 * operation.
384 * @param[in] task_request This parameter specifies the task request that
385 * is being started.
386 *
387 * @return This method returns an indication of whether the complete task
388 * operation succeeded.
389 * @retval SCI_SUCCESS This value is returned when the complete task operation
390 * begins successfully.
391 */
392 static
scif_sas_domain_ready_complete_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)393 SCI_STATUS scif_sas_domain_ready_complete_task_handler(
394 SCI_BASE_DOMAIN_T * domain,
395 SCI_BASE_REMOTE_DEVICE_T * remote_device,
396 SCI_BASE_REQUEST_T * task_request
397 )
398 {
399 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
400 remote_device;
401 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) task_request;
402
403 SCIF_LOG_TRACE((
404 sci_base_object_get_logger(domain),
405 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
406 "scif_sas_domain_ready_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
407 domain, remote_device, task_request
408 ));
409
410 // Remove the IO from the list of outstanding requests on the domain.
411 sci_fast_list_remove_element(&fw_request->list_element);
412
413 return fw_device->state_handlers->parent.complete_task_handler(
414 &fw_device->parent, &fw_request->parent
415 );
416 }
417
418
419 /**
420 * @brief This method provides READY state specific handling for when a user
421 * attempts to start a high priority IO request.
422 *
423 * @param[in] domain This parameter specifies the domain object
424 * on which the user is attempting to perform a start high priority
425 * IO operation (which is exclusively for Phy Control hard reset).
426 * @param[in] remote_device This parameter specifies the remote device
427 * object on which the user is attempting to perform a start
428 * high priority IO operation.
429 * @param[in] io_request This parameter specifies the io request that is
430 * being started.
431 *
432 * @return This method returns an indication of whether the start IO
433 * operation succeeded.
434 * @retval SCI_SUCCESS This value is returned when the start IO operation
435 * begins successfully.
436 */
437 static
scif_sas_domain_ready_start_high_priority_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)438 SCI_STATUS scif_sas_domain_ready_start_high_priority_io_handler(
439 SCI_BASE_DOMAIN_T * domain,
440 SCI_BASE_REMOTE_DEVICE_T * remote_device,
441 SCI_BASE_REQUEST_T * io_request
442 )
443 {
444 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
445 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
446 remote_device;
447 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
448 SCI_STATUS status;
449
450 SCIF_LOG_TRACE((
451 sci_base_object_get_logger(domain),
452 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
453 "scif_sas_domain_ready_start_high_priority_request_handler(0x%x, 0x%x, 0x%x) enter\n",
454 domain, remote_device, io_request
455 ));
456
457 status = fw_device->state_handlers->start_high_priority_io_handler(
458 &fw_device->parent, &fw_request->parent
459 );
460
461 if (status == SCI_SUCCESS)
462 {
463 // Add the IO to the list of outstanding requests on the domain.
464
465 // When domain is in READY state, this high priority io is likely
466 // a smp Phy Control or Discover request sent to parent device of
467 // a target device, which is to be Target Reset. This high priority
468 // IO's probably has already been added to the domain's list as a
469 // SCIF_SAS_TASK_REQUEST. We need to check if it is already on the
470 // list.
471
472 if ( ! sci_fast_list_is_on_this_list(
473 &fw_domain->request_list, &fw_request->list_element))
474
475 sci_fast_list_insert_tail(
476 &fw_domain->request_list, &fw_request->list_element
477 );
478 }
479
480 return status;
481 }
482
483
484 /**
485 * @brief This method provides READY state specific handling for
486 * when a user attempts to complete an high priroity IO request.
487 *
488 * @param[in] domain This parameter specifies the domain object
489 * on which the user is attempting to perform a complete high
490 * priority IO operation (which is exclusively for Phy Control
491 * hard reset).
492 * @param[in] remote_device This parameter specifies the remote device
493 * object on which the user is attempting to perform a complete
494 * IO operation.
495 * @param[in] io_request This parameter specifies the io request that is
496 * being completed.
497 *
498 * @return This method returns an indication of whether the complete IO
499 * operation succeeded.
500 * @retval SCI_SUCCESS This value is returned when the complete IO operation
501 * is successful.
502 */
503 static
scif_sas_domain_ready_complete_high_priority_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,void * response_data,SCI_IO_STATUS completion_status)504 SCI_STATUS scif_sas_domain_ready_complete_high_priority_io_handler(
505 SCI_BASE_DOMAIN_T * domain,
506 SCI_BASE_REMOTE_DEVICE_T * remote_device,
507 SCI_BASE_REQUEST_T * io_request,
508 void * response_data,
509 SCI_IO_STATUS completion_status
510 )
511 {
512 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
513 remote_device;
514 SCIF_SAS_REQUEST_T * fw_request= (SCIF_SAS_REQUEST_T*) io_request;
515
516 SCIC_TRANSPORT_PROTOCOL protocol;
517
518 SCIF_LOG_TRACE((
519 sci_base_object_get_logger(domain),
520 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
521 "scif_sas_domain_ready_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
522 domain, remote_device, io_request, response_data
523 ));
524
525 protocol = scic_io_request_get_protocol(fw_request->core_object);
526
527 // If the request is an SMP HARD/LINK RESET request, then the request
528 // came through the task management path (partially). As a result,
529 // the accounting for the request is managed in the task request
530 // completion path. Thus, only change the domain request counter if
531 // the request is not an SMP target reset of some sort.
532 if (
533 (protocol != SCIC_SMP_PROTOCOL)
534 || (fw_device->protocol_device.smp_device.current_activity !=
535 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET)
536 )
537 {
538 sci_fast_list_remove_element(&fw_request->list_element);
539 }
540
541 return fw_device->state_handlers->complete_high_priority_io_handler(
542 &fw_device->parent, &fw_request->parent, response_data, completion_status
543 );
544 }
545
546 //******************************************************************************
547 //* S T O P P I N G H A N D L E R S
548 //******************************************************************************
549
550 static
scif_sas_domain_stopping_device_stop_complete_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)551 SCI_STATUS scif_sas_domain_stopping_device_stop_complete_handler(
552 SCI_BASE_DOMAIN_T * domain,
553 SCI_BASE_REMOTE_DEVICE_T * remote_device
554 )
555 {
556 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
557
558 SCIF_LOG_TRACE((
559 sci_base_object_get_logger(domain),
560 SCIF_LOG_OBJECT_DOMAIN,
561 "scif_sas_domain_stopping_device_stop_complete_handler(0x%x, 0x%x) enter\n",
562 domain, remote_device
563 ));
564
565 // Attempt to transition to the stopped state.
566 scif_sas_domain_transition_to_stopped_state(fw_domain);
567
568 return SCI_SUCCESS;
569 }
570
571 /**
572 * @brief This method provides STOPPING state specific handling for
573 * when a user attempts to complete an IO request.
574 *
575 * @param[in] domain This parameter specifies the domain object
576 * on which the user is attempting to perform a complete IO
577 * operation.
578 * @param[in] remote_device This parameter specifies the remote device
579 * object on which the user is attempting to perform a complete
580 * IO operation.
581 * @param[in] io_request This parameter specifies the io request that is
582 * being completed.
583 *
584 * @return This method returns an indication of whether the complete IO
585 * operation succeeded.
586 * @retval SCI_SUCCESS This value is returned when the complete IO operation
587 * is successful.
588 */
589 static
scif_sas_domain_stopping_complete_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)590 SCI_STATUS scif_sas_domain_stopping_complete_io_handler(
591 SCI_BASE_DOMAIN_T * domain,
592 SCI_BASE_REMOTE_DEVICE_T * remote_device,
593 SCI_BASE_REQUEST_T * io_request
594 )
595 {
596 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
597 SCI_STATUS status;
598
599 SCIF_LOG_TRACE((
600 sci_base_object_get_logger(domain),
601 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
602 "scif_sas_domain_stopping_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
603 domain, remote_device, io_request
604 ));
605
606 status = scif_sas_domain_ready_complete_io_handler(
607 domain, remote_device, io_request
608 );
609
610 // Attempt to transition to the stopped state.
611 scif_sas_domain_transition_to_stopped_state(fw_domain);
612
613 return status;
614 }
615
616
617 /**
618 * @brief This method provides STOPPING state specific handling for
619 * when a user attempts to complete an IO request.
620 *
621 * @param[in] domain This parameter specifies the domain object
622 * on which the user is attempting to perform a complete IO
623 * operation.
624 * @param[in] remote_device This parameter specifies the remote device
625 * object on which the user is attempting to perform a complete
626 * IO operation.
627 * @param[in] io_request This parameter specifies the io request that is
628 * being completed.
629 *
630 * @return This method returns an indication of whether the complete IO
631 * operation succeeded.
632 * @retval SCI_SUCCESS This value is returned when the complete IO operation
633 * is successful.
634 */
635 static
scif_sas_domain_stopping_complete_high_priority_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,void * response_data,SCI_IO_STATUS completion_status)636 SCI_STATUS scif_sas_domain_stopping_complete_high_priority_io_handler(
637 SCI_BASE_DOMAIN_T * domain,
638 SCI_BASE_REMOTE_DEVICE_T * remote_device,
639 SCI_BASE_REQUEST_T * io_request,
640 void * response_data,
641 SCI_IO_STATUS completion_status
642 )
643 {
644 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
645 SCI_STATUS status;
646
647 SCIF_LOG_TRACE((
648 sci_base_object_get_logger(domain),
649 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
650 "scif_sas_domain_stopping_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
651 domain, remote_device, io_request
652 ));
653
654 status = scif_sas_domain_ready_complete_high_priority_io_handler(
655 domain, remote_device, io_request, response_data, completion_status
656 );
657
658 // Attempt to transition to the stopped state.
659 scif_sas_domain_transition_to_stopped_state(fw_domain);
660
661 return status;
662 }
663
664
665 /**
666 * @brief This method provides STOPPING state specific handling for
667 * when a user attempts to complete a task request.
668 *
669 * @param[in] domain This parameter specifies the domain object
670 * on which the user is attempting to perform a complete task
671 * operation.
672 *
673 * @return This method returns an indication of whether the complete task
674 * operation succeeded.
675 * @retval SCI_SUCCESS This value is returned when the complete task operation
676 * begins successfully.
677 */
678 static
scif_sas_domain_stopping_complete_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)679 SCI_STATUS scif_sas_domain_stopping_complete_task_handler(
680 SCI_BASE_DOMAIN_T * domain,
681 SCI_BASE_REMOTE_DEVICE_T * remote_device,
682 SCI_BASE_REQUEST_T * task_request
683 )
684 {
685 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
686 SCI_STATUS status;
687
688 SCIF_LOG_TRACE((
689 sci_base_object_get_logger(domain),
690 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
691 "scif_sas_domain_stopping_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
692 domain, remote_device, task_request
693 ));
694
695 status = scif_sas_domain_ready_complete_task_handler(
696 domain, remote_device, task_request
697 );
698
699 // Attempt to transition to the stopped state.
700 scif_sas_domain_transition_to_stopped_state(fw_domain);
701
702 return SCI_SUCCESS;
703 }
704
705 //******************************************************************************
706 //* D I S C O V E R I N G H A N D L E R S
707 //******************************************************************************
708
709 /**
710 * @brief This method provides DISCOVERING state specific processing for
711 * reception of a port NOT ready notification from the core. A port
712 * NOT ready notification forces the discovery operation to complete
713 * in error. Additionally, all IOs are aborted and devices removed.
714 *
715 * @param[in] domain This parameter specifies the domain object
716 * for which the core port is no longer ready.
717 *
718 * @return
719 */
720 static
scif_sas_domain_discovering_port_not_ready_handler(SCI_BASE_DOMAIN_T * domain,U32 reason_code)721 SCI_STATUS scif_sas_domain_discovering_port_not_ready_handler(
722 SCI_BASE_DOMAIN_T * domain,
723 U32 reason_code
724 )
725 {
726 SCIF_LOG_TRACE((
727 sci_base_object_get_logger(domain),
728 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
729 "scif_sas_domain_discovering_port_not_ready_handler(0x%x, 0x%x) enter\n",
730 domain,
731 reason_code
732 ));
733
734 // Change to the STOPPING state to cause existing request
735 // completions to be terminated and devices removed.
736 sci_base_state_machine_change_state(
737 &domain->state_machine, SCI_BASE_DOMAIN_STATE_STOPPING
738 );
739
740 return SCI_SUCCESS;
741 }
742
743 static
scif_sas_domain_discovering_device_start_complete_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)744 SCI_STATUS scif_sas_domain_discovering_device_start_complete_handler(
745 SCI_BASE_DOMAIN_T * domain,
746 SCI_BASE_REMOTE_DEVICE_T * remote_device
747 )
748 {
749 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain;
750
751 SCIF_LOG_TRACE((
752 sci_base_object_get_logger(domain),
753 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
754 "scif_sas_domain_discovering_device_start_complete_handler(0x%x) enter\n",
755 domain, remote_device
756 ));
757
758 //domain will decide what's next step.
759 scif_sas_domain_continue_discover(fw_domain);
760
761 return SCI_SUCCESS;
762 }
763
764 // ---------------------------------------------------------------------------
765
766 static
scif_sas_domain_discovering_device_stop_complete_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)767 SCI_STATUS scif_sas_domain_discovering_device_stop_complete_handler(
768 SCI_BASE_DOMAIN_T * domain,
769 SCI_BASE_REMOTE_DEVICE_T * remote_device
770 )
771 {
772 SCIF_LOG_TRACE((
773 sci_base_object_get_logger(domain),
774 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
775 "scif_sas_domain_discovering_device_stop_complete_handler(0x%x) enter\n",
776 domain, remote_device
777 ));
778
779 return SCI_FAILURE;
780 }
781
782
783 /**
784 * @brief This method provides DISCOVERING state specific handling for when a user
785 * attempts to start a high priority IO request.
786 *
787 * @param[in] domain This parameter specifies the domain object
788 * on which the user is attempting to perform a start IO
789 * operation.
790 * @param[in] remote_device This parameter specifies the remote device
791 * object on which the user is attempting to perform a start IO
792 * operation.
793 * @param[in] io_request This parameter specifies the io request that is
794 * being started.
795 *
796 * @return This method returns an indication of whether the start IO
797 * operation succeeded.
798 * @retval SCI_SUCCESS This value is returned when the start IO operation
799 * begins successfully.
800 */
801 static
scif_sas_domain_discovering_start_high_priority_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)802 SCI_STATUS scif_sas_domain_discovering_start_high_priority_io_handler(
803 SCI_BASE_DOMAIN_T * domain,
804 SCI_BASE_REMOTE_DEVICE_T * remote_device,
805 SCI_BASE_REQUEST_T * io_request
806 )
807 {
808 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
809 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
810 remote_device;
811 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
812 SCI_STATUS status;
813
814 SCIF_LOG_TRACE((
815 sci_base_object_get_logger(domain),
816 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
817 "scif_sas_domain_discovery_start_high_priority_request_handler(0x%x, 0x%x, 0x%x) enter\n",
818 domain, remote_device, io_request
819 ));
820
821 status = fw_device->state_handlers->start_high_priority_io_handler(
822 &fw_device->parent, &fw_request->parent
823 );
824
825 if (status == SCI_SUCCESS)
826 {
827 // Add the IO to the list of outstanding requests on the domain.
828
829 // It is possible this high priority IO's has already been added to
830 // the domain's list as a SCIF_SAS_TASK_REQUEST. We need to check
831 // if it is already on the list.
832 if ( ! sci_fast_list_is_on_this_list(
833 &fw_domain->request_list, &fw_request->list_element))
834
835 sci_fast_list_insert_tail(
836 &fw_domain->request_list, &fw_request->list_element
837 );
838 }
839
840 return status;
841 }
842
843
844 /**
845 * @brief This method provides DISCOVERING state specific handling for
846 * when a user attempts to complete an IO request. User IOs are
847 * allowed to be completed during discovery.
848 *
849 * @param[in] domain This parameter specifies the domain object
850 * on which the user is attempting to perform a complete IO
851 * operation.
852 * @param[in] remote_device This parameter specifies the remote device
853 * object on which the user is attempting to perform a complete
854 * IO operation.
855 * @param[in] io_request This parameter specifies the io request that is
856 * being completed.
857 *
858 * @return This method returns an indication of whether the complete IO
859 * operation succeeded.
860 * @retval SCI_SUCCESS This value is returned when the complete IO operation
861 * is successful.
862 */
863 static
scif_sas_domain_discovering_complete_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)864 SCI_STATUS scif_sas_domain_discovering_complete_io_handler(
865 SCI_BASE_DOMAIN_T * domain,
866 SCI_BASE_REMOTE_DEVICE_T * remote_device,
867 SCI_BASE_REQUEST_T * io_request
868 )
869 {
870 SCIF_LOG_TRACE((
871 sci_base_object_get_logger(domain),
872 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
873 "scif_sas_domain_discovering_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
874 domain, remote_device, io_request
875 ));
876
877 return scif_sas_domain_ready_complete_io_handler(
878 domain, remote_device, io_request
879 );
880 }
881
882 /**
883 * @brief This method provides DISCOVERING state specific handling for
884 * when a user attempts to complete an high priroity IO request. User
885 * IOs are allowed to be completed during discovery.
886 *
887 * @param[in] domain This parameter specifies the domain object
888 * on which the user is attempting to perform a complete IO
889 * operation.
890 * @param[in] remote_device This parameter specifies the remote device
891 * object on which the user is attempting to perform a complete
892 * IO operation.
893 * @param[in] io_request This parameter specifies the io request that is
894 * being completed.
895 *
896 * @return This method returns an indication of whether the complete IO
897 * operation succeeded.
898 * @retval SCI_SUCCESS This value is returned when the complete IO operation
899 * is successful.
900 */
901 static
scif_sas_domain_discovering_complete_high_priority_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,void * response_data,SCI_IO_STATUS completion_status)902 SCI_STATUS scif_sas_domain_discovering_complete_high_priority_io_handler(
903 SCI_BASE_DOMAIN_T * domain,
904 SCI_BASE_REMOTE_DEVICE_T * remote_device,
905 SCI_BASE_REQUEST_T * io_request,
906 void * response_data,
907 SCI_IO_STATUS completion_status
908 )
909 {
910 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
911 remote_device;
912 SCIF_SAS_REQUEST_T * fw_request= (SCIF_SAS_REQUEST_T*) io_request;
913
914 SCIC_TRANSPORT_PROTOCOL protocol;
915
916 SCIF_LOG_TRACE((
917 sci_base_object_get_logger(domain),
918 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
919 "scif_sas_domain_discovering_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
920 domain, remote_device, io_request, response_data
921 ));
922
923 protocol = scic_io_request_get_protocol(fw_request->core_object);
924
925 // Remove the IO from the list of outstanding requests on the domain.
926
927 // If the request is an SMP HARD/LINK RESET request, then the request
928 // came through the task management path (partially). As a result,
929 // the accounting for the request is managed in the task request
930 // completion path. Thus, only change the domain request counter if
931 // the request is not an SMP target reset of some sort.
932 if (
933 (protocol != SCIC_SMP_PROTOCOL)
934 || (fw_device->protocol_device.smp_device.current_activity !=
935 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET)
936 )
937 {
938 sci_fast_list_remove_element(&fw_request->list_element);
939 }
940
941 return fw_device->state_handlers->complete_high_priority_io_handler(
942 &fw_device->parent, &fw_request->parent, response_data, completion_status
943 );
944 }
945
946
947 /**
948 * @brief This method provides DISCOVERING state specific handling for
949 * when the framework attempts to complete an IO request. Internal
950 * Framework IOs allowed to be continued during discovery.
951 *
952 * @param[in] domain This parameter specifies the domain object
953 * on which the user is attempting to perform a continue IO
954 * operation.
955 * @param[in] remote_device This parameter specifies the remote device
956 * object on which the user is attempting to perform a continue
957 * IO operation.
958 * @param[in] io_request This parameter specifies the io request that is
959 * being continued.
960 *
961 * @return This method returns an indication of whether the continue IO
962 * operation succeeded.
963 * @retval SCI_SUCCESS This value is returned when the continue IO operation
964 * is successful.
965 */
966 static
scif_sas_domain_discovering_continue_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)967 SCI_STATUS scif_sas_domain_discovering_continue_io_handler(
968 SCI_BASE_DOMAIN_T * domain,
969 SCI_BASE_REMOTE_DEVICE_T * remote_device,
970 SCI_BASE_REQUEST_T * io_request
971 )
972 {
973 SCIF_LOG_TRACE((
974 sci_base_object_get_logger(domain),
975 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
976 "scif_sas_domain_discovering_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n",
977 domain, remote_device, io_request
978 ));
979
980 /// @todo fix return code handling.
981 return SCI_FAILURE;
982 }
983
984
985 /**
986 * @brief This method provides handling when a user attempts to start
987 * a task on a domain in DISCOVER state, only hard reset is allowed.
988 *
989 * @param[in] domain This parameter specifies the domain object
990 * on which the user is attempting to perform a start task
991 * operation.
992 * @param[in] remote_device This parameter specifies the remote device
993 * object on which the user is attempting to perform a start IO
994 * operation.
995 * @param[in] task_request This parameter specifies the task request that
996 * is being started.
997 *
998 * @return This method returns a status of start task operations
999 * @retval SCI_FAILURE_INVALID_STATE This value is returned for any tasks,
1000 * except for HARD RESET.
1001 */
1002 static
scif_sas_domain_discovering_start_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)1003 SCI_STATUS scif_sas_domain_discovering_start_task_handler(
1004 SCI_BASE_DOMAIN_T * domain,
1005 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1006 SCI_BASE_REQUEST_T * task_request
1007 )
1008 {
1009 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
1010 remote_device;
1011 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request;
1012
1013 //Only let target reset go through.
1014 if (scif_sas_task_request_get_function(fw_task)
1015 == SCI_SAS_HARD_RESET)
1016 {
1017 //If the domain is in the middle of smp DISCOVER process,
1018 //interrupt it. After target reset is done, resume the smp DISCOVERY.
1019 scif_sas_domain_cancel_smp_activities(fw_device->domain);
1020
1021 return scif_sas_domain_ready_start_task_handler(domain, remote_device, task_request);
1022 }
1023 else{
1024 SCIF_LOG_WARNING((
1025 sci_base_object_get_logger(domain),
1026 SCIF_LOG_OBJECT_DOMAIN,
1027 "Domain:0x%x Device:0x%x State:0x%x start task message invalid\n",
1028 domain, remote_device,
1029 sci_base_state_machine_get_state(&domain->state_machine)
1030 ));
1031
1032 return SCI_FAILURE_INVALID_STATE;
1033 }
1034 }
1035
1036
1037 /**
1038 * @brief This method provides DISCOVERING state specific handling for
1039 * when a user attempts to complete a task request. User task
1040 * management requests are allowed to be completed during discovery.
1041 *
1042 * @param[in] domain This parameter specifies the domain object
1043 * on which the user is attempting to perform a complete IO
1044 * operation.
1045 * @param[in] remote_device This parameter specifies the remote device
1046 * object on which the user is attempting to perform a complete
1047 * IO operation.
1048 * @param[in] task_request This parameter specifies the task request that
1049 * is being completed.
1050 *
1051 * @return This method returns an indication of whether the complete task
1052 * management operation succeeded.
1053 * @retval SCI_SUCCESS This value is returned when the complete task request
1054 * is successful.
1055 */
1056 static
scif_sas_domain_discovering_complete_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)1057 SCI_STATUS scif_sas_domain_discovering_complete_task_handler(
1058 SCI_BASE_DOMAIN_T * domain,
1059 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1060 SCI_BASE_REQUEST_T * task_request
1061 )
1062 {
1063 SCI_STATUS status;
1064
1065 SCIF_LOG_TRACE((
1066 sci_base_object_get_logger(domain),
1067 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
1068 "scif_sas_domain_discovering_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
1069 domain, remote_device, task_request
1070 ));
1071
1072 status = scif_sas_domain_ready_complete_task_handler(
1073 domain, remote_device, task_request
1074 );
1075
1076 return status;
1077 }
1078
1079 //******************************************************************************
1080 //* D E F A U L T H A N D L E R S
1081 //******************************************************************************
1082
1083 /**
1084 * @brief This method provides default handling (i.e. returns an error)
1085 * when a user attempts to discover a domain and a discovery
1086 * operation is not allowed.
1087 *
1088 * @param[in] domain This parameter specifies the domain object
1089 * on which the user is attempting to perform an discover
1090 * operation.
1091 * @param[in] op_timeout This parameter specifies the timeout
1092 * (in milliseconds) for the entire discovery operation.
1093 * This timeout value should be some multiple of the
1094 * individual device_timeout value.
1095 * @param[in] device_timeout This parameter specifies the timeout
1096 * (in milliseconds) for an individual device being discovered
1097 * and configured during this operation.
1098 *
1099 * @return This method returns an indication that discovery operations
1100 * are not allowed.
1101 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1102 */
1103 static
scif_sas_domain_default_discover_handler(SCI_BASE_DOMAIN_T * domain,U32 op_timeout,U32 device_timeout)1104 SCI_STATUS scif_sas_domain_default_discover_handler(
1105 SCI_BASE_DOMAIN_T * domain,
1106 U32 op_timeout,
1107 U32 device_timeout
1108 )
1109 {
1110 SCIF_LOG_WARNING((
1111 sci_base_object_get_logger((SCIF_SAS_DOMAIN_T *)domain),
1112 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
1113 "Domain:0x%x State:0x%x requested to discover in invalid state\n",
1114 domain,
1115 sci_base_state_machine_get_state(&domain->state_machine)
1116 ));
1117
1118 return SCI_FAILURE_INVALID_STATE;
1119 }
1120
1121 /**
1122 * @brief This method provides default processing for reception of a port
1123 * ready notification from the core.
1124 *
1125 * @param[in] domain This parameter specifies the domain object
1126 * on which the core port has just come ready.
1127 *
1128 * @return
1129 */
1130 static
scif_sas_domain_default_port_ready_handler(SCI_BASE_DOMAIN_T * domain)1131 SCI_STATUS scif_sas_domain_default_port_ready_handler(
1132 SCI_BASE_DOMAIN_T * domain
1133 )
1134 {
1135 SCIF_LOG_INFO((
1136 sci_base_object_get_logger(domain),
1137 SCIF_LOG_OBJECT_DOMAIN,
1138 "Domain:0x%x State:0x%x port now ready\n",
1139 domain,
1140 sci_base_state_machine_get_state(&domain->state_machine)
1141 ));
1142
1143 return SCI_SUCCESS;
1144 }
1145
1146 /**
1147 * @brief This method provides default processing for reception of a port
1148 * NOT ready notification from the core.
1149 *
1150 * @param[in] domain This parameter specifies the domain object
1151 * on which the core port has just come ready.
1152 *
1153 * @return
1154 */
1155 static
scif_sas_domain_default_port_not_ready_handler(SCI_BASE_DOMAIN_T * domain,U32 reason_code)1156 SCI_STATUS scif_sas_domain_default_port_not_ready_handler(
1157 SCI_BASE_DOMAIN_T * domain,
1158 U32 reason_code
1159 )
1160 {
1161 SCIF_LOG_WARNING((
1162 sci_base_object_get_logger(domain),
1163 SCIF_LOG_OBJECT_DOMAIN,
1164 "Domain:0x%x State:0x%x Port Not Ready 0x%x in invalid state\n",
1165 domain,
1166 sci_base_state_machine_get_state(&domain->state_machine),
1167 reason_code
1168 ));
1169
1170 return SCI_FAILURE_INVALID_STATE;
1171 }
1172
1173 /**
1174 * @brief This method provides default handling (i.e. returns an error)
1175 * when a user attempts to start an IO on a domain and a start
1176 * IO operation is not allowed.
1177 *
1178 * @param[in] domain This parameter specifies the domain object
1179 * on which the user is attempting to perform a start IO
1180 * operation.
1181 * @param[in] remote_device This parameter specifies the remote device
1182 * object on which the user is attempting to perform a start IO
1183 * operation.
1184 * @param[in] io_request This parameter specifies the io request that is
1185 * being started.
1186 *
1187 * @return This method returns an indication that start IO operations
1188 * are not allowed.
1189 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1190 */
1191 static
scif_sas_domain_default_start_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)1192 SCI_STATUS scif_sas_domain_default_start_io_handler(
1193 SCI_BASE_DOMAIN_T * domain,
1194 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1195 SCI_BASE_REQUEST_T * io_request
1196 )
1197 {
1198 SCIF_LOG_WARNING((
1199 sci_base_object_get_logger(domain),
1200 SCIF_LOG_OBJECT_DOMAIN,
1201 "Domain:0x%x Device:0x%x State:0x%x start IO message invalid\n",
1202 domain, remote_device,
1203 sci_base_state_machine_get_state(&domain->state_machine)
1204 ));
1205
1206 return SCI_FAILURE_INVALID_STATE;
1207 }
1208
1209 /**
1210 * @brief This method provides default handling (i.e. returns an error)
1211 * when a user attempts to complete an IO on a domain and a
1212 * complete IO operation is not allowed.
1213 *
1214 * @param[in] domain This parameter specifies the domain object
1215 * on which the user is attempting to perform a complete IO
1216 * operation.
1217 * @param[in] remote_device This parameter specifies the remote device
1218 * object on which the user is attempting to perform a complete IO
1219 * operation.
1220 * @param[in] io_request This parameter specifies the io request that is
1221 * being completed.
1222 *
1223 * @return This method returns an indication that complete IO operations
1224 * are not allowed.
1225 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1226 */
1227 static
scif_sas_domain_default_complete_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)1228 SCI_STATUS scif_sas_domain_default_complete_io_handler(
1229 SCI_BASE_DOMAIN_T * domain,
1230 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1231 SCI_BASE_REQUEST_T * io_request
1232 )
1233 {
1234 SCIF_LOG_WARNING((
1235 sci_base_object_get_logger(domain),
1236 SCIF_LOG_OBJECT_DOMAIN,
1237 "Domain:0x%x Device:0x%x State:0x%x complete IO message invalid\n",
1238 domain, remote_device,
1239 sci_base_state_machine_get_state(&domain->state_machine)
1240 ));
1241
1242 return SCI_FAILURE_INVALID_STATE;
1243 }
1244
1245
1246 /**
1247 * @brief This method provides default handling (i.e. returns an error)
1248 * when a user attempts to complete an IO on a domain and a
1249 * complete IO operation is not allowed.
1250 *
1251 * @param[in] domain This parameter specifies the domain object
1252 * on which the user is attempting to perform a complete IO
1253 * operation.
1254 * @param[in] remote_device This parameter specifies the remote device
1255 * object on which the user is attempting to perform a complete IO
1256 * operation.
1257 * @param[in] io_request This parameter specifies the io request that is
1258 * being completed.
1259 *
1260 * @return This method returns an indication that complete IO operations
1261 * are not allowed.
1262 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1263 */
1264 static
scif_sas_domain_default_complete_high_priority_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,void * response_data,SCI_IO_STATUS completion_status)1265 SCI_STATUS scif_sas_domain_default_complete_high_priority_io_handler(
1266 SCI_BASE_DOMAIN_T * domain,
1267 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1268 SCI_BASE_REQUEST_T * io_request,
1269 void * response_data,
1270 SCI_IO_STATUS completion_status
1271 )
1272 {
1273 SCIF_LOG_WARNING((
1274 sci_base_object_get_logger(domain),
1275 SCIF_LOG_OBJECT_DOMAIN,
1276 "Domain:0x%x Device:0x%x State:0x%x complete IO message invalid\n",
1277 domain, remote_device,
1278 sci_base_state_machine_get_state(&domain->state_machine)
1279 ));
1280
1281 return SCI_FAILURE_INVALID_STATE;
1282 }
1283
1284 /**
1285 * @brief This method provides default handling (i.e. returns an error)
1286 * when a user attempts to continue an IO on a domain and a
1287 * continue IO operation is not allowed.
1288 *
1289 * @param[in] domain This parameter specifies the domain object
1290 * on which the user is attempting to perform a continue IO
1291 * operation.
1292 * @param[in] remote_device This parameter specifies the remote device
1293 * object on which the user is attempting to perform a start IO
1294 * operation.
1295 * @param[in] io_request This parameter specifies the io request that is
1296 * being started.
1297 *
1298 * @return This method returns an indication that continue IO operations
1299 * are not allowed.
1300 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1301 */
1302 static
scif_sas_domain_default_continue_io_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)1303 SCI_STATUS scif_sas_domain_default_continue_io_handler(
1304 SCI_BASE_DOMAIN_T * domain,
1305 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1306 SCI_BASE_REQUEST_T * io_request
1307 )
1308 {
1309 SCIF_LOG_WARNING((
1310 sci_base_object_get_logger(domain),
1311 SCIF_LOG_OBJECT_DOMAIN,
1312 "Domain:0x%x Device:0x%x State:0x%x contineu IO message invalid\n",
1313 domain, remote_device,
1314 sci_base_state_machine_get_state(&domain->state_machine)
1315 ));
1316
1317 return SCI_FAILURE_INVALID_STATE;
1318 }
1319
1320 /**
1321 * @brief This method provides default handling (i.e. returns an error)
1322 * when a user attempts to start a task on a domain and a start
1323 * task operation is not allowed.
1324 *
1325 * @param[in] domain This parameter specifies the domain object
1326 * on which the user is attempting to perform a start task
1327 * operation.
1328 * @param[in] remote_device This parameter specifies the remote device
1329 * object on which the user is attempting to perform a start IO
1330 * operation.
1331 * @param[in] task_request This parameter specifies the task request that
1332 * is being started.
1333 *
1334 * @return This method returns an indication that start task operations
1335 * are not allowed.
1336 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1337 */
1338 static
scif_sas_domain_default_start_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)1339 SCI_STATUS scif_sas_domain_default_start_task_handler(
1340 SCI_BASE_DOMAIN_T * domain,
1341 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1342 SCI_BASE_REQUEST_T * task_request
1343 )
1344 {
1345 SCIF_LOG_WARNING((
1346 sci_base_object_get_logger(domain),
1347 SCIF_LOG_OBJECT_DOMAIN,
1348 "Domain:0x%x Device:0x%x State:0x%x start task message invalid\n",
1349 domain, remote_device,
1350 sci_base_state_machine_get_state(&domain->state_machine)
1351 ));
1352
1353 return SCI_FAILURE_INVALID_STATE;
1354 }
1355
1356 /**
1357 * @brief This method provides default handling (i.e. returns an error)
1358 * when a user attempts to complete a task on a domain and a
1359 * complete task operation is not allowed.
1360 *
1361 * @param[in] domain This parameter specifies the domain object
1362 * on which the user is attempting to perform a complete task
1363 * operation.
1364 * @param[in] remote_device This parameter specifies the remote device
1365 * object on which the user is attempting to perform a start IO
1366 * operation.
1367 * @param[in] task_request This parameter specifies the task request that
1368 * is being started.
1369 *
1370 * @return This method returns an indication that complete task operations
1371 * are not allowed.
1372 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1373 */
1374 static
scif_sas_domain_default_complete_task_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * task_request)1375 SCI_STATUS scif_sas_domain_default_complete_task_handler(
1376 SCI_BASE_DOMAIN_T * domain,
1377 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1378 SCI_BASE_REQUEST_T * task_request
1379 )
1380 {
1381 SCIF_LOG_WARNING((
1382 sci_base_object_get_logger(domain),
1383 SCIF_LOG_OBJECT_DOMAIN,
1384 "Domain:0x%x Device:0x%x State:0x%x complete task message invalid\n",
1385 domain, remote_device,
1386 sci_base_state_machine_get_state(&domain->state_machine)
1387 ));
1388
1389 return SCI_FAILURE_INVALID_STATE;
1390 }
1391
1392 /**
1393 * @brief This method provides default handling (i.e. returns an error)
1394 * when a remote device start operation completes in a state.
1395 *
1396 * @param[in] domain This parameter specifies the domain object
1397 * on which the remote device start operation is completing.
1398 * @param[in] remote_device This parameter specifies the remote device
1399 * for which the start operation is completing.
1400 *
1401 * @return This method returns an indication that start operation
1402 * completion is not allowed.
1403 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1404 */
1405 static
scif_sas_domain_default_device_start_complete_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)1406 SCI_STATUS scif_sas_domain_default_device_start_complete_handler(
1407 SCI_BASE_DOMAIN_T * domain,
1408 SCI_BASE_REMOTE_DEVICE_T * remote_device
1409 )
1410 {
1411 SCIF_LOG_WARNING((
1412 sci_base_object_get_logger(domain),
1413 SCIF_LOG_OBJECT_DOMAIN,
1414 "Domain:0x%x Device:0x%x State:0x%x device stop complete message invalid\n",
1415 domain, remote_device,
1416 sci_base_state_machine_get_state(&domain->state_machine)
1417 ));
1418
1419 return SCI_FAILURE_INVALID_STATE;
1420 }
1421
1422 /**
1423 * @brief This method provides default handling (i.e. returns an error)
1424 * when a remote device stop operation completes in a state.
1425 *
1426 * @param[in] domain This parameter specifies the domain object
1427 * on which the remote device stop operation is completing.
1428 * @param[in] remote_device This parameter specifies the remote device
1429 * for which the stop operation is completing.
1430 *
1431 * @return This method returns an indication that stop operation
1432 * completion is not allowed.
1433 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1434 */
1435 static
scif_sas_domain_default_device_stop_complete_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)1436 SCI_STATUS scif_sas_domain_default_device_stop_complete_handler(
1437 SCI_BASE_DOMAIN_T * domain,
1438 SCI_BASE_REMOTE_DEVICE_T * remote_device
1439 )
1440 {
1441 SCIF_LOG_WARNING((
1442 sci_base_object_get_logger(domain),
1443 SCIF_LOG_OBJECT_DOMAIN,
1444 "Domain:0x%x Device:0x%x State:0x%x device stop complete message invalid\n",
1445 domain, remote_device,
1446 sci_base_state_machine_get_state(&domain->state_machine)
1447 ));
1448
1449 return SCI_FAILURE_INVALID_STATE;
1450 }
1451
1452 /**
1453 * @brief This method provides default handling (i.e. returns an error)
1454 * when sci user try to destruct a remote device of this domain.
1455 *
1456 * @param[in] domain This parameter specifies the domain object
1457 * on which the remote device is to be destructed.
1458 * @param[in] remote_device This parameter specifies the remote device
1459 * to be destructed.
1460 *
1461 * @return This method returns an indication that device destruction
1462 * is not allowed.
1463 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1464 */
1465 static
scif_sas_domain_default_device_destruct_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)1466 SCI_STATUS scif_sas_domain_default_device_destruct_handler(
1467 SCI_BASE_DOMAIN_T * domain,
1468 SCI_BASE_REMOTE_DEVICE_T * remote_device
1469 )
1470 {
1471 SCIF_LOG_WARNING((
1472 sci_base_object_get_logger(domain),
1473 SCIF_LOG_OBJECT_DOMAIN,
1474 "Domain:0x%x Device:0x%x State:0x%x device destruct in invalid state\n",
1475 domain, remote_device,
1476 sci_base_state_machine_get_state(&domain->state_machine)
1477 ));
1478
1479 return SCI_FAILURE_INVALID_STATE;
1480 }
1481
1482
1483 /**
1484 * @brief This method provides handling when sci user destruct a remote
1485 * device of this domain in discovering state. Mainly the device
1486 * is removed from domain's remote_device_list.
1487 *
1488 * @param[in] domain This parameter specifies the domain object
1489 * on which the remote device is to be destructed.
1490 * @param[in] remote_device This parameter specifies the remote device
1491 * to be destructed.
1492 *
1493 * @return This method returns a status of the device destruction.
1494 * @retval SCI_SUCCESS This value is returned when a remote device is
1495 * successfully removed from domain.
1496 */
1497 static
scif_sas_domain_discovering_device_destruct_handler(SCI_BASE_DOMAIN_T * domain,SCI_BASE_REMOTE_DEVICE_T * remote_device)1498 SCI_STATUS scif_sas_domain_discovering_device_destruct_handler(
1499 SCI_BASE_DOMAIN_T * domain,
1500 SCI_BASE_REMOTE_DEVICE_T * remote_device
1501 )
1502 {
1503 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain;
1504
1505 SCIF_LOG_WARNING((
1506 sci_base_object_get_logger(domain),
1507 SCIF_LOG_OBJECT_DOMAIN,
1508 "Domain:0x%x Device:0x%x State:0x%x device destruct in domain DISCOVERING state\n",
1509 domain, remote_device,
1510 sci_base_state_machine_get_state(&domain->state_machine)
1511 ));
1512
1513 //remove the remote device from domain's remote_device_list
1514 sci_abstract_list_erase(
1515 &(fw_domain->remote_device_list),
1516 remote_device
1517 );
1518
1519 return SCI_SUCCESS;
1520 }
1521
1522
1523 #define scif_sas_domain_stopped_discover_handler \
1524 scif_sas_domain_ready_discover_handler
1525
1526 #define scif_sas_domain_default_start_high_priority_io_handler \
1527 scif_sas_domain_default_start_io_handler
1528
1529
1530 SCI_BASE_DOMAIN_STATE_HANDLER_T
1531 scif_sas_domain_state_handler_table[SCI_BASE_DOMAIN_MAX_STATES] =
1532 {
1533 // SCI_BASE_DOMAIN_STATE_INITIAL
1534 {
1535 scif_sas_domain_default_discover_handler,
1536 scif_sas_domain_default_port_ready_handler,
1537 scif_sas_domain_default_port_not_ready_handler,
1538 scif_sas_domain_default_device_start_complete_handler,
1539 scif_sas_domain_default_device_stop_complete_handler,
1540 scif_sas_domain_default_device_destruct_handler,
1541 scif_sas_domain_default_start_io_handler,
1542 scif_sas_domain_default_start_high_priority_io_handler,
1543 scif_sas_domain_default_complete_io_handler,
1544 scif_sas_domain_default_complete_high_priority_io_handler,
1545 scif_sas_domain_default_continue_io_handler,
1546 scif_sas_domain_default_start_task_handler,
1547 scif_sas_domain_default_complete_task_handler
1548 },
1549 // SCI_BASE_DOMAIN_STATE_STARTING
1550 {
1551 scif_sas_domain_default_discover_handler,
1552 scif_sas_domain_starting_port_ready_handler,
1553 scif_sas_domain_default_port_not_ready_handler,
1554 scif_sas_domain_default_device_start_complete_handler,
1555 scif_sas_domain_default_device_stop_complete_handler,
1556 scif_sas_domain_default_device_destruct_handler,
1557 scif_sas_domain_default_start_io_handler,
1558 scif_sas_domain_default_start_high_priority_io_handler,
1559 scif_sas_domain_default_complete_io_handler,
1560 scif_sas_domain_default_complete_high_priority_io_handler,
1561 scif_sas_domain_default_continue_io_handler,
1562 scif_sas_domain_default_start_task_handler,
1563 scif_sas_domain_default_complete_task_handler
1564 },
1565 // SCI_BASE_DOMAIN_STATE_READY
1566 {
1567 scif_sas_domain_ready_discover_handler,
1568 scif_sas_domain_default_port_ready_handler,
1569 scif_sas_domain_ready_port_not_ready_handler,
1570 scif_sas_domain_default_device_start_complete_handler,
1571 scif_sas_domain_default_device_stop_complete_handler,
1572 scif_sas_domain_default_device_destruct_handler,
1573 scif_sas_domain_ready_start_io_handler,
1574 scif_sas_domain_ready_start_high_priority_io_handler,
1575 scif_sas_domain_ready_complete_io_handler,
1576 scif_sas_domain_ready_complete_high_priority_io_handler,
1577 scif_sas_domain_ready_continue_io_handler,
1578 scif_sas_domain_ready_start_task_handler,
1579 scif_sas_domain_ready_complete_task_handler
1580 },
1581 // SCI_BASE_DOMAIN_STATE_STOPPING
1582 {
1583 scif_sas_domain_default_discover_handler,
1584 scif_sas_domain_default_port_ready_handler,
1585 scif_sas_domain_default_port_not_ready_handler,
1586 scif_sas_domain_default_device_start_complete_handler,
1587 scif_sas_domain_stopping_device_stop_complete_handler,
1588 scif_sas_domain_default_device_destruct_handler,
1589 scif_sas_domain_default_start_io_handler,
1590 scif_sas_domain_default_start_high_priority_io_handler,
1591 scif_sas_domain_stopping_complete_io_handler,
1592 scif_sas_domain_stopping_complete_high_priority_io_handler,
1593 scif_sas_domain_default_continue_io_handler,
1594 scif_sas_domain_default_start_task_handler,
1595 scif_sas_domain_stopping_complete_task_handler
1596 },
1597 // SCI_BASE_DOMAIN_STATE_STOPPED
1598 {
1599 scif_sas_domain_stopped_discover_handler,
1600 scif_sas_domain_default_port_ready_handler,
1601 scif_sas_domain_default_port_not_ready_handler,
1602 scif_sas_domain_default_device_start_complete_handler,
1603 scif_sas_domain_default_device_stop_complete_handler,
1604 scif_sas_domain_default_device_destruct_handler,
1605 scif_sas_domain_default_start_io_handler,
1606 scif_sas_domain_default_start_high_priority_io_handler,
1607 scif_sas_domain_default_complete_io_handler,
1608 scif_sas_domain_default_complete_high_priority_io_handler,
1609 scif_sas_domain_default_continue_io_handler,
1610 scif_sas_domain_default_start_task_handler,
1611 scif_sas_domain_default_complete_task_handler
1612 },
1613 // SCI_BASE_DOMAIN_STATE_DISCOVERING
1614 {
1615 scif_sas_domain_default_discover_handler,
1616 scif_sas_domain_default_port_ready_handler,
1617 scif_sas_domain_discovering_port_not_ready_handler,
1618 scif_sas_domain_discovering_device_start_complete_handler,
1619 scif_sas_domain_discovering_device_stop_complete_handler,
1620 scif_sas_domain_discovering_device_destruct_handler, //
1621 scif_sas_domain_default_start_io_handler,
1622 scif_sas_domain_discovering_start_high_priority_io_handler,
1623 scif_sas_domain_discovering_complete_io_handler,
1624 scif_sas_domain_discovering_complete_high_priority_io_handler, //
1625 scif_sas_domain_discovering_continue_io_handler,
1626 scif_sas_domain_discovering_start_task_handler,
1627 scif_sas_domain_discovering_complete_task_handler
1628 }
1629 };
1630
1631