1/*-
2 * This file is provided under a dual BSD/GPLv2 license.  When using or
3 * redistributing this file, you may do so under either license.
4 *
5 * GPL LICENSE SUMMARY
6 *
7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of version 2 of the GNU General Public License as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * BSD LICENSE
25 *
26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 *
33 *   * Redistributions of source code must retain the above copyright
34 *     notice, this list of conditions and the following disclaimer.
35 *   * Redistributions in binary form must reproduce the above copyright
36 *     notice, this list of conditions and the following disclaimer in
37 *     the documentation and/or other materials provided with the
38 *     distribution.
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51 *
52 * $FreeBSD$
53 */
54#ifndef _SCIF_CONTROLLER_H_
55#define _SCIF_CONTROLLER_H_
56
57/**
58 * @file
59 *
60 * @brief This file contains all of the interface methods that can be called
61 *        by an SCIF user on a SCIF controller object.
62 */
63
64#ifdef __cplusplus
65extern "C" {
66#endif // __cplusplus
67
68#include <dev/isci/scil/sci_types.h>
69#include <dev/isci/scil/sci_status.h>
70
71
72/**
73 * @brief This method will attempt to construct a framework controller object
74 *        utilizing the supplied parameter information.
75 *
76 * @param[in]  library This parameter specifies the handle to the framework
77 *             library object associated with the controller being constructed.
78 * @param[in]  controller This parameter specifies the framework controller to
79 *             be constructed.
80 * @param[in]  user_object This parameter is a reference to the SCIL users
81 *             controller object and will be used to associate with the
82 *             framework controller.
83 *
84 * @return Indicate if the controller was successfully constructed or if
85 *         it failed in some way.
86 * @retval SCI_SUCCESS This value is returned if the controller was
87 *         successfully constructed.
88 * @retval SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION This value is returned
89 *         if the controller does not support the supplied oem parameter
90 *         data version.
91 * @retval SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is returned
92 *         if the controller doesn't support the port configuration scheme
93 *         (APC or MPC).
94 */
95SCI_STATUS scif_controller_construct(
96   SCI_LIBRARY_HANDLE_T      library,
97   SCI_CONTROLLER_HANDLE_T   controller,
98   void *                    user_object
99);
100
101/**
102 * @brief This method will initialize the SCI Framework controller object.
103 *        This includes initialization of the associated core controller.
104 *
105 * @param[in]  controller This parameter specifies the controller to be
106 *             initialized.
107 *
108 * @return Indicate if the controller was successfully initialized or if
109 *         it failed in some way.
110 * @retval SCI_SUCCESS This value is returned if the controller hardware
111 *         was successfully initialized.
112 */
113SCI_STATUS scif_controller_initialize(
114   SCI_CONTROLLER_HANDLE_T  controller
115);
116
117/**
118 * @brief This method returns the suggested scif_controller_start()
119 *        timeout amount.  The user is free to use any timeout value,
120 *        but this method provides the suggested minimum start timeout
121 *        value.  The returned value is based upon empirical information
122 *        determined as a result of interoperability testing.
123 *
124 * @param[in]  controller the handle to the controller object for which
125 *             to return the suggested start timeout.
126 *
127 * @return  This method returns the number of milliseconds for the
128 *          suggested start operation timeout.
129 */
130U32 scif_controller_get_suggested_start_timeout(
131   SCI_CONTROLLER_HANDLE_T  controller
132);
133
134/**
135 * @brief This method will start the SCIF controller.  The SCI User completion
136 *        callback is called when the following conditions are met:
137 *        -# the return status of this method is SCI_SUCCESS.
138 *        -# after all of the phys have successfully started or been given
139 *           the opportunity to start.
140 *
141 * @pre   The controller must be in the INITIALIZED or STARTED state.
142 *
143 * @param[in]  controller the handle to the controller object to start.
144 * @param[in]  timeout This parameter specifies the number of milliseconds
145 *             in which the start operation should complete.
146 *
147 * @return Indicate if the controller start method succeeded or failed in
148 *         some way.
149 * @retval SCI_SUCCESS if the start operation succeeded.
150 * @retval SCI_WARNING_ALREADY_IN_STATE if the controller is already in
151 *         the STARTED state.
152 * @retval SCI_FAILURE_INVALID_STATE if the controller is not either in
153 *         the INITIALIZED or STARTED states.
154 * @retval SCI_FAILURE_INVALID_MEMORY_DESCRIPTOR if there are
155 *         inconsistent or invalid values in the supplied
156 *         SCI_PHYSICAL_MEMORY_DESCRIPTOR array.
157 * @retval SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION This value is
158 *         returned if the phy to port allocation cannot be supported.
159 *
160 * @see For additional information please refer to: scic_controller_start()
161 */
162SCI_STATUS scif_controller_start(
163   SCI_CONTROLLER_HANDLE_T  controller,
164   U32                      timeout
165);
166
167/**
168 * @brief This method will stop an individual framework controller object. This
169 *        includes quiescing IOs, releasing affiliations, and other shutdown
170 *        related operations. This method will invoke the associated user
171 *        callback upon completion.  The completion callback is called when
172 *        the following conditions are met:
173 *           -# the method return status is SCI_SUCCESS.
174 *           -# the controller has been quiesced.
175 *        This method will ensure that all framework IO requests are quiesced
176 *        and any additional framework operations are halted.
177 *
178 * @pre   The controller must be in the STARTED or STOPPED state.
179 *
180 * @param[in]  controller the handle to the controller object to stop.
181 * @param[in]  timeout This parameter specifies the number of milliseconds
182 *             in which the stop operation should complete.
183 *
184 * @return Indicate if the controller stop method succeeded or failed in
185 *         some way.
186 * @retval SCI_SUCCESS if the stop operation successfully began.
187 * @retval SCI_WARNING_ALREADY_IN_STATE if the controller is already in
188 *         the STOPPED state.
189 * @retval SCI_FAILURE_INVALID_STATE if the controller is not either in
190 *         the STARTED or STOPPED states.
191 *
192 * @see For additional information please refer to: scic_controller_stop()
193 */
194SCI_STATUS scif_controller_stop(
195   SCI_CONTROLLER_HANDLE_T  controller,
196   U32                      timeout
197);
198
199/**
200 * @brief This method will reset the supplied framework controller regardless
201 *        of the state of said controller.  This operation is considered
202 *        destructive.  Outstanding IO requests are not aborted or completed
203 *        at the actual remote device.  However, the framework will
204 *        manufacture completion callbacks to the OS driver for the IO
205 *        requests.
206 *
207 * @param[in]  controller the handle to the controller object to reset.
208 *
209 * @return Indicate if the controller reset method succeeded or failed in
210 *         some way.
211 * @retval SCI_SUCCESS if the reset operation successfully started.
212 * @retval SCI_FATAL_ERROR if the controller reset operation is unable to
213 *         complete.
214 *
215 * @see For additional information please refer to: scic_controller_reset()
216 */
217SCI_STATUS scif_controller_reset(
218   SCI_CONTROLLER_HANDLE_T  controller
219);
220
221/**
222 * @brief This method returns the SCI Core controller handle associated
223 *        with this controller.
224 *
225 * @param[in]  scif_controller the handle to the controller object for which
226 *             to retrieve the core specific controller handle
227 *
228 * @return Return the SCI core controller handle associated with the supplied
229 *         framework controller.
230 */
231SCI_CONTROLLER_HANDLE_T scif_controller_get_scic_handle(
232   SCI_CONTROLLER_HANDLE_T   scif_controller
233);
234
235/**
236 * @brief This method is called by the SCIF user to send/start a framework
237 *        IO request.
238 *
239 * @param[in]  controller the handle to the controller object for which
240 *             to start an IO request.
241 * @param[in]  remote_device the handle to the remote device object for which
242 *             to start an IO request.
243 * @param[in]  io_request the handle to the io request object to start.
244 * @param[in]  io_tag This parameter specifies a previously allocated IO tag
245 *             that the user desires to be utilized for this request.
246 *             This parameter is optional.  The user is allowed to supply
247 *             SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter.
248 *             @see scic_controller_allocate_tag() for more information
249 *             on allocating a tag.
250 *
251 * @return Indicate if the controller successfully started the IO request.
252 * @retval SCI_IO_SUCCESS if the IO request was successfully started.
253 *
254 * @see For additional information please refer to: scic_controller_start_io()
255 *
256 * @todo Determine the failure situations and return values.
257 */
258SCI_IO_STATUS scif_controller_start_io(
259   SCI_CONTROLLER_HANDLE_T     controller,
260   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
261   SCI_IO_REQUEST_HANDLE_T     io_request,
262   U16                         io_tag
263);
264
265/**
266 * @brief This method is called by the SCIF user to send/start a framework
267 *        task management request.
268 *
269 * @param[in]  controller the handle to the controller object for which
270 *             to start the task management request.
271 * @param[in]  remote_device the handle to the remote device object for which
272 *             to start the task management request.
273 * @param[in]  task_request the handle to the task request object to start.
274 * @param[in]  io_tag This parameter specifies a previously allocated IO tag
275 *             that the user desires to be utilized for this request.  Note
276 *             this not the io_tag of the request being managed.  It is to
277 *             be utilized for the task request itself.
278 *             This parameter is optional.  The user is allowed to supply
279 *             SCI_CONTROLLER_INVALID_IO_TAG as the value for this parameter.
280 *             @see scic_controller_allocate_tag() for more information
281 *             on allocating a tag.
282 *
283 * @return Indicate if the controller successfully started the IO request.
284 * @retval SCI_TASK_SUCCESS if the task request was successfully started.
285 *
286 * @see For additional information please refer to: scic_controller_start_task()
287 *
288 * @todo Determine the failure situations and return values.
289 */
290SCI_TASK_STATUS scif_controller_start_task(
291   SCI_CONTROLLER_HANDLE_T     controller,
292   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
293   SCI_TASK_REQUEST_HANDLE_T   task_request,
294   U16                         io_tag
295);
296
297/**
298 * @brief This method is called by the SCI user to complete a previously
299 *        started IO request.  After this method is invoked, the user should
300 *        consider the IO request as invalid until it is properly reused
301 *        (i.e. re-constructed).
302 *
303 * @param[in]  controller The handle to the controller object for which
304 *             to complete the IO request.
305 * @param[in]  remote_device The handle to the remote device object for which
306 *             to complete the IO request.
307 * @param[in]  io_request the handle to the io request object to complete.
308 *
309 * @return Indicate if the controller successfully completed the IO request.
310 * @retval SCI_SUCCESS if the completion process was successful.
311 *
312 * @see For additional information please refer to:
313 *      scic_controller_complete_io()
314 */
315SCI_STATUS scif_controller_complete_io(
316   SCI_CONTROLLER_HANDLE_T     controller,
317   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
318   SCI_IO_REQUEST_HANDLE_T     io_request
319);
320
321/**
322 * @brief This method will perform framework specific completion operations for
323 *        a task management request. After this method is invoked, the user
324 *        should consider the task request as invalid until it is properly
325 *        reused (i.e. re-constructed).
326 *
327 * @param[in]  controller The handle to the controller object for which
328 *             to complete the task management request.
329 * @param[in]  remote_device The handle to the remote device object for which
330 *             to complete the task management request.
331 * @param[in]  task_request the handle to the task management request object
332 *             to complete.
333 *
334 * @return Indicate if the controller successfully completed the task
335 *         management request.
336 * @retval SCI_SUCCESS if the completion process was successful.
337 */
338SCI_STATUS scif_controller_complete_task(
339   SCI_CONTROLLER_HANDLE_T     controller,
340   SCI_REMOTE_DEVICE_HANDLE_T  remote_device,
341   SCI_TASK_REQUEST_HANDLE_T   task_request
342);
343
344/**
345 * @brief This method simply provides the user with a unique handle for a
346 *        given SAS/SATA domain index.
347 *
348 * @param[in]  controller This parameter represents the handle to the
349 *             controller object from which to retrieve a domain (SAS or
350 *             SATA) handle.
351 * @param[in]  port_index This parameter specifies the domain index in
352 *             the controller for which to retrieve the domain handle.
353 *             @note 0 <= port_index < maximum number of phys.
354 * @param[out] domain_handle This parameter specifies the retrieved domain
355 *             handle to be provided to the caller.
356 *
357 * @return Indicate if the retrieval of the domain handle was successful.
358 * @retval SCI_SUCCESS This value is returned if the retrieval was successful.
359 * @retval SCI_FAILURE_INVALID_PORT This value is returned if the supplied
360 *         port index is not invalid.
361 */
362SCI_STATUS scif_controller_get_domain_handle(
363   SCI_CONTROLLER_HANDLE_T   controller,
364   U8                        port_index,
365   SCI_DOMAIN_HANDLE_T     * domain_handle
366);
367
368/**
369 * @brief This method allows the user to configure the SCI Framework
370 *        into either a performance mode or a memory savings mode.
371 *
372 * @param[in]  controller This parameter represents the handle to the
373 *             controller object for which to update the operating
374 *             mode.
375 * @param[in]  mode This parameter specifies the new mode for the
376 *             controller.
377 *
378 * @return Indicate if the user successfully change the operating mode
379 *         of the controller.
380 * @retval SCI_SUCCESS The user successfully updated the mode.
381 */
382SCI_STATUS scif_controller_set_mode(
383   SCI_CONTROLLER_HANDLE_T   controller,
384   SCI_CONTROLLER_MODE       mode
385);
386
387/**
388 * @brief This method simply returns the T10 SCSI to ATA Translation (SAT)
389 *        specification version to which this translator is compliant for
390 *        supported commands.
391 *
392 * @return An integer value indicating the SAT version to which this
393 *         translator complies.
394 */
395U32 scif_controller_get_sat_compliance_version(
396   void
397);
398
399/**
400 * @brief This method simply returns the revision of the T10 SCSI to ATA
401 *        Translation (SAT) specification version to which this translator
402 *        is compliant for supported commands.
403 *
404 * @return An integer value indicating the revision of the SAT version
405 *         to which this translator complies.
406 */
407U32 scif_controller_get_sat_compliance_version_revision(
408   void
409);
410
411/**
412 * @brief This method is called by the SCI user to start internal io.
413 */
414typedef void (*SCI_START_INTERNAL_IO_ROUTINE)(
415   SCI_CONTROLLER_HANDLE_T controller
416);
417
418#if !defined(DISABLE_INTERRUPTS)
419/**
420 * @brief This method allows the user to configure the interrupt coalescence.
421 *           Please refer to the comment header for
422 *           scic_controller_set_interrupt_coalescence() to find details.
423 */
424SCI_STATUS scif_controller_set_interrupt_coalescence(
425   SCI_CONTROLLER_HANDLE_T controller,
426   U32                     coalesce_number,
427   U32                     coalesce_timeout
428);
429
430/**
431 * @brief This method retrieves the interrupt coalescence information.
432 *           Please refer to the comment header for
433 *           scic_controller_get_interrupt_coalescence() to find details.
434 */
435void scif_controller_get_interrupt_coalescence(
436   SCI_CONTROLLER_HANDLE_T controller,
437   U32                   * coalesce_number,
438   U32                   * coalesce_timeout
439);
440
441#else // !defined(DISABLE_INTERRUPTS)
442
443#define scif_controller_set_interrupt_coalescence(controller, num, timeout) \
444        SCI_FAILURE
445#define scif_controller_get_interrupt_coalescence(controller, num, timeout)
446
447#endif // !defined(DISABLE_INTERRUPTS)
448
449#ifdef __cplusplus
450}
451#endif // __cplusplus
452
453#endif // _SCIF_CONTROLLER_H_
454
455