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