xref: /freebsd/sys/dev/isci/scil/scif_sas_remote_device.h (revision 0b3105a37d7adcadcb720112fed4dc4e8040be99)
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_SAS_REMOTE_DEVICE_H_
55 #define _SCIF_SAS_REMOTE_DEVICE_H_
56 
57 /**
58  * @file
59  *
60  * @brief This file contains the protected interface structures, constants,
61  *        and methods for the SCIF_SAS_REMOTE_DEVICE object.
62  */
63 
64 #ifdef __cplusplus
65 extern "C" {
66 #endif // __cplusplus
67 
68 #include <dev/isci/scil/scif_remote_device.h>
69 
70 #include <dev/isci/scil/sci_base_remote_device.h>
71 #include <dev/isci/scil/sci_base_request.h>
72 #include <dev/isci/scil/sci_base_state_machine_logger.h>
73 #include <dev/isci/scil/scif_sas_stp_remote_device.h>
74 #include <dev/isci/scil/scif_sas_smp_remote_device.h>
75 
76 
77 struct SCIF_SAS_DOMAIN;
78 struct SCIF_SAS_REMOTE_DEVICE;
79 struct SCIF_SAS_REQUEST;
80 
81 /**
82  * This constant indicates the number of milliseconds to wait for the core
83  * to start/stop it's remote device object.
84  */
85 #define SCIF_SAS_REMOTE_DEVICE_CORE_OP_TIMEOUT 1000
86 
87 /**
88  * @enum _SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES
89  *
90  * @brief This enumeration depicts all the substates for the remote device's
91  *        starting substate machine.
92  */
93 typedef enum _SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES
94 {
95    /**
96     * This state indicates that the framework is waiting for the core to
97     * issue a scic_cb_remote_device_start_complete() notification.
98     */
99    SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_COMPLETE,
100 
101    /**
102     * This state indicates that the core has received the core's
103     * scic_cb_remote_device_start_complete() notification.
104     */
105    SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_AWAIT_READY,
106 
107    SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATE_MAX_STATES
108 
109 } SCIF_SAS_REMOTE_DEVICE_STARTING_SUBSTATES;
110 
111 /**
112  * @enum _SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES
113  *
114  * @brief This enumeration depicts all of the substates for the remote
115  *        device READY substate machine.
116  */
117 typedef enum _SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES
118 {
119    /**
120     * The Operational sub-state indicates that the remote device object
121     * is capable of receiving and handling all request types.
122     */
123    SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_OPERATIONAL,
124 
125    /**
126     * This substate indicates that core remote device is not ready.
127     * As a result, no new IO or Task Management requests are allowed.
128     */
129    SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_SUSPENDED,
130 
131    /**
132     * This substate indicates that task management to this device is
133     * ongoing and new IO requests are not allowed.
134     */
135    SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_TASK_MGMT,
136 
137    /**
138    * This substate indicates that core remote device is not ready due
139    *  to an NCQ error.  As a result, no new IO requests are allowed.
140    */
141    SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_NCQ_ERROR,
142 
143    SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATE_MAX_STATES
144 
145 } SCIF_SAS_REMOTE_DEVICE_READY_SUBSTATES;
146 
147 struct SCIF_SAS_REMOTE_DEVICE;
148 typedef void (*SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T)(
149    struct SCIF_SAS_REMOTE_DEVICE *,
150    SCI_STATUS
151 );
152 
153 typedef void (*SCIF_SAS_REMOTE_DEVICE_HANDLER_T)(
154    struct SCIF_SAS_REMOTE_DEVICE *
155 );
156 
157 typedef void (*SCIF_SAS_REMOTE_DEVICE_NOT_READY_HANDLER_T)(
158    struct SCIF_SAS_REMOTE_DEVICE *,
159    U32
160 );
161 
162 /**
163  * @struct SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER
164  *
165  * @brief This structure defines the state handler methods for states and
166  *        substates applicable for the framework remote device object.
167  */
168 typedef struct SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER
169 {
170    SCI_BASE_REMOTE_DEVICE_STATE_HANDLER_T      parent;
171    SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T start_complete_handler;
172    SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T stop_complete_handler;
173    SCIF_SAS_REMOTE_DEVICE_HANDLER_T            ready_handler;
174    SCIF_SAS_REMOTE_DEVICE_NOT_READY_HANDLER_T  not_ready_handler;
175    SCI_BASE_REMOTE_DEVICE_REQUEST_HANDLER_T    start_high_priority_io_handler;
176    SCI_BASE_REMOTE_DEVICE_HIGH_PRIORITY_REQUEST_COMPLETE_HANDLER_T    complete_high_priority_io_handler;
177 } SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T;
178 
179 /**
180  * @struct SCIF_SAS_REMOTE_DEVICE
181  *
182  * @brief The SCI SAS Framework remote device object abstracts the SAS remote
183  *        device level behavior for the framework component.  Additionally,
184  *        it provides a higher level of abstraction for the core remote
185  *        device object.
186  */
187 typedef struct SCIF_SAS_REMOTE_DEVICE
188 {
189    /**
190     * The SCI_BASE_REMOTE_DEVICE is the parent object for the
191     * SCIF_SAS_REMOTE_DEVICE object.
192     */
193    SCI_BASE_REMOTE_DEVICE_T  parent;
194 
195    /**
196     * This field contains the handle for the SCI Core remote device object
197     * that is managed by this framework controller.
198     */
199    SCI_REMOTE_DEVICE_HANDLE_T  core_object;
200 
201    /**
202     * This field references the list of state specific handler methods to
203     * be utilized for this remote device instance.
204     */
205    SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T * state_handlers;
206 
207    /**
208     * This field specifies the state machine utilized to manage the
209     * starting remote device substate machine.
210     */
211    SCI_BASE_STATE_MACHINE_T starting_substate_machine;
212 
213    /**
214     * This field specifies the state machine utilized to manage the
215     * starting remote device substate machine.
216     */
217    SCI_BASE_STATE_MACHINE_T ready_substate_machine;
218 
219    union
220    {
221       /**
222        * This field specifies the information specific to SATA/STP device
223        * instances.  This field is not utilized for SSP/SMP.
224        */
225       SCIF_SAS_STP_REMOTE_DEVICE_T  stp_device;
226 
227       /**
228        * This field specifies the information specific to SMP device instances.
229        * This field is not utilized for SSP/SATA/STP.
230        */
231       SCIF_SAS_SMP_REMOTE_DEVICE_T  smp_device;
232 
233    }protocol_device;
234 
235    /**
236     * This field indicates the domain object containing this remote device.
237     */
238    struct SCIF_SAS_DOMAIN * domain;
239 
240    /**
241     * This field counts the number of requests (IO and task management)
242     * that are currently outstanding for this device.
243     */
244    U32 request_count;
245 
246    /**
247     * This field counts the number of only task management request that are
248     * currently outstanding for this device.
249     */
250    U32 task_request_count;
251 
252    /**
253     * This field is utilize to store the status value of various operations
254     * the can be executed on this remote device instance.
255     */
256    SCI_STATUS operation_status;
257 
258    /**
259     * This field is utilize to indicate that the remote device should be
260     * destructed when it finally reaches the stopped state.  This will
261     * include destructing the core remote device as well.
262     */
263    BOOL  destruct_when_stopped;
264 
265    /**
266     * This field marks a device state of being discovered or not, majorly used
267     * during re-discover procedure.
268     */
269    BOOL is_currently_discovered;
270 
271    /**
272     * This filed stores the expander device this device connected to, only if this
273     * device is behind expander. So this field also served as a flag to tell if a
274     * device is a EA one.
275     */
276    struct SCIF_SAS_REMOTE_DEVICE * containing_device;
277 
278    /**
279     * This field stores the expander phy identifier for an expander attached
280     * device. This field is only used by expander attached device.
281     */
282    U8 expander_phy_identifier;
283 
284    /**
285     * This field stores the port width for a device. Most devices are narrow port
286     * device, their port width is 1. If a device is a wide port device, their
287     * port width is larger than 1.
288     */
289    U8 device_port_width;
290 
291    /**
292     * This field stores the destination state for a remote device in UPDATING
293     * PORT WIDTH state. The possible destination states for a remote device in
294     * UPDATING_PORT_WIDTH state are READY or STOPPING.
295     */
296    U16 destination_state;
297 
298    /**
299     * This field stores the scheduled/delayed EA target reset request.
300     */
301    struct SCIF_SAS_REQUEST * ea_target_reset_request_scheduled;
302 
303    #ifdef SCI_LOGGING
304    /**
305     * This field is the observer of the base state machine for this device
306     * object.
307     */
308    SCI_BASE_OBSERVER_T base_state_machine_observer;
309 
310    /**
311     * This field is the state machine logger of the startig substate machine for
312     * this device object.
313     */
314    SCI_BASE_STATE_MACHINE_LOGGER_T starting_substate_machine_logger;
315 
316    /**
317     * This field is the state machine logger of the ready substate machine for
318     * this device object.
319     */
320    SCI_BASE_STATE_MACHINE_LOGGER_T ready_substate_machine_logger;
321    #endif // SCI_LOGGING
322 
323 } SCIF_SAS_REMOTE_DEVICE_T;
324 
325 extern SCI_BASE_STATE_T scif_sas_remote_device_state_table[];
326 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
327    scif_sas_remote_device_state_handler_table[];
328 
329 extern SCI_BASE_STATE_T scif_sas_remote_device_starting_substate_table[];
330 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
331    scif_sas_remote_device_starting_substate_handler_table[];
332 
333 extern SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table[];
334 extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
335    scif_sas_remote_device_ready_substate_handler_table[];
336 
337 /**
338  * @enum
339  *
340  * This enumeration is used to define the end destination state for the
341  * framework remote device.
342  */
343 enum SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE
344 {
345    SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UNSPECIFIED,
346    SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_READY,
347    SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_STOPPING,
348    SCIF_SAS_REMOTE_DEVICE_DESTINATION_STATE_UPDATING_PORT_WIDTH
349 };
350 
351 //******************************************************************************
352 //* P R O T E C T E D   M E T H O D S
353 //******************************************************************************
354 void scif_sas_remote_device_save_report_phy_sata_information(
355    SMP_RESPONSE_REPORT_PHY_SATA_T * report_phy_sata_response
356 );
357 
358 void scif_sas_remote_device_target_reset(
359    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
360    struct SCIF_SAS_REQUEST  * fw_request
361 );
362 
363 void scif_sas_remote_device_target_reset_complete(
364    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
365    struct SCIF_SAS_REQUEST  * fw_request,
366    SCI_STATUS                 completion_status
367 );
368 
369 #ifdef SCI_LOGGING
370 void scif_sas_remote_device_initialize_state_logging(
371    SCIF_SAS_REMOTE_DEVICE_T * remote_device
372 );
373 
374 void scif_sas_remote_device_deinitialize_state_logging(
375    SCIF_SAS_REMOTE_DEVICE_T * remote_device
376 );
377 #else // SCI_LOGGING
378 #define scif_sas_remote_device_initialize_state_logging(x)
379 #define scif_sas_remote_device_deinitialize_state_logging(x)
380 #endif // SCI_LOGGING
381 
382 //******************************************************************************
383 //* R E A D Y   O P E R A T I O N A L   S T A T E   H A N D L E R S
384 //******************************************************************************
385 
386 SCI_STATUS scif_sas_remote_device_ready_operational_complete_io_handler(
387    SCI_BASE_REMOTE_DEVICE_T * remote_device,
388    SCI_BASE_REQUEST_T       * io_request
389 );
390 
391 SCI_STATUS scif_sas_remote_device_ready_operational_complete_task_handler(
392    SCI_BASE_REMOTE_DEVICE_T * remote_device,
393    SCI_BASE_REQUEST_T       * task_request
394 );
395 
396 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_task_handler(
397    SCI_BASE_REMOTE_DEVICE_T * remote_device,
398    SCI_BASE_REQUEST_T       * task_request
399 );
400 
401 //******************************************************************************
402 //* D E F A U L T   S T A T E   H A N D L E R S
403 //******************************************************************************
404 
405 SCI_STATUS scif_sas_remote_device_default_start_handler(
406    SCI_BASE_REMOTE_DEVICE_T * remote_device
407 );
408 
409 SCI_STATUS scif_sas_remote_device_default_stop_handler(
410    SCI_BASE_REMOTE_DEVICE_T * remote_device
411 );
412 
413 SCI_STATUS scif_sas_remote_device_default_reset_handler(
414    SCI_BASE_REMOTE_DEVICE_T * remote_device
415 );
416 
417 SCI_STATUS scif_sas_remote_device_default_reset_complete_handler(
418    SCI_BASE_REMOTE_DEVICE_T * remote_device
419 );
420 
421 SCI_STATUS scif_sas_remote_device_default_start_io_handler(
422    SCI_BASE_REMOTE_DEVICE_T * remote_device,
423    SCI_BASE_REQUEST_T       * io_request
424 );
425 
426 void scif_sas_remote_device_default_start_complete_handler(
427    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
428    SCI_STATUS                 completion_status
429 );
430 
431 void scif_sas_remote_device_default_stop_complete_handler(
432    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
433    SCI_STATUS                 completion_status
434 );
435 
436 SCI_STATUS scif_sas_remote_device_default_destruct_handler(
437    SCI_BASE_REMOTE_DEVICE_T * remote_device
438 );
439 
440 SCI_STATUS scif_sas_remote_device_default_complete_io_handler(
441    SCI_BASE_REMOTE_DEVICE_T * remote_device,
442    SCI_BASE_REQUEST_T       * io_request
443 );
444 
445 SCI_STATUS scif_sas_remote_device_default_complete_high_priority_io_handler(
446    SCI_BASE_REMOTE_DEVICE_T * remote_device,
447    SCI_BASE_REQUEST_T       * io_request,
448    void                     * response_data,
449    SCI_IO_STATUS              completion_status
450 );
451 
452 SCI_STATUS scif_sas_remote_device_default_continue_io_handler(
453    SCI_BASE_REMOTE_DEVICE_T * remote_device,
454    SCI_BASE_REQUEST_T       * io_request
455 );
456 
457 SCI_STATUS scif_sas_remote_device_default_start_task_handler(
458    SCI_BASE_REMOTE_DEVICE_T * remote_device,
459    SCI_BASE_REQUEST_T       * task_request
460 );
461 
462 SCI_STATUS scif_sas_remote_device_default_complete_task_handler(
463    SCI_BASE_REMOTE_DEVICE_T * remote_device,
464    SCI_BASE_REQUEST_T       * task_request
465 );
466 
467 void scif_sas_remote_device_default_ready_handler(
468    SCIF_SAS_REMOTE_DEVICE_T * fw_device
469 );
470 
471 void scif_sas_remote_device_default_not_ready_handler(
472    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
473    U32                        reason_code
474 );
475 
476 SCI_STATUS scif_sas_remote_device_ready_task_management_start_high_priority_io_handler(
477    SCI_BASE_REMOTE_DEVICE_T * remote_device,
478    SCI_BASE_REQUEST_T       * io_request
479 );
480 
481 SCI_STATUS scif_sas_remote_device_ready_task_management_complete_high_priority_io_handler(
482    SCI_BASE_REMOTE_DEVICE_T * remote_device,
483    SCI_BASE_REQUEST_T       * io_request,
484    void                     * response_data,
485    SCI_IO_STATUS              completion_status
486 );
487 
488 #if !defined(DISABLE_WIDE_PORTED_TARGETS)
489 SCI_STATUS scif_sas_remote_device_update_port_width(
490    SCIF_SAS_REMOTE_DEVICE_T * fw_device,
491    U8                         new_port_width
492 );
493 #else // !defined(DISABLE_WIDE_PORTED_TARGETS)
494 #define scif_sas_remote_device_update_port_width(device) SCI_FAILURE
495 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
496 
497 #ifdef __cplusplus
498 }
499 #endif // __cplusplus
500 
501 #endif // _SCIF_SAS_REMOTE_DEVICE_H_
502 
503