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
65extern "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
77struct SCIF_SAS_DOMAIN;
78struct SCIF_SAS_REMOTE_DEVICE;
79struct 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 */
93typedef 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 */
117typedef 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
147struct SCIF_SAS_REMOTE_DEVICE;
148typedef void (*SCIF_SAS_REMOTE_DEVICE_COMPLETION_HANDLER_T)(
149   struct SCIF_SAS_REMOTE_DEVICE *,
150   SCI_STATUS
151);
152
153typedef void (*SCIF_SAS_REMOTE_DEVICE_HANDLER_T)(
154   struct SCIF_SAS_REMOTE_DEVICE *
155);
156
157typedef 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 */
168typedef 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 */
187typedef 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
325extern SCI_BASE_STATE_T scif_sas_remote_device_state_table[];
326extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
327   scif_sas_remote_device_state_handler_table[];
328
329extern SCI_BASE_STATE_T scif_sas_remote_device_starting_substate_table[];
330extern SCIF_SAS_REMOTE_DEVICE_STATE_HANDLER_T
331   scif_sas_remote_device_starting_substate_handler_table[];
332
333extern SCI_BASE_STATE_T scif_sas_remote_device_ready_substate_table[];
334extern 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 */
343enum 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//******************************************************************************
354void scif_sas_remote_device_save_report_phy_sata_information(
355   SMP_RESPONSE_REPORT_PHY_SATA_T * report_phy_sata_response
356);
357
358void scif_sas_remote_device_target_reset(
359   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
360   struct SCIF_SAS_REQUEST  * fw_request
361);
362
363void 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
370void scif_sas_remote_device_initialize_state_logging(
371   SCIF_SAS_REMOTE_DEVICE_T * remote_device
372);
373
374void 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
386SCI_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
391SCI_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
396SCI_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
405SCI_STATUS scif_sas_remote_device_default_start_handler(
406   SCI_BASE_REMOTE_DEVICE_T * remote_device
407);
408
409SCI_STATUS scif_sas_remote_device_default_stop_handler(
410   SCI_BASE_REMOTE_DEVICE_T * remote_device
411);
412
413SCI_STATUS scif_sas_remote_device_default_reset_handler(
414   SCI_BASE_REMOTE_DEVICE_T * remote_device
415);
416
417SCI_STATUS scif_sas_remote_device_default_reset_complete_handler(
418   SCI_BASE_REMOTE_DEVICE_T * remote_device
419);
420
421SCI_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
426void scif_sas_remote_device_default_start_complete_handler(
427   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
428   SCI_STATUS                 completion_status
429);
430
431void scif_sas_remote_device_default_stop_complete_handler(
432   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
433   SCI_STATUS                 completion_status
434);
435
436SCI_STATUS scif_sas_remote_device_default_destruct_handler(
437   SCI_BASE_REMOTE_DEVICE_T * remote_device
438);
439
440SCI_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
445SCI_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
452SCI_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
457SCI_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
462SCI_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
467void scif_sas_remote_device_default_ready_handler(
468   SCIF_SAS_REMOTE_DEVICE_T * fw_device
469);
470
471void scif_sas_remote_device_default_not_ready_handler(
472   SCIF_SAS_REMOTE_DEVICE_T * fw_device,
473   U32                        reason_code
474);
475
476SCI_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
481SCI_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)
489SCI_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