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 the implementation of the SCIF_SAS_CONTROLLER
60 * object.
61 */
62
63
64 #include <dev/isci/scil/sci_status.h>
65 #include <dev/isci/scil/sci_util.h>
66 #include <dev/isci/scil/sci_controller.h>
67 #include <dev/isci/scil/scic_controller.h>
68 #include <dev/isci/scil/scic_user_callback.h>
69 #include <dev/isci/scil/scif_user_callback.h>
70
71 #include <dev/isci/scil/scif_sas_controller.h>
72 #include <dev/isci/scil/scif_sas_library.h>
73 #include <dev/isci/scil/scif_sas_logger.h>
74
75
76 //******************************************************************************
77 //* P U B L I C M E T H O D S
78 //******************************************************************************
79
scif_controller_construct(SCI_LIBRARY_HANDLE_T library,SCI_CONTROLLER_HANDLE_T controller,void * user_object)80 SCI_STATUS scif_controller_construct(
81 SCI_LIBRARY_HANDLE_T library,
82 SCI_CONTROLLER_HANDLE_T controller,
83 void * user_object
84 )
85 {
86 SCI_STATUS status = SCI_SUCCESS;
87 SCIF_SAS_LIBRARY_T * fw_library = (SCIF_SAS_LIBRARY_T*) library;
88 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
89
90 // Validate the user supplied parameters.
91 if ((library == SCI_INVALID_HANDLE) || (controller == SCI_INVALID_HANDLE))
92 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
93
94 SCIF_LOG_TRACE((
95 sci_base_object_get_logger(library),
96 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
97 "scif_controller_construct(0x%x, 0x%x) enter\n",
98 library, controller
99 ));
100
101 // Construct the base controller. As part of constructing the base
102 // controller we ask it to also manage the MDL iteration for the Core.
103 sci_base_controller_construct(
104 &fw_controller->parent,
105 sci_base_object_get_logger(fw_library),
106 scif_sas_controller_state_table,
107 fw_controller->mdes,
108 SCIF_SAS_MAX_MEMORY_DESCRIPTORS,
109 sci_controller_get_memory_descriptor_list_handle(fw_controller->core_object)
110 );
111
112 scif_sas_controller_initialize_state_logging(fw_controller);
113
114 sci_object_set_association(fw_controller, user_object);
115
116 status = scic_controller_construct(
117 fw_library->core_object, fw_controller->core_object, fw_controller
118 );
119
120 // If the core controller was successfully constructed, then
121 // finish construction of the framework controller.
122 if (status == SCI_SUCCESS)
123 {
124 // Set the association in the core controller to this framework
125 // controller.
126 sci_object_set_association(
127 (SCI_OBJECT_HANDLE_T) fw_controller->core_object, fw_controller
128 );
129
130 sci_base_state_machine_change_state(
131 &fw_controller->parent.state_machine,
132 SCI_BASE_CONTROLLER_STATE_RESET
133 );
134 }
135
136 return status;
137 }
138
139 // ---------------------------------------------------------------------------
140
scif_controller_initialize(SCI_CONTROLLER_HANDLE_T controller)141 SCI_STATUS scif_controller_initialize(
142 SCI_CONTROLLER_HANDLE_T controller
143 )
144 {
145 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
146
147 // Validate the user supplied parameters.
148 if (controller == SCI_INVALID_HANDLE)
149 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
150
151 SCIF_LOG_TRACE((
152 sci_base_object_get_logger(controller),
153 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
154 "scif_controller_initialize(0x%x) enter\n",
155 controller
156 ));
157
158 return fw_controller->state_handlers->initialize_handler(
159 &fw_controller->parent
160 );
161 }
162
163 // ---------------------------------------------------------------------------
164
scif_controller_get_suggested_start_timeout(SCI_CONTROLLER_HANDLE_T controller)165 U32 scif_controller_get_suggested_start_timeout(
166 SCI_CONTROLLER_HANDLE_T controller
167 )
168 {
169 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
170
171 // Validate the user supplied parameters.
172 if (controller == SCI_INVALID_HANDLE)
173 return 0;
174
175 // Currently we aren't adding any additional time into the suggested
176 // timeout value for the start operation. Simply utilize the core
177 // value.
178 return scic_controller_get_suggested_start_timeout(fw_controller->core_object);
179 }
180
181 // ---------------------------------------------------------------------------
182
scif_controller_start(SCI_CONTROLLER_HANDLE_T controller,U32 timeout)183 SCI_STATUS scif_controller_start(
184 SCI_CONTROLLER_HANDLE_T controller,
185 U32 timeout
186 )
187 {
188 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
189
190 // Validate the user supplied parameters.
191 if (controller == SCI_INVALID_HANDLE)
192 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
193
194 SCIF_LOG_TRACE((
195 sci_base_object_get_logger(controller),
196 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
197 "scif_controller_start(0x%x, 0x%x) enter\n",
198 controller, timeout
199 ));
200
201 return fw_controller->state_handlers->
202 start_handler(&fw_controller->parent, timeout);
203 }
204
205 // ---------------------------------------------------------------------------
206
scif_controller_stop(SCI_CONTROLLER_HANDLE_T controller,U32 timeout)207 SCI_STATUS scif_controller_stop(
208 SCI_CONTROLLER_HANDLE_T controller,
209 U32 timeout
210 )
211 {
212 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
213
214 // Validate the user supplied parameters.
215 if (controller == SCI_INVALID_HANDLE)
216 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
217
218 SCIF_LOG_TRACE((
219 sci_base_object_get_logger(controller),
220 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
221 "scif_controller_stop(0x%x, 0x%x) enter\n",
222 controller, timeout
223 ));
224
225 return fw_controller->state_handlers->
226 stop_handler(&fw_controller->parent, timeout);
227
228 }
229
230 // ---------------------------------------------------------------------------
231
scif_controller_reset(SCI_CONTROLLER_HANDLE_T controller)232 SCI_STATUS scif_controller_reset(
233 SCI_CONTROLLER_HANDLE_T controller
234 )
235 {
236 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
237
238 // Validate the user supplied parameters.
239 if (controller == SCI_INVALID_HANDLE)
240 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
241
242 SCIF_LOG_TRACE((
243 sci_base_object_get_logger(controller),
244 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_CONTROLLER_RESET,
245 "scif_controller_reset(0x%x) enter\n",
246 controller
247 ));
248
249 return fw_controller->state_handlers->
250 reset_handler(&fw_controller->parent);
251 }
252
253 // ---------------------------------------------------------------------------
254
scif_controller_get_scic_handle(SCI_CONTROLLER_HANDLE_T controller)255 SCI_CONTROLLER_HANDLE_T scif_controller_get_scic_handle(
256 SCI_CONTROLLER_HANDLE_T controller
257 )
258 {
259 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
260
261 return fw_controller->core_object;
262 }
263
264 // ---------------------------------------------------------------------------
265
scif_controller_start_io(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_IO_REQUEST_HANDLE_T io_request,U16 io_tag)266 SCI_IO_STATUS scif_controller_start_io(
267 SCI_CONTROLLER_HANDLE_T controller,
268 SCI_REMOTE_DEVICE_HANDLE_T remote_device,
269 SCI_IO_REQUEST_HANDLE_T io_request,
270 U16 io_tag
271 )
272 {
273 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
274 SCI_STATUS status;
275
276 SCIF_LOG_TRACE((
277 sci_base_object_get_logger(controller),
278 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
279 "scif_controller_start_io(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
280 controller, remote_device, io_request, io_tag
281 ));
282
283 if (
284 sci_pool_empty(fw_controller->hprq.pool)
285 || scif_sas_controller_sufficient_resource(controller)
286 )
287 {
288 status = fw_controller->state_handlers->start_io_handler(
289 (SCI_BASE_CONTROLLER_T*) controller,
290 (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
291 (SCI_BASE_REQUEST_T*) io_request,
292 io_tag
293 );
294 }
295 else
296 status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
297
298 return (SCI_IO_STATUS)status;
299 }
300
301 // ---------------------------------------------------------------------------
302
scif_controller_start_task(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_TASK_REQUEST_HANDLE_T task_request,U16 io_tag)303 SCI_TASK_STATUS scif_controller_start_task(
304 SCI_CONTROLLER_HANDLE_T controller,
305 SCI_REMOTE_DEVICE_HANDLE_T remote_device,
306 SCI_TASK_REQUEST_HANDLE_T task_request,
307 U16 io_tag
308 )
309 {
310 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
311 SCI_STATUS status;
312
313 // Validate the user supplied parameters.
314 if ( (controller == SCI_INVALID_HANDLE)
315 || (remote_device == SCI_INVALID_HANDLE)
316 || (task_request == SCI_INVALID_HANDLE) )
317 {
318 return SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE;
319 }
320
321 SCIF_LOG_TRACE((
322 sci_base_object_get_logger(controller),
323 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
324 "scif_controller_start_task(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
325 controller, remote_device, task_request, io_tag
326 ));
327
328 if (scif_sas_controller_sufficient_resource(controller))
329 {
330 status = fw_controller->state_handlers->start_task_handler(
331 (SCI_BASE_CONTROLLER_T*) controller,
332 (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
333 (SCI_BASE_REQUEST_T*) task_request,
334 io_tag
335 );
336 }
337 else
338 status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
339
340 return (SCI_TASK_STATUS)status;
341 }
342
343 // ---------------------------------------------------------------------------
344
scif_controller_complete_io(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_IO_REQUEST_HANDLE_T io_request)345 SCI_STATUS scif_controller_complete_io(
346 SCI_CONTROLLER_HANDLE_T controller,
347 SCI_REMOTE_DEVICE_HANDLE_T remote_device,
348 SCI_IO_REQUEST_HANDLE_T io_request
349 )
350 {
351 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
352
353 SCIF_LOG_TRACE((
354 sci_base_object_get_logger(controller),
355 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
356 "scif_controller_complete_io(0x%x, 0x%x, 0x%x) enter\n",
357 controller, remote_device, io_request
358 ));
359
360 return fw_controller->state_handlers->complete_io_handler(
361 (SCI_BASE_CONTROLLER_T*) controller,
362 (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
363 (SCI_BASE_REQUEST_T*) io_request
364 );
365 }
366
367 // ---------------------------------------------------------------------------
368
scif_controller_complete_task(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_TASK_REQUEST_HANDLE_T task_request)369 SCI_STATUS scif_controller_complete_task(
370 SCI_CONTROLLER_HANDLE_T controller,
371 SCI_REMOTE_DEVICE_HANDLE_T remote_device,
372 SCI_TASK_REQUEST_HANDLE_T task_request
373 )
374 {
375 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
376
377 // Validate the user supplied parameters.
378 if ( (controller == SCI_INVALID_HANDLE)
379 || (remote_device == SCI_INVALID_HANDLE)
380 || (task_request == SCI_INVALID_HANDLE) )
381 {
382 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
383 }
384
385 SCIF_LOG_TRACE((
386 sci_base_object_get_logger(controller),
387 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
388 "scif_controller_complete_task(0x%x, 0x%x, 0x%x) enter\n",
389 controller, remote_device, task_request
390 ));
391
392 return fw_controller->state_handlers->complete_task_handler(
393 (SCI_BASE_CONTROLLER_T*) controller,
394 (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
395 (SCI_BASE_REQUEST_T*) task_request
396 );
397 }
398
399 // ---------------------------------------------------------------------------
400
scif_controller_get_domain_handle(SCI_CONTROLLER_HANDLE_T controller,U8 port_index,SCI_DOMAIN_HANDLE_T * domain_handle)401 SCI_STATUS scif_controller_get_domain_handle(
402 SCI_CONTROLLER_HANDLE_T controller,
403 U8 port_index,
404 SCI_DOMAIN_HANDLE_T * domain_handle
405 )
406 {
407 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
408
409 // Validate the user supplied parameters.
410 if (controller == SCI_INVALID_HANDLE)
411 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
412
413 // Retrieve the domain handle if the supplied index is legitimate.
414 if (port_index < SCI_MAX_PORTS)
415 {
416 *domain_handle = &fw_controller->domains[port_index];
417 return SCI_SUCCESS;
418 }
419
420 return SCI_FAILURE_INVALID_PORT;
421 }
422
423 /**
424 * @brief This method builds the memory descriptor list for this
425 * controller.
426 *
427 * @param[in] fw_controller This parameter specifies the framework
428 * controller object for which to build the MDL.
429 *
430 * @return none
431 */
scif_sas_controller_build_mdl(SCIF_SAS_CONTROLLER_T * fw_controller)432 void scif_sas_controller_build_mdl(
433 SCIF_SAS_CONTROLLER_T * fw_controller
434 )
435 {
436 // one internal request for each domain.
437 sci_base_mde_construct(
438 &fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO],
439 4,
440 fw_controller->internal_request_entries *
441 scif_sas_internal_request_get_object_size(),
442 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
443 );
444 }
445
446 // ---------------------------------------------------------------------------
447
scif_controller_set_mode(SCI_CONTROLLER_HANDLE_T controller,SCI_CONTROLLER_MODE mode)448 SCI_STATUS scif_controller_set_mode(
449 SCI_CONTROLLER_HANDLE_T controller,
450 SCI_CONTROLLER_MODE mode
451 )
452 {
453 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
454 SCI_STATUS status = SCI_SUCCESS;
455
456 if (
457 (fw_controller->parent.state_machine.current_state_id
458 == SCI_BASE_CONTROLLER_STATE_INITIALIZING)
459 || (fw_controller->parent.state_machine.current_state_id
460 == SCI_BASE_CONTROLLER_STATE_INITIALIZED)
461 )
462 {
463 switch (mode)
464 {
465 case SCI_MODE_SPEED:
466 fw_controller->internal_request_entries =
467 MIN(fw_controller->internal_request_entries, SCIF_SAS_MAX_INTERNAL_REQUEST_COUNT);
468 scif_sas_controller_build_mdl(fw_controller);
469 break;
470
471 case SCI_MODE_SIZE:
472 fw_controller->internal_request_entries =
473 MIN(fw_controller->internal_request_entries, SCIF_SAS_MIN_INTERNAL_REQUEST_COUNT);
474 scif_sas_controller_build_mdl(fw_controller);
475 break;
476
477 default:
478 status = SCI_FAILURE_INVALID_PARAMETER_VALUE;
479 break;
480 }
481 }
482 else
483 status = SCI_FAILURE_INVALID_STATE;
484
485 if (status != SCI_SUCCESS)
486 {
487 return status;
488 }
489 else
490 {
491 // Currently, the framework doesn't change any configurations for
492 // speed or size modes. Default to speed mode basically.
493 return scic_controller_set_mode(fw_controller->core_object, mode);
494 }
495 }
496
497 // ---------------------------------------------------------------------------
498
scif_controller_get_sat_compliance_version(void)499 U32 scif_controller_get_sat_compliance_version(
500 void
501 )
502 {
503 /// @todo Fix return of SAT compliance version.
504 return 0;
505 }
506
507 // ---------------------------------------------------------------------------
508
scif_controller_get_sat_compliance_version_revision(void)509 U32 scif_controller_get_sat_compliance_version_revision(
510 void
511 )
512 {
513 /// @todo Fix return of SAT compliance revision.
514 return 0;
515 }
516
517 // ---------------------------------------------------------------------------
518
scif_user_parameters_set(SCI_CONTROLLER_HANDLE_T controller,SCIF_USER_PARAMETERS_T * scif_parms)519 SCI_STATUS scif_user_parameters_set(
520 SCI_CONTROLLER_HANDLE_T controller,
521 SCIF_USER_PARAMETERS_T * scif_parms
522 )
523 {
524 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
525
526 //validate all the registry entries before overwriting the default parameter
527 //values.
528 if (scif_parms->sas.is_sata_ncq_enabled != 1 && scif_parms->sas.is_sata_ncq_enabled != 0)
529 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
530
531 if (scif_parms->sas.max_ncq_depth < 1 || scif_parms->sas.max_ncq_depth > 32)
532 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
533
534 if (scif_parms->sas.is_sata_standby_timer_enabled != 1
535 && scif_parms->sas.is_sata_standby_timer_enabled != 0)
536 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
537
538 if (scif_parms->sas.is_non_zero_buffer_offsets_enabled != 1
539 && scif_parms->sas.is_non_zero_buffer_offsets_enabled != 0)
540 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
541
542 if (scif_parms->sas.reset_type != SCI_SAS_ABORT_TASK
543 && scif_parms->sas.reset_type != SCI_SAS_ABORT_TASK_SET
544 && scif_parms->sas.reset_type != SCI_SAS_CLEAR_TASK_SET
545 && scif_parms->sas.reset_type != SCI_SAS_LOGICAL_UNIT_RESET
546 && scif_parms->sas.reset_type != SCI_SAS_I_T_NEXUS_RESET
547 && scif_parms->sas.reset_type != SCI_SAS_CLEAR_ACA
548 && scif_parms->sas.reset_type != SCI_SAS_QUERY_TASK
549 && scif_parms->sas.reset_type != SCI_SAS_QUERY_TASK_SET
550 && scif_parms->sas.reset_type != SCI_SAS_QUERY_ASYNCHRONOUS_EVENT
551 && scif_parms->sas.reset_type != SCI_SAS_HARD_RESET)
552 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
553
554 if (scif_parms->sas.clear_affiliation_during_controller_stop != 1
555 && scif_parms->sas.clear_affiliation_during_controller_stop !=0)
556 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
557
558 memcpy((&fw_controller->user_parameters), scif_parms, sizeof(*scif_parms));
559
560 // In the future more could be done to prevent setting parameters at the
561 // wrong time, but for now we'll simply set the values even if it is too
562 // late for them to take effect.
563 return SCI_SUCCESS;
564 }
565
566 // ---------------------------------------------------------------------------
567
568 #if !defined(DISABLE_INTERRUPTS)
569
570 /**
571 * @brief This routine check each domain of the controller to see if
572 * any domain is overriding interrupt coalescence.
573 *
574 * @param[in] fw_controller frame controller
575 * @param[in] fw_smp_phy The smp phy to be freed.
576 *
577 * @return none
578 */
579 static
scif_sas_controller_is_overriding_interrupt_coalescence(SCIF_SAS_CONTROLLER_T * fw_controller)580 BOOL scif_sas_controller_is_overriding_interrupt_coalescence(
581 SCIF_SAS_CONTROLLER_T * fw_controller
582 )
583 {
584 U8 index;
585
586 for(index = 0; index < SCI_MAX_DOMAINS; index++)
587 {
588 if(fw_controller->domains[index].parent.state_machine.current_state_id ==
589 SCI_BASE_DOMAIN_STATE_DISCOVERING)
590 return TRUE;
591 }
592
593 return FALSE;
594 }
595
scif_controller_set_interrupt_coalescence(SCI_CONTROLLER_HANDLE_T controller,U32 coalesce_number,U32 coalesce_timeout)596 SCI_STATUS scif_controller_set_interrupt_coalescence(
597 SCI_CONTROLLER_HANDLE_T controller,
598 U32 coalesce_number,
599 U32 coalesce_timeout
600 )
601 {
602 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T * )controller;
603
604 ///when framework is in the middle of temporarily overriding the interrupt
605 ///coalescence values, user's request of setting interrupt coalescence
606 ///will be saved. As soon as the framework done the temporary overriding,
607 ///it will serve user's request to set new interrupt coalescence.
608 if (scif_sas_controller_is_overriding_interrupt_coalescence(fw_controller))
609 {
610 U32 curr_coalesce_number;
611 U32 curr_coalesce_timeout;
612 SCI_STATUS core_status;
613
614 // save current interrupt coalescence info.
615 scic_controller_get_interrupt_coalescence (
616 fw_controller->core_object, &curr_coalesce_number, &curr_coalesce_timeout);
617
618 //try user's request out in the core, but immediately restore core's
619 //current setting.
620 core_status = scic_controller_set_interrupt_coalescence(
621 fw_controller->core_object, coalesce_number, coalesce_timeout);
622
623 if ( core_status == SCI_SUCCESS )
624 {
625 fw_controller->saved_interrupt_coalesce_number = (U16)coalesce_number;
626 fw_controller->saved_interrupt_coalesce_timeout = coalesce_timeout;
627 }
628
629 //restore current interrupt coalescence.
630 scic_controller_set_interrupt_coalescence(
631 fw_controller->core_object, curr_coalesce_number, curr_coalesce_timeout);
632
633 return core_status;
634 }
635 else
636 {
637 ///If framework is not internally overriding the interrupt coalescence,
638 ///serve user's request immediately by passing the reqeust to core.
639 return scic_controller_set_interrupt_coalescence(
640 fw_controller->core_object, coalesce_number, coalesce_timeout);
641 }
642 }
643
644 // ---------------------------------------------------------------------------
645
scif_controller_get_interrupt_coalescence(SCI_CONTROLLER_HANDLE_T controller,U32 * coalesce_number,U32 * coalesce_timeout)646 void scif_controller_get_interrupt_coalescence(
647 SCI_CONTROLLER_HANDLE_T controller,
648 U32 * coalesce_number,
649 U32 * coalesce_timeout
650 )
651 {
652 SCIF_SAS_CONTROLLER_T * scif_controller = (SCIF_SAS_CONTROLLER_T * )controller;
653
654 scic_controller_get_interrupt_coalescence(
655 scif_controller->core_object, coalesce_number, coalesce_timeout);
656 }
657
658 /**
659 * @brief This method will save the interrupt coalescence values. If
660 * the interrupt coalescence values have already been saved,
661 * then this method performs no operations.
662 *
663 * @param[in,out] fw_controller This parameter specifies the controller
664 * for which to save the interrupt coalescence values.
665 *
666 * @return none
667 */
scif_sas_controller_save_interrupt_coalescence(SCIF_SAS_CONTROLLER_T * fw_controller)668 void scif_sas_controller_save_interrupt_coalescence(
669 SCIF_SAS_CONTROLLER_T * fw_controller
670 )
671 {
672 if ( !scif_sas_controller_is_overriding_interrupt_coalescence(fw_controller))
673 {
674 // Override core's interrupt coalescing settings during SMP
675 // DISCOVER process cause' there is only 1 outstanding SMP
676 // request per domain is allowed.
677 scic_controller_get_interrupt_coalescence(
678 fw_controller->core_object,
679 (U32*)&(fw_controller->saved_interrupt_coalesce_number),
680 &(fw_controller->saved_interrupt_coalesce_timeout)
681 );
682
683 // Temporarily disable the interrupt coalescing.
684 scic_controller_set_interrupt_coalescence(fw_controller->core_object,0,0);
685 }
686 }
687
688 /**
689 * @brief This method will restore the interrupt coalescence values. If
690 * the interrupt coalescence values have not already been saved,
691 * then this method performs no operations.
692 *
693 * @param[in,out] fw_controller This parameter specifies the controller
694 * for which to restore the interrupt coalescence values.
695 *
696 * @return none
697 */
scif_sas_controller_restore_interrupt_coalescence(SCIF_SAS_CONTROLLER_T * fw_controller)698 void scif_sas_controller_restore_interrupt_coalescence(
699 SCIF_SAS_CONTROLLER_T * fw_controller
700 )
701 {
702 if ( !scif_sas_controller_is_overriding_interrupt_coalescence(fw_controller))
703 scic_controller_set_interrupt_coalescence(
704 fw_controller->core_object,
705 fw_controller->saved_interrupt_coalesce_number,
706 fw_controller->saved_interrupt_coalesce_timeout
707 );
708 }
709
710 #endif // !defined(DISABLE_INTERRUPTS)
711
712 // ---------------------------------------------------------------------------
713
scic_cb_controller_start_complete(SCI_CONTROLLER_HANDLE_T controller,SCI_STATUS completion_status)714 void scic_cb_controller_start_complete(
715 SCI_CONTROLLER_HANDLE_T controller,
716 SCI_STATUS completion_status
717 )
718 {
719 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)
720 sci_object_get_association(controller);
721
722 SCIF_LOG_TRACE((
723 sci_base_object_get_logger(controller),
724 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
725 "scic_cb_controller_start_complete(0x%x, 0x%x) enter\n",
726 controller, completion_status
727 ));
728
729 if (completion_status == SCI_SUCCESS
730 || completion_status == SCI_FAILURE_TIMEOUT)
731 {
732 // Even the initialization of the core controller timed out, framework
733 // controller should still transit to READY state.
734 sci_base_state_machine_change_state(
735 &fw_controller->parent.state_machine,
736 SCI_BASE_CONTROLLER_STATE_READY
737 );
738 }
739
740 scif_cb_controller_start_complete(fw_controller, completion_status);
741 }
742
743 // ---------------------------------------------------------------------------
744
scic_cb_controller_stop_complete(SCI_CONTROLLER_HANDLE_T controller,SCI_STATUS completion_status)745 void scic_cb_controller_stop_complete(
746 SCI_CONTROLLER_HANDLE_T controller,
747 SCI_STATUS completion_status
748 )
749 {
750 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)
751 sci_object_get_association(controller);
752
753 SCIF_LOG_TRACE((
754 sci_base_object_get_logger(controller),
755 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
756 "scic_cb_controller_stop_complete(0x%x, 0x%x) enter\n",
757 controller, completion_status
758 ));
759
760 if (completion_status == SCI_SUCCESS)
761 {
762 sci_base_state_machine_change_state(
763 &fw_controller->parent.state_machine,
764 SCI_BASE_CONTROLLER_STATE_STOPPED
765 );
766 }
767 else
768 {
769 sci_base_state_machine_change_state(
770 &fw_controller->parent.state_machine,
771 SCI_BASE_CONTROLLER_STATE_FAILED
772 );
773 }
774
775 scif_cb_controller_stop_complete(fw_controller, completion_status);
776 }
777
778
779 // ---------------------------------------------------------------------------
780
scic_cb_controller_error(SCI_CONTROLLER_HANDLE_T controller,SCI_CONTROLLER_ERROR error)781 void scic_cb_controller_error(
782 SCI_CONTROLLER_HANDLE_T controller,
783 SCI_CONTROLLER_ERROR error
784 )
785 {
786 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)
787 sci_object_get_association(controller);
788
789 fw_controller->parent.error = error;
790
791 SCIF_LOG_TRACE((
792 sci_base_object_get_logger(controller),
793 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
794 "scic_cb_controller_not_ready(0x%x) enter\n",
795 controller
796 ));
797
798 sci_base_state_machine_change_state(
799 &fw_controller->parent.state_machine,
800 SCI_BASE_CONTROLLER_STATE_FAILED
801 );
802 }
803
804 //******************************************************************************
805 //* P R O T E C T E D M E T H O D S
806 //******************************************************************************
807
808 /**
809 * @brief This method is utilized to continue an internal IO operation
810 * on the controller. This method is utilized for SAT translated
811 * requests that generate multiple ATA commands in order to fulfill
812 * the original SCSI request.
813 *
814 * @param[in] controller This parameter specifies the controller on which
815 * to continue an internal IO request.
816 * @param[in] remote_device This parameter specifies the remote device
817 * on which to continue an internal IO request.
818 * @param[in] io_request This parameter specifies the IO request to be
819 * continue.
820 *
821 * @return Indicate if the continue operation was successful.
822 * @retval SCI_SUCCESS This value is returned if the operation succeeded.
823 */
scif_sas_controller_continue_io(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_IO_REQUEST_HANDLE_T io_request)824 SCI_STATUS scif_sas_controller_continue_io(
825 SCI_CONTROLLER_HANDLE_T controller,
826 SCI_REMOTE_DEVICE_HANDLE_T remote_device,
827 SCI_IO_REQUEST_HANDLE_T io_request
828 )
829 {
830 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*) controller;
831
832 return fw_controller->state_handlers->continue_io_handler(
833 (SCI_BASE_CONTROLLER_T*) controller,
834 (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
835 (SCI_BASE_REQUEST_T*) io_request
836 );
837 }
838
839 /**
840 * @brief This method will attempt to destruct a framework controller.
841 * This includes free any resources retreived from the user (e.g.
842 * timers).
843 *
844 * @param[in] fw_controller This parameter specifies the framework
845 * controller to destructed.
846 *
847 * @return none
848 */
scif_sas_controller_destruct(SCIF_SAS_CONTROLLER_T * fw_controller)849 void scif_sas_controller_destruct(
850 SCIF_SAS_CONTROLLER_T * fw_controller
851 )
852 {
853 SCIF_LOG_TRACE((
854 sci_base_object_get_logger(fw_controller),
855 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
856 "scif_sas_controller_destruct(0x%x) enter\n",
857 fw_controller
858 ));
859 }
860
861 //-----------------------------------------------------------------------------
862 // INTERNAL REQUEST RELATED METHODS
863 //-----------------------------------------------------------------------------
864
865 /**
866 * @brief This routine is to allocate the memory for creating a new internal
867 * request.
868 *
869 * @param[in] scif_controller handle to frame controller
870 *
871 * @return void* address to internal request memory
872 */
scif_sas_controller_allocate_internal_request(SCIF_SAS_CONTROLLER_T * fw_controller)873 void * scif_sas_controller_allocate_internal_request(
874 SCIF_SAS_CONTROLLER_T * fw_controller
875 )
876 {
877 POINTER_UINT internal_io_address;
878
879 if( !sci_pool_empty(fw_controller->internal_request_memory_pool) )
880 {
881 sci_pool_get(
882 fw_controller->internal_request_memory_pool, internal_io_address
883 );
884
885 //clean the memory.
886 memset((char*)internal_io_address, 0, scif_sas_internal_request_get_object_size());
887
888 return (void *) internal_io_address;
889 }
890 else
891 return NULL;
892 }
893
894 /**
895 * @brief This routine is to free the memory for a completed internal request.
896 *
897 * @param[in] scif_controller handle to frame controller
898 * @param[in] fw_internal_io The internal IO to be freed.
899 *
900 * @return none
901 */
scif_sas_controller_free_internal_request(SCIF_SAS_CONTROLLER_T * fw_controller,void * fw_internal_request_buffer)902 void scif_sas_controller_free_internal_request(
903 SCIF_SAS_CONTROLLER_T * fw_controller,
904 void * fw_internal_request_buffer
905 )
906 {
907 SCIF_LOG_TRACE((
908 sci_base_object_get_logger(fw_controller),
909 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
910 "scif_controller_free_internal_request(0x%x, 0x%x) enter\n",
911 fw_controller, fw_internal_request_buffer
912 ));
913
914 //return the memory to the pool.
915 if( !sci_pool_full(fw_controller->internal_request_memory_pool) )
916 {
917 sci_pool_put(
918 fw_controller->internal_request_memory_pool,
919 (POINTER_UINT) fw_internal_request_buffer
920 );
921 }
922 }
923
924
925 /**
926 * @brief this routine is called by OS' DPC to start io requests from internal
927 * high priority request queue
928 * @param[in] fw_controller The framework controller.
929 *
930 * @return none
931 */
scif_sas_controller_start_high_priority_io(SCIF_SAS_CONTROLLER_T * fw_controller)932 void scif_sas_controller_start_high_priority_io(
933 SCIF_SAS_CONTROLLER_T * fw_controller
934 )
935 {
936 POINTER_UINT io_address;
937 SCIF_SAS_IO_REQUEST_T * fw_io;
938 SCI_STATUS status;
939
940 SCIF_LOG_TRACE((
941 sci_base_object_get_logger(fw_controller),
942 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
943 "scif_controller_start_high_priority_io(0x%x) enter\n",
944 fw_controller
945 ));
946
947 while ( !sci_pool_empty(fw_controller->hprq.pool) )
948 {
949 sci_pool_get(fw_controller->hprq.pool, io_address);
950
951 fw_io = (SCIF_SAS_IO_REQUEST_T *)io_address;
952
953 status = fw_controller->state_handlers->start_high_priority_io_handler(
954 (SCI_BASE_CONTROLLER_T*) fw_controller,
955 (SCI_BASE_REMOTE_DEVICE_T*) fw_io->parent.device,
956 (SCI_BASE_REQUEST_T*) fw_io,
957 SCI_CONTROLLER_INVALID_IO_TAG
958 );
959 }
960 }
961
962 /**
963 * @brief This method will check how many outstanding IOs currently and number
964 * of IOs in high priority queue, if the overall number exceeds the max_tc,
965 * return FALSE.
966 *
967 * @param[in] fw_controller The framework controller.
968 *
969 * @return BOOL Indicate whether there is sufficient resource to start an IO.
970 * @retvalue TRUE The controller has sufficient resource.
971 * @retvalue FALSE There is not sufficient resource available.
972 */
scif_sas_controller_sufficient_resource(SCIF_SAS_CONTROLLER_T * fw_controller)973 BOOL scif_sas_controller_sufficient_resource(
974 SCIF_SAS_CONTROLLER_T *fw_controller
975 )
976 {
977 SCIF_SAS_DOMAIN_T * fw_domain;
978 U32 domain_index;
979 U32 outstanding_io_count = 0;
980 U32 high_priority_io_count = 0;
981
982 for(domain_index = 0; domain_index < SCI_MAX_DOMAINS; domain_index++)
983 {
984 fw_domain = &fw_controller->domains[domain_index];
985 outstanding_io_count += fw_domain->request_list.element_count;
986 }
987
988 high_priority_io_count = sci_pool_count(fw_controller->hprq.pool);
989
990 if ( (outstanding_io_count + high_priority_io_count) > SCI_MAX_IO_REQUESTS )
991 return FALSE;
992
993 return TRUE;
994 }
995
996
997 /**
998 * @brief This method is the starting point to complete high prority io for a
999 * controller then down to domain, device.
1000 *
1001 * @param[in] fw_controller The framework controller
1002 * @param[in] remote_device The framework remote device.
1003 * @param[in] io_request The high priority io request to be completed.
1004 *
1005 * @return SCI_STATUS indicate the completion status from framework down to the
1006 * core.
1007 */
scif_sas_controller_complete_high_priority_io(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * remote_device,SCIF_SAS_REQUEST_T * io_request)1008 SCI_STATUS scif_sas_controller_complete_high_priority_io(
1009 SCIF_SAS_CONTROLLER_T *fw_controller,
1010 SCIF_SAS_REMOTE_DEVICE_T *remote_device,
1011 SCIF_SAS_REQUEST_T *io_request
1012 )
1013 {
1014 SCIF_LOG_TRACE((
1015 sci_base_object_get_logger(fw_controller),
1016 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
1017 "scif_sas_controller_complete_high_priority_io(0x%x, 0x%x, 0x%x) enter\n",
1018 fw_controller, remote_device, io_request
1019 ));
1020
1021 //call controller's new added complete_high_priority_io_handler
1022 return fw_controller->state_handlers->complete_high_priority_io_handler(
1023 (SCI_BASE_CONTROLLER_T*) fw_controller,
1024 (SCI_BASE_REMOTE_DEVICE_T*) remote_device,
1025 (SCI_BASE_REQUEST_T*) io_request
1026 );
1027 }
1028
1029 /**
1030
1031 * @brief This routine is to allocate the memory for creating a smp phy object.
1032 *
1033 * @param[in] scif_controller handle to frame controller
1034 *
1035 * @return SCIF_SAS_SMP_PHY_T * An allocated space for smp phy. If failed to allocate,
1036 * return NULL.
1037 */
scif_sas_controller_allocate_smp_phy(SCIF_SAS_CONTROLLER_T * fw_controller)1038 SCIF_SAS_SMP_PHY_T * scif_sas_controller_allocate_smp_phy(
1039 SCIF_SAS_CONTROLLER_T * fw_controller
1040 )
1041 {
1042 SCIF_SAS_SMP_PHY_T * smp_phy;
1043
1044 SCIF_LOG_TRACE((
1045 sci_base_object_get_logger(fw_controller),
1046 SCIF_LOG_OBJECT_CONTROLLER,
1047 "scif_controller_allocate_smp_phy(0x%x) enter\n",
1048 fw_controller
1049 ));
1050
1051 if( !sci_fast_list_is_empty(&fw_controller->smp_phy_memory_list) )
1052 {
1053 smp_phy = (SCIF_SAS_SMP_PHY_T *)
1054 sci_fast_list_remove_head(&fw_controller->smp_phy_memory_list);
1055
1056 //clean the memory.
1057 memset((char*)smp_phy,
1058 0,
1059 sizeof(SCIF_SAS_SMP_PHY_T)
1060 );
1061
1062 return smp_phy;
1063 }
1064 else
1065 return NULL;
1066 }
1067
1068 /**
1069 * @brief This routine is to free the memory for a released smp phy.
1070 *
1071 * @param[in] fw_controller The framework controller, a smp phy is released
1072 * to its memory.
1073 * @param[in] fw_smp_phy The smp phy to be freed.
1074 *
1075 * @return none
1076 */
scif_sas_controller_free_smp_phy(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_SMP_PHY_T * smp_phy)1077 void scif_sas_controller_free_smp_phy(
1078 SCIF_SAS_CONTROLLER_T * fw_controller,
1079 SCIF_SAS_SMP_PHY_T * smp_phy
1080 )
1081 {
1082 SCIF_LOG_TRACE((
1083 sci_base_object_get_logger(fw_controller),
1084 SCIF_LOG_OBJECT_CONTROLLER,
1085 "scif_controller_free_smp_phy(0x%x, 0x%x) enter\n",
1086 fw_controller, smp_phy
1087 ));
1088
1089 //return the memory to the list.
1090 sci_fast_list_insert_tail(
1091 &fw_controller->smp_phy_memory_list,
1092 &smp_phy->list_element
1093 );
1094 }
1095
1096
1097 /**
1098 * @brief This method clear affiliation for all the EA SATA devices associated
1099 * to this controller.
1100 *
1101 * @param[in] fw_controller This parameter specifies the framework
1102 * controller object for whose remote devices are to be stopped.
1103 *
1104 * @return This method returns a value indicating if the operation completed.
1105 * @retval SCI_COMPLETE This value indicates that all the EA SATA devices'
1106 * affiliation was cleared.
1107 * @retval SCI_INCOMPLETE This value indicates clear affiliation activity is
1108 * yet to be completed.
1109 */
scif_sas_controller_clear_affiliation(SCIF_SAS_CONTROLLER_T * fw_controller)1110 SCI_STATUS scif_sas_controller_clear_affiliation(
1111 SCIF_SAS_CONTROLLER_T * fw_controller
1112 )
1113 {
1114 U8 index;
1115 SCI_STATUS status;
1116 SCIF_SAS_DOMAIN_T * fw_domain;
1117
1118 SCIF_LOG_TRACE((
1119 sci_base_object_get_logger(fw_controller),
1120 SCIF_LOG_OBJECT_CONTROLLER,
1121 "scif_sas_controller_clear_affiliation(0x%x) enter\n",
1122 fw_controller
1123 ));
1124
1125 index = fw_controller->current_domain_to_clear_affiliation;
1126
1127 if (index < SCI_MAX_DOMAINS)
1128 {
1129 fw_domain = &fw_controller->domains[index];
1130
1131 //Need to stop all the on-going smp activities before clearing affiliation.
1132 scif_sas_domain_cancel_smp_activities(fw_domain);
1133
1134 scif_sas_domain_start_clear_affiliation(fw_domain);
1135
1136 status = SCI_WARNING_SEQUENCE_INCOMPLETE;
1137 }
1138 else
1139 { //the controller has done clear affiliation work to all its domains.
1140 scif_sas_controller_continue_to_stop(fw_controller);
1141 status = SCI_SUCCESS;
1142 }
1143
1144 return status;
1145 }
1146
1147
1148 /**
1149 * @brief This method sets SCIF user parameters to
1150 * default values. Users can override these values utilizing
1151 * the sciF_user_parameters_set() methods.
1152 *
1153 * @param[in] controller This parameter specifies the controller for
1154 * which to set the configuration parameters to their
1155 * default values.
1156 *
1157 * @return none
1158 */
scif_sas_controller_set_default_config_parameters(SCIF_SAS_CONTROLLER_T * this_controller)1159 void scif_sas_controller_set_default_config_parameters(
1160 SCIF_SAS_CONTROLLER_T * this_controller
1161 )
1162 {
1163 SCIF_USER_PARAMETERS_T * scif_parms = &(this_controller->user_parameters);
1164
1165 scif_parms->sas.is_sata_ncq_enabled = TRUE;
1166 scif_parms->sas.max_ncq_depth = 32;
1167 scif_parms->sas.is_sata_standby_timer_enabled = FALSE;
1168 scif_parms->sas.is_non_zero_buffer_offsets_enabled = FALSE;
1169 scif_parms->sas.reset_type = SCI_SAS_LOGICAL_UNIT_RESET;
1170 scif_parms->sas.clear_affiliation_during_controller_stop = TRUE;
1171 scif_parms->sas.ignore_fua = FALSE;
1172
1173 }
1174
1175
1176 /**
1177 * @brief This method releases resource for framework controller and associated
1178 * objects.
1179 *
1180 * @param[in] fw_controller This parameter specifies the framework
1181 * controller and associated objects whose resources are to be released.
1182 *
1183 * @return This method returns a value indicating if the operation succeeded.
1184 * @retval SCI_SUCCESS This value indicates that resource release succeeded.
1185 * @retval SCI_FAILURE This value indicates certain failure during the process
1186 * of resource release.
1187 */
scif_sas_controller_release_resource(SCIF_SAS_CONTROLLER_T * fw_controller)1188 SCI_STATUS scif_sas_controller_release_resource(
1189 SCIF_SAS_CONTROLLER_T * fw_controller
1190 )
1191 {
1192 U8 index;
1193 SCIF_SAS_DOMAIN_T * fw_domain;
1194
1195 SCIF_LOG_TRACE((
1196 sci_base_object_get_logger(fw_controller),
1197 SCIF_LOG_OBJECT_CONTROLLER,
1198 "scif_sas_controller_release_resource(0x%x) enter\n",
1199 fw_controller
1200 ));
1201
1202 //currently the only resource to be released is domain's timer.
1203 for (index = 0; index < SCI_MAX_DOMAINS; index++)
1204 {
1205 fw_domain = &fw_controller->domains[index];
1206
1207 scif_sas_domain_release_resource(fw_controller, fw_domain);
1208 }
1209
1210 return SCI_SUCCESS;
1211 }
1212
1213
1214 #ifdef SCI_LOGGING
1215 /**
1216 * This method will start state transition logging for the framework
1217 * controller object.
1218 *
1219 * @param[in] fw_controller The framework controller object on which to
1220 * observe state changes.
1221 *
1222 * @return none
1223 */
scif_sas_controller_initialize_state_logging(SCIF_SAS_CONTROLLER_T * fw_controller)1224 void scif_sas_controller_initialize_state_logging(
1225 SCIF_SAS_CONTROLLER_T * fw_controller
1226 )
1227 {
1228 sci_base_state_machine_logger_initialize(
1229 &fw_controller->parent.state_machine_logger,
1230 &fw_controller->parent.state_machine,
1231 &fw_controller->parent.parent,
1232 scif_cb_logger_log_states,
1233 "SCIF_SAS_CONTROLLER_T", "base state machine",
1234 SCIF_LOG_OBJECT_CONTROLLER
1235 );
1236 }
1237
1238 /**
1239 * This method will remove the logging of state transitions from the framework
1240 * controller object.
1241 *
1242 * @param[in] fw_controller The framework controller to change.
1243 *
1244 * @return none
1245 */
scif_sas_controller_deinitialize_state_logging(SCIF_SAS_CONTROLLER_T * fw_controller)1246 void scif_sas_controller_deinitialize_state_logging(
1247 SCIF_SAS_CONTROLLER_T * fw_controller
1248 )
1249 {
1250 sci_base_state_machine_logger_deinitialize(
1251 &fw_controller->parent.state_machine_logger,
1252 &fw_controller->parent.state_machine
1253 );
1254 }
1255 #endif // SCI_LOGGING
1256