xref: /freebsd/sys/dev/isci/scil/scif_sas_smp_remote_device.h (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
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 #ifndef _SCIF_SAS_SMP_REMOTE_DEVICE_H_
55 #define _SCIF_SAS_SMP_REMOTE_DEVICE_H_
56 
57 #ifdef __cplusplus
58 extern "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 
72 struct SCIF_SAS_CONTROLLER;
73 struct SCIF_SAS_REMOTE_DEVICE;
74 struct SCIF_SAS_INTERNAL_IO_REQUEST;
75 struct SCIF_SAS_REQUEST;
76 struct 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  */
118 typedef 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 
225 void scif_sas_smp_remote_device_clear(
226    struct SCIF_SAS_REMOTE_DEVICE * fw_device
227 );
228 
229 void scif_sas_smp_remote_device_construct(
230    struct SCIF_SAS_REMOTE_DEVICE * fw_device
231 );
232 
233 SCI_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 
240 SCI_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 
245 SCI_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 
250 SCI_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 
255 SCI_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 
260 SCI_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 
265 SCI_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 
270 SCI_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 
275 SCI_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 
280 void scif_sas_smp_remote_device_start_discover(
281    struct SCIF_SAS_REMOTE_DEVICE * fw_device
282 );
283 
284 void scif_sas_smp_remote_device_continue_discover(
285    struct SCIF_SAS_REMOTE_DEVICE * fw_device
286 );
287 
288 void scif_sas_smp_remote_device_finish_initial_discover(
289    struct SCIF_SAS_REMOTE_DEVICE * fw_device
290 );
291 
292 void scif_sas_smp_remote_device_finish_discover(
293    struct SCIF_SAS_REMOTE_DEVICE * fw_device
294 );
295 
296 void 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 
301 void scif_sas_smp_remote_device_fail_discover(
302    struct SCIF_SAS_REMOTE_DEVICE * fw_device
303 );
304 
305 void 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 
310 void 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 
316 void scif_sas_smp_remote_device_target_reset_poll(
317    struct SCIF_SAS_REQUEST       * fw_request
318 );
319 
320 void scif_sas_smp_remote_device_sata_spinup_hold_release(
321    struct SCIF_SAS_REMOTE_DEVICE * fw_device
322 );
323 
324 void 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 
329 void 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 
335 BOOL scif_sas_smp_remote_device_is_in_activity(
336    struct SCIF_SAS_REMOTE_DEVICE * fw_device
337 );
338 
339 SCIF_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 
344 void scif_sas_smp_remote_device_removed(
345    struct SCIF_SAS_REMOTE_DEVICE * this_device
346 );
347 
348 void 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 
353 void scif_sas_smp_remote_device_populate_smp_phy_list(
354    struct SCIF_SAS_REMOTE_DEVICE * fw_device
355 );
356 
357 SCI_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
363 void scif_sas_smp_remote_device_print_smp_phy_list(
364    struct SCIF_SAS_REMOTE_DEVICE * fw_device
365 );
366 #endif
367 
368 void scif_sas_smp_remote_device_configure_upstream_expander_route_info(
369    struct SCIF_SAS_REMOTE_DEVICE * this_device
370 );
371 
372 struct SCIF_SAS_REMOTE_DEVICE * scif_sas_remote_device_find_upstream_expander(
373    struct SCIF_SAS_REMOTE_DEVICE * this_device
374 );
375 
376 struct SCIF_SAS_REMOTE_DEVICE * scif_sas_remote_device_find_downstream_expander(
377    struct SCIF_SAS_REMOTE_DEVICE * this_device
378 );
379 
380 BOOL 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 
385 void scif_sas_smp_remote_device_configure_route_table(
386    struct SCIF_SAS_REMOTE_DEVICE * device_being_config
387 );
388 
389 void scif_sas_smp_remote_device_clean_route_table(
390    struct SCIF_SAS_REMOTE_DEVICE * fw_device
391 );
392 
393 void scif_sas_smp_remote_device_clean_route_table_entry(
394    struct SCIF_SAS_REMOTE_DEVICE * fw_device
395 );
396 
397 void scif_sas_smp_remote_device_cancel_config_route_table_activity(
398    struct SCIF_SAS_REMOTE_DEVICE * fw_device
399 );
400 
401 void scif_sas_smp_remote_device_cancel_smp_activity(
402    struct SCIF_SAS_REMOTE_DEVICE * fw_device
403 );
404 
405 U8 scif_sas_smp_remote_device_get_config_route_table_method(
406    struct SCIF_SAS_REMOTE_DEVICE * fw_device
407 );
408 
409 void scif_sas_smp_remote_device_start_clear_affiliation(
410    struct SCIF_SAS_REMOTE_DEVICE * fw_device
411 );
412 
413 void scif_sas_smp_remote_device_continue_clear_affiliation(
414    struct SCIF_SAS_REMOTE_DEVICE * fw_device
415 );
416 
417 void scif_sas_smp_remote_device_finish_clear_affiliation(
418    struct SCIF_SAS_REMOTE_DEVICE * fw_device
419 );
420 
421 void 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