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_SMP_REMOTE_DEVICE_H_
55#define _SCIF_SAS_SMP_REMOTE_DEVICE_H_
56
57#ifdef __cplusplus
58extern "C" {
59#endif // __cplusplus
60
61
62#include <dev/isci/scil/sci_fast_list.h>
63#include <dev/isci/scil/scif_sas_smp_phy.h>
64
65/**
66 * @file
67 *
68 * @brief This file contains the protected interface structures, constants,
69 *        and methods for the SCIF_SAS_SMP_REMOTE_DEVICE object.
70 */
71
72struct SCIF_SAS_CONTROLLER;
73struct SCIF_SAS_REMOTE_DEVICE;
74struct SCIF_SAS_INTERNAL_IO_REQUEST;
75struct SCIF_SAS_REQUEST;
76struct SCIF_SAS_SMP_PHY;
77
78#define SMP_REQUEST_RETRY_WAIT_DURATION   20
79#define SMP_SPINUP_HOLD_RELEASE_WAIT_DURATION 100
80
81/**
82 * @name SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CODES
83 *
84 * These constants depict the various SMP remote device activities.
85 */
86/*@{*/
87#define NOT_IN_SMP_ACTIVITY 0xff
88#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_NONE         0x0
89#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_DISCOVER     0x1
90#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET 0x2
91#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_SATA_SPINUP_HOLD_RELEASE 0x3
92#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CONFIG_ROUTE_TABLE 0x4
93#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAN_ROUTE_TABLE 0x5
94#define SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAR_AFFILIATION 0x6
95/*@}*/
96
97
98
99/**
100 * @name SCIF_SAS_CONFIG_ROUTE_TABLE_OPTION_CODES
101 *
102 * These constants depict the various configure route table options.
103 */
104/*@{*/
105#define SCIF_SAS_CONFIG_ROUTE_TABLE_LOWEST_PHY_ONLY   0
106#define SCIF_SAS_CONFIG_ROUTE_TABLE_MIDDLE_PHY_ONLY   1
107#define SCIF_SAS_CONFIG_ROUTE_TABLE_HIGHEST_PHY_ONLY  2
108#define SCIF_SAS_CONFIG_ROUTE_TABLE_ALL_PHYS          3
109/*@}*/
110
111/**
112 * @struct SCIF_SAS_SMP_REMOTE_DEVICE
113 *
114 * @brief The SCIF_SAS_SMP_REMOTE_DEVICE stores data for smp remote devices
115 *        (expanders) discovering attached targets.
116 *
117 */
118typedef struct SCIF_SAS_SMP_REMOTE_DEVICE
119{
120   /**
121    * This field stores the current SMP request function in the discovering
122    * sequence.
123    */
124   U32 current_smp_request;
125
126   /**
127    * This field indicates a smp device is either in the middle of normal discover
128    * process or in the middle of resetting a expander attahced remote device.
129    */
130   U8 current_activity;
131
132   /**
133    * This field stores the current expander phy index for sending out SMP
134    * DISCOVER request.
135    */
136   U8 current_activity_phy_index;
137
138   /**
139    * This field stores the current route index to config route table for
140    * a phy.
141    */
142   U16 curr_config_route_index;
143
144   /**
145    * This field indicates whether a route table of an expander has been cleaned
146    * since a DISCOVER process starts.
147    */
148   BOOL is_route_table_cleaned;
149
150   /**
151    * This field stores the smp phy whose route entries are edited by sending
152    * CONFIG ROUTE INFO commands.
153    */
154   struct SCIF_SAS_SMP_PHY * config_route_smp_phy_anchor;
155
156   /*
157    * This field stores the current smp phy on a destination device's smp phy list whose
158    * attached device's sas address is to be edited into this smp device's route table.
159    * When one config route info response is processed, we can find the next smp phy to edit
160    * using this field's value.
161    */
162   struct SCIF_SAS_SMP_PHY * curr_config_route_destination_smp_phy;
163
164   /*
165    * This field stores the current smp phy to which a PHY CONTROL (clear affiliation)
166    * command is sent out.
167    */
168   struct SCIF_SAS_SMP_PHY * curr_clear_affiliation_phy;
169
170   /**
171    * This field is to indicate a smp activity for this smp device is
172    * to be started (not yet). The scheduled activity could be Discover or Config
173    * Route Table.
174    */
175   U8 scheduled_activity;
176
177   /**
178    * This timer is used for waiting before retrying a smp request, or before
179    * sending Discover request after Phy Control during Target Reset.
180    */
181   void * smp_activity_timer;
182
183   /**
184    * This field save the retry count for internal smp request. Since when
185    * an internal smp request gets retried, it has been destructed already.
186    */
187   U8 io_retry_count;
188
189   /**
190    * This field stores the number of phys for expander device found by decoding
191    * the SMP REPORT GENERAL response.
192    */
193   U8  number_of_phys;
194
195   /**
196    * This field indicates the maximum number of expander route indexes per phy for
197    * this expander device.
198    */
199   U16 expander_route_indexes;
200
201   /**
202    * This field indicates whether an expander device supports table-to-table
203    * connection.
204    */
205   BOOL is_table_to_table_supported;
206
207   /**
208    * This field indicates whether an expander device is externally configurable.
209    * If it is, it is not self-configuring and is not able to config others.
210    */
211   BOOL is_externally_configurable;
212
213   /**
214    * This field indicates whether an expander device is able to config others.
215    */
216   BOOL is_able_to_config_others;
217
218   /**
219    * This field contains the list of all smp phys that connect to another smp phy.
220    */
221   SCI_FAST_LIST_T smp_phy_list;
222
223}SCIF_SAS_SMP_REMOTE_DEVICE_T;
224
225void scif_sas_smp_remote_device_clear(
226   struct SCIF_SAS_REMOTE_DEVICE * fw_device
227);
228
229void scif_sas_smp_remote_device_construct(
230   struct SCIF_SAS_REMOTE_DEVICE * fw_device
231);
232
233SCI_STATUS scif_sas_smp_remote_device_decode_smp_response(
234   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
235   struct SCIF_SAS_REQUEST       * fw_request,
236   void                          * response_data,
237   SCI_IO_STATUS                   completion_status
238);
239
240SCI_STATUS scif_sas_smp_remote_device_decode_report_general_response(
241   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
242   SMP_RESPONSE_T                * smp_response
243);
244
245SCI_STATUS scif_sas_smp_remote_device_decode_initial_discover_response(
246   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
247   SMP_RESPONSE_T                * smp_response
248);
249
250SCI_STATUS scif_sas_smp_remote_device_decode_report_phy_sata_response(
251   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
252   SMP_RESPONSE_T                * smp_response
253);
254
255SCI_STATUS scif_sas_smp_remote_device_decode_target_reset_phy_control_response(
256   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
257   SMP_RESPONSE_T           * smp_response
258);
259
260SCI_STATUS scif_sas_smp_remote_device_decode_discover_phy_control_response(
261   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
262   SMP_RESPONSE_T           * smp_response
263);
264
265SCI_STATUS scif_sas_smp_remote_device_decode_target_reset_discover_response(
266   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
267   SMP_RESPONSE_T           * smp_response
268);
269
270SCI_STATUS scif_sas_smp_remote_device_decode_spinup_hold_release_discover_response(
271   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
272   SMP_RESPONSE_T           * smp_response
273);
274
275SCI_STATUS scif_sas_smp_remote_device_decode_config_route_info_response(
276   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
277   SMP_RESPONSE_T           * smp_response
278);
279
280void scif_sas_smp_remote_device_start_discover(
281   struct SCIF_SAS_REMOTE_DEVICE * fw_device
282);
283
284void scif_sas_smp_remote_device_continue_discover(
285   struct SCIF_SAS_REMOTE_DEVICE * fw_device
286);
287
288void scif_sas_smp_remote_device_finish_initial_discover(
289   struct SCIF_SAS_REMOTE_DEVICE * fw_device
290);
291
292void scif_sas_smp_remote_device_finish_discover(
293   struct SCIF_SAS_REMOTE_DEVICE * fw_device
294);
295
296void scif_sas_smp_remote_device_continue_target_reset(
297   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
298   struct SCIF_SAS_REQUEST       * fw_request
299);
300
301void scif_sas_smp_remote_device_fail_discover(
302   struct SCIF_SAS_REMOTE_DEVICE * fw_device
303);
304
305void scif_sas_smp_remote_device_fail_target_reset(
306   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
307   struct SCIF_SAS_REQUEST       * fw_request
308);
309
310void scif_sas_smp_remote_device_continue_current_activity(
311   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
312   struct SCIF_SAS_REQUEST       * fw_request,
313   SCI_STATUS                      status
314);
315
316void scif_sas_smp_remote_device_target_reset_poll(
317   struct SCIF_SAS_REQUEST       * fw_request
318);
319
320void scif_sas_smp_remote_device_sata_spinup_hold_release(
321   struct SCIF_SAS_REMOTE_DEVICE * fw_device
322);
323
324void scif_sas_smp_remote_device_fail_target_spinup_hold_release(
325   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
326   struct SCIF_SAS_REMOTE_DEVICE * target_device
327);
328
329void scif_sas_smp_remote_device_retry_internal_io(
330   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
331   U8                         io_retry_count,
332   U32                        delay
333);
334
335BOOL scif_sas_smp_remote_device_is_in_activity(
336   struct SCIF_SAS_REMOTE_DEVICE * fw_device
337);
338
339SCIF_SAS_SMP_PHY_T * scif_sas_smp_remote_device_find_smp_phy_by_id(
340   U8                                  phy_identifier,
341   struct SCIF_SAS_SMP_REMOTE_DEVICE * smp_remote_device
342);
343
344void scif_sas_smp_remote_device_removed(
345   struct SCIF_SAS_REMOTE_DEVICE * this_device
346);
347
348void scif_sas_smp_remote_device_terminated_request_handler(
349   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
350   struct SCIF_SAS_REQUEST       * fw_request
351);
352
353void scif_sas_smp_remote_device_populate_smp_phy_list(
354   struct SCIF_SAS_REMOTE_DEVICE * fw_device
355);
356
357SCI_STATUS scif_sas_smp_remote_device_save_smp_phy_info(
358   struct SCIF_SAS_REMOTE_DEVICE * fw_device,
359   SMP_RESPONSE_DISCOVER_T       * discover_response
360);
361
362#ifdef SCI_SMP_PHY_LIST_DEBUG_PRINT
363void scif_sas_smp_remote_device_print_smp_phy_list(
364   struct SCIF_SAS_REMOTE_DEVICE * fw_device
365);
366#endif
367
368void scif_sas_smp_remote_device_configure_upstream_expander_route_info(
369   struct SCIF_SAS_REMOTE_DEVICE * this_device
370);
371
372struct SCIF_SAS_REMOTE_DEVICE * scif_sas_remote_device_find_upstream_expander(
373   struct SCIF_SAS_REMOTE_DEVICE * this_device
374);
375
376struct SCIF_SAS_REMOTE_DEVICE * scif_sas_remote_device_find_downstream_expander(
377   struct SCIF_SAS_REMOTE_DEVICE * this_device
378);
379
380BOOL scif_sas_smp_remote_device_do_config_route_info(
381   struct SCIF_SAS_REMOTE_DEVICE * device_being_config,
382   struct SCIF_SAS_SMP_PHY       * destination_smp_phy
383);
384
385void scif_sas_smp_remote_device_configure_route_table(
386   struct SCIF_SAS_REMOTE_DEVICE * device_being_config
387);
388
389void scif_sas_smp_remote_device_clean_route_table(
390   struct SCIF_SAS_REMOTE_DEVICE * fw_device
391);
392
393void scif_sas_smp_remote_device_clean_route_table_entry(
394   struct SCIF_SAS_REMOTE_DEVICE * fw_device
395);
396
397void scif_sas_smp_remote_device_cancel_config_route_table_activity(
398   struct SCIF_SAS_REMOTE_DEVICE * fw_device
399);
400
401void scif_sas_smp_remote_device_cancel_smp_activity(
402   struct SCIF_SAS_REMOTE_DEVICE * fw_device
403);
404
405U8 scif_sas_smp_remote_device_get_config_route_table_method(
406   struct SCIF_SAS_REMOTE_DEVICE * fw_device
407);
408
409void scif_sas_smp_remote_device_start_clear_affiliation(
410   struct SCIF_SAS_REMOTE_DEVICE * fw_device
411);
412
413void scif_sas_smp_remote_device_continue_clear_affiliation(
414   struct SCIF_SAS_REMOTE_DEVICE * fw_device
415);
416
417void scif_sas_smp_remote_device_finish_clear_affiliation(
418   struct SCIF_SAS_REMOTE_DEVICE * fw_device
419);
420
421void scif_sas_smp_remote_device_start_target_reset(
422   struct SCIF_SAS_REMOTE_DEVICE * expander_device,
423   struct SCIF_SAS_REMOTE_DEVICE * target_device,
424   struct SCIF_SAS_REQUEST       * fw_request
425);
426
427#ifdef __cplusplus
428}
429#endif // __cplusplus
430
431#endif // _SCIF_SAS_SMP_REMOTE_DEVICE_H_
432