xref: /freebsd/sys/dev/isci/scil/scic_controller.h (revision 19fae0f66023a97a9b464b3beeeabb2081f575b3)
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  * $FreeBSD$
55  */
56 #ifndef _SCIC_CONTROLLER_H_
57 #define _SCIC_CONTROLLER_H_
58 
59 /**
60  * @file
61  *
62  * @brief This file contains all of the interface methods that can be called
63  *        by an SCIC user on a controller object.
64  */
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif // __cplusplus
69 
70 #include <dev/isci/scil/sci_types.h>
71 #include <dev/isci/scil/sci_status.h>
72 #include <dev/isci/scil/sci_controller.h>
73 #include <dev/isci/scil/scic_config_parameters.h>
74 
75 /**
76  * @enum
77  *
78  * Allowed PORT configuration modes
79  *
80  * APC Automatic PORT configuration mode is defined by the OEM configuration
81  * parameters providing no PHY_MASK parameters for any PORT. i.e. There are
82  * no phys assigned to any of the ports at start.
83  *
84  * MPC Manual PORT configuration mode is defined by the OEM configuration
85  * parameters providing a PHY_MASK value for any PORT.  It is assumed that
86  * any PORT with no PHY_MASK is an invalid port and not all PHYs must be
87  * assigned. A PORT_PHY mask that assigns just a single PHY to a port and no
88  * other PHYs being assigned is sufficient to declare manual PORT configuration.
89  */
90 enum SCIC_PORT_CONFIGURATION_MODE
91 {
92    SCIC_PORT_MANUAL_CONFIGURATION_MODE,
93    SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE
94 };
95 
96 /**
97  * @enum _SCIC_INTERRUPT_TYPE
98  *
99  * @brief This enumeration depicts the various types of interrupts that
100  *        are potentially supported by a SCI Core implementation.
101  */
102 typedef enum _SCIC_INTERRUPT_TYPE
103 {
104    SCIC_LEGACY_LINE_INTERRUPT_TYPE,
105    SCIC_MSIX_INTERRUPT_TYPE,
106 
107    /**
108     * This enumeration value indicates the use of polling.
109     */
110    SCIC_NO_INTERRUPTS
111 
112 } SCIC_INTERRUPT_TYPE;
113 
114 /**
115  * @typedef SCIC_CONTROLLER_INTERRUPT_HANDLER
116  *
117  * @brief This method is called by the SCI user in order to have the SCI
118  *        implementation handle the interrupt.  This method performs
119  *        minimal processing to allow for streamlined interrupt time usage.
120  * @note
121  *        TRUE: returned if there is an interrupt to process and it was
122  *              processed.
123  *        FALSE: returned if no interrupt was processed.
124  *
125  */
126 typedef BOOL (*SCIC_CONTROLLER_INTERRUPT_HANDLER)(
127    SCI_CONTROLLER_HANDLE_T  controller
128 );
129 
130 /**
131  * @brief This method is called by the SCI user to process completions
132  *        generated as a result of a previously handled interrupt.  This
133  *        method will result in the completion of IO requests and handling
134  *        of other controller generated events.  This method should be
135  *        called some time after the interrupt handler.
136  *
137  * @note  Most, if not all, of the user callback APIs are invoked from within
138  *        this API.  As a result, the user should be cognizant of the operating
139  *        level at which they invoke this API.
140  *
141  */
142 typedef void (*SCIC_CONTROLLER_COMPLETION_HANDLER)(
143    SCI_CONTROLLER_HANDLE_T  controller
144 );
145 
146 /**
147  * @struct SCIC_CONTROLLER_HANDLER_METHODS
148  *
149  * @brief This structure contains an interrupt handler and completion
150  *        handler function pointers.
151  */
152 typedef struct SCIC_CONTROLLER_HANDLER_METHODS
153 {
154    SCIC_CONTROLLER_INTERRUPT_HANDLER  interrupt_handler;
155    SCIC_CONTROLLER_COMPLETION_HANDLER completion_handler;
156 
157 } SCIC_CONTROLLER_HANDLER_METHODS_T;
158 
159 /**
160  * @brief This method will attempt to construct a controller object
161  *        utilizing the supplied parameter information.
162  *
163  * @param[in]  library This parameter specifies the handle to the library
164  *             object associated with the controller being constructed.
165  * @param[in]  controller This parameter specifies the controller to be
166  *             constructed.
167  * @param[in]  user_object This parameter is a reference to the SCIL users
168  *             controller object and will be used to associate with the core
169  *             controller.
170  *
171  * @return Indicate if the controller was successfully constructed or if
172  *         it failed in some way.
173  * @retval SCI_SUCCESS This value is returned if the controller was
174  *         successfully constructed.
175  * @retval SCI_WARNING_TIMER_CONFLICT This value is returned if the
176  *         interrupt coalescence timer may cause SAS compliance issues
177  *         for SMP Target mode response processing.
178  * @retval SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE This value is returned if
179  *         the controller does not support the supplied type.
180  * @retval SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION This value is returned
181  *         if the controller does not support the supplied initialization
182  *         data version.
183  */
184 SCI_STATUS scic_controller_construct(
185    SCI_LIBRARY_HANDLE_T      library,
186    SCI_CONTROLLER_HANDLE_T   controller,
187    void *                    user_object
188 );
189 
190 /**
191  * @brief This method will enable all controller interrupts.
192  *
193  * @param[in]  controller This parameter specifies the controller for which
194  *             to enable interrupts.
195  *
196  * @return none
197  */
198 void scic_controller_enable_interrupts(
199    SCI_CONTROLLER_HANDLE_T      controller
200 );
201 
202 /**
203  * @brief This method will disable all controller interrupts.
204  *
205  * @param[in]  controller This parameter specifies the controller for which
206  *             to disable interrupts.
207  *
208  * @return none
209  */
210 void scic_controller_disable_interrupts(
211    SCI_CONTROLLER_HANDLE_T      controller
212 );
213 
214 /**
215  * @brief This method will return provide function pointers for the
216  *        interrupt handler and completion handler.  The interrupt handler
217  *        is expected to be invoked at interrupt time.  The completion
218  *        handler is scheduled to run as a result of the interrupt handler.
219  *        The completion handler performs the bulk work for processing
220  *        silicon events.
221  *
222  * @param[in]  interrupt_type This parameter informs the core which type
223  *             of interrupt/completion methods are being requested. These
224  *             are the types: SCIC_LEGACY_LINE_INTERRUPT_TYPE,
225  *             SCIC_MSIX_INTERRUPT_TYPE, SCIC_NO_INTERRUPTS (POLLING)
226  * @param[in]  message_count This parameter informs the core the
227  *             number of MSI-X messages to be utilized.  This parameter must
228  *             be 0 when requesting legacy line based handlers.
229  * @param[in]  handler_methods The caller provides a pointer to a buffer of
230  *             type SCIC_CONTROLLER_HANDLER_METHODS_T. The size depends on
231  *             the combination of the interrupt_type and message_count input
232  *             parameters:
233  *             SCIC_LEGACY_LINE_INTERRUPT_TYPE:
234  *             - size = sizeof(SCIC_CONTROLLER_HANDLER_METHODS_T)
235  *             SCIC_MSIX_INTERRUPT_TYPE:
236  *             - size = message_count*sizeof(SCIC_CONTROLLER_HANDLER_METHODS_T)
237  * @param[out] handler_methods SCIC fills out the caller's buffer with the
238  *             appropriate interrupt and completion handlers based on the info
239  *             provided in the interrupt_type and message_count input
240  *             parameters. For SCIC_LEGACY_LINE_INTERRUPT_TYPE, the buffer
241  *             receives a single SCIC_CONTROLLER_HANDLER_METHODS_T element
242  *             regardless that the message_count parameter is zero.
243  *             For SCIC_MSIX_INTERRUPT_TYPE, the buffer receives an array of
244  *             elements of type SCIC_CONTROLLER_HANDLER_METHODS_T where the
245  *             array size is equivalent to the message_count parameter. The
246  *             array is zero-relative where entry zero corresponds to
247  *             message-vector zero, entry one corresponds to message-vector one,
248  *             and so forth.
249  *
250  * @return Indicate if the handler retrieval operation was successful.
251  * @retval SCI_SUCCESS This value is returned if retrieval succeeded.
252  * @retval SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT This value is returned
253  *         if the user supplied an unsupported number of MSI-X messages.
254  *         For legacy line interrupts the only valid value is 0.
255  */
256 SCI_STATUS scic_controller_get_handler_methods(
257    SCIC_INTERRUPT_TYPE                  interrupt_type,
258    U16                                  message_count,
259    SCIC_CONTROLLER_HANDLER_METHODS_T *  handler_methods
260 );
261 
262 /**
263  * @brief This method will initialize the controller hardware managed by
264  *        the supplied core controller object.  This method will bring the
265  *        physical controller hardware out of reset and enable the core to
266  *        determine the capabilities of the hardware being managed.  Thus,
267  *        the core controller can determine it's exact physical (DMA capable)
268  *        memory requirements.
269  *
270  * @pre   The SCI Core user must have called scic_controller_construct()
271  *        on the supplied controller object previously.
272  *
273  * @param[in]  controller This parameter specifies the controller to be
274  *             initialized.
275  *
276  * @return Indicate if the controller was successfully initialized or if
277  *         it failed in some way.
278  * @retval SCI_SUCCESS This value is returned if the controller hardware
279  *         was successfully initialized.
280  */
281 SCI_STATUS scic_controller_initialize(
282    SCI_CONTROLLER_HANDLE_T   controller
283 );
284 
285 /**
286  * @brief This method returns the suggested scic_controller_start()
287  *        timeout amount.  The user is free to use any timeout value,
288  *        but this method provides the suggested minimum start timeout
289  *        value.  The returned value is based upon empirical information
290  *        determined as a result of interoperability testing.
291  *
292  * @param[in]  controller the handle to the controller object for which
293  *             to return the suggested start timeout.
294  *
295  * @return  This method returns the number of milliseconds for the
296  *          suggested start operation timeout.
297  */
298 U32 scic_controller_get_suggested_start_timeout(
299    SCI_CONTROLLER_HANDLE_T  controller
300 );
301 
302 /**
303  * @brief This method will start the supplied core controller.  This method
304  *        will start the staggered spin up operation.  The SCI User completion
305  *        callback is called when the following conditions are met:
306  *        -# the return status of this method is SCI_SUCCESS.
307  *        -# after all of the phys have successfully started or been given
308  *           the opportunity to start.
309  *
310  * @pre   The SCI Core user must have filled in the physical memory
311  *        descriptor structure via the
312  *        sci_controller_get_memory_descriptor_list() method.
313  * @pre   The SCI Core user must have invoked the scic_controller_initialize()
314  *        method prior to invoking this method.
315  *
316  * @pre   The controller must be in the INITIALIZED or STARTED state.
317  *
318  * @param[in]  controller the handle to the controller object to start.
319  * @param[in]  timeout This parameter specifies the number of milliseconds
320  *             in which the start operation should complete.
321  *
322  * @return Indicate if the controller start method succeeded or failed in
323  *         some way.
324  * @retval SCI_SUCCESS if the start operation succeeded.
325  * @retval SCI_WARNING_ALREADY_IN_STATE if the controller is already in
326  *         the STARTED state.
327  * @retval SCI_FAILURE_INVALID_STATE if the controller is not either in
328  *         the INITIALIZED or STARTED states.
329  * @retval SCI_FAILURE_INVALID_MEMORY_DESCRIPTOR if there are
330  *         inconsistent or invalid values in the supplied
331  *         SCI_PHYSICAL_MEMORY_DESCRIPTOR array.
332  */
333 SCI_STATUS scic_controller_start(
334    SCI_CONTROLLER_HANDLE_T  controller,
335    U32                      timeout
336 );
337 
338 /**
339  * @brief This method will stop an individual controller object.This method
340  *        will invoke the associated user callback upon completion.  The
341  *        completion callback is called when the following conditions are met:
342  *           -# the method return status is SCI_SUCCESS.
343  *           -# the controller has been quiesced.
344  *        This method will ensure that all IO requests are quiesced, phys
345  *        are stopped, and all additional operation by the hardware is halted.
346  *
347  * @pre   The controller must be in the STARTED or STOPPED state.
348  *
349  * @param[in]  controller the handle to the controller object to stop.
350  * @param[in]  timeout This parameter specifies the number of milliseconds
351  *             in which the stop operation should complete.
352  *
353  * @return Indicate if the controller stop method succeeded or failed in
354  *         some way.
355  * @retval SCI_SUCCESS if the stop operation successfully began.
356  * @retval SCI_WARNING_ALREADY_IN_STATE if the controller is already in
357  *         the STOPPED state.
358  * @retval SCI_FAILURE_INVALID_STATE if the controller is not either in
359  *         the STARTED or STOPPED states.
360  */
361 SCI_STATUS scic_controller_stop(
362    SCI_CONTROLLER_HANDLE_T  controller,
363    U32                      timeout
364 );
365 
366 /**
367  * @brief This method will reset the supplied core controller regardless of
368  *        the state of said controller.  This operation is considered
369  *        destructive.  In other words, all current operations are wiped
370  *        out.  No IO completions for outstanding devices occur.  Outstanding
371  *        IO requests are not aborted or completed at the actual remote
372  *        device.
373  *
374  * @param[in]  controller the handle to the controller object to reset.
375  *
376  * @return Indicate if the controller reset method succeeded or failed in
377  *         some way.
378  * @retval SCI_SUCCESS if the reset operation successfully started.
379  * @retval SCI_FATAL_ERROR if the controller reset operation is unable to
380  *         complete.
381  */
382 SCI_STATUS scic_controller_reset(
383    SCI_CONTROLLER_HANDLE_T  controller
384 );
385 
386 /**
387  * @brief This method is called by the SCI user to send/start an IO request.
388  *        If the method invocation is successful, then the IO request has
389  *        been queued to the hardware for processing.
390  *
391  * @warning
392  *         - IO tags are a protected resource.  It is incumbent upon the
393  *           SCI Core user to ensure that each of the methods that may
394  *           allocate or free available IO tags are handled in a mutually
395  *           exclusive manner.  This method is one of said methods requiring
396  *           proper critical code section protection (e.g. semaphore,
397  *           spin-lock, etc.).
398  *         - For SATA, the user is required to manage NCQ tags.  As a
399  *           result, it is expected the user will have set the NCQ tag
400  *           field in the host to device register FIS prior to calling
401  *           this method.  There is also a requirement for the user
402  *           to call scic_stp_io_set_ncq_tag() prior to invoking the
403  *           scic_controller_start_io() method.
404  *
405  * @param[in]  controller the handle to the controller object for which
406  *             to start an IO request.
407  * @param[in]  remote_device the handle to the remote device object for which
408  *             to start an IO request.
409  * @param[in]  io_request the handle to the io request object to start.
410  * @param[in]  io_tag This parameter specifies a previously allocated IO tag
411  *             that the user desires to be utilized for this request.
412  *             This parameter is optional.  The user is allowed to supply
413  *             SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter.
414  *             @see scic_controller_allocate_tag() for more information
415  *             on allocating a tag.
416  *
417  * @return Indicate if the controller successfully started the IO request.
418  * @retval SCI_IO_SUCCESS if the IO request was successfully started.
419  *
420  * @todo Determine the failure situations and return values.
421  */
422 SCI_IO_STATUS scic_controller_start_io(
423    SCI_CONTROLLER_HANDLE_T     controller,
424    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
425    SCI_IO_REQUEST_HANDLE_T     io_request,
426    U16                         io_tag
427 );
428 
429 #if !defined(DISABLE_TASK_MANAGEMENT)
430 
431 /**
432  * @brief This method is called by the SCIC user to send/start a framework
433  *        task management request.
434  *
435  * @warning
436  *         - IO tags are a protected resource.  It is incumbent upon the
437  *           SCI Core user to ensure that each of the methods that may
438  *           allocate or free available IO tags are handled in a mutually
439  *           exclusive manner.  This method is one of said methods requiring
440  *           proper critical code section protection (e.g. semaphore,
441  *           spin-lock, etc.).
442  *         - The user must synchronize this task with completion queue
443  *           processing.  If they are not synchronized then it is possible
444  *           for the io requests that are being managed by the task request
445  *           can complete before starting the task request.
446  *
447  * @param[in]  controller the handle to the controller object for which
448  *             to start the task management request.
449  * @param[in]  remote_device the handle to the remote device object for which
450  *             to start the task management request.
451  * @param[in]  task_request the handle to the task request object to start.
452  * @param[in]  io_tag This parameter specifies a previously allocated IO tag
453  *             that the user desires to be utilized for this request.  Note
454  *             this not the io_tag of the request being managed.  It is to
455  *             be utilized for the task request itself.
456  *             This parameter is optional.  The user is allowed to supply
457  *             SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter.
458  *             @see scic_controller_allocate_tag() for more information
459  *             on allocating a tag.
460  *
461  * @return Indicate if the controller successfully started the IO request.
462  * @retval SCI_TASK_SUCCESS if the task request was successfully started.
463  * @retval SCI_TASK_FAILURE_REQUIRES_SCSI_ABORT This value is returned if
464  *         there is/are task(s) outstanding that require termination or
465  *         completion before this request can succeed.
466  */
467 SCI_TASK_STATUS scic_controller_start_task(
468    SCI_CONTROLLER_HANDLE_T     controller,
469    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
470    SCI_TASK_REQUEST_HANDLE_T   task_request,
471    U16                         io_tag
472 );
473 
474 /**
475  * @brief This method will perform core specific completion operations for
476  *        task management request. After this method is invoked, the user should
477  *        consider the task request as invalid until it is properly reused
478  *        (i.e. re-constructed).
479  *
480  * @param[in]  controller The handle to the controller object for which
481  *             to complete the task management request.
482  * @param[in]  remote_device The handle to the remote device object for which
483  *             to complete the task management request.
484  * @param[in]  task_request the handle to the task management request object
485  *             to complete.
486  *
487  * @return Indicate if the controller successfully completed the task
488  *         management request.
489  * @retval SCI_SUCCESS if the completion process was successful.
490  */
491 SCI_STATUS scic_controller_complete_task(
492    SCI_CONTROLLER_HANDLE_T     controller,
493    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
494    SCI_TASK_REQUEST_HANDLE_T   task_request
495 );
496 
497 #else // !defined(DISABLE_TASK_MANAGEMENT)
498 
499 #define scic_controller_start_task(controller, dev, task, tag) SCI_TASK_FAILURE
500 #define scic_controller_complete_task(controller, dev, task) SCI_FAILURE
501 
502 #endif // !defined(DISABLE_TASK_MANAGEMENT)
503 
504 /**
505  * @brief This method is called by the SCI Core user to terminate an ongoing
506  *        (i.e. started) core IO request.  This does not abort the IO request
507  *        at the target, but rather removes the IO request from the host
508  *        controller.
509  *
510  * @param[in]  controller the handle to the controller object for which
511  *             to terminate a request.
512  * @param[in]  remote_device the handle to the remote device object for which
513  *             to terminate a request.
514  * @param[in]  request the handle to the io or task management request
515  *             object to terminate.
516  *
517  * @return Indicate if the controller successfully began the terminate process
518  *         for the IO request.
519  * @retval SCI_SUCCESS if the terminate process was successfully started for
520  *         the request.
521  *
522  * @todo Determine the failure situations and return values.
523  */
524 SCI_STATUS scic_controller_terminate_request(
525    SCI_CONTROLLER_HANDLE_T     controller,
526    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
527    SCI_IO_REQUEST_HANDLE_T     request
528 );
529 
530 /**
531  * @brief This method will perform core specific completion operations for
532  *        an IO request.  After this method is invoked, the user should
533  *        consider the IO request as invalid until it is properly reused
534  *        (i.e. re-constructed).
535  *
536  * @warning
537  *        - IO tags are a protected resource.  It is incumbent upon the
538  *          SCI Core user to ensure that each of the methods that may
539  *          allocate or free available IO tags are handled in a mutually
540  *          exclusive manner.  This method is one of said methods requiring
541  *          proper critical code section protection (e.g. semaphore,
542  *          spin-lock, etc.).
543  *        - If the IO tag for a request was allocated, by the SCI Core user,
544  *          using the scic_controller_allocate_io_tag() method, then it is
545  *          the responsibility of the caller to invoke the
546  *          scic_controller_free_io_tag() method to free the tag (i.e. this
547  *          method will not free the IO tag).
548  *
549  * @param[in]  controller The handle to the controller object for which
550  *             to complete the IO request.
551  * @param[in]  remote_device The handle to the remote device object for which
552  *             to complete the IO request.
553  * @param[in]  io_request the handle to the io request object to complete.
554  *
555  * @return Indicate if the controller successfully completed the IO request.
556  * @retval SCI_SUCCESS if the completion process was successful.
557  */
558 SCI_STATUS scic_controller_complete_io(
559    SCI_CONTROLLER_HANDLE_T     controller,
560    SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
561    SCI_IO_REQUEST_HANDLE_T     io_request
562 );
563 
564 
565 /**
566  * @brief This method simply provides the user with a unique handle for a
567  *        given SAS/SATA core port index.
568  *
569  * @param[in]  controller This parameter represents the handle to the
570  *             controller object from which to retrieve a port (SAS or
571  *             SATA) handle.
572  * @param[in]  port_index This parameter specifies the port index in
573  *             the controller for which to retrieve the port handle.
574  *             0 <= port_index < maximum number of phys.
575  * @param[out] port_handle This parameter specifies the retrieved port handle
576  *             to be provided to the caller.
577  *
578  * @return Indicate if the retrieval of the port handle was successful.
579  * @retval SCI_SUCCESS This value is returned if the retrieval was successful.
580  * @retval SCI_FAILURE_INVALID_PORT This value is returned if the supplied
581  *         port id is not in the supported range.
582  */
583 SCI_STATUS scic_controller_get_port_handle(
584    SCI_CONTROLLER_HANDLE_T   controller,
585    U8                        port_index,
586    SCI_PORT_HANDLE_T       * port_handle
587 );
588 
589 /**
590  * @brief This method simply provides the user with a unique handle for a
591  *        given SAS/SATA phy index/identifier.
592  *
593  * @param[in]  controller This parameter represents the handle to the
594  *             controller object from which to retrieve a phy (SAS or
595  *             SATA) handle.
596  * @param[in]  phy_index This parameter specifies the phy index in
597  *             the controller for which to retrieve the phy handle.
598  *             0 <= phy_index < maximum number of phys.
599  * @param[out] phy_handle This parameter specifies the retrieved phy handle
600  *             to be provided to the caller.
601  *
602  * @return Indicate if the retrieval of the phy handle was successful.
603  * @retval SCI_SUCCESS This value is returned if the retrieval was successful.
604  * @retval SCI_FAILURE_INVALID_PHY This value is returned if the supplied phy
605  *         id is not in the supported range.
606  */
607 SCI_STATUS scic_controller_get_phy_handle(
608    SCI_CONTROLLER_HANDLE_T   controller,
609    U8                        phy_index,
610    SCI_PHY_HANDLE_T        * phy_handle
611 );
612 
613 /**
614  * @brief This method will allocate a tag from the pool of free IO tags.
615  *        Direct allocation of IO tags by the SCI Core user is optional.
616  *        The scic_controller_start_io() method will allocate an IO
617  *        tag if this method is not utilized and the tag is not
618  *        supplied to the IO construct routine.  Direct allocation of IO tags
619  *        may provide additional performance improvements in environments
620  *        capable of supporting this usage model.  Additionally, direct
621  *        allocation of IO tags also provides additional flexibility to the
622  *        SCI Core user.  Specifically, the user may retain IO tags across
623  *        the lives of multiple IO requests.
624  *
625  * @warning IO tags are a protected resource.  It is incumbent upon the
626  *          SCI Core user to ensure that each of the methods that may
627  *          allocate or free available IO tags are handled in a mutually
628  *          exclusive manner.  This method is one of said methods requiring
629  *          proper critical code section protection (e.g. semaphore,
630  *          spin-lock, etc.).
631  *
632  * @param[in]  controller the handle to the controller object for which to
633  *             allocate the tag.
634  *
635  * @return An unsigned integer representing an available IO tag.
636  * @retval SCI_CONTROLLER_INVALID_IO_TAG This value is returned if there
637  *         are no currently available tags to be allocated.
638  * @retval All return other values indicate a legitimate tag.
639  */
640 U16 scic_controller_allocate_io_tag(
641    SCI_CONTROLLER_HANDLE_T  controller
642 );
643 
644 /**
645  * @brief This method will free an IO tag to the pool of free IO tags.
646  *        This method provides the SCI Core user more flexibility with
647  *        regards to IO tags.  The user may desire to keep an IO tag after
648  *        an IO request has completed, because they plan on re-using the
649  *        tag for a subsequent IO request.  This method is only legal if
650  *        the tag was allocated via scic_controller_allocate_io_tag().
651  *
652  * @warning
653  *        - IO tags are a protected resource.  It is incumbent upon the
654  *          SCI Core user to ensure that each of the methods that may
655  *          allocate or free available IO tags are handled in a mutually
656  *          exclusive manner.  This method is one of said methods requiring
657  *          proper critical code section protection (e.g. semaphore,
658  *          spin-lock, etc.).
659  *        - If the IO tag for a request was allocated, by the SCI Core user,
660  *          using the scic_controller_allocate_io_tag() method, then it is
661  *          the responsibility of the caller to invoke this method to free
662  *          the tag.
663  *
664  * @param[in]  controller This parameter specifies the handle to the
665  *             controller object for which to free/return the tag.
666  * @param[in]  io_tag This parameter represents the tag to be freed to the
667  *             pool of available tags.
668  *
669  * @return This method returns an indication of whether the tag was
670  *         successfully put back (freed) to the pool of available tags.
671  * @retval SCI_SUCCESS This return value indicates the tag was successfully
672  *         placed into the pool of available IO tags.
673  * @retval SCI_FAILURE_INVALID_IO_TAG This value is returned if the supplied
674  *         tag is not a valid IO tag value.
675  */
676 SCI_STATUS scic_controller_free_io_tag(
677    SCI_CONTROLLER_HANDLE_T  controller,
678    U16                      io_tag
679 );
680 
681 /**
682  * @brief This method returns the size of the core's scratch RAM.
683  *
684  * @return Size of the scratch RAM in dwords.
685  */
686 U32 scic_controller_get_scratch_ram_size(
687    SCI_CONTROLLER_HANDLE_T   controller
688 );
689 
690 /**
691  * @brief This method allows the user to read a U32 from the core's
692  *        scratch RAM.
693  *
694  * @param[in]  controller This parameter represents the handle to the
695  *             controller object for which to read scratch RAM.
696  * @param[in]  offset The offset (in dwords) into the scratch RAM.
697  * @param[out] value The location where the read value should be stored.
698  *
699  * @return Indicate if the user specified a valid offset into the
700  *         scratch RAM.
701  * @retval SCI_SUCCESS The scratch RAM was successfully read.
702  * @retval SCI_FAILURE_INVALID_PARAMETER_VALUE The user specified an
703  *          invalid offset.
704  */
705 SCI_STATUS scic_controller_read_scratch_ram_dword(
706    SCI_CONTROLLER_HANDLE_T   controller,
707    U32                       offset,
708    U32                     * value
709 );
710 
711 /**
712  * @brief This method allows the user to write a U32 to the core's
713  *        scratch RAM.
714  *
715  * @param[in]  controller This parameter represents the handle to the
716  *             controller object for which to write scratch RAM.
717  * @param[in]  offset The offset (in dwords) into the scratch RAM.
718  * @param[out] value The value to be written to scratch RAM.
719  *
720  * @return Indicate if the user specified a valid offset into the
721  *         scratch RAM.
722  * @retval SCI_SUCCESS The scratch RAM was successfully written.
723  * @retval SCI_FAILURE_INVALID_PARAMETER_VALUE The user specified an
724  *          invalid offset.
725  */
726 SCI_STATUS scic_controller_write_scratch_ram_dword(
727     SCI_CONTROLLER_HANDLE_T   controller,
728     U32                       offset,
729     U32                       value
730 );
731 
732 /**
733  * @brief This method allows the user to configure the SCI core into
734  *        either a performance mode or a memory savings mode.
735  *
736  * @param[in]  controller This parameter represents the handle to the
737  *             controller object for which to update the operating
738  *             mode.
739  * @param[in]  mode This parameter specifies the new mode for the
740  *             controller.
741  *
742  * @return Indicate if the user successfully change the operating mode
743  *         of the controller.
744  * @retval SCI_SUCCESS The user successfully updated the mode.
745  */
746 SCI_STATUS scic_controller_set_mode(
747    SCI_CONTROLLER_HANDLE_T   controller,
748    SCI_CONTROLLER_MODE       mode
749 );
750 
751 
752 #if !defined(DISABLE_INTERRUPTS)
753 /**
754  * @brief This method allows the user to configure the interrupt coalescence.
755  *
756  * @param[in]  controller This parameter represents the handle to the
757  *                controller object for which its interrupt coalesce register
758  *                is overridden.
759  *
760  * @param[in]  coalesce_number Used to control the number of entries in the
761  *                Completion Queue before an interrupt is generated. If the
762  *                number of entries exceed this number, an interrupt will be
763  *                generated. The valid range of the input is [0, 256].
764  *                A setting of 0 results in coalescing being disabled.
765  * @param[in]  coalesce_timeout Timeout value in microseconds. The valid range
766  *                of the input is [0, 2700000] . A setting of 0 is allowed and
767  *                results in no interrupt coalescing timeout.
768  *
769  * @return Indicate if the user successfully set the interrupt coalesce parameters.
770  * @retval SCI_SUCCESS The user successfully updated the interrupt coalescence.
771  * @retval SCI_FAILURE_INVALID_PARAMETER_VALUE The user input value is out of range.
772  */
773 SCI_STATUS scic_controller_set_interrupt_coalescence(
774    SCI_CONTROLLER_HANDLE_T controller,
775    U32                     coalesce_number,
776    U32                     coalesce_timeout
777 );
778 
779 /**
780  * @brief This method retrieves the interrupt coalescing values
781  *
782  * @param[in] controller This parameter specifies the controller for
783  *            which its interrupt coalescing number is read.
784  *
785  * @param[out] coalesce_number, interrupt coalescing number read from controller.
786  *
787  * @param[out] coalesce_timeout, timeout value in microseconds.
788  *
789  * @return None
790  */
791 void scic_controller_get_interrupt_coalescence(
792    SCI_CONTROLLER_HANDLE_T   controller,
793    U32                     * coalesce_number,
794    U32                     * coalesce_timeout
795 );
796 #else // !defined(DISABLE_INTERRUPTS)
797 #define scic_controller_set_interrupt_coalescence(controller, num, timeout) \
798         SCI_FAILURE
799 #define scic_controller_get_interrupt_coalescence(controller, num, timeout)
800 #endif // !defined(DISABLE_INTERRUPTS)
801 
802 
803 /**
804  * @brief This method suspend the controller, reinitialize RAMs, then resume
805  *           the controller.
806  *
807  * @param[in] controller This parameter specifies the controller which is transitioning.
808  *
809  * @param[in] restrict_completions This parameter specifies whether the controller should
810  *               ignore completion processing for non-fastpath events.  This will cause
811  *               the completions to be thrown away.
812  *
813  * @return SCI_STATUS The status of controller transition.
814  */
815 SCI_STATUS scic_controller_transition(
816    SCI_CONTROLLER_HANDLE_T   controller,
817    BOOL                      restrict_completions
818 );
819 
820 
821 /**
822  * @brief This method suspends the controller.
823  *
824  * @param[in] controller This parameter specifies the controller which is to be suspended.
825  *
826  * @return SCI_STATUS The status of controller suspend.
827  */
828 SCI_STATUS scic_controller_suspend(
829    SCI_CONTROLLER_HANDLE_T   controller
830 );
831 
832 /**
833  * @brief This method resumes the controller.
834  *
835  * @param[in] controller This parameter specifies the controller which is to be resumed.
836  *
837  * @return SCI_STATUS The status of controller resume.
838  */
839 SCI_STATUS scic_controller_resume(
840    SCI_CONTROLLER_HANDLE_T   controller
841 );
842 
843 SCI_STATUS scic_controller_get_max_ports(
844    SCI_CONTROLLER_HANDLE_T   controller,
845    U8                      * count
846 );
847 
848 SCI_STATUS scic_controller_get_max_phys(
849    SCI_CONTROLLER_HANDLE_T   controller,
850    U8                      * count
851 );
852 
853 #ifdef __cplusplus
854 }
855 #endif // __cplusplus
856 
857 #endif // _SCIC_CONTROLLER_H_
858 
859