xref: /freebsd/sys/dev/ocs_fc/ocs_mgmt.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
1ef270ab1SKenneth D. Merry /*-
2ef270ab1SKenneth D. Merry  * Copyright (c) 2017 Broadcom. All rights reserved.
3ef270ab1SKenneth D. Merry  * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries.
4ef270ab1SKenneth D. Merry  *
5ef270ab1SKenneth D. Merry  * Redistribution and use in source and binary forms, with or without
6ef270ab1SKenneth D. Merry  * modification, are permitted provided that the following conditions are met:
7ef270ab1SKenneth D. Merry  *
8ef270ab1SKenneth D. Merry  * 1. Redistributions of source code must retain the above copyright notice,
9ef270ab1SKenneth D. Merry  *    this list of conditions and the following disclaimer.
10ef270ab1SKenneth D. Merry  *
11ef270ab1SKenneth D. Merry  * 2. Redistributions in binary form must reproduce the above copyright notice,
12ef270ab1SKenneth D. Merry  *    this list of conditions and the following disclaimer in the documentation
13ef270ab1SKenneth D. Merry  *    and/or other materials provided with the distribution.
14ef270ab1SKenneth D. Merry  *
15ef270ab1SKenneth D. Merry  * 3. Neither the name of the copyright holder nor the names of its contributors
16ef270ab1SKenneth D. Merry  *    may be used to endorse or promote products derived from this software
17ef270ab1SKenneth D. Merry  *    without specific prior written permission.
18ef270ab1SKenneth D. Merry  *
19ef270ab1SKenneth D. Merry  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20ef270ab1SKenneth D. Merry  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ef270ab1SKenneth D. Merry  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ef270ab1SKenneth D. Merry  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23ef270ab1SKenneth D. Merry  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24ef270ab1SKenneth D. Merry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25ef270ab1SKenneth D. Merry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26ef270ab1SKenneth D. Merry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27ef270ab1SKenneth D. Merry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28ef270ab1SKenneth D. Merry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29ef270ab1SKenneth D. Merry  * POSSIBILITY OF SUCH DAMAGE.
30ef270ab1SKenneth D. Merry  */
31ef270ab1SKenneth D. Merry 
32ef270ab1SKenneth D. Merry /**
33ef270ab1SKenneth D. Merry  * @file
34ef270ab1SKenneth D. Merry  * The ocs_mgmt top level functions for Fibre Channel.
35ef270ab1SKenneth D. Merry  */
36ef270ab1SKenneth D. Merry 
37ef270ab1SKenneth D. Merry /**
38ef270ab1SKenneth D. Merry  * @defgroup mgmt Management Functions
39ef270ab1SKenneth D. Merry  */
40ef270ab1SKenneth D. Merry 
41ef270ab1SKenneth D. Merry #include "ocs.h"
42ef270ab1SKenneth D. Merry #include "ocs_mgmt.h"
4329e2dbd4SRam Kishore Vegesna #include "ocs_gendump.h"
44ef270ab1SKenneth D. Merry #include "ocs_vpd.h"
45ef270ab1SKenneth D. Merry 
46ef270ab1SKenneth D. Merry #define SFP_PAGE_SIZE 128
47ef270ab1SKenneth D. Merry 
48ef270ab1SKenneth D. Merry /* Executables*/
49ef270ab1SKenneth D. Merry 
50ef270ab1SKenneth D. Merry static int ocs_mgmt_firmware_write(ocs_t *ocs, char *, void *buf, uint32_t buf_len, void*, uint32_t);
51ef270ab1SKenneth D. Merry static int ocs_mgmt_firmware_reset(ocs_t *ocs, char *, void *buf, uint32_t buf_len, void*, uint32_t);
52ef270ab1SKenneth D. Merry static int ocs_mgmt_function_reset(ocs_t *ocs, char *, void *buf, uint32_t buf_len, void*, uint32_t);
53ef270ab1SKenneth D. Merry 
54ef270ab1SKenneth D. Merry static void ocs_mgmt_fw_write_cb(int32_t status, uint32_t actual_write_length, uint32_t change_status, void *arg);
55ef270ab1SKenneth D. Merry static int ocs_mgmt_force_assert(ocs_t *ocs, char *, void *buf, uint32_t buf_len, void*, uint32_t);
56ef270ab1SKenneth D. Merry 
57ef270ab1SKenneth D. Merry /* Getters */
58ef270ab1SKenneth D. Merry 
59ef270ab1SKenneth D. Merry static void get_nodes_count(ocs_t *, char *, ocs_textbuf_t*);
60ef270ab1SKenneth D. Merry static void get_desc(ocs_t *, char *, ocs_textbuf_t*);
61ef270ab1SKenneth D. Merry static void get_fw_rev(ocs_t *, char *, ocs_textbuf_t*);
62ef270ab1SKenneth D. Merry static void get_fw_rev2(ocs_t *, char *, ocs_textbuf_t*);
63ef270ab1SKenneth D. Merry static void get_ipl(ocs_t *, char *, ocs_textbuf_t*);
64ef270ab1SKenneth D. Merry static void get_wwnn(ocs_t *, char *, ocs_textbuf_t*);
65ef270ab1SKenneth D. Merry static void get_wwpn(ocs_t *, char *, ocs_textbuf_t*);
66ef270ab1SKenneth D. Merry static void get_fcid(ocs_t *, char *, ocs_textbuf_t *);
67ef270ab1SKenneth D. Merry static void get_sn(ocs_t *, char *, ocs_textbuf_t*);
68ef270ab1SKenneth D. Merry static void get_pn(ocs_t *, char *, ocs_textbuf_t*);
69ef270ab1SKenneth D. Merry static void get_sli4_intf_reg(ocs_t *, char *, ocs_textbuf_t*);
70ef270ab1SKenneth D. Merry static void get_phy_port_num(ocs_t *, char *, ocs_textbuf_t*);
71ef270ab1SKenneth D. Merry static void get_asic_id(ocs_t *, char *, ocs_textbuf_t*);
72ef270ab1SKenneth D. Merry static void get_pci_vendor(ocs_t *, char *, ocs_textbuf_t*);
73ef270ab1SKenneth D. Merry static void get_pci_device(ocs_t *, char *, ocs_textbuf_t*);
74ef270ab1SKenneth D. Merry static void get_pci_subsystem_vendor(ocs_t *, char *, ocs_textbuf_t*);
75ef270ab1SKenneth D. Merry static void get_pci_subsystem_device(ocs_t *, char *, ocs_textbuf_t*);
76ef270ab1SKenneth D. Merry static void get_businfo(ocs_t *, char *, ocs_textbuf_t*);
77ef270ab1SKenneth D. Merry static void get_sfp_a0(ocs_t *, char *, ocs_textbuf_t*);
78ef270ab1SKenneth D. Merry static void get_sfp_a2(ocs_t *, char *, ocs_textbuf_t*);
79ef270ab1SKenneth D. Merry static void get_hw_rev1(ocs_t *, char *, ocs_textbuf_t*);
80ef270ab1SKenneth D. Merry static void get_hw_rev2(ocs_t *, char *, ocs_textbuf_t*);
81ef270ab1SKenneth D. Merry static void get_hw_rev3(ocs_t *, char *, ocs_textbuf_t*);
82ef270ab1SKenneth D. Merry static void get_debug_mq_dump(ocs_t*, char*, ocs_textbuf_t*);
83ef270ab1SKenneth D. Merry static void get_debug_cq_dump(ocs_t*, char*, ocs_textbuf_t*);
84ef270ab1SKenneth D. Merry static void get_debug_wq_dump(ocs_t*, char*, ocs_textbuf_t*);
85ef270ab1SKenneth D. Merry static void get_debug_eq_dump(ocs_t*, char*, ocs_textbuf_t*);
86ef270ab1SKenneth D. Merry static void get_logmask(ocs_t*, char*, ocs_textbuf_t*);
87ef270ab1SKenneth D. Merry static void get_current_speed(ocs_t*, char*, ocs_textbuf_t*);
88ef270ab1SKenneth D. Merry static void get_current_topology(ocs_t*, char*, ocs_textbuf_t*);
89ef270ab1SKenneth D. Merry static void get_current_link_state(ocs_t*, char*, ocs_textbuf_t*);
90ef270ab1SKenneth D. Merry static void get_configured_speed(ocs_t*, char*, ocs_textbuf_t*);
91ef270ab1SKenneth D. Merry static void get_configured_topology(ocs_t*, char*, ocs_textbuf_t*);
92ef270ab1SKenneth D. Merry static void get_configured_link_state(ocs_t*, char*, ocs_textbuf_t*);
93ef270ab1SKenneth D. Merry static void get_linkcfg(ocs_t*, char*, ocs_textbuf_t*);
94ef270ab1SKenneth D. Merry static void get_req_wwnn(ocs_t*, char*, ocs_textbuf_t*);
95ef270ab1SKenneth D. Merry static void get_req_wwpn(ocs_t*, char*, ocs_textbuf_t*);
96ef270ab1SKenneth D. Merry static void get_nodedb_mask(ocs_t*, char*, ocs_textbuf_t*);
97ef270ab1SKenneth D. Merry static void get_profile_list(ocs_t*, char*, ocs_textbuf_t*);
98ef270ab1SKenneth D. Merry static void get_active_profile(ocs_t*, char*, ocs_textbuf_t*);
99ef270ab1SKenneth D. Merry static void get_port_protocol(ocs_t*, char*, ocs_textbuf_t*);
100ef270ab1SKenneth D. Merry static void get_driver_version(ocs_t*, char*, ocs_textbuf_t*);
101ef270ab1SKenneth D. Merry static void get_chip_type(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
102ef270ab1SKenneth D. Merry static void get_tgt_rscn_delay(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
103ef270ab1SKenneth D. Merry static void get_tgt_rscn_period(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
104ef270ab1SKenneth D. Merry static void get_inject_drop_cmd(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
105ef270ab1SKenneth D. Merry static void get_inject_free_drop_cmd(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
106ef270ab1SKenneth D. Merry static void get_inject_drop_data(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
107ef270ab1SKenneth D. Merry static void get_inject_drop_resp(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
108ef270ab1SKenneth D. Merry static void get_cmd_err_inject(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
109ef270ab1SKenneth D. Merry static void get_cmd_delay_value(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
110ef270ab1SKenneth D. Merry static void get_nv_wwpn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
111ef270ab1SKenneth D. Merry static void get_nv_wwnn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
112ef270ab1SKenneth D. Merry static void get_loglevel(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
113ef270ab1SKenneth D. Merry static void get_node_abort_cnt(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf);
114ef270ab1SKenneth D. Merry 
115ef270ab1SKenneth D. Merry /* Setters */
116ef270ab1SKenneth D. Merry static int set_debug_mq_dump(ocs_t*, char*, char*);
117ef270ab1SKenneth D. Merry static int set_debug_cq_dump(ocs_t*, char*, char*);
118ef270ab1SKenneth D. Merry static int set_debug_wq_dump(ocs_t*, char*, char*);
119ef270ab1SKenneth D. Merry static int set_debug_eq_dump(ocs_t*, char*, char*);
120ef270ab1SKenneth D. Merry static int set_logmask(ocs_t*, char*, char*);
121ef270ab1SKenneth D. Merry static int set_configured_link_state(ocs_t*, char*, char*);
122ef270ab1SKenneth D. Merry static int set_linkcfg(ocs_t*, char*, char*);
123ef270ab1SKenneth D. Merry static int set_nodedb_mask(ocs_t*, char*, char*);
124ef270ab1SKenneth D. Merry static int set_port_protocol(ocs_t*, char*, char*);
125ef270ab1SKenneth D. Merry static int set_active_profile(ocs_t*, char*, char*);
126ef270ab1SKenneth D. Merry static int set_tgt_rscn_delay(ocs_t*, char*, char*);
127ef270ab1SKenneth D. Merry static int set_tgt_rscn_period(ocs_t*, char*, char*);
128ef270ab1SKenneth D. Merry static int set_inject_drop_cmd(ocs_t*, char*, char*);
129ef270ab1SKenneth D. Merry static int set_inject_free_drop_cmd(ocs_t*, char*, char*);
130ef270ab1SKenneth D. Merry static int set_inject_drop_data(ocs_t*, char*, char*);
131ef270ab1SKenneth D. Merry static int set_inject_drop_resp(ocs_t*, char*, char*);
132ef270ab1SKenneth D. Merry static int set_cmd_err_inject(ocs_t*, char*, char*);
133ef270ab1SKenneth D. Merry static int set_cmd_delay_value(ocs_t*, char*, char*);
134ef270ab1SKenneth D. Merry static int set_nv_wwn(ocs_t*, char*, char*);
135ef270ab1SKenneth D. Merry static int set_loglevel(ocs_t*, char*, char*);
136ef270ab1SKenneth D. Merry 
137ef270ab1SKenneth D. Merry static void ocs_mgmt_linkcfg_cb(int32_t status, uintptr_t value, void *arg);
138ef270ab1SKenneth D. Merry 
139ef270ab1SKenneth D. Merry ocs_mgmt_table_entry_t mgmt_table[] = {
140ef270ab1SKenneth D. Merry 		{"nodes_count", get_nodes_count, NULL, NULL},
141ef270ab1SKenneth D. Merry 		{"desc", get_desc, NULL, NULL},
142ef270ab1SKenneth D. Merry 		{"fw_rev", get_fw_rev, NULL, NULL},
143ef270ab1SKenneth D. Merry 		{"fw_rev2", get_fw_rev2, NULL, NULL},
144ef270ab1SKenneth D. Merry 		{"ipl", get_ipl, NULL, NULL},
145ef270ab1SKenneth D. Merry 		{"hw_rev1", get_hw_rev1, NULL, NULL},
146ef270ab1SKenneth D. Merry 		{"hw_rev2", get_hw_rev2, NULL, NULL},
147ef270ab1SKenneth D. Merry 		{"hw_rev3", get_hw_rev3, NULL, NULL},
148ef270ab1SKenneth D. Merry 		{"wwnn", get_wwnn, NULL, NULL},
149ef270ab1SKenneth D. Merry 		{"wwpn", get_wwpn, NULL, NULL},
150ef270ab1SKenneth D. Merry 		{"fc_id", get_fcid, NULL, NULL},
151ef270ab1SKenneth D. Merry 		{"sn", get_sn, NULL, NULL},
152ef270ab1SKenneth D. Merry 		{"pn", get_pn, NULL, NULL},
153ef270ab1SKenneth D. Merry 		{"sli4_intf_reg", get_sli4_intf_reg, NULL, NULL},
154ef270ab1SKenneth D. Merry 		{"phy_port_num", get_phy_port_num, NULL, NULL},
155ef270ab1SKenneth D. Merry 		{"asic_id_reg", get_asic_id, NULL, NULL},
156ef270ab1SKenneth D. Merry 		{"pci_vendor", get_pci_vendor, NULL, NULL},
157ef270ab1SKenneth D. Merry 		{"pci_device", get_pci_device, NULL, NULL},
158ef270ab1SKenneth D. Merry 		{"pci_subsystem_vendor", get_pci_subsystem_vendor, NULL, NULL},
159ef270ab1SKenneth D. Merry 		{"pci_subsystem_device", get_pci_subsystem_device, NULL, NULL},
160ef270ab1SKenneth D. Merry 		{"businfo", get_businfo, NULL, NULL},
161ef270ab1SKenneth D. Merry 		{"sfp_a0", get_sfp_a0, NULL, NULL},
162ef270ab1SKenneth D. Merry 		{"sfp_a2", get_sfp_a2, NULL, NULL},
163ef270ab1SKenneth D. Merry 		{"profile_list", get_profile_list, NULL, NULL},
164ef270ab1SKenneth D. Merry 		{"driver_version", get_driver_version, NULL, NULL},
165ef270ab1SKenneth D. Merry 		{"current_speed", get_current_speed, NULL, NULL},
166ef270ab1SKenneth D. Merry 		{"current_topology", get_current_topology, NULL, NULL},
167ef270ab1SKenneth D. Merry 		{"current_link_state", get_current_link_state, NULL, NULL},
168ef270ab1SKenneth D. Merry 		{"chip_type", get_chip_type, NULL, NULL},
169ef270ab1SKenneth D. Merry 		{"configured_speed", get_configured_speed, set_configured_speed, NULL},
170ef270ab1SKenneth D. Merry 		{"configured_topology", get_configured_topology, set_configured_topology, NULL},
171ef270ab1SKenneth D. Merry 		{"configured_link_state", get_configured_link_state, set_configured_link_state, NULL},
172ef270ab1SKenneth D. Merry 		{"debug_mq_dump", get_debug_mq_dump, set_debug_mq_dump, NULL},
173ef270ab1SKenneth D. Merry 		{"debug_cq_dump", get_debug_cq_dump, set_debug_cq_dump, NULL},
174ef270ab1SKenneth D. Merry 		{"debug_wq_dump", get_debug_wq_dump, set_debug_wq_dump, NULL},
175ef270ab1SKenneth D. Merry 		{"debug_eq_dump", get_debug_eq_dump, set_debug_eq_dump, NULL},
176ef270ab1SKenneth D. Merry 		{"logmask", get_logmask, set_logmask, NULL},
177ef270ab1SKenneth D. Merry 		{"loglevel", get_loglevel, set_loglevel, NULL},
178ef270ab1SKenneth D. Merry 		{"linkcfg", get_linkcfg, set_linkcfg, NULL},
179ef270ab1SKenneth D. Merry 		{"requested_wwnn", get_req_wwnn, set_req_wwnn, NULL},
180ef270ab1SKenneth D. Merry 		{"requested_wwpn", get_req_wwpn, set_req_wwpn, NULL},
181ef270ab1SKenneth D. Merry 		{"nodedb_mask", get_nodedb_mask, set_nodedb_mask, NULL},
182ef270ab1SKenneth D. Merry 		{"port_protocol", get_port_protocol, set_port_protocol, NULL},
183ef270ab1SKenneth D. Merry 		{"active_profile", get_active_profile, set_active_profile, NULL},
184ef270ab1SKenneth D. Merry 		{"firmware_write", NULL, NULL, ocs_mgmt_firmware_write},
185ef270ab1SKenneth D. Merry 		{"firmware_reset", NULL, NULL, ocs_mgmt_firmware_reset},
186ef270ab1SKenneth D. Merry 		{"function_reset", NULL, NULL, ocs_mgmt_function_reset},
187ef270ab1SKenneth D. Merry 		{"force_assert", NULL, NULL, ocs_mgmt_force_assert},
188ef270ab1SKenneth D. Merry 
189ef270ab1SKenneth D. Merry 		{"tgt_rscn_delay", get_tgt_rscn_delay, set_tgt_rscn_delay, NULL},
190ef270ab1SKenneth D. Merry 		{"tgt_rscn_period", get_tgt_rscn_period, set_tgt_rscn_period, NULL},
191ef270ab1SKenneth D. Merry 		{"inject_drop_cmd", get_inject_drop_cmd, set_inject_drop_cmd, NULL},
192ef270ab1SKenneth D. Merry 		{"inject_free_drop_cmd", get_inject_free_drop_cmd, set_inject_free_drop_cmd, NULL},
193ef270ab1SKenneth D. Merry 		{"inject_drop_data", get_inject_drop_data, set_inject_drop_data, NULL},
194ef270ab1SKenneth D. Merry 		{"inject_drop_resp", get_inject_drop_resp, set_inject_drop_resp, NULL},
195ef270ab1SKenneth D. Merry 		{"cmd_err_inject", get_cmd_err_inject, set_cmd_err_inject, NULL},
196ef270ab1SKenneth D. Merry 		{"cmd_delay_value", get_cmd_delay_value, set_cmd_delay_value, NULL},
197ef270ab1SKenneth D. Merry 		{"nv_wwpn", get_nv_wwpn, NULL, NULL},
198ef270ab1SKenneth D. Merry 		{"nv_wwnn", get_nv_wwnn, NULL, NULL},
199ef270ab1SKenneth D. Merry 		{"nv_wwn", NULL, set_nv_wwn, NULL},
200ef270ab1SKenneth D. Merry 		{"node_abort_cnt", get_node_abort_cnt, NULL, NULL},
201ef270ab1SKenneth D. Merry };
202ef270ab1SKenneth D. Merry 
203ef270ab1SKenneth D. Merry /**
204ef270ab1SKenneth D. Merry  * @ingroup mgmt
205ef270ab1SKenneth D. Merry  * @brief Get a list of options supported by the driver.
206ef270ab1SKenneth D. Merry  *
207ef270ab1SKenneth D. Merry  * @par Description
208ef270ab1SKenneth D. Merry  * This is the top level "get list" handler for the driver. It
209ef270ab1SKenneth D. Merry  * performs the following:
210ef270ab1SKenneth D. Merry  *  - Adds entries to the textbuf for any actions supported by this level in the driver.
211ef270ab1SKenneth D. Merry  *  - Calls a back-end function to add any actions supported by the back-end.
212ef270ab1SKenneth D. Merry  *  - Calls a function on each child (domain) to recursively add supported actions.
213ef270ab1SKenneth D. Merry  *
214ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
215ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to accumulate the results.
216ef270ab1SKenneth D. Merry  *
217ef270ab1SKenneth D. Merry  * @return Returns 0 on success, or a negative value on failure.
218ef270ab1SKenneth D. Merry  */
219ef270ab1SKenneth D. Merry 
220ef270ab1SKenneth D. Merry void
ocs_mgmt_get_list(ocs_t * ocs,ocs_textbuf_t * textbuf)221ef270ab1SKenneth D. Merry ocs_mgmt_get_list(ocs_t *ocs, ocs_textbuf_t *textbuf)
222ef270ab1SKenneth D. Merry {
223ef270ab1SKenneth D. Merry 	ocs_domain_t *domain;
224ef270ab1SKenneth D. Merry 	uint32_t i;
225ef270ab1SKenneth D. Merry 	int access;
226ef270ab1SKenneth D. Merry 
227ef270ab1SKenneth D. Merry 	ocs_mgmt_start_unnumbered_section(textbuf, "ocs");
228ef270ab1SKenneth D. Merry 
229ef270ab1SKenneth D. Merry 	for (i=0;i<ARRAY_SIZE(mgmt_table);i++) {
230ef270ab1SKenneth D. Merry 		access = 0;
231ef270ab1SKenneth D. Merry 		if (mgmt_table[i].get_handler) {
232ef270ab1SKenneth D. Merry 			access |= MGMT_MODE_RD;
233ef270ab1SKenneth D. Merry 		}
234ef270ab1SKenneth D. Merry 		if (mgmt_table[i].set_handler) {
235ef270ab1SKenneth D. Merry 			access |= MGMT_MODE_WR;
236ef270ab1SKenneth D. Merry 		}
237ef270ab1SKenneth D. Merry 		if (mgmt_table[i].action_handler) {
238ef270ab1SKenneth D. Merry 			access |= MGMT_MODE_EX;
239ef270ab1SKenneth D. Merry 		}
240ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_property_name(textbuf, access, mgmt_table[i].name);
241ef270ab1SKenneth D. Merry 	}
242ef270ab1SKenneth D. Merry 
243ef270ab1SKenneth D. Merry 	if ((ocs->mgmt_functions) && (ocs->mgmt_functions->get_list_handler)) {
244ef270ab1SKenneth D. Merry 		ocs->mgmt_functions->get_list_handler(textbuf, ocs);
245ef270ab1SKenneth D. Merry 	}
246ef270ab1SKenneth D. Merry 
247ef270ab1SKenneth D. Merry 	if ((ocs->tgt_mgmt_functions) && (ocs->tgt_mgmt_functions->get_list_handler)) {
248ef270ab1SKenneth D. Merry 		ocs->tgt_mgmt_functions->get_list_handler(textbuf, &(ocs->tgt_ocs));
249ef270ab1SKenneth D. Merry 	}
250ef270ab1SKenneth D. Merry 
251ef270ab1SKenneth D. Merry 	/* Have each of my children add their actions */
252ef270ab1SKenneth D. Merry 	if (ocs_device_lock_try(ocs) == TRUE) {
253ef270ab1SKenneth D. Merry 		/* If we get here then we are holding the device lock */
254ef270ab1SKenneth D. Merry 		ocs_list_foreach(&ocs->domain_list, domain) {
255ef270ab1SKenneth D. Merry 			if ((domain->mgmt_functions) && (domain->mgmt_functions->get_list_handler)) {
256ef270ab1SKenneth D. Merry 				domain->mgmt_functions->get_list_handler(textbuf, domain);
257ef270ab1SKenneth D. Merry 			}
258ef270ab1SKenneth D. Merry 		}
259ef270ab1SKenneth D. Merry 		ocs_device_unlock(ocs);
260ef270ab1SKenneth D. Merry 	}
261ef270ab1SKenneth D. Merry 
262ef270ab1SKenneth D. Merry 	ocs_mgmt_end_unnumbered_section(textbuf, "ocs");
263ef270ab1SKenneth D. Merry 
264ef270ab1SKenneth D. Merry }
265ef270ab1SKenneth D. Merry 
266ef270ab1SKenneth D. Merry /**
267ef270ab1SKenneth D. Merry  * @ingroup mgmt
268ef270ab1SKenneth D. Merry  * @brief Return the value of a management item.
269ef270ab1SKenneth D. Merry  *
270ef270ab1SKenneth D. Merry  * @par Description
271ef270ab1SKenneth D. Merry  * This is the top level "get" handler for the driver. It
272ef270ab1SKenneth D. Merry  * performs the following:
273ef270ab1SKenneth D. Merry  *  - Checks that the qualifier portion of the name begins with my qualifier (ocs).
274ef270ab1SKenneth D. Merry  *  - If the remaining part of the name matches a parameter that is known at this level,
275ef270ab1SKenneth D. Merry  *    writes the value into textbuf.
276ef270ab1SKenneth D. Merry  *  - If the name is not known, sends the request to the back-ends to fulfill (if possible).
277ef270ab1SKenneth D. Merry  *  - If the request has not been fulfilled by the back-end,
278ef270ab1SKenneth D. Merry  *    passes the request to each of the children (domains) to
279ef270ab1SKenneth D. Merry  *    have them (recursively) try to respond.
280ef270ab1SKenneth D. Merry  *
281ef270ab1SKenneth D. Merry  *  In passing the request to other entities, the request is considered to be answered
282ef270ab1SKenneth D. Merry  *  when a response has been written into textbuf, indicated by textbuf->buffer_written
283ef270ab1SKenneth D. Merry  *  being non-zero.
284ef270ab1SKenneth D. Merry  *
285ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
286ef270ab1SKenneth D. Merry  * @param name Name of the status item to be retrieved.
287ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to return the results.
288ef270ab1SKenneth D. Merry  *
289ef270ab1SKenneth D. Merry  * @return Returns 0 if the value was found and returned, or -1 if an error occurred.
290ef270ab1SKenneth D. Merry  */
291ef270ab1SKenneth D. Merry 
292ef270ab1SKenneth D. Merry int
ocs_mgmt_get(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)293ef270ab1SKenneth D. Merry ocs_mgmt_get(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
294ef270ab1SKenneth D. Merry {
295ef270ab1SKenneth D. Merry 	ocs_domain_t *domain;
296ef270ab1SKenneth D. Merry 	char qualifier[6];
297ef270ab1SKenneth D. Merry 	int retval = -1;
298ef270ab1SKenneth D. Merry 	uint32_t i;
299ef270ab1SKenneth D. Merry 
300ef270ab1SKenneth D. Merry 	ocs_mgmt_start_unnumbered_section(textbuf, "ocs");
301ef270ab1SKenneth D. Merry 
302ef270ab1SKenneth D. Merry 	snprintf(qualifier, sizeof(qualifier), "/ocs");
303ef270ab1SKenneth D. Merry 
304ef270ab1SKenneth D. Merry 	/* See if the name starts with my qualifier.  If not then this request isn't for me */
305ef270ab1SKenneth D. Merry 	if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
306ef270ab1SKenneth D. Merry 		char *unqualified_name = name + strlen(qualifier) + 1;
307ef270ab1SKenneth D. Merry 
308ef270ab1SKenneth D. Merry 		for (i=0;i<ARRAY_SIZE(mgmt_table);i++) {
309ef270ab1SKenneth D. Merry 			if (ocs_strcmp(unqualified_name, mgmt_table[i].name) == 0) {
310ef270ab1SKenneth D. Merry 				if (mgmt_table[i].get_handler) {
311ef270ab1SKenneth D. Merry 					mgmt_table[i].get_handler(ocs, name, textbuf);
312ef270ab1SKenneth D. Merry 					ocs_mgmt_end_unnumbered_section(textbuf, "ocs");
313ef270ab1SKenneth D. Merry 					return 0;
314ef270ab1SKenneth D. Merry 				}
315ef270ab1SKenneth D. Merry 			}
316ef270ab1SKenneth D. Merry 		}
317ef270ab1SKenneth D. Merry 
318ef270ab1SKenneth D. Merry 		if ((ocs->mgmt_functions) && (ocs->mgmt_functions->get_handler)) {
319ef270ab1SKenneth D. Merry 			retval = ocs->mgmt_functions->get_handler(textbuf, qualifier, (char*)name, ocs);
320ef270ab1SKenneth D. Merry 		}
321ef270ab1SKenneth D. Merry 
322ef270ab1SKenneth D. Merry 		if (retval != 0) {
323ef270ab1SKenneth D. Merry 			if ((ocs->tgt_mgmt_functions) && (ocs->tgt_mgmt_functions->get_handler)) {
324ef270ab1SKenneth D. Merry 				retval = ocs->tgt_mgmt_functions->get_handler(textbuf, qualifier,
325ef270ab1SKenneth D. Merry 						(char*)name, &(ocs->tgt_ocs));
326ef270ab1SKenneth D. Merry 			}
327ef270ab1SKenneth D. Merry 		}
328ef270ab1SKenneth D. Merry 
329ef270ab1SKenneth D. Merry 		if (retval != 0) {
330ef270ab1SKenneth D. Merry 			/* The driver didn't handle it, pass it to each domain */
331ef270ab1SKenneth D. Merry 
332ef270ab1SKenneth D. Merry 			ocs_device_lock(ocs);
333ef270ab1SKenneth D. Merry 			ocs_list_foreach(&ocs->domain_list, domain) {
334ef270ab1SKenneth D. Merry 				if ((domain->mgmt_functions) && (domain->mgmt_functions->get_handler)) {
335ef270ab1SKenneth D. Merry 					retval = domain->mgmt_functions->get_handler(textbuf, qualifier, (char*)name, domain);
336ef270ab1SKenneth D. Merry 				}
337ef270ab1SKenneth D. Merry 
338ef270ab1SKenneth D. Merry 				if (retval ==  0) {
339ef270ab1SKenneth D. Merry 					break;
340ef270ab1SKenneth D. Merry 				}
341ef270ab1SKenneth D. Merry 			}
342ef270ab1SKenneth D. Merry 			ocs_device_unlock(ocs);
343ef270ab1SKenneth D. Merry 		}
344ef270ab1SKenneth D. Merry 	}
345ef270ab1SKenneth D. Merry 
346ef270ab1SKenneth D. Merry 	ocs_mgmt_end_unnumbered_section(textbuf, "ocs");
347ef270ab1SKenneth D. Merry 
348ef270ab1SKenneth D. Merry 	return retval;
349ef270ab1SKenneth D. Merry }
350ef270ab1SKenneth D. Merry 
351ef270ab1SKenneth D. Merry /**
352ef270ab1SKenneth D. Merry  * @ingroup mgmt
353ef270ab1SKenneth D. Merry  * @brief Set the value of a mgmt item.
354ef270ab1SKenneth D. Merry  *
355ef270ab1SKenneth D. Merry  * @par Description
356ef270ab1SKenneth D. Merry  * This is the top level "set" handler for the driver. It
357ef270ab1SKenneth D. Merry  * performs the following:
358ef270ab1SKenneth D. Merry  *  - Checks that the qualifier portion of the name begins with my qualifier (ocs).
359ef270ab1SKenneth D. Merry  *  - If the remaining part of the name matches a parameter that is known at this level,
360ef270ab1SKenneth D. Merry  *    calls the correct function to change the configuration.
361ef270ab1SKenneth D. Merry  *  - If the name is not known, sends the request to the back-ends to fulfill (if possible).
362ef270ab1SKenneth D. Merry  *  - If the request has not been fulfilled by the back-end, passes the request to each of the
363ef270ab1SKenneth D. Merry  *    children (domains) to have them (recursively) try to respond.
364ef270ab1SKenneth D. Merry  *
365ef270ab1SKenneth D. Merry  *  In passing the request to other entities, the request is considered to be handled
366ef270ab1SKenneth D. Merry  *  if the function returns 0.
367ef270ab1SKenneth D. Merry  *
368ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
369ef270ab1SKenneth D. Merry  * @param name Name of the property to be changed.
370ef270ab1SKenneth D. Merry  * @param value Requested new value of the property.
371ef270ab1SKenneth D. Merry  *
372ef270ab1SKenneth D. Merry  * @return Returns 0 if the configuration value was updated, or -1 otherwise.
373ef270ab1SKenneth D. Merry  */
374ef270ab1SKenneth D. Merry 
375ef270ab1SKenneth D. Merry int
ocs_mgmt_set(ocs_t * ocs,char * name,char * value)376ef270ab1SKenneth D. Merry ocs_mgmt_set(ocs_t *ocs, char *name, char *value)
377ef270ab1SKenneth D. Merry {
378ef270ab1SKenneth D. Merry 	ocs_domain_t *domain;
379ef270ab1SKenneth D. Merry 	int result = -1;
380ef270ab1SKenneth D. Merry 	char qualifier[80];
381ef270ab1SKenneth D. Merry 	uint32_t i;
382ef270ab1SKenneth D. Merry 
383ef270ab1SKenneth D. Merry 	snprintf(qualifier, sizeof(qualifier), "/ocs");
384ef270ab1SKenneth D. Merry 
385ef270ab1SKenneth D. Merry 	/* If it doesn't start with my qualifier I don't know what to do with it */
386ef270ab1SKenneth D. Merry 	if (ocs_strncmp(name, qualifier, strlen(qualifier)) == 0) {
387ef270ab1SKenneth D. Merry 		char *unqualified_name = name + strlen(qualifier) +1;
388ef270ab1SKenneth D. Merry 
389ef270ab1SKenneth D. Merry 		/* See if it's a value I can set */
390ef270ab1SKenneth D. Merry 		for (i=0;i<ARRAY_SIZE(mgmt_table);i++) {
391ef270ab1SKenneth D. Merry 			if (ocs_strcmp(unqualified_name, mgmt_table[i].name) == 0) {
392ef270ab1SKenneth D. Merry 				if (mgmt_table[i].set_handler) {
393ef270ab1SKenneth D. Merry 					return mgmt_table[i].set_handler(ocs, name, value);
394ef270ab1SKenneth D. Merry 				}
395ef270ab1SKenneth D. Merry 			}
396ef270ab1SKenneth D. Merry 		}
397ef270ab1SKenneth D. Merry 
398ef270ab1SKenneth D. Merry 		if ((ocs->mgmt_functions) && (ocs->mgmt_functions->set_handler)) {
399ef270ab1SKenneth D. Merry 			result = ocs->mgmt_functions->set_handler(qualifier, name, (char *)value, ocs);
400ef270ab1SKenneth D. Merry 		}
401ef270ab1SKenneth D. Merry 
402ef270ab1SKenneth D. Merry 		if (result != 0) {
403ef270ab1SKenneth D. Merry 			if ((ocs->tgt_mgmt_functions) && (ocs->tgt_mgmt_functions->set_handler)) {
404ef270ab1SKenneth D. Merry 				result = ocs->tgt_mgmt_functions->set_handler(qualifier, name,
405ef270ab1SKenneth D. Merry 						(char *)value, &(ocs->tgt_ocs));
406ef270ab1SKenneth D. Merry 			}
407ef270ab1SKenneth D. Merry 		}
408ef270ab1SKenneth D. Merry 
409ef270ab1SKenneth D. Merry 		/* If I didn't know how to set this config value pass the request to each of my children */
410ef270ab1SKenneth D. Merry 		if (result != 0) {
411ef270ab1SKenneth D. Merry 			ocs_device_lock(ocs);
412ef270ab1SKenneth D. Merry 			ocs_list_foreach(&ocs->domain_list, domain) {
413ef270ab1SKenneth D. Merry 				if ((domain->mgmt_functions) && (domain->mgmt_functions->set_handler)) {
414ef270ab1SKenneth D. Merry 					result = domain->mgmt_functions->set_handler(qualifier, name, (char*)value, domain);
415ef270ab1SKenneth D. Merry 				}
416ef270ab1SKenneth D. Merry 				if (result == 0) {
417ef270ab1SKenneth D. Merry 					break;
418ef270ab1SKenneth D. Merry 				}
419ef270ab1SKenneth D. Merry 			}
420ef270ab1SKenneth D. Merry 			ocs_device_unlock(ocs);
421ef270ab1SKenneth D. Merry 		}
422ef270ab1SKenneth D. Merry 	}
423ef270ab1SKenneth D. Merry 
424ef270ab1SKenneth D. Merry 	return result;
425ef270ab1SKenneth D. Merry }
426ef270ab1SKenneth D. Merry 
427ef270ab1SKenneth D. Merry /**
428ef270ab1SKenneth D. Merry  * @ingroup mgmt
429ef270ab1SKenneth D. Merry  * @brief Perform a management action.
430ef270ab1SKenneth D. Merry  *
431ef270ab1SKenneth D. Merry  * @par Description
432ef270ab1SKenneth D. Merry  * This is the top level "exec" handler for the driver. It
433ef270ab1SKenneth D. Merry  * performs the following:
434ef270ab1SKenneth D. Merry  *  - Checks that the qualifier portion of the name begins with my qualifier (ocs).
435ef270ab1SKenneth D. Merry  *  - If the remaining part of the name matches an action that is known at this level,
436ef270ab1SKenneth D. Merry  *    calls the correct function to perform the action.
437ef270ab1SKenneth D. Merry  *  - If the name is not known, sends the request to the back-ends to fulfill (if possible).
438ef270ab1SKenneth D. Merry  *  - If the request has not been fulfilled by the back-end, passes the request to each of the
439ef270ab1SKenneth D. Merry  *    children (domains) to have them (recursively) try to respond.
440ef270ab1SKenneth D. Merry  *
441ef270ab1SKenneth D. Merry  *  In passing the request to other entities, the request is considered to be handled
442ef270ab1SKenneth D. Merry  *  if the function returns 0.
443ef270ab1SKenneth D. Merry  *
444ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
445ef270ab1SKenneth D. Merry  * @param action Name of the action to be performed.
446ef270ab1SKenneth D. Merry  * @param arg_in Pointer to an argument being passed to the action.
447ef270ab1SKenneth D. Merry  * @param arg_in_length Length of the argument pointed to by @c arg_in.
448ef270ab1SKenneth D. Merry  * @param arg_out Pointer to an argument being passed to the action.
449ef270ab1SKenneth D. Merry  * @param arg_out_length Length of the argument pointed to by @c arg_out.
450ef270ab1SKenneth D. Merry  *
451ef270ab1SKenneth D. Merry  * @return Returns 0 if the action was completed, or -1 otherwise.
452ef270ab1SKenneth D. Merry  *
453ef270ab1SKenneth D. Merry  *
454ef270ab1SKenneth D. Merry  */
455ef270ab1SKenneth D. Merry 
456ef270ab1SKenneth D. Merry int
ocs_mgmt_exec(ocs_t * ocs,char * action,void * arg_in,uint32_t arg_in_length,void * arg_out,uint32_t arg_out_length)457ef270ab1SKenneth D. Merry ocs_mgmt_exec(ocs_t *ocs, char *action, void *arg_in,
458ef270ab1SKenneth D. Merry 		uint32_t arg_in_length, void *arg_out, uint32_t arg_out_length)
459ef270ab1SKenneth D. Merry {
460ef270ab1SKenneth D. Merry 	ocs_domain_t *domain;
461ef270ab1SKenneth D. Merry 	int result = -1;
462ef270ab1SKenneth D. Merry 	char qualifier[80];
463ef270ab1SKenneth D. Merry 	uint32_t i;
464ef270ab1SKenneth D. Merry 
465ef270ab1SKenneth D. Merry 	snprintf(qualifier, sizeof(qualifier), "/ocs");
466ef270ab1SKenneth D. Merry 
467ef270ab1SKenneth D. Merry 	/* If it doesn't start with my qualifier I don't know what to do with it */
468ef270ab1SKenneth D. Merry 	if (ocs_strncmp(action, qualifier, strlen(qualifier)) == 0) {
469ef270ab1SKenneth D. Merry 		char *unqualified_name = action + strlen(qualifier) +1;
470ef270ab1SKenneth D. Merry 
471ef270ab1SKenneth D. Merry 		/* See if it's an action I can perform */
472ef270ab1SKenneth D. Merry 		for (i=0;i<ARRAY_SIZE(mgmt_table); i++) {
473ef270ab1SKenneth D. Merry 			if (ocs_strcmp(unqualified_name, mgmt_table[i].name) == 0) {
474ef270ab1SKenneth D. Merry 				if (mgmt_table[i].action_handler) {
475ef270ab1SKenneth D. Merry 					return mgmt_table[i].action_handler(ocs, action, arg_in, arg_in_length,
476ef270ab1SKenneth D. Merry 							arg_out, arg_out_length);
477ef270ab1SKenneth D. Merry 				}
478ef270ab1SKenneth D. Merry 			}
479ef270ab1SKenneth D. Merry 		}
480ef270ab1SKenneth D. Merry 
48129e2dbd4SRam Kishore Vegesna 		/* See if it's a value I can supply */
48229e2dbd4SRam Kishore Vegesna 		if (ocs_strcmp(unqualified_name, "driver/gendump") == 0) {
48329e2dbd4SRam Kishore Vegesna 			return ocs_gen_dump(ocs);
48429e2dbd4SRam Kishore Vegesna 		}
48529e2dbd4SRam Kishore Vegesna 
48629e2dbd4SRam Kishore Vegesna 		if (ocs_strcmp(unqualified_name, "driver/dump_to_host") == 0) {
48729e2dbd4SRam Kishore Vegesna 			return ocs_dump_to_host(ocs, arg_out, arg_out_length);
48829e2dbd4SRam Kishore Vegesna 		}
48929e2dbd4SRam Kishore Vegesna 
490ef270ab1SKenneth D. Merry 		if ((ocs->mgmt_functions) && (ocs->mgmt_functions->exec_handler)) {
491ef270ab1SKenneth D. Merry 			result = ocs->mgmt_functions->exec_handler(qualifier, action, arg_in, arg_in_length,
492ef270ab1SKenneth D. Merry 								   arg_out, arg_out_length, ocs);
493ef270ab1SKenneth D. Merry 		}
494ef270ab1SKenneth D. Merry 
495ef270ab1SKenneth D. Merry 		if (result != 0) {
496ef270ab1SKenneth D. Merry 			if ((ocs->tgt_mgmt_functions) && (ocs->tgt_mgmt_functions->exec_handler)) {
497ef270ab1SKenneth D. Merry 				result = ocs->tgt_mgmt_functions->exec_handler(qualifier, action,
498ef270ab1SKenneth D. Merry 						arg_in, arg_in_length, arg_out, arg_out_length,
499ef270ab1SKenneth D. Merry 						&(ocs->tgt_ocs));
500ef270ab1SKenneth D. Merry 			}
501ef270ab1SKenneth D. Merry 		}
502ef270ab1SKenneth D. Merry 
503ef270ab1SKenneth D. Merry 		/* If I didn't know how to do this action pass the request to each of my children */
504ef270ab1SKenneth D. Merry 		if (result != 0) {
505ef270ab1SKenneth D. Merry 			ocs_device_lock(ocs);
506ef270ab1SKenneth D. Merry 			ocs_list_foreach(&ocs->domain_list, domain) {
507ef270ab1SKenneth D. Merry 				if ((domain->mgmt_functions) && (domain->mgmt_functions->exec_handler)) {
508ef270ab1SKenneth D. Merry 					result = domain->mgmt_functions->exec_handler(qualifier, action, arg_in, arg_in_length, arg_out,
509ef270ab1SKenneth D. Merry 							arg_out_length, domain);
510ef270ab1SKenneth D. Merry 				}
511ef270ab1SKenneth D. Merry 				if (result == 0) {
512ef270ab1SKenneth D. Merry 					break;
513ef270ab1SKenneth D. Merry 				}
514ef270ab1SKenneth D. Merry 			}
515ef270ab1SKenneth D. Merry 			ocs_device_unlock(ocs);
516ef270ab1SKenneth D. Merry 		}
517ef270ab1SKenneth D. Merry 	}
518ef270ab1SKenneth D. Merry 
519ef270ab1SKenneth D. Merry 	return result;
520ef270ab1SKenneth D. Merry }
521ef270ab1SKenneth D. Merry 
522ef270ab1SKenneth D. Merry void
ocs_mgmt_get_all(ocs_t * ocs,ocs_textbuf_t * textbuf)523ef270ab1SKenneth D. Merry ocs_mgmt_get_all(ocs_t *ocs, ocs_textbuf_t *textbuf)
524ef270ab1SKenneth D. Merry {
525ef270ab1SKenneth D. Merry 	ocs_domain_t *domain;
526ef270ab1SKenneth D. Merry 	uint32_t i;
527ef270ab1SKenneth D. Merry 
528ef270ab1SKenneth D. Merry 	ocs_mgmt_start_unnumbered_section(textbuf, "ocs");
529ef270ab1SKenneth D. Merry 
530ef270ab1SKenneth D. Merry 	for (i=0;i<ARRAY_SIZE(mgmt_table);i++) {
531ef270ab1SKenneth D. Merry 		if (mgmt_table[i].get_handler) {
532ef270ab1SKenneth D. Merry 			mgmt_table[i].get_handler(ocs, mgmt_table[i].name, textbuf);
533ef270ab1SKenneth D. Merry 		} else if (mgmt_table[i].action_handler) {
534ef270ab1SKenneth D. Merry 			/* No get_handler, but there's an action_handler. Just report
535ef270ab1SKenneth D. Merry 			   the name */
536ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_property_name(textbuf, MGMT_MODE_EX, mgmt_table[i].name);
537ef270ab1SKenneth D. Merry 		}
538ef270ab1SKenneth D. Merry 	}
539ef270ab1SKenneth D. Merry 
540ef270ab1SKenneth D. Merry 	if ((ocs->mgmt_functions) && (ocs->mgmt_functions->get_all_handler)) {
541ef270ab1SKenneth D. Merry 		ocs->mgmt_functions->get_all_handler(textbuf, ocs);
542ef270ab1SKenneth D. Merry 	}
543ef270ab1SKenneth D. Merry 
544ef270ab1SKenneth D. Merry 	if ((ocs->tgt_mgmt_functions) && (ocs->tgt_mgmt_functions->get_all_handler)) {
545ef270ab1SKenneth D. Merry 		ocs->tgt_mgmt_functions->get_all_handler(textbuf, &(ocs->tgt_ocs));
546ef270ab1SKenneth D. Merry 	}
547ef270ab1SKenneth D. Merry 
548ef270ab1SKenneth D. Merry 	ocs_device_lock(ocs);
549ef270ab1SKenneth D. Merry 	ocs_list_foreach(&ocs->domain_list, domain) {
550ef270ab1SKenneth D. Merry 		if ((domain->mgmt_functions) && (domain->mgmt_functions->get_all_handler)) {
551ef270ab1SKenneth D. Merry 			domain->mgmt_functions->get_all_handler(textbuf, domain);
552ef270ab1SKenneth D. Merry 		}
553ef270ab1SKenneth D. Merry 	}
554ef270ab1SKenneth D. Merry 	ocs_device_unlock(ocs);
555ef270ab1SKenneth D. Merry 
556ef270ab1SKenneth D. Merry 	ocs_mgmt_end_unnumbered_section(textbuf, "ocs");
557ef270ab1SKenneth D. Merry }
558ef270ab1SKenneth D. Merry 
559ef270ab1SKenneth D. Merry static int32_t
ocs_mgmt_firmware_reset(ocs_t * ocs,char * name,void * buf,uint32_t buf_len,void * arg_out,uint32_t arg_out_length)560ef270ab1SKenneth D. Merry ocs_mgmt_firmware_reset(ocs_t *ocs, char *name, void *buf, uint32_t buf_len, void *arg_out, uint32_t arg_out_length)
561ef270ab1SKenneth D. Merry {
562ef270ab1SKenneth D. Merry 	int rc = 0;
563ef270ab1SKenneth D. Merry 	int index = 0;
564ef270ab1SKenneth D. Merry 	uint8_t bus, dev, func;
565ef270ab1SKenneth D. Merry 	ocs_t *other_ocs;
566ef270ab1SKenneth D. Merry 
567ef270ab1SKenneth D. Merry 	ocs_get_bus_dev_func(ocs, &bus, &dev, &func);
568ef270ab1SKenneth D. Merry 
569ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "Resetting port\n");
570ef270ab1SKenneth D. Merry 	if (ocs_hw_reset(&ocs->hw, OCS_HW_RESET_FIRMWARE)) {
571ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "failed to reset port\n");
572ef270ab1SKenneth D. Merry 		rc = -1;
573ef270ab1SKenneth D. Merry 	} else {
574ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "successfully reset port\n");
575ef270ab1SKenneth D. Merry 
576ef270ab1SKenneth D. Merry 		/* now reset all functions on the same device */
577ef270ab1SKenneth D. Merry 
578ef270ab1SKenneth D. Merry 		while ((other_ocs = ocs_get_instance(index++)) != NULL) {
579ef270ab1SKenneth D. Merry 			uint8_t other_bus, other_dev, other_func;
580ef270ab1SKenneth D. Merry 
581ef270ab1SKenneth D. Merry 			ocs_get_bus_dev_func(other_ocs, &other_bus, &other_dev, &other_func);
582ef270ab1SKenneth D. Merry 
583ef270ab1SKenneth D. Merry 			if ((bus == other_bus) && (dev == other_dev)) {
584ef270ab1SKenneth D. Merry 				if (other_ocs->hw.state !=
585ef270ab1SKenneth D. Merry                                       OCS_HW_STATE_UNINITIALIZED) {
586ef270ab1SKenneth D. Merry                                         other_ocs->hw.state =
587ef270ab1SKenneth D. Merry                                                 OCS_HW_STATE_QUEUES_ALLOCATED;
588ef270ab1SKenneth D. Merry                                 }
589ef270ab1SKenneth D. Merry 
590ef270ab1SKenneth D. Merry 				ocs_device_detach(other_ocs);
591ef270ab1SKenneth D. Merry 				if (ocs_device_attach(other_ocs)) {
592ef270ab1SKenneth D. Merry 					ocs_log_err(other_ocs,
593ef270ab1SKenneth D. Merry 						"device %d attach failed \n", index);
594ef270ab1SKenneth D. Merry 					rc = -1;
595ef270ab1SKenneth D. Merry 				}
596ef270ab1SKenneth D. Merry 			}
597ef270ab1SKenneth D. Merry 		}
598ef270ab1SKenneth D. Merry 	}
599ef270ab1SKenneth D. Merry 	return rc;
600ef270ab1SKenneth D. Merry }
601ef270ab1SKenneth D. Merry 
602ef270ab1SKenneth D. Merry static int32_t
ocs_mgmt_function_reset(ocs_t * ocs,char * name,void * buf,uint32_t buf_len,void * arg_out,uint32_t arg_out_length)603ef270ab1SKenneth D. Merry ocs_mgmt_function_reset(ocs_t *ocs, char *name, void *buf, uint32_t buf_len, void *arg_out, uint32_t arg_out_length)
604ef270ab1SKenneth D. Merry {
605ef270ab1SKenneth D. Merry 	int32_t rc;
606ef270ab1SKenneth D. Merry 
607ef270ab1SKenneth D. Merry 	ocs_device_detach(ocs);
608ef270ab1SKenneth D. Merry 	rc = ocs_device_attach(ocs);
609ef270ab1SKenneth D. Merry 
610ef270ab1SKenneth D. Merry 	return rc;
611ef270ab1SKenneth D. Merry }
612ef270ab1SKenneth D. Merry 
613ef270ab1SKenneth D. Merry static int32_t
ocs_mgmt_firmware_write(ocs_t * ocs,char * name,void * buf,uint32_t buf_len,void * arg_out,uint32_t arg_out_length)614ef270ab1SKenneth D. Merry ocs_mgmt_firmware_write(ocs_t *ocs, char *name, void *buf, uint32_t buf_len, void *arg_out, uint32_t arg_out_length)
615ef270ab1SKenneth D. Merry {
616ef270ab1SKenneth D. Merry 	int rc = 0;
617ef270ab1SKenneth D. Merry 	uint32_t bytes_left;
618ef270ab1SKenneth D. Merry 	uint32_t xfer_size;
619ef270ab1SKenneth D. Merry 	uint32_t offset;
620ef270ab1SKenneth D. Merry 	uint8_t *userp;
621ef270ab1SKenneth D. Merry 	ocs_dma_t dma;
622ef270ab1SKenneth D. Merry 	int last = 0;
623ef270ab1SKenneth D. Merry 	ocs_mgmt_fw_write_result_t result;
624ef270ab1SKenneth D. Merry 	uint32_t change_status = 0;
625ef270ab1SKenneth D. Merry         char status_str[80];
626ef270ab1SKenneth D. Merry 
627ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "fw_write");
628ef270ab1SKenneth D. Merry 
629ef270ab1SKenneth D. Merry 	bytes_left = buf_len;
630ef270ab1SKenneth D. Merry 	offset = 0;
631ef270ab1SKenneth D. Merry 	userp = (uint8_t *)buf;
632ef270ab1SKenneth D. Merry 
633ef270ab1SKenneth D. Merry 	if (ocs_dma_alloc(ocs, &dma, FW_WRITE_BUFSIZE, 4096)) {
634ef270ab1SKenneth D. Merry 		ocs_log_err(ocs, "ocs_mgmt_firmware_write: malloc failed");
635ef270ab1SKenneth D. Merry 		return -ENOMEM;
636ef270ab1SKenneth D. Merry 	}
637ef270ab1SKenneth D. Merry 
638ef270ab1SKenneth D. Merry 	while (bytes_left > 0) {
639ef270ab1SKenneth D. Merry 		if (bytes_left > FW_WRITE_BUFSIZE) {
640ef270ab1SKenneth D. Merry 			xfer_size = FW_WRITE_BUFSIZE;
641ef270ab1SKenneth D. Merry 		} else {
642ef270ab1SKenneth D. Merry 			xfer_size = bytes_left;
643ef270ab1SKenneth D. Merry 		}
644ef270ab1SKenneth D. Merry 
645ef270ab1SKenneth D. Merry 		/* Copy xfer_size bytes from user space to kernel buffer */
646ef270ab1SKenneth D. Merry 		if (ocs_copy_from_user(dma.virt, userp, xfer_size)) {
647ef270ab1SKenneth D. Merry 			rc = -EFAULT;
648ef270ab1SKenneth D. Merry 			break;
649ef270ab1SKenneth D. Merry 		}
650ef270ab1SKenneth D. Merry 
651ef270ab1SKenneth D. Merry 		/* See if this is the last block */
652ef270ab1SKenneth D. Merry 		if (bytes_left == xfer_size) {
653ef270ab1SKenneth D. Merry 			last = 1;
654ef270ab1SKenneth D. Merry 		}
655ef270ab1SKenneth D. Merry 
656ef270ab1SKenneth D. Merry 		/* Send the HW command */
657ef270ab1SKenneth D. Merry 		ocs_hw_firmware_write(&ocs->hw, &dma, xfer_size, offset, last, ocs_mgmt_fw_write_cb, &result);
658ef270ab1SKenneth D. Merry 
659ef270ab1SKenneth D. Merry 		/* Wait for semaphore to be signaled when the command completes
660ef270ab1SKenneth D. Merry 		 * TODO:  Should there be a timeout on this?  If so, how long? */
661ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
662ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
663ef270ab1SKenneth D. Merry 			rc = -ENXIO;
664ef270ab1SKenneth D. Merry 			break;
665ef270ab1SKenneth D. Merry 		}
666ef270ab1SKenneth D. Merry 
667ef270ab1SKenneth D. Merry 		if (result.actual_xfer == 0) {
668ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "actual_write_length is %d\n", result.actual_xfer);
669ef270ab1SKenneth D. Merry 			rc = -EFAULT;
670ef270ab1SKenneth D. Merry 			break;
671ef270ab1SKenneth D. Merry 		}
672ef270ab1SKenneth D. Merry 
673ef270ab1SKenneth D. Merry 		/* Check status */
674ef270ab1SKenneth D. Merry 		if (result.status != 0) {
675ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "write returned status %d\n", result.status);
676ef270ab1SKenneth D. Merry 			rc = -EFAULT;
677ef270ab1SKenneth D. Merry 			break;
678ef270ab1SKenneth D. Merry 		}
679ef270ab1SKenneth D. Merry 
680ef270ab1SKenneth D. Merry 		if (last) {
681ef270ab1SKenneth D. Merry 			change_status = result.change_status;
682ef270ab1SKenneth D. Merry 		}
683ef270ab1SKenneth D. Merry 
684ef270ab1SKenneth D. Merry 		bytes_left -= result.actual_xfer;
685ef270ab1SKenneth D. Merry 		offset += result.actual_xfer;
686ef270ab1SKenneth D. Merry 		userp += result.actual_xfer;
687ef270ab1SKenneth D. Merry 	}
688ef270ab1SKenneth D. Merry 
689ef270ab1SKenneth D. Merry 	/* Create string with status and copy to userland */
690ef270ab1SKenneth D. Merry 	if ((arg_out_length > 0) && (arg_out != NULL)) {
691ef270ab1SKenneth D. Merry 		if (arg_out_length > sizeof(status_str)) {
692ef270ab1SKenneth D. Merry 			arg_out_length = sizeof(status_str);
693ef270ab1SKenneth D. Merry 		}
694f9be23fdSMark Johnston 		ocs_memset(status_str, 0, sizeof(status_str));
695ef270ab1SKenneth D. Merry 		ocs_snprintf(status_str, arg_out_length, "%d", change_status);
696ef270ab1SKenneth D. Merry 		if (ocs_copy_to_user(arg_out, status_str, arg_out_length)) {
697ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "copy to user failed for change_status\n");
698ef270ab1SKenneth D. Merry 		}
699ef270ab1SKenneth D. Merry 	}
700ef270ab1SKenneth D. Merry 
701ef270ab1SKenneth D. Merry 	ocs_dma_free(ocs, &dma);
702ef270ab1SKenneth D. Merry 
703ef270ab1SKenneth D. Merry 	return rc;
704ef270ab1SKenneth D. Merry }
705ef270ab1SKenneth D. Merry 
706ef270ab1SKenneth D. Merry static void
ocs_mgmt_fw_write_cb(int32_t status,uint32_t actual_write_length,uint32_t change_status,void * arg)707ef270ab1SKenneth D. Merry ocs_mgmt_fw_write_cb(int32_t status, uint32_t actual_write_length, uint32_t change_status, void *arg)
708ef270ab1SKenneth D. Merry {
709ef270ab1SKenneth D. Merry 	ocs_mgmt_fw_write_result_t *result = arg;
710ef270ab1SKenneth D. Merry 
711ef270ab1SKenneth D. Merry 	result->status = status;
712ef270ab1SKenneth D. Merry 	result->actual_xfer = actual_write_length;
713ef270ab1SKenneth D. Merry 	result->change_status = change_status;
714ef270ab1SKenneth D. Merry 
715ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
716ef270ab1SKenneth D. Merry }
717ef270ab1SKenneth D. Merry 
718ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_sfp_result {
719ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
720ef270ab1SKenneth D. Merry 	ocs_lock_t cb_lock;
721ef270ab1SKenneth D. Merry 	int32_t running;
722ef270ab1SKenneth D. Merry 	int32_t status;
723ef270ab1SKenneth D. Merry 	uint32_t bytes_read;
724ef270ab1SKenneth D. Merry 	uint32_t page_data[32];
725ef270ab1SKenneth D. Merry } ocs_mgmt_sfp_result_t;
726ef270ab1SKenneth D. Merry 
727ef270ab1SKenneth D. Merry static void
ocs_mgmt_sfp_cb(void * os,int32_t status,uint32_t bytes_read,uint32_t * data,void * arg)728ef270ab1SKenneth D. Merry ocs_mgmt_sfp_cb(void *os, int32_t status, uint32_t bytes_read, uint32_t *data, void *arg)
729ef270ab1SKenneth D. Merry {
730ef270ab1SKenneth D. Merry 	ocs_mgmt_sfp_result_t *result = arg;
731ef270ab1SKenneth D. Merry 	ocs_t *ocs = os;
732ef270ab1SKenneth D. Merry 
733ef270ab1SKenneth D. Merry 	ocs_lock(&(result->cb_lock));
734ef270ab1SKenneth D. Merry 	result->running++;
735ef270ab1SKenneth D. Merry 	if(result->running == 2) {
736ef270ab1SKenneth D. Merry 		/* get_sfp() has timed out */
737ef270ab1SKenneth D. Merry 		ocs_unlock(&(result->cb_lock));
738ef270ab1SKenneth D. Merry 		ocs_free(ocs, result, sizeof(ocs_mgmt_sfp_result_t));
739ef270ab1SKenneth D. Merry 		return;
740ef270ab1SKenneth D. Merry 	}
741ef270ab1SKenneth D. Merry 
742ef270ab1SKenneth D. Merry 	result->status = status;
743ef270ab1SKenneth D. Merry 	result->bytes_read = bytes_read;
744ef270ab1SKenneth D. Merry 	ocs_memcpy(&result->page_data, data, SFP_PAGE_SIZE);
745ef270ab1SKenneth D. Merry 
746ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
747ef270ab1SKenneth D. Merry 	ocs_unlock(&(result->cb_lock));
748ef270ab1SKenneth D. Merry }
749ef270ab1SKenneth D. Merry 
750ef270ab1SKenneth D. Merry static int32_t
ocs_mgmt_get_sfp(ocs_t * ocs,uint16_t page,void * buf,uint32_t buf_len)751ef270ab1SKenneth D. Merry ocs_mgmt_get_sfp(ocs_t *ocs, uint16_t page, void *buf, uint32_t buf_len)
752ef270ab1SKenneth D. Merry {
753ef270ab1SKenneth D. Merry 	int rc = 0;
754aeb665b5SEd Maste 	ocs_mgmt_sfp_result_t *result = ocs_malloc(ocs, sizeof(ocs_mgmt_sfp_result_t),  OCS_M_ZERO | OCS_M_NOWAIT);
755ef270ab1SKenneth D. Merry 
756ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result->semaphore), 0, "get_sfp");
757ef270ab1SKenneth D. Merry 	ocs_lock_init(ocs, &(result->cb_lock), "get_sfp");
758ef270ab1SKenneth D. Merry 
759ef270ab1SKenneth D. Merry 	/* Send the HW command */
760ef270ab1SKenneth D. Merry 	ocs_hw_get_sfp(&ocs->hw, page, ocs_mgmt_sfp_cb, result);
761ef270ab1SKenneth D. Merry 
762ef270ab1SKenneth D. Merry 	/* Wait for semaphore to be signaled when the command completes */
763ef270ab1SKenneth D. Merry 	if (ocs_sem_p(&(result->semaphore), 5 * 1000 * 1000) != 0) {
764ef270ab1SKenneth D. Merry 		/* Timed out, callback will free memory */
765ef270ab1SKenneth D. Merry 		ocs_lock(&(result->cb_lock));
766ef270ab1SKenneth D. Merry 		result->running++;
767ef270ab1SKenneth D. Merry 		if(result->running == 1) {
768ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
769ef270ab1SKenneth D. Merry 			ocs_unlock(&(result->cb_lock));
770ef270ab1SKenneth D. Merry 			return (-ENXIO);
771ef270ab1SKenneth D. Merry 		}
772ef270ab1SKenneth D. Merry 		/* sfp_cb() has already executed, proceed as normal */
773ef270ab1SKenneth D. Merry 		ocs_unlock(&(result->cb_lock));
774ef270ab1SKenneth D. Merry 	}
775ef270ab1SKenneth D. Merry 
776ef270ab1SKenneth D. Merry 	/* Check status */
777ef270ab1SKenneth D. Merry 	if (result->status != 0) {
778ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "read_transceiver_data returned status %d\n",
779ef270ab1SKenneth D. Merry 			     result->status);
780ef270ab1SKenneth D. Merry 		rc = -EFAULT;
781ef270ab1SKenneth D. Merry 	}
782ef270ab1SKenneth D. Merry 
783ef270ab1SKenneth D. Merry 	if (rc == 0) {
784ef270ab1SKenneth D. Merry 		rc = (result->bytes_read > buf_len ? buf_len : result->bytes_read);
785ef270ab1SKenneth D. Merry 		/* Copy the results back to the supplied buffer */
786ef270ab1SKenneth D. Merry 		ocs_memcpy(buf, result->page_data, rc);
787ef270ab1SKenneth D. Merry 	}
788ef270ab1SKenneth D. Merry 
789ef270ab1SKenneth D. Merry 	ocs_free(ocs, result, sizeof(ocs_mgmt_sfp_result_t));
790ef270ab1SKenneth D. Merry 	return rc;
791ef270ab1SKenneth D. Merry }
792ef270ab1SKenneth D. Merry 
793ef270ab1SKenneth D. Merry static int32_t
ocs_mgmt_force_assert(ocs_t * ocs,char * name,void * buf,uint32_t buf_len,void * arg_out,uint32_t arg_out_length)794ef270ab1SKenneth D. Merry ocs_mgmt_force_assert(ocs_t *ocs, char *name, void *buf, uint32_t buf_len, void *arg_out, uint32_t arg_out_length)
795ef270ab1SKenneth D. Merry {
796ef270ab1SKenneth D. Merry 	ocs_assert(FALSE, 0);
797ef270ab1SKenneth D. Merry }
798ef270ab1SKenneth D. Merry 
799ef270ab1SKenneth D. Merry static void
get_nodes_count(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)800ef270ab1SKenneth D. Merry get_nodes_count(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
801ef270ab1SKenneth D. Merry {
802ef270ab1SKenneth D. Merry 	ocs_xport_t *xport = ocs->xport;
803ef270ab1SKenneth D. Merry 
804ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "nodes_count", "%d", xport->nodes_count);
805ef270ab1SKenneth D. Merry }
806ef270ab1SKenneth D. Merry 
807ef270ab1SKenneth D. Merry static void
get_driver_version(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)808ef270ab1SKenneth D. Merry get_driver_version(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
809ef270ab1SKenneth D. Merry {
810ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "driver_version", ocs->driver_version);
811ef270ab1SKenneth D. Merry }
812ef270ab1SKenneth D. Merry 
813ef270ab1SKenneth D. Merry static void
get_desc(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)814ef270ab1SKenneth D. Merry get_desc(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
815ef270ab1SKenneth D. Merry {
816ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "desc", ocs->desc);
817ef270ab1SKenneth D. Merry }
818ef270ab1SKenneth D. Merry 
819ef270ab1SKenneth D. Merry static void
get_fw_rev(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)820ef270ab1SKenneth D. Merry get_fw_rev(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
821ef270ab1SKenneth D. Merry {
822ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "fw_rev", ocs_hw_get_ptr(&ocs->hw, OCS_HW_FW_REV));
823ef270ab1SKenneth D. Merry }
824ef270ab1SKenneth D. Merry 
825ef270ab1SKenneth D. Merry static void
get_fw_rev2(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)826ef270ab1SKenneth D. Merry get_fw_rev2(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
827ef270ab1SKenneth D. Merry {
828ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "fw_rev2", ocs_hw_get_ptr(&ocs->hw, OCS_HW_FW_REV2));
829ef270ab1SKenneth D. Merry }
830ef270ab1SKenneth D. Merry 
831ef270ab1SKenneth D. Merry static void
get_ipl(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)832ef270ab1SKenneth D. Merry get_ipl(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
833ef270ab1SKenneth D. Merry {
834ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "ipl", ocs_hw_get_ptr(&ocs->hw, OCS_HW_IPL));
835ef270ab1SKenneth D. Merry }
836ef270ab1SKenneth D. Merry 
837ef270ab1SKenneth D. Merry static void
get_hw_rev1(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)838ef270ab1SKenneth D. Merry get_hw_rev1(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
839ef270ab1SKenneth D. Merry {
840ef270ab1SKenneth D. Merry 	uint32_t value;
841ef270ab1SKenneth D. Merry 
842ef270ab1SKenneth D. Merry 	ocs_hw_get(&ocs->hw, OCS_HW_HW_REV1, &value);
843ef270ab1SKenneth D. Merry 
844ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hw_rev1", "%u", value);
845ef270ab1SKenneth D. Merry }
846ef270ab1SKenneth D. Merry 
847ef270ab1SKenneth D. Merry static void
get_hw_rev2(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)848ef270ab1SKenneth D. Merry get_hw_rev2(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
849ef270ab1SKenneth D. Merry {
850ef270ab1SKenneth D. Merry 	uint32_t value;
851ef270ab1SKenneth D. Merry 
852ef270ab1SKenneth D. Merry 	ocs_hw_get(&ocs->hw, OCS_HW_HW_REV2, &value);
853ef270ab1SKenneth D. Merry 
854ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hw_rev2", "%u", value);
855ef270ab1SKenneth D. Merry }
856ef270ab1SKenneth D. Merry 
857ef270ab1SKenneth D. Merry static void
get_hw_rev3(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)858ef270ab1SKenneth D. Merry get_hw_rev3(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
859ef270ab1SKenneth D. Merry {
860ef270ab1SKenneth D. Merry 	uint32_t value;
861ef270ab1SKenneth D. Merry 	ocs_hw_get(&ocs->hw, OCS_HW_HW_REV3, &value);
862ef270ab1SKenneth D. Merry 
863ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "hw_rev3", "%u", value);
864ef270ab1SKenneth D. Merry }
865ef270ab1SKenneth D. Merry 
866ef270ab1SKenneth D. Merry static void
get_wwnn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)867ef270ab1SKenneth D. Merry get_wwnn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
868ef270ab1SKenneth D. Merry {
869ef270ab1SKenneth D. Merry 	uint64_t *wwnn;
870ef270ab1SKenneth D. Merry 
871ef270ab1SKenneth D. Merry 	wwnn = ocs_hw_get_ptr(&ocs->hw, OCS_HW_WWN_NODE);
872ef270ab1SKenneth D. Merry 
873ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "wwnn", "0x%llx", (unsigned long long)ocs_htobe64(*wwnn));
874ef270ab1SKenneth D. Merry }
875ef270ab1SKenneth D. Merry 
876ef270ab1SKenneth D. Merry static void
get_wwpn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)877ef270ab1SKenneth D. Merry get_wwpn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
878ef270ab1SKenneth D. Merry {
879ef270ab1SKenneth D. Merry 	uint64_t *wwpn;
880ef270ab1SKenneth D. Merry 
881ef270ab1SKenneth D. Merry 	wwpn = ocs_hw_get_ptr(&ocs->hw, OCS_HW_WWN_PORT);
882ef270ab1SKenneth D. Merry 
883ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "wwpn", "0x%llx", (unsigned long long)ocs_htobe64(*wwpn));
884ef270ab1SKenneth D. Merry }
885ef270ab1SKenneth D. Merry 
886ef270ab1SKenneth D. Merry static void
get_fcid(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)887ef270ab1SKenneth D. Merry get_fcid(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
888ef270ab1SKenneth D. Merry {
889ef270ab1SKenneth D. Merry 
890ef270ab1SKenneth D. Merry 	if (ocs->domain && ocs->domain->attached) {
891ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fc_id", "0x%06x",
892ef270ab1SKenneth D. Merry 						ocs->domain->sport->fc_id);
893ef270ab1SKenneth D. Merry 	} else {
894ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "fc_id", "UNKNOWN");
895ef270ab1SKenneth D. Merry 	}
896ef270ab1SKenneth D. Merry 
897ef270ab1SKenneth D. Merry }
898ef270ab1SKenneth D. Merry 
899ef270ab1SKenneth D. Merry static void
get_sn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)900ef270ab1SKenneth D. Merry get_sn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
901ef270ab1SKenneth D. Merry {
902ef270ab1SKenneth D. Merry 	uint8_t *pserial;
903ef270ab1SKenneth D. Merry 	uint32_t len;
904ef270ab1SKenneth D. Merry 	char sn_buf[256];
905ef270ab1SKenneth D. Merry 
906ef270ab1SKenneth D. Merry 	pserial = ocs_scsi_get_property_ptr(ocs, OCS_SCSI_SERIALNUMBER);
907ef270ab1SKenneth D. Merry 	if (pserial) {
908ef270ab1SKenneth D. Merry 		len = *pserial ++;
909ef270ab1SKenneth D. Merry 		strncpy(sn_buf, (char*)pserial, len);
910ef270ab1SKenneth D. Merry 		sn_buf[len] = '\0';
911ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "sn", sn_buf);
912ef270ab1SKenneth D. Merry 	}
913ef270ab1SKenneth D. Merry }
914ef270ab1SKenneth D. Merry 
915ef270ab1SKenneth D. Merry static void
get_pn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)916ef270ab1SKenneth D. Merry get_pn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
917ef270ab1SKenneth D. Merry {
918ef270ab1SKenneth D. Merry 	uint8_t *pserial;
919ef270ab1SKenneth D. Merry 	uint32_t len;
920ef270ab1SKenneth D. Merry 	char sn_buf[256];
921ef270ab1SKenneth D. Merry 
922ef270ab1SKenneth D. Merry 	pserial = ocs_scsi_get_property_ptr(ocs, OCS_SCSI_PARTNUMBER);
923ef270ab1SKenneth D. Merry 	if (pserial) {
924ef270ab1SKenneth D. Merry 		len = *pserial ++;
925ef270ab1SKenneth D. Merry 		strncpy(sn_buf, (char*)pserial, len);
926ef270ab1SKenneth D. Merry 		sn_buf[len] = '\0';
927ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "pn", sn_buf);
928ef270ab1SKenneth D. Merry 	} else {
929ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "pn", ocs->model);
930ef270ab1SKenneth D. Merry 	}
931ef270ab1SKenneth D. Merry }
932ef270ab1SKenneth D. Merry 
933ef270ab1SKenneth D. Merry static void
get_sli4_intf_reg(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)934ef270ab1SKenneth D. Merry get_sli4_intf_reg(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
935ef270ab1SKenneth D. Merry {
936ef270ab1SKenneth D. Merry 
937ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "sli4_intf_reg", "0x%04x",
938ef270ab1SKenneth D. Merry 		ocs_config_read32(ocs, SLI4_INTF_REG));
939ef270ab1SKenneth D. Merry }
940ef270ab1SKenneth D. Merry 
941ef270ab1SKenneth D. Merry static void
get_phy_port_num(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)942ef270ab1SKenneth D. Merry get_phy_port_num(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
943ef270ab1SKenneth D. Merry {
944ef270ab1SKenneth D. Merry 	char *phy_port = NULL;
945ef270ab1SKenneth D. Merry 
946ef270ab1SKenneth D. Merry 	phy_port = ocs_scsi_get_property_ptr(ocs, OCS_SCSI_PORTNUM);
947ef270ab1SKenneth D. Merry 	if (phy_port) {
948ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "phy_port_num", phy_port);
949ef270ab1SKenneth D. Merry 	} else {
950ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "phy_port_num", "unknown");
951ef270ab1SKenneth D. Merry 	}
952ef270ab1SKenneth D. Merry }
953ef270ab1SKenneth D. Merry static void
get_asic_id(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)954ef270ab1SKenneth D. Merry get_asic_id(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
955ef270ab1SKenneth D. Merry {
956ef270ab1SKenneth D. Merry 
957ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "asic_id_reg", "0x%04x",
958ef270ab1SKenneth D. Merry 		ocs_config_read32(ocs, SLI4_ASIC_ID_REG));
959ef270ab1SKenneth D. Merry }
960ef270ab1SKenneth D. Merry 
961ef270ab1SKenneth D. Merry static void
get_chip_type(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)962ef270ab1SKenneth D. Merry get_chip_type(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
963ef270ab1SKenneth D. Merry {
964ef270ab1SKenneth D. Merry 	uint32_t family;
965ef270ab1SKenneth D. Merry 	uint32_t asic_id;
966ef270ab1SKenneth D. Merry 	uint32_t asic_gen_num;
967ef270ab1SKenneth D. Merry 	uint32_t asic_rev_num;
968ef270ab1SKenneth D. Merry 	uint32_t rev_id;
969ef270ab1SKenneth D. Merry 	char result_buf[80];
970ef270ab1SKenneth D. Merry 	char tmp_buf[80];
971ef270ab1SKenneth D. Merry 
972ef270ab1SKenneth D. Merry 	family = (ocs_config_read32(ocs, SLI4_INTF_REG) & 0x00000f00) >> 8;
973ef270ab1SKenneth D. Merry 	asic_id = ocs_config_read32(ocs, SLI4_ASIC_ID_REG);
974ef270ab1SKenneth D. Merry 	asic_rev_num = asic_id & 0xff;
975ef270ab1SKenneth D. Merry 	asic_gen_num = (asic_id & 0xff00) >> 8;
976ef270ab1SKenneth D. Merry 
977ef270ab1SKenneth D. Merry 	rev_id = ocs_config_read32(ocs, SLI4_PCI_CLASS_REVISION) & 0xff;
978ef270ab1SKenneth D. Merry 
979ef270ab1SKenneth D. Merry 	switch(family) {
980ef270ab1SKenneth D. Merry 	case 0x00:
981ef270ab1SKenneth D. Merry 		/* BE2 */
982ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf,  "BE2 A", sizeof(result_buf));
983ef270ab1SKenneth D. Merry 		ocs_snprintf(tmp_buf, 2, "%d", rev_id);
984ef270ab1SKenneth D. Merry 		strcat(result_buf, tmp_buf);
985ef270ab1SKenneth D. Merry 		break;
986ef270ab1SKenneth D. Merry 	case 0x01:
987ef270ab1SKenneth D. Merry 		/* BE3 */
988ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf, "BE3", sizeof(result_buf));
989ef270ab1SKenneth D. Merry 		if (rev_id >= 0x10) {
990ef270ab1SKenneth D. Merry 			strcat(result_buf, "-R");
991ef270ab1SKenneth D. Merry 		}
992ef270ab1SKenneth D. Merry 		ocs_snprintf(tmp_buf, 3, " %c", ((rev_id & 0xf0) >> 4) + 'A');
993ef270ab1SKenneth D. Merry 		strcat(result_buf, tmp_buf);
994ef270ab1SKenneth D. Merry 		ocs_snprintf(tmp_buf, 2, "%d", rev_id & 0x0f);
995ef270ab1SKenneth D. Merry 		strcat(result_buf, tmp_buf);
996ef270ab1SKenneth D. Merry 		break;
997ef270ab1SKenneth D. Merry 	case 0x02:
998ef270ab1SKenneth D. Merry 		/* Skyhawk A0 */
999ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf, "Skyhawk A0", sizeof(result_buf));
1000ef270ab1SKenneth D. Merry 		break;
1001ef270ab1SKenneth D. Merry 	case 0x0a:
1002ef270ab1SKenneth D. Merry 		/* Lancer A0 */
1003ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf, "Lancer A", sizeof(result_buf));
1004ef270ab1SKenneth D. Merry 		ocs_snprintf(tmp_buf, 2, "%d", rev_id & 0x0f);
1005ef270ab1SKenneth D. Merry 		strcat(result_buf, tmp_buf);
1006ef270ab1SKenneth D. Merry 		break;
1007ef270ab1SKenneth D. Merry 	case 0x0b:
1008ef270ab1SKenneth D. Merry 		/* Lancer B0 or D0 */
1009ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf, "Lancer", sizeof(result_buf));
1010ef270ab1SKenneth D. Merry 		ocs_snprintf(tmp_buf, 3, " %c", ((rev_id & 0xf0) >> 4) + 'A');
1011ef270ab1SKenneth D. Merry 		strcat(result_buf, tmp_buf);
1012ef270ab1SKenneth D. Merry 		ocs_snprintf(tmp_buf, 2, "%d", rev_id & 0x0f);
1013ef270ab1SKenneth D. Merry 		strcat(result_buf, tmp_buf);
1014ef270ab1SKenneth D. Merry 		break;
1015ef270ab1SKenneth D. Merry 	case 0x0c:
1016ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf, "Lancer G6", sizeof(result_buf));
1017ef270ab1SKenneth D. Merry 		break;
1018ef270ab1SKenneth D. Merry 	case 0x0f:
1019ef270ab1SKenneth D. Merry 		/* Refer to ASIC_ID */
1020ef270ab1SKenneth D. Merry 		switch(asic_gen_num) {
1021ef270ab1SKenneth D. Merry 		case 0x00:
1022ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "BE2", sizeof(result_buf));
1023ef270ab1SKenneth D. Merry 			break;
1024ef270ab1SKenneth D. Merry 		case 0x03:
1025ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "BE3-R", sizeof(result_buf));
1026ef270ab1SKenneth D. Merry 			break;
1027ef270ab1SKenneth D. Merry 		case 0x04:
1028ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "Skyhawk-R", sizeof(result_buf));
1029ef270ab1SKenneth D. Merry 			break;
1030ef270ab1SKenneth D. Merry 		case 0x05:
1031ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "Corsair", sizeof(result_buf));
1032ef270ab1SKenneth D. Merry 			break;
1033ef270ab1SKenneth D. Merry 		case 0x0b:
1034ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "Lancer", sizeof(result_buf));
1035ef270ab1SKenneth D. Merry 			break;
1036ef270ab1SKenneth D. Merry 		case 0x0c:
1037ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "LancerG6", sizeof(result_buf));
1038ef270ab1SKenneth D. Merry 			break;
1039ef270ab1SKenneth D. Merry 		default:
1040ef270ab1SKenneth D. Merry 			ocs_strncpy(result_buf, "Unknown", sizeof(result_buf));
1041ef270ab1SKenneth D. Merry 		}
1042ef270ab1SKenneth D. Merry 		if (ocs_strcmp(result_buf, "Unknown") != 0) {
1043ef270ab1SKenneth D. Merry 			ocs_snprintf(tmp_buf, 3, " %c", ((asic_rev_num & 0xf0) >> 4) + 'A');
1044ef270ab1SKenneth D. Merry 			strcat(result_buf, tmp_buf);
1045ef270ab1SKenneth D. Merry 			ocs_snprintf(tmp_buf, 2, "%d", asic_rev_num & 0x0f);
1046ef270ab1SKenneth D. Merry 			strcat(result_buf, tmp_buf);
1047ef270ab1SKenneth D. Merry 		}
1048ef270ab1SKenneth D. Merry 		break;
1049ef270ab1SKenneth D. Merry 	default:
1050ef270ab1SKenneth D. Merry 		ocs_strncpy(result_buf, "Unknown", sizeof(result_buf));
1051ef270ab1SKenneth D. Merry 	}
1052ef270ab1SKenneth D. Merry 
1053ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "chip_type", result_buf);
1054ef270ab1SKenneth D. Merry 
1055ef270ab1SKenneth D. Merry }
1056ef270ab1SKenneth D. Merry 
1057ef270ab1SKenneth D. Merry static void
get_pci_vendor(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1058ef270ab1SKenneth D. Merry get_pci_vendor(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1059ef270ab1SKenneth D. Merry {
1060ef270ab1SKenneth D. Merry 
1061ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "pci_vendor", "0x%04x", ocs->pci_vendor);
1062ef270ab1SKenneth D. Merry }
1063ef270ab1SKenneth D. Merry 
1064ef270ab1SKenneth D. Merry static void
get_pci_device(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1065ef270ab1SKenneth D. Merry get_pci_device(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1066ef270ab1SKenneth D. Merry {
1067ef270ab1SKenneth D. Merry 
1068ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "pci_device", "0x%04x", ocs->pci_device);
1069ef270ab1SKenneth D. Merry }
1070ef270ab1SKenneth D. Merry 
1071ef270ab1SKenneth D. Merry static void
get_pci_subsystem_vendor(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1072ef270ab1SKenneth D. Merry get_pci_subsystem_vendor(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1073ef270ab1SKenneth D. Merry {
1074ef270ab1SKenneth D. Merry 
1075ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "pci_subsystem_vendor", "0x%04x", ocs->pci_subsystem_vendor);
1076ef270ab1SKenneth D. Merry }
1077ef270ab1SKenneth D. Merry 
1078ef270ab1SKenneth D. Merry static void
get_pci_subsystem_device(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1079ef270ab1SKenneth D. Merry get_pci_subsystem_device(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1080ef270ab1SKenneth D. Merry {
1081ef270ab1SKenneth D. Merry 
1082ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "pci_subsystem_device", "0x%04x", ocs->pci_subsystem_device);
1083ef270ab1SKenneth D. Merry }
1084ef270ab1SKenneth D. Merry 
1085ef270ab1SKenneth D. Merry static void
get_tgt_rscn_delay(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1086ef270ab1SKenneth D. Merry get_tgt_rscn_delay(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1087ef270ab1SKenneth D. Merry {
1088ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "tgt_rscn_delay", "%ld", (unsigned long)ocs->tgt_rscn_delay_msec / 1000);
1089ef270ab1SKenneth D. Merry }
1090ef270ab1SKenneth D. Merry 
1091ef270ab1SKenneth D. Merry static void
get_tgt_rscn_period(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1092ef270ab1SKenneth D. Merry get_tgt_rscn_period(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1093ef270ab1SKenneth D. Merry {
1094ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "tgt_rscn_period", "%ld", (unsigned long)ocs->tgt_rscn_period_msec / 1000);
1095ef270ab1SKenneth D. Merry }
1096ef270ab1SKenneth D. Merry 
1097ef270ab1SKenneth D. Merry static void
get_inject_drop_cmd(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1098ef270ab1SKenneth D. Merry get_inject_drop_cmd(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1099ef270ab1SKenneth D. Merry {
1100ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "inject_drop_cmd", "%d",
1101ef270ab1SKenneth D. Merry 			(ocs->err_injection == INJECT_DROP_CMD ? 1:0));
1102ef270ab1SKenneth D. Merry }
1103ef270ab1SKenneth D. Merry 
1104ef270ab1SKenneth D. Merry static void
get_inject_free_drop_cmd(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1105ef270ab1SKenneth D. Merry get_inject_free_drop_cmd(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1106ef270ab1SKenneth D. Merry {
1107ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "inject_free_drop_cmd", "%d",
1108ef270ab1SKenneth D. Merry 			(ocs->err_injection == INJECT_FREE_DROPPED ? 1:0));
1109ef270ab1SKenneth D. Merry }
1110ef270ab1SKenneth D. Merry 
1111ef270ab1SKenneth D. Merry static void
get_inject_drop_data(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1112ef270ab1SKenneth D. Merry get_inject_drop_data(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1113ef270ab1SKenneth D. Merry {
1114ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "inject_drop_data", "%d",
1115ef270ab1SKenneth D. Merry 			(ocs->err_injection == INJECT_DROP_DATA ? 1:0));
1116ef270ab1SKenneth D. Merry }
1117ef270ab1SKenneth D. Merry 
1118ef270ab1SKenneth D. Merry static void
get_inject_drop_resp(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1119ef270ab1SKenneth D. Merry get_inject_drop_resp(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1120ef270ab1SKenneth D. Merry {
1121ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "inject_drop_resp", "%d",
1122ef270ab1SKenneth D. Merry 			(ocs->err_injection == INJECT_DROP_RESP ? 1:0));
1123ef270ab1SKenneth D. Merry }
1124ef270ab1SKenneth D. Merry 
1125ef270ab1SKenneth D. Merry static void
get_cmd_err_inject(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1126ef270ab1SKenneth D. Merry get_cmd_err_inject(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1127ef270ab1SKenneth D. Merry {
1128ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "cmd_err_inject", "0x%02x", ocs->cmd_err_inject);
1129ef270ab1SKenneth D. Merry }
1130ef270ab1SKenneth D. Merry 
1131ef270ab1SKenneth D. Merry static void
get_cmd_delay_value(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1132ef270ab1SKenneth D. Merry get_cmd_delay_value(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1133ef270ab1SKenneth D. Merry {
1134ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "cmd_delay_value", "%ld", (unsigned long)ocs->delay_value_msec);
1135ef270ab1SKenneth D. Merry }
1136ef270ab1SKenneth D. Merry 
1137ef270ab1SKenneth D. Merry static void
get_businfo(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1138ef270ab1SKenneth D. Merry get_businfo(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1139ef270ab1SKenneth D. Merry {
1140ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "businfo", ocs->businfo);
1141ef270ab1SKenneth D. Merry }
1142ef270ab1SKenneth D. Merry 
1143ef270ab1SKenneth D. Merry static void
get_sfp_a0(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1144ef270ab1SKenneth D. Merry get_sfp_a0(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1145ef270ab1SKenneth D. Merry {
1146ef270ab1SKenneth D. Merry 	uint8_t *page_data;
1147ef270ab1SKenneth D. Merry 	char *buf;
1148ef270ab1SKenneth D. Merry 	int i;
1149ef270ab1SKenneth D. Merry 	int32_t bytes_read;
1150ef270ab1SKenneth D. Merry 
1151ef270ab1SKenneth D. Merry 	page_data = ocs_malloc(ocs, SFP_PAGE_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
1152ef270ab1SKenneth D. Merry 	if (page_data == NULL) {
1153ef270ab1SKenneth D. Merry 		return;
1154ef270ab1SKenneth D. Merry 	}
1155ef270ab1SKenneth D. Merry 
1156ef270ab1SKenneth D. Merry 	buf = ocs_malloc(ocs, (SFP_PAGE_SIZE * 3) + 1, OCS_M_ZERO | OCS_M_NOWAIT);
1157ef270ab1SKenneth D. Merry 	if (buf == NULL) {
1158ef270ab1SKenneth D. Merry 		ocs_free(ocs, page_data, SFP_PAGE_SIZE);
1159ef270ab1SKenneth D. Merry 		return;
1160ef270ab1SKenneth D. Merry 	}
1161ef270ab1SKenneth D. Merry 
1162ef270ab1SKenneth D. Merry 	bytes_read = ocs_mgmt_get_sfp(ocs, 0xa0, page_data, SFP_PAGE_SIZE);
1163ef270ab1SKenneth D. Merry 
1164ef270ab1SKenneth D. Merry 	if (bytes_read <= 0) {
1165ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "sfp_a0", "(unknown)");
1166ef270ab1SKenneth D. Merry 	} else {
1167ef270ab1SKenneth D. Merry 		char *d = buf;
1168ef270ab1SKenneth D. Merry 		uint8_t *s = page_data;
1169ef270ab1SKenneth D. Merry 		int buffer_remaining = (SFP_PAGE_SIZE * 3) + 1;
1170ef270ab1SKenneth D. Merry 		int bytes_added;
1171ef270ab1SKenneth D. Merry 
1172ef270ab1SKenneth D. Merry 		for (i = 0; i < bytes_read; i++) {
1173ef270ab1SKenneth D. Merry 			bytes_added = ocs_snprintf(d, buffer_remaining, "%02x ", *s);
1174ef270ab1SKenneth D. Merry 			++s;
1175ef270ab1SKenneth D. Merry 			d += bytes_added;
1176ef270ab1SKenneth D. Merry 			buffer_remaining -= bytes_added;
1177ef270ab1SKenneth D. Merry 		}
1178ef270ab1SKenneth D. Merry 		*d = '\0';
1179ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "sfp_a0", buf);
1180ef270ab1SKenneth D. Merry 	}
1181ef270ab1SKenneth D. Merry 
1182ef270ab1SKenneth D. Merry 	ocs_free(ocs, page_data, SFP_PAGE_SIZE);
1183ef270ab1SKenneth D. Merry 	ocs_free(ocs, buf, (3 * SFP_PAGE_SIZE) + 1);
1184ef270ab1SKenneth D. Merry }
1185ef270ab1SKenneth D. Merry 
1186ef270ab1SKenneth D. Merry static void
get_sfp_a2(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1187ef270ab1SKenneth D. Merry get_sfp_a2(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1188ef270ab1SKenneth D. Merry {
1189ef270ab1SKenneth D. Merry 	uint8_t *page_data;
1190ef270ab1SKenneth D. Merry 	char *buf;
1191ef270ab1SKenneth D. Merry 	int i;
1192ef270ab1SKenneth D. Merry 	int32_t bytes_read;
1193ef270ab1SKenneth D. Merry 
1194ef270ab1SKenneth D. Merry 	page_data = ocs_malloc(ocs, SFP_PAGE_SIZE, OCS_M_ZERO | OCS_M_NOWAIT);
1195ef270ab1SKenneth D. Merry 	if (page_data == NULL) {
1196ef270ab1SKenneth D. Merry 		return;
1197ef270ab1SKenneth D. Merry 	}
1198ef270ab1SKenneth D. Merry 
1199ef270ab1SKenneth D. Merry 	buf = ocs_malloc(ocs, (SFP_PAGE_SIZE * 3) + 1, OCS_M_ZERO | OCS_M_NOWAIT);
1200ef270ab1SKenneth D. Merry 	if (buf == NULL) {
1201ef270ab1SKenneth D. Merry 		ocs_free(ocs, page_data, SFP_PAGE_SIZE);
1202ef270ab1SKenneth D. Merry 		return;
1203ef270ab1SKenneth D. Merry 	}
1204ef270ab1SKenneth D. Merry 
1205ef270ab1SKenneth D. Merry 	bytes_read = ocs_mgmt_get_sfp(ocs, 0xa2, page_data, SFP_PAGE_SIZE);
1206ef270ab1SKenneth D. Merry 
1207ef270ab1SKenneth D. Merry 	if (bytes_read <= 0) {
1208ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "sfp_a2", "(unknown)");
1209ef270ab1SKenneth D. Merry 	} else {
1210ef270ab1SKenneth D. Merry 		char *d = buf;
1211ef270ab1SKenneth D. Merry 		uint8_t *s = page_data;
1212ef270ab1SKenneth D. Merry 		int buffer_remaining = (SFP_PAGE_SIZE * 3) + 1;
1213ef270ab1SKenneth D. Merry 		int bytes_added;
1214ef270ab1SKenneth D. Merry 
1215ef270ab1SKenneth D. Merry 		for (i=0; i < bytes_read; i++) {
1216ef270ab1SKenneth D. Merry 			bytes_added = ocs_snprintf(d, buffer_remaining, "%02x ", *s);
1217ef270ab1SKenneth D. Merry 			++s;
1218ef270ab1SKenneth D. Merry 			d += bytes_added;
1219ef270ab1SKenneth D. Merry 			buffer_remaining -= bytes_added;
1220ef270ab1SKenneth D. Merry 		}
1221ef270ab1SKenneth D. Merry 		*d = '\0';
1222ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "sfp_a2", buf);
1223ef270ab1SKenneth D. Merry 	}
1224ef270ab1SKenneth D. Merry 
1225ef270ab1SKenneth D. Merry 	ocs_free(ocs, page_data, SFP_PAGE_SIZE);
1226ef270ab1SKenneth D. Merry 	ocs_free(ocs, buf, (3 * SFP_PAGE_SIZE) + 1);
1227ef270ab1SKenneth D. Merry }
1228ef270ab1SKenneth D. Merry 
1229ef270ab1SKenneth D. Merry static void
get_debug_mq_dump(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1230ef270ab1SKenneth D. Merry get_debug_mq_dump(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1231ef270ab1SKenneth D. Merry {
1232ef270ab1SKenneth D. Merry 
1233ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RW, "debug_mq_dump",
1234ef270ab1SKenneth D. Merry 		ocs_debug_is_enabled(OCS_DEBUG_ENABLE_MQ_DUMP));
1235ef270ab1SKenneth D. Merry }
1236ef270ab1SKenneth D. Merry 
1237ef270ab1SKenneth D. Merry static void
get_debug_cq_dump(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1238ef270ab1SKenneth D. Merry get_debug_cq_dump(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1239ef270ab1SKenneth D. Merry {
1240ef270ab1SKenneth D. Merry 
1241ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RW, "debug_cq_dump",
1242ef270ab1SKenneth D. Merry 		ocs_debug_is_enabled(OCS_DEBUG_ENABLE_CQ_DUMP));
1243ef270ab1SKenneth D. Merry }
1244ef270ab1SKenneth D. Merry 
1245ef270ab1SKenneth D. Merry static void
get_debug_wq_dump(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1246ef270ab1SKenneth D. Merry get_debug_wq_dump(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1247ef270ab1SKenneth D. Merry {
1248ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RW, "debug_wq_dump",
1249ef270ab1SKenneth D. Merry 		ocs_debug_is_enabled(OCS_DEBUG_ENABLE_WQ_DUMP));
1250ef270ab1SKenneth D. Merry }
1251ef270ab1SKenneth D. Merry 
1252ef270ab1SKenneth D. Merry static void
get_debug_eq_dump(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1253ef270ab1SKenneth D. Merry get_debug_eq_dump(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1254ef270ab1SKenneth D. Merry {
1255ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_boolean(textbuf, MGMT_MODE_RW, "debug_eq_dump",
1256ef270ab1SKenneth D. Merry 		ocs_debug_is_enabled(OCS_DEBUG_ENABLE_EQ_DUMP));
1257ef270ab1SKenneth D. Merry }
1258ef270ab1SKenneth D. Merry 
1259ef270ab1SKenneth D. Merry static void
get_logmask(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1260ef270ab1SKenneth D. Merry get_logmask(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1261ef270ab1SKenneth D. Merry {
1262ef270ab1SKenneth D. Merry 
1263ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "logmask", "0x%02x", ocs->logmask);
1264ef270ab1SKenneth D. Merry 
1265ef270ab1SKenneth D. Merry }
1266ef270ab1SKenneth D. Merry 
1267ef270ab1SKenneth D. Merry static void
get_loglevel(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1268ef270ab1SKenneth D. Merry get_loglevel(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1269ef270ab1SKenneth D. Merry {
1270ef270ab1SKenneth D. Merry 
1271ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "loglevel", "%d", loglevel);
1272ef270ab1SKenneth D. Merry 
1273ef270ab1SKenneth D. Merry }
1274ef270ab1SKenneth D. Merry 
1275ef270ab1SKenneth D. Merry static void
get_current_speed(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1276ef270ab1SKenneth D. Merry get_current_speed(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1277ef270ab1SKenneth D. Merry {
1278ef270ab1SKenneth D. Merry 	uint32_t value;
1279ef270ab1SKenneth D. Merry 
1280ef270ab1SKenneth D. Merry 	ocs_hw_get(&(ocs->hw), OCS_HW_LINK_SPEED, &value);
1281ef270ab1SKenneth D. Merry 
1282ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "current_speed", "%d", value);
1283ef270ab1SKenneth D. Merry }
1284ef270ab1SKenneth D. Merry 
1285ef270ab1SKenneth D. Merry static void
get_configured_speed(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1286ef270ab1SKenneth D. Merry get_configured_speed(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1287ef270ab1SKenneth D. Merry {
1288ef270ab1SKenneth D. Merry 	uint32_t value;
1289ef270ab1SKenneth D. Merry 
1290ef270ab1SKenneth D. Merry 	ocs_hw_get(&(ocs->hw), OCS_HW_LINK_CONFIG_SPEED, &value);
1291ef270ab1SKenneth D. Merry 	if (value == 0) {
1292ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "configured_speed", "auto");
1293ef270ab1SKenneth D. Merry 	} else {
1294ef270ab1SKenneth D. Merry 		ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "configured_speed", "%d", value);
1295ef270ab1SKenneth D. Merry 	}
1296ef270ab1SKenneth D. Merry 
1297ef270ab1SKenneth D. Merry }
1298ef270ab1SKenneth D. Merry 
1299ef270ab1SKenneth D. Merry static void
get_current_topology(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1300ef270ab1SKenneth D. Merry get_current_topology(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1301ef270ab1SKenneth D. Merry {
1302ef270ab1SKenneth D. Merry 	uint32_t value;
1303ef270ab1SKenneth D. Merry 
1304ef270ab1SKenneth D. Merry 	ocs_hw_get(&(ocs->hw), OCS_HW_TOPOLOGY, &value);
1305ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "current_topology", "%d", value);
1306ef270ab1SKenneth D. Merry 
1307ef270ab1SKenneth D. Merry }
1308ef270ab1SKenneth D. Merry 
1309ef270ab1SKenneth D. Merry static void
get_configured_topology(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1310ef270ab1SKenneth D. Merry get_configured_topology(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1311ef270ab1SKenneth D. Merry {
1312ef270ab1SKenneth D. Merry 	uint32_t value;
1313ef270ab1SKenneth D. Merry 
1314ef270ab1SKenneth D. Merry 	ocs_hw_get(&(ocs->hw), OCS_HW_CONFIG_TOPOLOGY, &value);
1315ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "configured_topology", "%d", value);
1316ef270ab1SKenneth D. Merry 
1317ef270ab1SKenneth D. Merry }
1318ef270ab1SKenneth D. Merry 
1319ef270ab1SKenneth D. Merry static void
get_current_link_state(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1320ef270ab1SKenneth D. Merry get_current_link_state(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1321ef270ab1SKenneth D. Merry {
1322ef270ab1SKenneth D. Merry 	ocs_xport_stats_t value;
1323ef270ab1SKenneth D. Merry 
1324ef270ab1SKenneth D. Merry 	if (ocs_xport_status(ocs->xport, OCS_XPORT_PORT_STATUS, &value) == 0) {
1325ef270ab1SKenneth D. Merry 		if (value.value == OCS_XPORT_PORT_ONLINE) {
1326ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "current_link_state", "online");
1327ef270ab1SKenneth D. Merry 		} else {
1328ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "current_link_state", "offline");
1329ef270ab1SKenneth D. Merry 		}
1330ef270ab1SKenneth D. Merry 	}
1331ef270ab1SKenneth D. Merry }
1332ef270ab1SKenneth D. Merry 
1333ef270ab1SKenneth D. Merry static void
get_configured_link_state(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1334ef270ab1SKenneth D. Merry get_configured_link_state(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1335ef270ab1SKenneth D. Merry {
1336ef270ab1SKenneth D. Merry 	ocs_xport_stats_t value;
1337ef270ab1SKenneth D. Merry 
1338ef270ab1SKenneth D. Merry 	if (ocs_xport_status(ocs->xport, OCS_XPORT_CONFIG_PORT_STATUS, &value) == 0) {
1339ef270ab1SKenneth D. Merry 		if (value.value == OCS_XPORT_PORT_ONLINE) {
1340ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "configured_link_state", "online");
1341ef270ab1SKenneth D. Merry 		} else {
1342ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "configured_link_state", "offline");
1343ef270ab1SKenneth D. Merry 		}
1344ef270ab1SKenneth D. Merry 	}
1345ef270ab1SKenneth D. Merry }
1346ef270ab1SKenneth D. Merry 
1347ef270ab1SKenneth D. Merry /**
1348ef270ab1SKenneth D. Merry  * @brief HW link config enum to mgmt string value mapping.
1349ef270ab1SKenneth D. Merry  *
1350ef270ab1SKenneth D. Merry  * This structure provides a mapping from the ocs_hw_linkcfg_e
1351ef270ab1SKenneth D. Merry  * enum (enum exposed for the OCS_HW_PORT_SET_LINK_CONFIG port
1352ef270ab1SKenneth D. Merry  * control) to the mgmt string that is passed in by the mgmt application
1353ef270ab1SKenneth D. Merry  * (elxsdkutil).
1354ef270ab1SKenneth D. Merry  */
1355ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_linkcfg_map_s {
1356ef270ab1SKenneth D. Merry 	ocs_hw_linkcfg_e linkcfg;
1357ef270ab1SKenneth D. Merry 	const char *mgmt_str;
1358ef270ab1SKenneth D. Merry } ocs_mgmt_linkcfg_map_t;
1359ef270ab1SKenneth D. Merry 
1360ef270ab1SKenneth D. Merry static ocs_mgmt_linkcfg_map_t mgmt_linkcfg_map[] = {
1361ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_4X10G, OCS_CONFIG_LINKCFG_4X10G},
1362ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_1X40G, OCS_CONFIG_LINKCFG_1X40G},
1363ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_2X16G, OCS_CONFIG_LINKCFG_2X16G},
1364ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_4X8G, OCS_CONFIG_LINKCFG_4X8G},
1365ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_4X1G, OCS_CONFIG_LINKCFG_4X1G},
1366ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_2X10G, OCS_CONFIG_LINKCFG_2X10G},
1367ef270ab1SKenneth D. Merry 	{OCS_HW_LINKCFG_2X10G_2X8G, OCS_CONFIG_LINKCFG_2X10G_2X8G}};
1368ef270ab1SKenneth D. Merry 
1369ef270ab1SKenneth D. Merry /**
1370ef270ab1SKenneth D. Merry  * @brief Get the HW linkcfg enum from the mgmt config string.
1371ef270ab1SKenneth D. Merry  *
1372ef270ab1SKenneth D. Merry  * @param mgmt_str mgmt string value.
1373ef270ab1SKenneth D. Merry  *
1374ef270ab1SKenneth D. Merry  * @return Returns the HW linkcfg enum corresponding to clp_str.
1375ef270ab1SKenneth D. Merry  */
1376ef270ab1SKenneth D. Merry static ocs_hw_linkcfg_e
ocs_hw_linkcfg_from_mgmt(const char * mgmt_str)1377ef270ab1SKenneth D. Merry ocs_hw_linkcfg_from_mgmt(const char *mgmt_str)
1378ef270ab1SKenneth D. Merry {
1379ef270ab1SKenneth D. Merry 	uint32_t i;
1380ef270ab1SKenneth D. Merry 	for (i = 0; i < ARRAY_SIZE(mgmt_linkcfg_map); i++) {
1381ef270ab1SKenneth D. Merry 		if (ocs_strncmp(mgmt_linkcfg_map[i].mgmt_str,
1382ef270ab1SKenneth D. Merry 				mgmt_str, ocs_strlen(mgmt_str)) == 0) {
1383ef270ab1SKenneth D. Merry 			return mgmt_linkcfg_map[i].linkcfg;
1384ef270ab1SKenneth D. Merry 		}
1385ef270ab1SKenneth D. Merry 	}
1386ef270ab1SKenneth D. Merry 	return OCS_HW_LINKCFG_NA;
1387ef270ab1SKenneth D. Merry }
1388ef270ab1SKenneth D. Merry 
1389ef270ab1SKenneth D. Merry /**
1390ef270ab1SKenneth D. Merry  * @brief Get the mgmt string value from the HW linkcfg enum.
1391ef270ab1SKenneth D. Merry  *
1392ef270ab1SKenneth D. Merry  * @param linkcfg HW linkcfg enum.
1393ef270ab1SKenneth D. Merry  *
1394ef270ab1SKenneth D. Merry  * @return Returns the mgmt string value corresponding to the given HW linkcfg.
1395ef270ab1SKenneth D. Merry  */
1396ef270ab1SKenneth D. Merry static const char *
ocs_mgmt_from_hw_linkcfg(ocs_hw_linkcfg_e linkcfg)1397ef270ab1SKenneth D. Merry ocs_mgmt_from_hw_linkcfg(ocs_hw_linkcfg_e linkcfg)
1398ef270ab1SKenneth D. Merry {
1399ef270ab1SKenneth D. Merry 	uint32_t i;
1400ef270ab1SKenneth D. Merry 	for (i = 0; i < ARRAY_SIZE(mgmt_linkcfg_map); i++) {
1401ef270ab1SKenneth D. Merry 		if (mgmt_linkcfg_map[i].linkcfg == linkcfg) {
1402ef270ab1SKenneth D. Merry 			return mgmt_linkcfg_map[i].mgmt_str;
1403ef270ab1SKenneth D. Merry 		}
1404ef270ab1SKenneth D. Merry 	}
1405ef270ab1SKenneth D. Merry 	return OCS_CONFIG_LINKCFG_UNKNOWN;
1406ef270ab1SKenneth D. Merry }
1407ef270ab1SKenneth D. Merry 
1408ef270ab1SKenneth D. Merry /**
1409ef270ab1SKenneth D. Merry  * @brief Link configuration callback argument
1410ef270ab1SKenneth D. Merry  */
1411ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_linkcfg_arg_s {
1412ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
1413ef270ab1SKenneth D. Merry 	int32_t status;
1414ef270ab1SKenneth D. Merry 	ocs_hw_linkcfg_e linkcfg;
1415ef270ab1SKenneth D. Merry } ocs_mgmt_linkcfg_arg_t;
1416ef270ab1SKenneth D. Merry 
1417ef270ab1SKenneth D. Merry /**
1418ef270ab1SKenneth D. Merry  * @brief Get linkcfg config value
1419ef270ab1SKenneth D. Merry  *
1420ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1421ef270ab1SKenneth D. Merry  * @param name Not used.
1422ef270ab1SKenneth D. Merry  * @param textbuf The textbuf to which the result is written.
1423ef270ab1SKenneth D. Merry  *
1424ef270ab1SKenneth D. Merry  * @return None.
1425ef270ab1SKenneth D. Merry  */
1426ef270ab1SKenneth D. Merry static void
get_linkcfg(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1427ef270ab1SKenneth D. Merry get_linkcfg(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1428ef270ab1SKenneth D. Merry {
1429ef270ab1SKenneth D. Merry 	const char *linkcfg_str = NULL;
1430ef270ab1SKenneth D. Merry 	uint32_t value;
1431ef270ab1SKenneth D. Merry 	ocs_hw_linkcfg_e linkcfg;
1432ef270ab1SKenneth D. Merry 	ocs_hw_get(&ocs->hw, OCS_HW_LINKCFG, &value);
1433ef270ab1SKenneth D. Merry 	linkcfg = (ocs_hw_linkcfg_e)value;
1434ef270ab1SKenneth D. Merry 	linkcfg_str = ocs_mgmt_from_hw_linkcfg(linkcfg);
1435ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "linkcfg", linkcfg_str);
1436ef270ab1SKenneth D. Merry }
1437ef270ab1SKenneth D. Merry 
1438ef270ab1SKenneth D. Merry /**
1439ef270ab1SKenneth D. Merry  * @brief Get requested WWNN config value
1440ef270ab1SKenneth D. Merry  *
1441ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1442ef270ab1SKenneth D. Merry  * @param name Not used.
1443ef270ab1SKenneth D. Merry  * @param textbuf The textbuf to which the result is written.
1444ef270ab1SKenneth D. Merry  *
1445ef270ab1SKenneth D. Merry  * @return None.
1446ef270ab1SKenneth D. Merry  */
1447ef270ab1SKenneth D. Merry static void
get_req_wwnn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1448ef270ab1SKenneth D. Merry get_req_wwnn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1449ef270ab1SKenneth D. Merry {
1450ef270ab1SKenneth D. Merry 	ocs_xport_t *xport = ocs->xport;
1451ef270ab1SKenneth D. Merry 
1452ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "requested_wwnn", "0x%llx", (unsigned long long)xport->req_wwnn);
1453ef270ab1SKenneth D. Merry }
1454ef270ab1SKenneth D. Merry 
1455ef270ab1SKenneth D. Merry /**
1456ef270ab1SKenneth D. Merry  * @brief Get requested WWPN config value
1457ef270ab1SKenneth D. Merry  *
1458ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1459ef270ab1SKenneth D. Merry  * @param name Not used.
1460ef270ab1SKenneth D. Merry  * @param textbuf The textbuf to which the result is written.
1461ef270ab1SKenneth D. Merry  *
1462ef270ab1SKenneth D. Merry  * @return None.
1463ef270ab1SKenneth D. Merry  */
1464ef270ab1SKenneth D. Merry static void
get_req_wwpn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1465ef270ab1SKenneth D. Merry get_req_wwpn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1466ef270ab1SKenneth D. Merry {
1467ef270ab1SKenneth D. Merry 	ocs_xport_t *xport = ocs->xport;
1468ef270ab1SKenneth D. Merry 
1469ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "requested_wwpn", "0x%llx", (unsigned long long)xport->req_wwpn);
1470ef270ab1SKenneth D. Merry }
1471ef270ab1SKenneth D. Merry 
1472ef270ab1SKenneth D. Merry /**
1473ef270ab1SKenneth D. Merry  * @brief Get requested nodedb_mask config value
1474ef270ab1SKenneth D. Merry  *
1475ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1476ef270ab1SKenneth D. Merry  * @param name Not used.
1477ef270ab1SKenneth D. Merry  * @param textbuf The textbuf to which the result is written.
1478ef270ab1SKenneth D. Merry  *
1479ef270ab1SKenneth D. Merry  * @return None.
1480ef270ab1SKenneth D. Merry  */
1481ef270ab1SKenneth D. Merry static void
get_nodedb_mask(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1482ef270ab1SKenneth D. Merry get_nodedb_mask(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1483ef270ab1SKenneth D. Merry {
1484ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RW, "nodedb_mask", "0x%08x", ocs->nodedb_mask);
1485ef270ab1SKenneth D. Merry }
1486ef270ab1SKenneth D. Merry 
1487ef270ab1SKenneth D. Merry /**
1488ef270ab1SKenneth D. Merry  * @brief Set requested WWNN value.
1489ef270ab1SKenneth D. Merry  *
1490ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1491ef270ab1SKenneth D. Merry  * @param name Not used.
1492ef270ab1SKenneth D. Merry  * @param value Value to which the linkcfg is set.
1493ef270ab1SKenneth D. Merry  *
1494ef270ab1SKenneth D. Merry  * @return Returns 0 on success.
1495ef270ab1SKenneth D. Merry  */
1496ef270ab1SKenneth D. Merry 
1497ef270ab1SKenneth D. Merry int
set_req_wwnn(ocs_t * ocs,char * name,char * value)1498ef270ab1SKenneth D. Merry set_req_wwnn(ocs_t *ocs, char *name, char *value)
1499ef270ab1SKenneth D. Merry {
1500ef270ab1SKenneth D. Merry 	int rc;
1501ef270ab1SKenneth D. Merry 	uint64_t wwnn;
1502ef270ab1SKenneth D. Merry 
1503ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "default") == 0) {
1504ef270ab1SKenneth D. Merry 		wwnn = 0;
1505ef270ab1SKenneth D. Merry 	}
1506ef270ab1SKenneth D. Merry 	else if (parse_wwn(value, &wwnn) != 0) {
1507ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "Invalid WWNN: %s\n", value);
1508ef270ab1SKenneth D. Merry 		return 1;
1509ef270ab1SKenneth D. Merry 	}
1510ef270ab1SKenneth D. Merry 
1511ef270ab1SKenneth D. Merry 	rc = ocs_xport_control(ocs->xport, OCS_XPORT_WWNN_SET, wwnn);
1512ef270ab1SKenneth D. Merry 
1513ef270ab1SKenneth D. Merry 	if(rc) {
1514ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "OCS_XPORT_WWNN_SET failed: %d\n", rc);
1515ef270ab1SKenneth D. Merry 		return rc;
1516ef270ab1SKenneth D. Merry 	}
1517ef270ab1SKenneth D. Merry 
1518ef270ab1SKenneth D. Merry 	rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1519ef270ab1SKenneth D. Merry 	if (rc) {
1520ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "port offline failed : %d\n", rc);
1521ef270ab1SKenneth D. Merry 	}
1522ef270ab1SKenneth D. Merry 
1523ef270ab1SKenneth D. Merry 	rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1524ef270ab1SKenneth D. Merry 	if (rc) {
1525ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "port online failed : %d\n", rc);
1526ef270ab1SKenneth D. Merry 	}
1527ef270ab1SKenneth D. Merry 
1528ef270ab1SKenneth D. Merry 	return rc;
1529ef270ab1SKenneth D. Merry }
1530ef270ab1SKenneth D. Merry 
1531ef270ab1SKenneth D. Merry /**
1532ef270ab1SKenneth D. Merry  * @brief Set requested WWNP value.
1533ef270ab1SKenneth D. Merry  *
1534ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1535ef270ab1SKenneth D. Merry  * @param name Not used.
1536ef270ab1SKenneth D. Merry  * @param value Value to which the linkcfg is set.
1537ef270ab1SKenneth D. Merry  *
1538ef270ab1SKenneth D. Merry  * @return Returns 0 on success.
1539ef270ab1SKenneth D. Merry  */
1540ef270ab1SKenneth D. Merry 
1541ef270ab1SKenneth D. Merry int
set_req_wwpn(ocs_t * ocs,char * name,char * value)1542ef270ab1SKenneth D. Merry set_req_wwpn(ocs_t *ocs, char *name, char *value)
1543ef270ab1SKenneth D. Merry {
1544ef270ab1SKenneth D. Merry 	int rc;
1545ef270ab1SKenneth D. Merry 	uint64_t wwpn;
1546ef270ab1SKenneth D. Merry 
1547ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "default") == 0) {
1548ef270ab1SKenneth D. Merry 		wwpn = 0;
1549ef270ab1SKenneth D. Merry 	}
1550ef270ab1SKenneth D. Merry 	else if (parse_wwn(value, &wwpn) != 0) {
1551ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "Invalid WWPN: %s\n", value);
1552ef270ab1SKenneth D. Merry 		return 1;
1553ef270ab1SKenneth D. Merry 	}
1554ef270ab1SKenneth D. Merry 
1555ef270ab1SKenneth D. Merry 	rc = ocs_xport_control(ocs->xport, OCS_XPORT_WWPN_SET, wwpn);
1556ef270ab1SKenneth D. Merry 
1557ef270ab1SKenneth D. Merry 	if(rc) {
1558ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "OCS_XPORT_WWPN_SET failed: %d\n", rc);
1559ef270ab1SKenneth D. Merry 		return rc;
1560ef270ab1SKenneth D. Merry 	}
1561ef270ab1SKenneth D. Merry 
1562ef270ab1SKenneth D. Merry 	rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1563ef270ab1SKenneth D. Merry 	if (rc) {
1564ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "port offline failed : %d\n", rc);
1565ef270ab1SKenneth D. Merry 	}
1566ef270ab1SKenneth D. Merry 
1567ef270ab1SKenneth D. Merry 	rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1568ef270ab1SKenneth D. Merry 	if (rc) {
1569ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "port online failed : %d\n", rc);
1570ef270ab1SKenneth D. Merry 	}
1571ef270ab1SKenneth D. Merry 
1572ef270ab1SKenneth D. Merry 	return rc;
1573ef270ab1SKenneth D. Merry }
1574ef270ab1SKenneth D. Merry 
1575ef270ab1SKenneth D. Merry /**
1576ef270ab1SKenneth D. Merry  * @brief Set node debug mask value
1577ef270ab1SKenneth D. Merry  *
1578ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1579ef270ab1SKenneth D. Merry  * @param name Not used.
1580ef270ab1SKenneth D. Merry  * @param value Value to which the nodedb_mask is set.
1581ef270ab1SKenneth D. Merry  *
1582ef270ab1SKenneth D. Merry  * @return Returns 0 on success.
1583ef270ab1SKenneth D. Merry  */
1584ef270ab1SKenneth D. Merry static int
set_nodedb_mask(ocs_t * ocs,char * name,char * value)1585ef270ab1SKenneth D. Merry set_nodedb_mask(ocs_t *ocs, char *name, char *value)
1586ef270ab1SKenneth D. Merry {
1587ef270ab1SKenneth D. Merry 	ocs->nodedb_mask = ocs_strtoul(value, 0, 0);
1588ef270ab1SKenneth D. Merry 	return 0;
1589ef270ab1SKenneth D. Merry }
1590ef270ab1SKenneth D. Merry 
1591ef270ab1SKenneth D. Merry /**
1592ef270ab1SKenneth D. Merry  * @brief Set linkcfg config value.
1593ef270ab1SKenneth D. Merry  *
1594ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1595ef270ab1SKenneth D. Merry  * @param name Not used.
1596ef270ab1SKenneth D. Merry  * @param value Value to which the linkcfg is set.
1597ef270ab1SKenneth D. Merry  *
1598ef270ab1SKenneth D. Merry  * @return Returns 0 on success.
1599ef270ab1SKenneth D. Merry  */
1600ef270ab1SKenneth D. Merry static int
set_linkcfg(ocs_t * ocs,char * name,char * value)1601ef270ab1SKenneth D. Merry set_linkcfg(ocs_t *ocs, char *name, char *value)
1602ef270ab1SKenneth D. Merry {
1603ef270ab1SKenneth D. Merry 	ocs_hw_linkcfg_e linkcfg;
1604ef270ab1SKenneth D. Merry 	ocs_mgmt_linkcfg_arg_t cb_arg;
1605ef270ab1SKenneth D. Merry 	ocs_hw_rtn_e status;
1606ef270ab1SKenneth D. Merry 
1607ef270ab1SKenneth D. Merry 	ocs_sem_init(&cb_arg.semaphore, 0, "mgmt_linkcfg");
1608ef270ab1SKenneth D. Merry 
1609ef270ab1SKenneth D. Merry 	/* translate mgmt linkcfg string to HW linkcfg enum */
1610ef270ab1SKenneth D. Merry 	linkcfg = ocs_hw_linkcfg_from_mgmt(value);
1611ef270ab1SKenneth D. Merry 
1612ef270ab1SKenneth D. Merry 	/* set HW linkcfg */
1613ef270ab1SKenneth D. Merry 	status = ocs_hw_port_control(&ocs->hw, OCS_HW_PORT_SET_LINK_CONFIG,
1614ef270ab1SKenneth D. Merry 				      (uintptr_t)linkcfg, ocs_mgmt_linkcfg_cb, &cb_arg);
1615ef270ab1SKenneth D. Merry 	if (status) {
1616ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "ocs_hw_set_linkcfg failed\n");
1617ef270ab1SKenneth D. Merry 		return -1;
1618ef270ab1SKenneth D. Merry 	}
1619ef270ab1SKenneth D. Merry 
1620ef270ab1SKenneth D. Merry 	if (ocs_sem_p(&cb_arg.semaphore, OCS_SEM_FOREVER)) {
1621ef270ab1SKenneth D. Merry 		ocs_log_err(ocs, "ocs_sem_p failed\n");
1622ef270ab1SKenneth D. Merry 		return -1;
1623ef270ab1SKenneth D. Merry 	}
1624ef270ab1SKenneth D. Merry 
1625ef270ab1SKenneth D. Merry 	if (cb_arg.status) {
1626ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "failed to set linkcfg from HW status=%d\n",
1627ef270ab1SKenneth D. Merry 			     cb_arg.status);
1628ef270ab1SKenneth D. Merry 		return -1;
1629ef270ab1SKenneth D. Merry 	}
1630ef270ab1SKenneth D. Merry 
1631ef270ab1SKenneth D. Merry 	return 0;
1632ef270ab1SKenneth D. Merry }
1633ef270ab1SKenneth D. Merry 
1634ef270ab1SKenneth D. Merry /**
1635ef270ab1SKenneth D. Merry  * @brief Linkcfg callback
1636ef270ab1SKenneth D. Merry  *
1637ef270ab1SKenneth D. Merry  * @param status Result of the linkcfg get/set operation.
1638ef270ab1SKenneth D. Merry  * @param value Resulting linkcfg value.
1639ef270ab1SKenneth D. Merry  * @param arg Callback argument.
1640ef270ab1SKenneth D. Merry  *
1641ef270ab1SKenneth D. Merry  * @return None.
1642ef270ab1SKenneth D. Merry  */
1643ef270ab1SKenneth D. Merry static void
ocs_mgmt_linkcfg_cb(int32_t status,uintptr_t value,void * arg)1644ef270ab1SKenneth D. Merry ocs_mgmt_linkcfg_cb(int32_t status, uintptr_t value, void *arg)
1645ef270ab1SKenneth D. Merry {
1646ef270ab1SKenneth D. Merry 	ocs_mgmt_linkcfg_arg_t *cb_arg = (ocs_mgmt_linkcfg_arg_t *)arg;
1647ef270ab1SKenneth D. Merry 	cb_arg->status = status;
1648ef270ab1SKenneth D. Merry 	cb_arg->linkcfg = (ocs_hw_linkcfg_e)value;
1649ef270ab1SKenneth D. Merry 	ocs_sem_v(&cb_arg->semaphore);
1650ef270ab1SKenneth D. Merry }
1651ef270ab1SKenneth D. Merry 
1652ef270ab1SKenneth D. Merry static int
set_debug_mq_dump(ocs_t * ocs,char * name,char * value)1653ef270ab1SKenneth D. Merry set_debug_mq_dump(ocs_t *ocs, char *name, char *value)
1654ef270ab1SKenneth D. Merry {
1655ef270ab1SKenneth D. Merry 	int result;
1656ef270ab1SKenneth D. Merry 
1657ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "false") == 0) {
1658ef270ab1SKenneth D. Merry 		ocs_debug_disable(OCS_DEBUG_ENABLE_MQ_DUMP);
1659ef270ab1SKenneth D. Merry 		result = 0;
1660ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "true") == 0) {
1661ef270ab1SKenneth D. Merry 		ocs_debug_enable(OCS_DEBUG_ENABLE_MQ_DUMP);
1662ef270ab1SKenneth D. Merry 		result = 0;
1663ef270ab1SKenneth D. Merry 	} else {
1664ef270ab1SKenneth D. Merry 		result = -1;
1665ef270ab1SKenneth D. Merry 	}
1666ef270ab1SKenneth D. Merry 
1667ef270ab1SKenneth D. Merry 	return result;
1668ef270ab1SKenneth D. Merry }
1669ef270ab1SKenneth D. Merry 
1670ef270ab1SKenneth D. Merry static int
set_debug_cq_dump(ocs_t * ocs,char * name,char * value)1671ef270ab1SKenneth D. Merry set_debug_cq_dump(ocs_t *ocs, char *name, char *value)
1672ef270ab1SKenneth D. Merry {
1673ef270ab1SKenneth D. Merry 	int result;
1674ef270ab1SKenneth D. Merry 
1675ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "false") == 0) {
1676ef270ab1SKenneth D. Merry 		ocs_debug_disable(OCS_DEBUG_ENABLE_CQ_DUMP);
1677ef270ab1SKenneth D. Merry 		result = 0;
1678ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "true") == 0) {
1679ef270ab1SKenneth D. Merry 		ocs_debug_enable(OCS_DEBUG_ENABLE_CQ_DUMP);
1680ef270ab1SKenneth D. Merry 		result = 0;
1681ef270ab1SKenneth D. Merry 	} else {
1682ef270ab1SKenneth D. Merry 		result = -1;
1683ef270ab1SKenneth D. Merry 	}
1684ef270ab1SKenneth D. Merry 
1685ef270ab1SKenneth D. Merry 	return result;
1686ef270ab1SKenneth D. Merry }
1687ef270ab1SKenneth D. Merry 
1688ef270ab1SKenneth D. Merry static int
set_debug_wq_dump(ocs_t * ocs,char * name,char * value)1689ef270ab1SKenneth D. Merry set_debug_wq_dump(ocs_t *ocs, char *name, char *value)
1690ef270ab1SKenneth D. Merry {
1691ef270ab1SKenneth D. Merry 	int result;
1692ef270ab1SKenneth D. Merry 
1693ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "false") == 0) {
1694ef270ab1SKenneth D. Merry 		ocs_debug_disable(OCS_DEBUG_ENABLE_WQ_DUMP);
1695ef270ab1SKenneth D. Merry 		result = 0;
1696ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "true") == 0) {
1697ef270ab1SKenneth D. Merry 		ocs_debug_enable(OCS_DEBUG_ENABLE_WQ_DUMP);
1698ef270ab1SKenneth D. Merry 		result = 0;
1699ef270ab1SKenneth D. Merry 	} else {
1700ef270ab1SKenneth D. Merry 		result = -1;
1701ef270ab1SKenneth D. Merry 	}
1702ef270ab1SKenneth D. Merry 
1703ef270ab1SKenneth D. Merry 	return result;
1704ef270ab1SKenneth D. Merry }
1705ef270ab1SKenneth D. Merry 
1706ef270ab1SKenneth D. Merry static int
set_debug_eq_dump(ocs_t * ocs,char * name,char * value)1707ef270ab1SKenneth D. Merry set_debug_eq_dump(ocs_t *ocs, char *name, char *value)
1708ef270ab1SKenneth D. Merry {
1709ef270ab1SKenneth D. Merry 	int result;
1710ef270ab1SKenneth D. Merry 
1711ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "false") == 0) {
1712ef270ab1SKenneth D. Merry 		ocs_debug_disable(OCS_DEBUG_ENABLE_EQ_DUMP);
1713ef270ab1SKenneth D. Merry 		result = 0;
1714ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "true") == 0) {
1715ef270ab1SKenneth D. Merry 		ocs_debug_enable(OCS_DEBUG_ENABLE_EQ_DUMP);
1716ef270ab1SKenneth D. Merry 		result = 0;
1717ef270ab1SKenneth D. Merry 	} else {
1718ef270ab1SKenneth D. Merry 		result = -1;
1719ef270ab1SKenneth D. Merry 	}
1720ef270ab1SKenneth D. Merry 
1721ef270ab1SKenneth D. Merry 	return result;
1722ef270ab1SKenneth D. Merry }
1723ef270ab1SKenneth D. Merry 
1724ef270ab1SKenneth D. Merry static int
set_logmask(ocs_t * ocs,char * name,char * value)1725ef270ab1SKenneth D. Merry set_logmask(ocs_t *ocs, char *name, char *value)
1726ef270ab1SKenneth D. Merry {
1727ef270ab1SKenneth D. Merry 
1728ef270ab1SKenneth D. Merry 	ocs->logmask = ocs_strtoul(value, NULL, 0);
1729ef270ab1SKenneth D. Merry 
1730ef270ab1SKenneth D. Merry 	return 0;
1731ef270ab1SKenneth D. Merry }
1732ef270ab1SKenneth D. Merry 
1733ef270ab1SKenneth D. Merry static int
set_loglevel(ocs_t * ocs,char * name,char * value)1734ef270ab1SKenneth D. Merry set_loglevel(ocs_t *ocs, char *name, char *value)
1735ef270ab1SKenneth D. Merry {
1736ef270ab1SKenneth D. Merry 
1737ef270ab1SKenneth D. Merry 	loglevel = ocs_strtoul(value, NULL, 0);
1738ef270ab1SKenneth D. Merry 
1739ef270ab1SKenneth D. Merry 	return 0;
1740ef270ab1SKenneth D. Merry }
1741ef270ab1SKenneth D. Merry 
1742ef270ab1SKenneth D. Merry int
set_configured_speed(ocs_t * ocs,char * name,char * value)1743ef270ab1SKenneth D. Merry set_configured_speed(ocs_t *ocs, char *name, char *value)
1744ef270ab1SKenneth D. Merry {
1745ef270ab1SKenneth D. Merry 	int result = 0;
1746ef270ab1SKenneth D. Merry 	ocs_hw_rtn_e hw_rc;
1747ef270ab1SKenneth D. Merry 	int xport_rc;
1748ef270ab1SKenneth D. Merry 	uint32_t spd;
1749ef270ab1SKenneth D. Merry 
1750ef270ab1SKenneth D. Merry 	spd = ocs_strtoul(value, NULL, 0);
1751ef270ab1SKenneth D. Merry 
1752ef270ab1SKenneth D. Merry 	if ((spd != 0) && (spd != 2000) && (spd != 4000) &&
1753ef270ab1SKenneth D. Merry 		(spd != 8000) && (spd != 16000) && (spd != 32000)) {
1754ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "unsupported speed %d\n", spd);
1755ef270ab1SKenneth D. Merry 		return 1;
1756ef270ab1SKenneth D. Merry 	}
1757ef270ab1SKenneth D. Merry 
1758ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "Taking port offline\n");
1759ef270ab1SKenneth D. Merry 	xport_rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1760ef270ab1SKenneth D. Merry 	if (xport_rc != 0) {
1761ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "Port offline failed\n");
1762ef270ab1SKenneth D. Merry 		result = 1;
1763ef270ab1SKenneth D. Merry 	} else {
1764ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "Setting port to speed %d\n", spd);
1765ef270ab1SKenneth D. Merry 		hw_rc = ocs_hw_set(&ocs->hw, OCS_HW_LINK_SPEED, spd);
1766ef270ab1SKenneth D. Merry 		if (hw_rc != OCS_HW_RTN_SUCCESS) {
1767ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "Speed set failed\n");
1768ef270ab1SKenneth D. Merry 			result = 1;
1769ef270ab1SKenneth D. Merry 		}
1770ef270ab1SKenneth D. Merry 
1771ef270ab1SKenneth D. Merry 		/* If we failed to set the speed we still want to try to bring
1772ef270ab1SKenneth D. Merry 		 * the port back online */
1773ef270ab1SKenneth D. Merry 
1774ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "Bringing port online\n");
1775ef270ab1SKenneth D. Merry 		xport_rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1776ef270ab1SKenneth D. Merry 		if (xport_rc != 0) {
1777ef270ab1SKenneth D. Merry 			result = 1;
1778ef270ab1SKenneth D. Merry 		}
1779ef270ab1SKenneth D. Merry 	}
1780ef270ab1SKenneth D. Merry 
1781ef270ab1SKenneth D. Merry 	return result;
1782ef270ab1SKenneth D. Merry }
1783ef270ab1SKenneth D. Merry 
1784ef270ab1SKenneth D. Merry int
set_configured_topology(ocs_t * ocs,char * name,char * value)1785ef270ab1SKenneth D. Merry set_configured_topology(ocs_t *ocs, char *name, char *value)
1786ef270ab1SKenneth D. Merry {
1787ef270ab1SKenneth D. Merry 	int result = 0;
1788ef270ab1SKenneth D. Merry 	ocs_hw_rtn_e hw_rc;
1789ef270ab1SKenneth D. Merry 	int xport_rc;
1790ef270ab1SKenneth D. Merry 	uint32_t topo;
1791ef270ab1SKenneth D. Merry 
1792ef270ab1SKenneth D. Merry 	topo = ocs_strtoul(value, NULL, 0);
1793ef270ab1SKenneth D. Merry 	if (topo >= OCS_HW_TOPOLOGY_NONE) {
1794ef270ab1SKenneth D. Merry 		return 1;
1795ef270ab1SKenneth D. Merry 	}
1796ef270ab1SKenneth D. Merry 
1797ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "Taking port offline\n");
1798ef270ab1SKenneth D. Merry 	xport_rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1799ef270ab1SKenneth D. Merry 	if (xport_rc != 0) {
1800ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "Port offline failed\n");
1801ef270ab1SKenneth D. Merry 		result = 1;
1802ef270ab1SKenneth D. Merry 	} else {
1803ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "Setting port to topology %d\n", topo);
1804ef270ab1SKenneth D. Merry 		hw_rc = ocs_hw_set(&ocs->hw, OCS_HW_TOPOLOGY, topo);
1805ef270ab1SKenneth D. Merry 		if (hw_rc != OCS_HW_RTN_SUCCESS) {
1806ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "Topology set failed\n");
1807ef270ab1SKenneth D. Merry 			result = 1;
1808*965e2154SRam Kishore Vegesna 		} else {
1809*965e2154SRam Kishore Vegesna 			// Set the persistent topology before port is online
1810*965e2154SRam Kishore Vegesna 			hw_rc = ocs_hw_set_persistent_topology(&ocs->hw, topo, OCS_CMD_NOWAIT);
1811*965e2154SRam Kishore Vegesna 			if (hw_rc != OCS_HW_RTN_SUCCESS)
1812*965e2154SRam Kishore Vegesna 				ocs_log_err(ocs, "Set persistent topology feature failed: %d\n", hw_rc);
1813ef270ab1SKenneth D. Merry 		}
1814ef270ab1SKenneth D. Merry 
1815ef270ab1SKenneth D. Merry 		/* If we failed to set the topology we still want to try to bring
1816ef270ab1SKenneth D. Merry 		 * the port back online */
1817ef270ab1SKenneth D. Merry 
1818ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "Bringing port online\n");
1819ef270ab1SKenneth D. Merry 		xport_rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1820ef270ab1SKenneth D. Merry 		if (xport_rc != 0) {
1821ef270ab1SKenneth D. Merry 			result = 1;
1822ef270ab1SKenneth D. Merry 		}
1823ef270ab1SKenneth D. Merry 	}
1824ef270ab1SKenneth D. Merry 
1825ef270ab1SKenneth D. Merry 	return result;
1826ef270ab1SKenneth D. Merry }
1827ef270ab1SKenneth D. Merry 
1828ef270ab1SKenneth D. Merry static int
set_configured_link_state(ocs_t * ocs,char * name,char * value)1829ef270ab1SKenneth D. Merry set_configured_link_state(ocs_t *ocs, char *name, char *value)
1830ef270ab1SKenneth D. Merry {
1831ef270ab1SKenneth D. Merry 	int result = 0;
1832ef270ab1SKenneth D. Merry 	int xport_rc;
1833ef270ab1SKenneth D. Merry 
1834ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "offline") == 0) {
1835ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "Setting port to %s\n", value);
1836ef270ab1SKenneth D. Merry 		xport_rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE);
1837ef270ab1SKenneth D. Merry 		if (xport_rc != 0) {
1838ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "Setting port to offline failed\n");
1839ef270ab1SKenneth D. Merry 			result = -1;
1840ef270ab1SKenneth D. Merry 		}
1841ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "online") == 0) {
1842ef270ab1SKenneth D. Merry 		ocs_log_debug(ocs, "Setting port to %s\n", value);
1843ef270ab1SKenneth D. Merry 		xport_rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE);
1844ef270ab1SKenneth D. Merry 		if (xport_rc != 0) {
1845ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "Setting port to online failed\n");
1846ef270ab1SKenneth D. Merry 			result = -1;
1847ef270ab1SKenneth D. Merry 		}
1848ef270ab1SKenneth D. Merry 	} else {
1849ef270ab1SKenneth D. Merry 		ocs_log_test(ocs, "Unsupported link state \"%s\"\n", value);
1850ef270ab1SKenneth D. Merry 		result = -1;
1851ef270ab1SKenneth D. Merry 	}
1852ef270ab1SKenneth D. Merry 
1853ef270ab1SKenneth D. Merry 	return result;
1854ef270ab1SKenneth D. Merry }
1855ef270ab1SKenneth D. Merry 
1856ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_get_port_protocol_result {
1857ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
1858ef270ab1SKenneth D. Merry 	int32_t status;
1859ef270ab1SKenneth D. Merry 	ocs_hw_port_protocol_e port_protocol;
1860ef270ab1SKenneth D. Merry } ocs_mgmt_get_port_protocol_result_t;
1861ef270ab1SKenneth D. Merry 
1862ef270ab1SKenneth D. Merry static void
ocs_mgmt_get_port_protocol_cb(int32_t status,ocs_hw_port_protocol_e port_protocol,void * arg)1863ef270ab1SKenneth D. Merry ocs_mgmt_get_port_protocol_cb(int32_t status,
1864ef270ab1SKenneth D. Merry 			      ocs_hw_port_protocol_e port_protocol,
1865ef270ab1SKenneth D. Merry 			      void    *arg)
1866ef270ab1SKenneth D. Merry {
1867ef270ab1SKenneth D. Merry 	ocs_mgmt_get_port_protocol_result_t *result = arg;
1868ef270ab1SKenneth D. Merry 
1869ef270ab1SKenneth D. Merry 	result->status = status;
1870ef270ab1SKenneth D. Merry 	result->port_protocol = port_protocol;
1871ef270ab1SKenneth D. Merry 
1872ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
1873ef270ab1SKenneth D. Merry }
1874ef270ab1SKenneth D. Merry 
1875ef270ab1SKenneth D. Merry static void
get_port_protocol(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)1876ef270ab1SKenneth D. Merry get_port_protocol(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
1877ef270ab1SKenneth D. Merry {
1878ef270ab1SKenneth D. Merry 	ocs_mgmt_get_port_protocol_result_t result;
1879ef270ab1SKenneth D. Merry 	uint8_t bus;
1880ef270ab1SKenneth D. Merry 	uint8_t dev;
1881ef270ab1SKenneth D. Merry 	uint8_t func;
1882ef270ab1SKenneth D. Merry 
1883ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "get_port_protocol");
1884ef270ab1SKenneth D. Merry 
1885ef270ab1SKenneth D. Merry 	ocs_get_bus_dev_func(ocs, &bus, &dev, &func);
1886ef270ab1SKenneth D. Merry 
1887ef270ab1SKenneth D. Merry 	if(ocs_hw_get_port_protocol(&ocs->hw, func, ocs_mgmt_get_port_protocol_cb, &result) == OCS_HW_RTN_SUCCESS) {
1888ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
1889ef270ab1SKenneth D. Merry 			/* Undefined failure */
1890ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
1891ef270ab1SKenneth D. Merry 		}
1892ef270ab1SKenneth D. Merry 		if (result.status == 0) {
1893ef270ab1SKenneth D. Merry 			switch (result.port_protocol) {
1894ef270ab1SKenneth D. Merry 			case OCS_HW_PORT_PROTOCOL_ISCSI:
1895ef270ab1SKenneth D. Merry 				ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "port_protocol", "iSCSI");
1896ef270ab1SKenneth D. Merry 				break;
1897ef270ab1SKenneth D. Merry 			case OCS_HW_PORT_PROTOCOL_FCOE:
1898ef270ab1SKenneth D. Merry 				ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "port_protocol", "FCoE");
1899ef270ab1SKenneth D. Merry 				break;
1900ef270ab1SKenneth D. Merry 			case OCS_HW_PORT_PROTOCOL_FC:
1901ef270ab1SKenneth D. Merry 				ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "port_protocol", "FC");
1902ef270ab1SKenneth D. Merry 				break;
1903ef270ab1SKenneth D. Merry 			case OCS_HW_PORT_PROTOCOL_OTHER:
1904ef270ab1SKenneth D. Merry 				ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "port_protocol", "Other");
1905ef270ab1SKenneth D. Merry 				break;
1906ef270ab1SKenneth D. Merry 			}
1907ef270ab1SKenneth D. Merry 		} else {
1908ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "getting port profile status 0x%x\n", result.status);
1909ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "port_protocol", "Unknown");
1910ef270ab1SKenneth D. Merry 		}
1911ef270ab1SKenneth D. Merry 	}
1912ef270ab1SKenneth D. Merry }
1913ef270ab1SKenneth D. Merry 
1914ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_set_port_protocol_result {
1915ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
1916ef270ab1SKenneth D. Merry 	int32_t status;
1917ef270ab1SKenneth D. Merry } ocs_mgmt_set_port_protocol_result_t;
1918ef270ab1SKenneth D. Merry 
1919ef270ab1SKenneth D. Merry static void
ocs_mgmt_set_port_protocol_cb(int32_t status,void * arg)1920ef270ab1SKenneth D. Merry ocs_mgmt_set_port_protocol_cb(int32_t status,
1921ef270ab1SKenneth D. Merry 			      void    *arg)
1922ef270ab1SKenneth D. Merry {
1923ef270ab1SKenneth D. Merry 	ocs_mgmt_get_port_protocol_result_t *result = arg;
1924ef270ab1SKenneth D. Merry 
1925ef270ab1SKenneth D. Merry 	result->status = status;
1926ef270ab1SKenneth D. Merry 
1927ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
1928ef270ab1SKenneth D. Merry }
1929ef270ab1SKenneth D. Merry 
1930ef270ab1SKenneth D. Merry /**
1931ef270ab1SKenneth D. Merry  * @brief  Set port protocol
1932ef270ab1SKenneth D. Merry  * @par Description
1933ef270ab1SKenneth D. Merry  * This is a management action handler to set the current
1934ef270ab1SKenneth D. Merry  * port protocol.  Input value should be one of iSCSI,
1935ef270ab1SKenneth D. Merry  * FC, or FCoE.
1936ef270ab1SKenneth D. Merry  *
1937ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
1938ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
1939ef270ab1SKenneth D. Merry  * @param value The value to be assigned
1940ef270ab1SKenneth D. Merry  *
1941ef270ab1SKenneth D. Merry  * @return Returns 0 on success, non-zero on failure.
1942ef270ab1SKenneth D. Merry  */
1943ef270ab1SKenneth D. Merry static int32_t
set_port_protocol(ocs_t * ocs,char * name,char * value)1944ef270ab1SKenneth D. Merry set_port_protocol(ocs_t *ocs, char *name, char *value)
1945ef270ab1SKenneth D. Merry {
1946ef270ab1SKenneth D. Merry 	ocs_mgmt_set_port_protocol_result_t result;
1947ef270ab1SKenneth D. Merry 	int32_t rc = 0;
1948ef270ab1SKenneth D. Merry 	ocs_hw_port_protocol_e new_protocol;
1949ef270ab1SKenneth D. Merry 	uint8_t bus;
1950ef270ab1SKenneth D. Merry 	uint8_t dev;
1951ef270ab1SKenneth D. Merry 	uint8_t func;
1952ef270ab1SKenneth D. Merry 
1953ef270ab1SKenneth D. Merry 	ocs_get_bus_dev_func(ocs, &bus, &dev, &func);
1954ef270ab1SKenneth D. Merry 
1955ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "set_port_protocol");
1956ef270ab1SKenneth D. Merry 
1957ef270ab1SKenneth D. Merry 	if (ocs_strcasecmp(value, "iscsi") == 0) {
1958ef270ab1SKenneth D. Merry 		new_protocol = OCS_HW_PORT_PROTOCOL_ISCSI;
1959ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "fc") == 0) {
1960ef270ab1SKenneth D. Merry 		new_protocol = OCS_HW_PORT_PROTOCOL_FC;
1961ef270ab1SKenneth D. Merry 	} else if (ocs_strcasecmp(value, "fcoe") == 0) {
1962ef270ab1SKenneth D. Merry 		new_protocol = OCS_HW_PORT_PROTOCOL_FCOE;
1963ef270ab1SKenneth D. Merry 	} else {
1964ef270ab1SKenneth D. Merry 		return -1;
1965ef270ab1SKenneth D. Merry 	}
1966ef270ab1SKenneth D. Merry 
1967ef270ab1SKenneth D. Merry 	rc = ocs_hw_set_port_protocol(&ocs->hw, new_protocol, func,
1968ef270ab1SKenneth D. Merry 				       ocs_mgmt_set_port_protocol_cb, &result);
1969ef270ab1SKenneth D. Merry 	if (rc == OCS_HW_RTN_SUCCESS) {
1970ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
1971ef270ab1SKenneth D. Merry 			/* Undefined failure */
1972ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
19734915e5c7SRam Kishore Vegesna 			return -ENXIO;
1974ef270ab1SKenneth D. Merry 		}
1975ef270ab1SKenneth D. Merry 		if (result.status == 0) {
1976ef270ab1SKenneth D. Merry 			/* Success. */
1977ef270ab1SKenneth D. Merry 			rc = 0;
1978ef270ab1SKenneth D. Merry 		} else {
1979ef270ab1SKenneth D. Merry 			rc = -1;
1980ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "setting active profile status 0x%x\n",
1981ef270ab1SKenneth D. Merry 				     result.status);
1982ef270ab1SKenneth D. Merry 		}
1983ef270ab1SKenneth D. Merry 	}
1984ef270ab1SKenneth D. Merry 
1985ef270ab1SKenneth D. Merry 	return rc;
1986ef270ab1SKenneth D. Merry }
1987ef270ab1SKenneth D. Merry 
1988ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_get_profile_list_result_s {
1989ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
1990ef270ab1SKenneth D. Merry 	int32_t status;
1991ef270ab1SKenneth D. Merry 	ocs_hw_profile_list_t *list;
1992ef270ab1SKenneth D. Merry } ocs_mgmt_get_profile_list_result_t;
1993ef270ab1SKenneth D. Merry 
1994ef270ab1SKenneth D. Merry static void
ocs_mgmt_get_profile_list_cb(int32_t status,ocs_hw_profile_list_t * list,void * ul_arg)1995ef270ab1SKenneth D. Merry ocs_mgmt_get_profile_list_cb(int32_t status, ocs_hw_profile_list_t *list, void *ul_arg)
1996ef270ab1SKenneth D. Merry {
1997ef270ab1SKenneth D. Merry 	ocs_mgmt_get_profile_list_result_t *result = ul_arg;
1998ef270ab1SKenneth D. Merry 
1999ef270ab1SKenneth D. Merry 	result->status = status;
2000ef270ab1SKenneth D. Merry 	result->list = list;
2001ef270ab1SKenneth D. Merry 
2002ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
2003ef270ab1SKenneth D. Merry }
2004ef270ab1SKenneth D. Merry 
2005ef270ab1SKenneth D. Merry /**
2006ef270ab1SKenneth D. Merry  * @brief  Get list of profiles
2007ef270ab1SKenneth D. Merry  * @par Description
2008ef270ab1SKenneth D. Merry  * This is a management action handler to get the list of
2009ef270ab1SKenneth D. Merry  * profiles supported by the SLI port.  Although the spec says
2010ef270ab1SKenneth D. Merry  * that all SLI platforms support this, only Skyhawk actually
2011ef270ab1SKenneth D. Merry  * has a useful implementation.
2012ef270ab1SKenneth D. Merry  *
2013ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2014ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2015ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to return the results.
2016ef270ab1SKenneth D. Merry  *
2017ef270ab1SKenneth D. Merry  * @return none
2018ef270ab1SKenneth D. Merry  */
2019ef270ab1SKenneth D. Merry static void
get_profile_list(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)2020ef270ab1SKenneth D. Merry get_profile_list(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
2021ef270ab1SKenneth D. Merry {
2022ef270ab1SKenneth D. Merry 	ocs_mgmt_get_profile_list_result_t result;
2023ef270ab1SKenneth D. Merry 
2024ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "get_profile_list");
2025ef270ab1SKenneth D. Merry 
2026ef270ab1SKenneth D. Merry 	if(ocs_hw_get_profile_list(&ocs->hw, ocs_mgmt_get_profile_list_cb, &result) == OCS_HW_RTN_SUCCESS) {
2027ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2028ef270ab1SKenneth D. Merry 			/* Undefined failure */
2029ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
2030ef270ab1SKenneth D. Merry 		}
2031ef270ab1SKenneth D. Merry 		if (result.status == 0) {
2032ef270ab1SKenneth D. Merry 			/* Success. */
2033ef270ab1SKenneth D. Merry #define MAX_LINE_SIZE 520
2034ef270ab1SKenneth D. Merry #define BUFFER_SIZE MAX_LINE_SIZE*40
2035ef270ab1SKenneth D. Merry 			char *result_buf;
2036ef270ab1SKenneth D. Merry 			char result_line[MAX_LINE_SIZE];
2037ef270ab1SKenneth D. Merry 			uint32_t bytes_left;
2038ef270ab1SKenneth D. Merry 			uint32_t i;
2039ef270ab1SKenneth D. Merry 
2040ef270ab1SKenneth D. Merry 			result_buf = ocs_malloc(ocs, BUFFER_SIZE, OCS_M_ZERO);
2041ef270ab1SKenneth D. Merry 			bytes_left = BUFFER_SIZE;
2042ef270ab1SKenneth D. Merry 
2043ef270ab1SKenneth D. Merry 			for (i=0; i<result.list->num_descriptors; i++) {
2044ef270ab1SKenneth D. Merry 				sprintf(result_line, "0x%02x:%s\n", result.list->descriptors[i].profile_id,
2045ef270ab1SKenneth D. Merry 					result.list->descriptors[i].profile_description);
2046ef270ab1SKenneth D. Merry 				if (strlen(result_line) < bytes_left) {
2047ef270ab1SKenneth D. Merry 					strcat(result_buf, result_line);
2048ef270ab1SKenneth D. Merry 					bytes_left -= strlen(result_line);
2049ef270ab1SKenneth D. Merry 				}
2050ef270ab1SKenneth D. Merry 			}
2051ef270ab1SKenneth D. Merry 
2052ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RD, "profile_list", result_buf);
2053ef270ab1SKenneth D. Merry 
2054ef270ab1SKenneth D. Merry 			ocs_free(ocs, result_buf, BUFFER_SIZE);
2055ef270ab1SKenneth D. Merry 			ocs_free(ocs, result.list, sizeof(ocs_hw_profile_list_t));
2056ef270ab1SKenneth D. Merry 		} else {
2057ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "getting profile list status 0x%x\n", result.status);
2058ef270ab1SKenneth D. Merry 		}
2059ef270ab1SKenneth D. Merry 	}
2060ef270ab1SKenneth D. Merry }
2061ef270ab1SKenneth D. Merry 
2062ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_get_active_profile_result {
2063ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
2064ef270ab1SKenneth D. Merry 	int32_t status;
2065ef270ab1SKenneth D. Merry 	uint32_t active_profile_id;
2066ef270ab1SKenneth D. Merry } ocs_mgmt_get_active_profile_result_t;
2067ef270ab1SKenneth D. Merry 
2068ef270ab1SKenneth D. Merry static void
ocs_mgmt_get_active_profile_cb(int32_t status,uint32_t active_profile,void * ul_arg)2069ef270ab1SKenneth D. Merry ocs_mgmt_get_active_profile_cb(int32_t status, uint32_t active_profile, void *ul_arg)
2070ef270ab1SKenneth D. Merry {
2071ef270ab1SKenneth D. Merry 	ocs_mgmt_get_active_profile_result_t *result = ul_arg;
2072ef270ab1SKenneth D. Merry 
2073ef270ab1SKenneth D. Merry 	result->status = status;
2074ef270ab1SKenneth D. Merry 	result->active_profile_id = active_profile;
2075ef270ab1SKenneth D. Merry 
2076ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
2077ef270ab1SKenneth D. Merry }
2078ef270ab1SKenneth D. Merry 
2079ef270ab1SKenneth D. Merry #define MAX_PROFILE_LENGTH 5
2080ef270ab1SKenneth D. Merry 
2081ef270ab1SKenneth D. Merry /**
2082ef270ab1SKenneth D. Merry  * @brief  Get active profile
2083ef270ab1SKenneth D. Merry  * @par Description
2084ef270ab1SKenneth D. Merry  * This is a management action handler to get the currently
2085ef270ab1SKenneth D. Merry  * active profile for an SLI port.  Although the spec says that
2086ef270ab1SKenneth D. Merry  * all SLI platforms support this, only Skyhawk actually has a
2087ef270ab1SKenneth D. Merry  * useful implementation.
2088ef270ab1SKenneth D. Merry  *
2089ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2090ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2091ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to return the results.
2092ef270ab1SKenneth D. Merry  *
2093ef270ab1SKenneth D. Merry  * @return none
2094ef270ab1SKenneth D. Merry  */
2095ef270ab1SKenneth D. Merry static void
get_active_profile(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)2096ef270ab1SKenneth D. Merry get_active_profile(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
2097ef270ab1SKenneth D. Merry {
2098ef270ab1SKenneth D. Merry 	char result_string[MAX_PROFILE_LENGTH];
2099ef270ab1SKenneth D. Merry 	ocs_mgmt_get_active_profile_result_t result;
2100ef270ab1SKenneth D. Merry 
2101ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "get_active_profile");
2102ef270ab1SKenneth D. Merry 
2103ef270ab1SKenneth D. Merry 	if(ocs_hw_get_active_profile(&ocs->hw, ocs_mgmt_get_active_profile_cb, &result) == OCS_HW_RTN_SUCCESS) {
2104ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2105ef270ab1SKenneth D. Merry 			/* Undefined failure */
2106ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
2107ef270ab1SKenneth D. Merry 		}
2108ef270ab1SKenneth D. Merry 		if (result.status == 0) {
2109ef270ab1SKenneth D. Merry 			/* Success. */
2110ef270ab1SKenneth D. Merry 			sprintf(result_string, "0x%02x", result.active_profile_id);
2111ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "active_profile", result_string);
2112ef270ab1SKenneth D. Merry 		} else {
2113ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "getting active profile status 0x%x\n", result.status);
2114ef270ab1SKenneth D. Merry 		}
2115ef270ab1SKenneth D. Merry 	}
2116ef270ab1SKenneth D. Merry }
2117ef270ab1SKenneth D. Merry 
2118ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_set_active_profile_result {
2119ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
2120ef270ab1SKenneth D. Merry 	int32_t status;
2121ef270ab1SKenneth D. Merry } ocs_mgmt_set_active_profile_result_t;
2122ef270ab1SKenneth D. Merry 
2123ef270ab1SKenneth D. Merry static void
ocs_mgmt_set_active_profile_cb(int32_t status,void * ul_arg)2124ef270ab1SKenneth D. Merry ocs_mgmt_set_active_profile_cb(int32_t status, void *ul_arg)
2125ef270ab1SKenneth D. Merry {
2126ef270ab1SKenneth D. Merry 	ocs_mgmt_get_profile_list_result_t *result = ul_arg;
2127ef270ab1SKenneth D. Merry 
2128ef270ab1SKenneth D. Merry 	result->status = status;
2129ef270ab1SKenneth D. Merry 
2130ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
2131ef270ab1SKenneth D. Merry }
2132ef270ab1SKenneth D. Merry 
2133ef270ab1SKenneth D. Merry /**
2134ef270ab1SKenneth D. Merry  * @brief  Set active profile
2135ef270ab1SKenneth D. Merry  * @par Description
2136ef270ab1SKenneth D. Merry  * This is a management action handler to set the currently
2137ef270ab1SKenneth D. Merry  * active profile for an SLI port.  Although the spec says that
2138ef270ab1SKenneth D. Merry  * all SLI platforms support this, only Skyhawk actually has a
2139ef270ab1SKenneth D. Merry  * useful implementation.
2140ef270ab1SKenneth D. Merry  *
2141ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2142ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2143ef270ab1SKenneth D. Merry  * @param value Requested new value of the property.
2144ef270ab1SKenneth D. Merry  *
2145ef270ab1SKenneth D. Merry  * @return Returns 0 on success, non-zero on failure.
2146ef270ab1SKenneth D. Merry  */
2147ef270ab1SKenneth D. Merry static int32_t
set_active_profile(ocs_t * ocs,char * name,char * value)2148ef270ab1SKenneth D. Merry set_active_profile(ocs_t *ocs, char *name, char *value)
2149ef270ab1SKenneth D. Merry {
2150ef270ab1SKenneth D. Merry 	ocs_mgmt_set_active_profile_result_t result;
2151ef270ab1SKenneth D. Merry 	int32_t rc = 0;
2152ef270ab1SKenneth D. Merry 	int32_t new_profile;
2153ef270ab1SKenneth D. Merry 
2154ef270ab1SKenneth D. Merry 	new_profile = ocs_strtoul(value, NULL, 0);
2155ef270ab1SKenneth D. Merry 
2156ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "set_active_profile");
2157ef270ab1SKenneth D. Merry 
2158ef270ab1SKenneth D. Merry 	rc = ocs_hw_set_active_profile(&ocs->hw, ocs_mgmt_set_active_profile_cb, new_profile, &result);
2159ef270ab1SKenneth D. Merry 	if (rc == OCS_HW_RTN_SUCCESS) {
2160ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2161ef270ab1SKenneth D. Merry 			/* Undefined failure */
2162ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
21634915e5c7SRam Kishore Vegesna 			return -ENXIO;
2164ef270ab1SKenneth D. Merry 		}
2165ef270ab1SKenneth D. Merry 		if (result.status == 0) {
2166ef270ab1SKenneth D. Merry 			/* Success. */
2167ef270ab1SKenneth D. Merry 			rc = 0;
2168ef270ab1SKenneth D. Merry 		} else {
2169ef270ab1SKenneth D. Merry 			rc = -1;
2170ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "setting active profile status 0x%x\n", result.status);
2171ef270ab1SKenneth D. Merry 		}
2172ef270ab1SKenneth D. Merry 	}
2173ef270ab1SKenneth D. Merry 
2174ef270ab1SKenneth D. Merry 	return rc;
2175ef270ab1SKenneth D. Merry }
2176ef270ab1SKenneth D. Merry 
2177ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_get_nvparms_result {
2178ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
2179ef270ab1SKenneth D. Merry 	int32_t status;
2180ef270ab1SKenneth D. Merry 	uint8_t	wwpn[8];
2181ef270ab1SKenneth D. Merry 	uint8_t wwnn[8];
2182ef270ab1SKenneth D. Merry 	uint8_t hard_alpa;
2183ef270ab1SKenneth D. Merry 	uint32_t preferred_d_id;
2184ef270ab1SKenneth D. Merry } ocs_mgmt_get_nvparms_result_t;
2185ef270ab1SKenneth D. Merry 
2186ef270ab1SKenneth D. Merry static void
ocs_mgmt_get_nvparms_cb(int32_t status,uint8_t * wwpn,uint8_t * wwnn,uint8_t hard_alpa,uint32_t preferred_d_id,void * ul_arg)2187ef270ab1SKenneth D. Merry ocs_mgmt_get_nvparms_cb(int32_t status, uint8_t *wwpn, uint8_t *wwnn, uint8_t hard_alpa,
2188ef270ab1SKenneth D. Merry 		uint32_t preferred_d_id, void *ul_arg)
2189ef270ab1SKenneth D. Merry {
2190ef270ab1SKenneth D. Merry 	ocs_mgmt_get_nvparms_result_t *result = ul_arg;
2191ef270ab1SKenneth D. Merry 
2192ef270ab1SKenneth D. Merry 	result->status = status;
2193ef270ab1SKenneth D. Merry 	ocs_memcpy(result->wwpn, wwpn, sizeof(result->wwpn));
2194ef270ab1SKenneth D. Merry 	ocs_memcpy(result->wwnn, wwnn, sizeof(result->wwnn));
2195ef270ab1SKenneth D. Merry 	result->hard_alpa = hard_alpa;
2196ef270ab1SKenneth D. Merry 	result->preferred_d_id = preferred_d_id;
2197ef270ab1SKenneth D. Merry 
2198ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
2199ef270ab1SKenneth D. Merry }
2200ef270ab1SKenneth D. Merry 
2201ef270ab1SKenneth D. Merry /**
2202ef270ab1SKenneth D. Merry  * @brief  Get wwpn
2203ef270ab1SKenneth D. Merry  * @par Description
2204ef270ab1SKenneth D. Merry  *
2205ef270ab1SKenneth D. Merry  *
2206ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2207ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2208ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to return the results.
2209ef270ab1SKenneth D. Merry  *
2210ef270ab1SKenneth D. Merry  * @return none
2211ef270ab1SKenneth D. Merry  */
2212ef270ab1SKenneth D. Merry static void
get_nv_wwpn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)2213ef270ab1SKenneth D. Merry get_nv_wwpn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
2214ef270ab1SKenneth D. Merry {
2215ef270ab1SKenneth D. Merry 	char result_string[24];
2216ca21db85SRam Kishore Vegesna 	ocs_mgmt_get_nvparms_result_t result;
2217ef270ab1SKenneth D. Merry 
2218ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "get_nv_wwpn");
2219ef270ab1SKenneth D. Merry 
2220ef270ab1SKenneth D. Merry 	if(ocs_hw_get_nvparms(&ocs->hw, ocs_mgmt_get_nvparms_cb, &result) == OCS_HW_RTN_SUCCESS) {
2221ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2222ef270ab1SKenneth D. Merry 			/* Undefined failure */
2223ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
2224ef270ab1SKenneth D. Merry 			return;
2225ef270ab1SKenneth D. Merry 		}
2226ef270ab1SKenneth D. Merry 		if (result.status == 0) {
2227ef270ab1SKenneth D. Merry 			/* Success.  Copy wwpn from result struct to result string */
2228ef270ab1SKenneth D. Merry 			sprintf(result_string, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
2229ef270ab1SKenneth D. Merry 					result.wwpn[0], result.wwpn[1], result.wwpn[2],
2230ef270ab1SKenneth D. Merry 					result.wwpn[3], result.wwpn[4], result.wwpn[5],
2231ef270ab1SKenneth D. Merry 					result.wwpn[6], result.wwpn[7]);
2232ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "nv_wwpn", result_string);
2233ef270ab1SKenneth D. Merry 		} else {
2234ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "getting wwpn status 0x%x\n", result.status);
2235ef270ab1SKenneth D. Merry 		}
2236ef270ab1SKenneth D. Merry 	}
2237ef270ab1SKenneth D. Merry }
2238ef270ab1SKenneth D. Merry 
2239ef270ab1SKenneth D. Merry /**
2240ef270ab1SKenneth D. Merry  * @brief  Get wwnn
2241ef270ab1SKenneth D. Merry  * @par Description
2242ef270ab1SKenneth D. Merry  *
2243ef270ab1SKenneth D. Merry  *
2244ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2245ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2246ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to return the results.
2247ef270ab1SKenneth D. Merry  *
2248ef270ab1SKenneth D. Merry  * @return none
2249ef270ab1SKenneth D. Merry  */
2250ef270ab1SKenneth D. Merry static void
get_nv_wwnn(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)2251ef270ab1SKenneth D. Merry get_nv_wwnn(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
2252ef270ab1SKenneth D. Merry {
2253ef270ab1SKenneth D. Merry 	char result_string[24];
2254ca21db85SRam Kishore Vegesna 	ocs_mgmt_get_nvparms_result_t result;
2255ef270ab1SKenneth D. Merry 
2256ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "get_nv_wwnn");
2257ef270ab1SKenneth D. Merry 
2258ef270ab1SKenneth D. Merry 	if(ocs_hw_get_nvparms(&ocs->hw, ocs_mgmt_get_nvparms_cb, &result) == OCS_HW_RTN_SUCCESS) {
2259ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2260ef270ab1SKenneth D. Merry 			/* Undefined failure */
2261ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
2262ef270ab1SKenneth D. Merry 			return;
2263ef270ab1SKenneth D. Merry 		}
2264ef270ab1SKenneth D. Merry 		if (result.status == 0) {
2265ef270ab1SKenneth D. Merry 			/* Success. Copy wwnn from result struct to result string */
2266ef270ab1SKenneth D. Merry 			ocs_snprintf(result_string, sizeof(result_string), "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
2267ef270ab1SKenneth D. Merry 					result.wwnn[0], result.wwnn[1], result.wwnn[2],
2268ef270ab1SKenneth D. Merry 					result.wwnn[3], result.wwnn[4], result.wwnn[5],
2269ef270ab1SKenneth D. Merry 					result.wwnn[6], result.wwnn[7]);
2270ef270ab1SKenneth D. Merry 			ocs_mgmt_emit_string(textbuf, MGMT_MODE_RW, "nv_wwnn", result_string);
2271ef270ab1SKenneth D. Merry 		} else {
2272ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "getting wwnn status 0x%x\n", result.status);
2273ef270ab1SKenneth D. Merry 		}
2274ef270ab1SKenneth D. Merry 	}
2275ef270ab1SKenneth D. Merry }
2276ef270ab1SKenneth D. Merry 
2277ef270ab1SKenneth D. Merry /**
2278ef270ab1SKenneth D. Merry  * @brief Get accumulated node abort counts
2279ef270ab1SKenneth D. Merry  * @par Description Get the sum of all nodes abort count.
2280ef270ab1SKenneth D. Merry  *
2281ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2282ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2283ef270ab1SKenneth D. Merry  * @param textbuf Pointer to an ocs_textbuf, which is used to return the results.
2284ef270ab1SKenneth D. Merry  *
2285ef270ab1SKenneth D. Merry  * @return None.
2286ef270ab1SKenneth D. Merry  */
2287ef270ab1SKenneth D. Merry static void
get_node_abort_cnt(ocs_t * ocs,char * name,ocs_textbuf_t * textbuf)2288ef270ab1SKenneth D. Merry get_node_abort_cnt(ocs_t *ocs, char *name, ocs_textbuf_t *textbuf)
2289ef270ab1SKenneth D. Merry {
2290ef270ab1SKenneth D. Merry 	uint32_t abort_counts = 0;
2291ef270ab1SKenneth D. Merry 	ocs_domain_t *domain;
2292ef270ab1SKenneth D. Merry 	ocs_sport_t *sport;
2293ef270ab1SKenneth D. Merry 	ocs_node_t *node;
2294ef270ab1SKenneth D. Merry 
2295ef270ab1SKenneth D. Merry 	if (ocs_device_lock_try(ocs) != TRUE) {
2296ef270ab1SKenneth D. Merry 		/* Didn't get the lock */
2297ef270ab1SKenneth D. Merry 		return;
2298ef270ab1SKenneth D. Merry 	}
2299ef270ab1SKenneth D. Merry 
2300ef270ab1SKenneth D. Merry 		/* Here the Device lock is held */
2301ef270ab1SKenneth D. Merry 		ocs_list_foreach(&ocs->domain_list, domain) {
2302ef270ab1SKenneth D. Merry 			if (ocs_domain_lock_try(domain) != TRUE) {
2303ef270ab1SKenneth D. Merry 				/* Didn't get the lock */
2304ef270ab1SKenneth D. Merry 				ocs_device_unlock(ocs);
2305ef270ab1SKenneth D. Merry 				return;
2306ef270ab1SKenneth D. Merry 			}
2307ef270ab1SKenneth D. Merry 
2308ef270ab1SKenneth D. Merry 				/* Here the Domain lock is held */
2309ef270ab1SKenneth D. Merry 				ocs_list_foreach(&domain->sport_list, sport) {
2310ef270ab1SKenneth D. Merry 					if (ocs_sport_lock_try(sport) != TRUE) {
2311ef270ab1SKenneth D. Merry 						/* Didn't get the lock */
2312ef270ab1SKenneth D. Merry 						ocs_domain_unlock(domain);
2313ef270ab1SKenneth D. Merry 						ocs_device_unlock(ocs);
2314ef270ab1SKenneth D. Merry 						return;
2315ef270ab1SKenneth D. Merry 					}
2316ef270ab1SKenneth D. Merry 
2317ef270ab1SKenneth D. Merry 						/* Here the sport lock is held */
2318ef270ab1SKenneth D. Merry 						ocs_list_foreach(&sport->node_list, node) {
2319ef270ab1SKenneth D. Merry 							abort_counts += node->abort_cnt;
2320ef270ab1SKenneth D. Merry 						}
2321ef270ab1SKenneth D. Merry 
2322ef270ab1SKenneth D. Merry 					ocs_sport_unlock(sport);
2323ef270ab1SKenneth D. Merry 				}
2324ef270ab1SKenneth D. Merry 
2325ef270ab1SKenneth D. Merry 			ocs_domain_unlock(domain);
2326ef270ab1SKenneth D. Merry 		}
2327ef270ab1SKenneth D. Merry 
2328ef270ab1SKenneth D. Merry 	ocs_device_unlock(ocs);
2329ef270ab1SKenneth D. Merry 
2330ef270ab1SKenneth D. Merry 	ocs_mgmt_emit_int(textbuf, MGMT_MODE_RD, "node_abort_cnt", "%d" , abort_counts);
2331ef270ab1SKenneth D. Merry }
2332ef270ab1SKenneth D. Merry 
2333ef270ab1SKenneth D. Merry typedef struct ocs_mgmt_set_nvparms_result {
2334ef270ab1SKenneth D. Merry 	ocs_sem_t semaphore;
2335ef270ab1SKenneth D. Merry 	int32_t status;
2336ef270ab1SKenneth D. Merry } ocs_mgmt_set_nvparms_result_t;
2337ef270ab1SKenneth D. Merry 
2338ef270ab1SKenneth D. Merry static void
ocs_mgmt_set_nvparms_cb(int32_t status,void * ul_arg)2339ef270ab1SKenneth D. Merry ocs_mgmt_set_nvparms_cb(int32_t status, void *ul_arg)
2340ef270ab1SKenneth D. Merry {
2341ef270ab1SKenneth D. Merry 	ocs_mgmt_get_profile_list_result_t *result = ul_arg;
2342ef270ab1SKenneth D. Merry 
2343ef270ab1SKenneth D. Merry 	result->status = status;
2344ef270ab1SKenneth D. Merry 
2345ef270ab1SKenneth D. Merry 	ocs_sem_v(&(result->semaphore));
2346ef270ab1SKenneth D. Merry }
2347ef270ab1SKenneth D. Merry 
2348ef270ab1SKenneth D. Merry /**
2349ef270ab1SKenneth D. Merry  * @brief  Set wwn
2350ef270ab1SKenneth D. Merry  * @par Description Sets the Non-volatile worldwide names,
2351ef270ab1SKenneth D. Merry  * if provided.
2352ef270ab1SKenneth D. Merry  *
2353ef270ab1SKenneth D. Merry  * @param ocs Pointer to the ocs structure.
2354ef270ab1SKenneth D. Merry  * @param name Name of the action being performed.
2355ef270ab1SKenneth D. Merry  * @param wwn_p Requested new WWN values.
2356ef270ab1SKenneth D. Merry  *
2357ef270ab1SKenneth D. Merry  * @return Returns 0 on success, non-zero on failure.
2358ef270ab1SKenneth D. Merry  */
2359ef270ab1SKenneth D. Merry static int32_t
set_nv_wwn(ocs_t * ocs,char * name,char * wwn_p)2360ef270ab1SKenneth D. Merry set_nv_wwn(ocs_t *ocs, char *name, char *wwn_p)
2361ef270ab1SKenneth D. Merry {
2362ef270ab1SKenneth D. Merry 	ocs_mgmt_get_nvparms_result_t result;
2363ef270ab1SKenneth D. Merry 	uint8_t new_wwpn[8];
2364ef270ab1SKenneth D. Merry 	uint8_t new_wwnn[8];
2365ef270ab1SKenneth D. Merry 	char *wwpn_p = NULL;
2366ef270ab1SKenneth D. Merry 	char *wwnn_p = NULL;
2367ef270ab1SKenneth D. Merry 	int32_t rc = -1;
23684915e5c7SRam Kishore Vegesna 	int wwpn = 0;
23694915e5c7SRam Kishore Vegesna 	int wwnn = 0;
2370ef270ab1SKenneth D. Merry 	int i;
2371ef270ab1SKenneth D. Merry 
2372ef270ab1SKenneth D. Merry 	/* This is a read-modify-write operation, so first we have to read
2373ef270ab1SKenneth D. Merry 	 * the current values
2374ef270ab1SKenneth D. Merry 	 */
2375ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "set_nv_wwn1");
2376ef270ab1SKenneth D. Merry 
2377ef270ab1SKenneth D. Merry 	rc = ocs_hw_get_nvparms(&ocs->hw, ocs_mgmt_get_nvparms_cb, &result);
2378ef270ab1SKenneth D. Merry 
2379ef270ab1SKenneth D. Merry 	if (rc == OCS_HW_RTN_SUCCESS) {
2380ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2381ef270ab1SKenneth D. Merry 			/* Undefined failure */
2382ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
2383ef270ab1SKenneth D. Merry 			return -ENXIO;
2384ef270ab1SKenneth D. Merry 		}
2385ef270ab1SKenneth D. Merry 		if (result.status != 0) {
2386ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "getting nvparms status 0x%x\n", result.status);
2387ef270ab1SKenneth D. Merry 			return -1;
2388ef270ab1SKenneth D. Merry 		}
2389ef270ab1SKenneth D. Merry 	}
2390ef270ab1SKenneth D. Merry 
2391ef270ab1SKenneth D. Merry 	/* wwn_p contains wwpn_p@wwnn_p values */
2392ef270ab1SKenneth D. Merry 	if (wwn_p != NULL) {
2393ef270ab1SKenneth D. Merry 		wwpn_p = ocs_strsep(&wwn_p, "@");
2394ef270ab1SKenneth D. Merry 		wwnn_p = wwn_p;
2395ef270ab1SKenneth D. Merry 	}
2396ef270ab1SKenneth D. Merry 
23974915e5c7SRam Kishore Vegesna 	if (wwpn_p != NULL) {
2398ef270ab1SKenneth D. Merry 		wwpn = ocs_strcmp(wwpn_p, "NA");
23994915e5c7SRam Kishore Vegesna 	}
24004915e5c7SRam Kishore Vegesna 
24014915e5c7SRam Kishore Vegesna 	if (wwnn_p != NULL) {
2402ef270ab1SKenneth D. Merry 		wwnn = ocs_strcmp(wwnn_p, "NA");
24034915e5c7SRam Kishore Vegesna 	}
2404ef270ab1SKenneth D. Merry 
2405ef270ab1SKenneth D. Merry 	/* Parse the new WWPN */
2406ef270ab1SKenneth D. Merry 	if ((wwpn_p != NULL) && (wwpn != 0)) {
2407ef270ab1SKenneth D. Merry 		if (ocs_sscanf(wwpn_p, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
2408ef270ab1SKenneth D. Merry 				&(new_wwpn[0]), &(new_wwpn[1]), &(new_wwpn[2]),
2409ef270ab1SKenneth D. Merry 				&(new_wwpn[3]), &(new_wwpn[4]), &(new_wwpn[5]),
2410ef270ab1SKenneth D. Merry 				&(new_wwpn[6]), &(new_wwpn[7])) != 8) {
2411ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "can't parse WWPN %s\n", wwpn_p);
2412ef270ab1SKenneth D. Merry 			return -1;
2413ef270ab1SKenneth D. Merry 		}
2414ef270ab1SKenneth D. Merry 	}
2415ef270ab1SKenneth D. Merry 
2416ef270ab1SKenneth D. Merry 	/* Parse the new WWNN */
2417ef270ab1SKenneth D. Merry 	if ((wwnn_p != NULL) && (wwnn != 0 )) {
2418ef270ab1SKenneth D. Merry 		if (ocs_sscanf(wwnn_p, "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
2419ef270ab1SKenneth D. Merry 				&(new_wwnn[0]), &(new_wwnn[1]), &(new_wwnn[2]),
2420ef270ab1SKenneth D. Merry 				&(new_wwnn[3]), &(new_wwnn[4]), &(new_wwnn[5]),
2421ef270ab1SKenneth D. Merry 				&(new_wwnn[6]), &(new_wwnn[7])) != 8) {
2422ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "can't parse WWNN %s\n", wwnn_p);
2423ef270ab1SKenneth D. Merry 			return -1;
2424ef270ab1SKenneth D. Merry 		}
2425ef270ab1SKenneth D. Merry 	}
2426ef270ab1SKenneth D. Merry 
2427ef270ab1SKenneth D. Merry 	for (i = 0; i < 8; i++) {
2428ef270ab1SKenneth D. Merry 		/* Use active wwpn, if new one is not provided */
2429ef270ab1SKenneth D. Merry 		if (wwpn == 0) {
2430ef270ab1SKenneth D. Merry 			new_wwpn[i] = result.wwpn[i];
2431ef270ab1SKenneth D. Merry 		}
2432ef270ab1SKenneth D. Merry 
2433ef270ab1SKenneth D. Merry 		/* Use active wwnn, if new one is not provided */
2434ef270ab1SKenneth D. Merry 		if (wwnn == 0) {
2435ef270ab1SKenneth D. Merry 			new_wwnn[i] = result.wwnn[i];
2436ef270ab1SKenneth D. Merry 		}
2437ef270ab1SKenneth D. Merry 	}
2438ef270ab1SKenneth D. Merry 
2439ef270ab1SKenneth D. Merry 	/* Modify the nv_wwnn and nv_wwpn, then write it back */
2440ef270ab1SKenneth D. Merry 	ocs_sem_init(&(result.semaphore), 0, "set_nv_wwn2");
2441ef270ab1SKenneth D. Merry 
2442ef270ab1SKenneth D. Merry 	rc = ocs_hw_set_nvparms(&ocs->hw, ocs_mgmt_set_nvparms_cb, new_wwpn,
2443ef270ab1SKenneth D. Merry 				 new_wwnn, result.hard_alpa, result.preferred_d_id,
2444ef270ab1SKenneth D. Merry 				 &result);
2445ef270ab1SKenneth D. Merry 	if (rc == OCS_HW_RTN_SUCCESS) {
2446ef270ab1SKenneth D. Merry 		if (ocs_sem_p(&(result.semaphore), OCS_SEM_FOREVER) != 0) {
2447ef270ab1SKenneth D. Merry 			/* Undefined failure */
2448ef270ab1SKenneth D. Merry 			ocs_log_err(ocs, "ocs_sem_p failed\n");
2449ef270ab1SKenneth D. Merry 			return -ENXIO;
2450ef270ab1SKenneth D. Merry 		}
2451ef270ab1SKenneth D. Merry 		if (result.status != 0) {
2452ef270ab1SKenneth D. Merry 			ocs_log_test(ocs, "setting wwn status 0x%x\n", result.status);
2453ef270ab1SKenneth D. Merry 			return -1;
2454ef270ab1SKenneth D. Merry 		}
2455ef270ab1SKenneth D. Merry 	}
2456ef270ab1SKenneth D. Merry 
2457ef270ab1SKenneth D. Merry 	return rc;
2458ef270ab1SKenneth D. Merry }
2459ef270ab1SKenneth D. Merry 
2460ef270ab1SKenneth D. Merry static int
set_tgt_rscn_delay(ocs_t * ocs,char * name,char * value)2461ef270ab1SKenneth D. Merry set_tgt_rscn_delay(ocs_t *ocs, char *name, char *value)
2462ef270ab1SKenneth D. Merry {
2463ef270ab1SKenneth D. Merry 	ocs->tgt_rscn_delay_msec = ocs_strtoul(value, NULL, 0) * 1000;
2464ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2465ef270ab1SKenneth D. Merry 	return 0;
2466ef270ab1SKenneth D. Merry }
2467ef270ab1SKenneth D. Merry 
2468ef270ab1SKenneth D. Merry static int
set_tgt_rscn_period(ocs_t * ocs,char * name,char * value)2469ef270ab1SKenneth D. Merry set_tgt_rscn_period(ocs_t *ocs, char *name, char *value)
2470ef270ab1SKenneth D. Merry {
2471ef270ab1SKenneth D. Merry 	ocs->tgt_rscn_period_msec = ocs_strtoul(value, NULL, 0) * 1000;
2472ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2473ef270ab1SKenneth D. Merry 	return 0;
2474ef270ab1SKenneth D. Merry }
2475ef270ab1SKenneth D. Merry 
2476ef270ab1SKenneth D. Merry static int
set_inject_drop_cmd(ocs_t * ocs,char * name,char * value)2477ef270ab1SKenneth D. Merry set_inject_drop_cmd(ocs_t *ocs, char *name, char *value)
2478ef270ab1SKenneth D. Merry {
2479ef270ab1SKenneth D. Merry 	ocs->err_injection = (ocs_strtoul(value, NULL, 0) == 0 ? NO_ERR_INJECT : INJECT_DROP_CMD);
2480ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2481ef270ab1SKenneth D. Merry 	return 0;
2482ef270ab1SKenneth D. Merry }
2483ef270ab1SKenneth D. Merry 
2484ef270ab1SKenneth D. Merry static int
set_inject_free_drop_cmd(ocs_t * ocs,char * name,char * value)2485ef270ab1SKenneth D. Merry set_inject_free_drop_cmd(ocs_t *ocs, char *name, char *value)
2486ef270ab1SKenneth D. Merry {
2487ef270ab1SKenneth D. Merry 	ocs->err_injection = (ocs_strtoul(value, NULL, 0) == 0 ? NO_ERR_INJECT : INJECT_FREE_DROPPED);
2488ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2489ef270ab1SKenneth D. Merry 	return 0;
2490ef270ab1SKenneth D. Merry }
2491ef270ab1SKenneth D. Merry 
2492ef270ab1SKenneth D. Merry static int
set_inject_drop_data(ocs_t * ocs,char * name,char * value)2493ef270ab1SKenneth D. Merry set_inject_drop_data(ocs_t *ocs, char *name, char *value)
2494ef270ab1SKenneth D. Merry {
2495ef270ab1SKenneth D. Merry 	ocs->err_injection = (ocs_strtoul(value, NULL, 0) == 0 ? NO_ERR_INJECT : INJECT_DROP_DATA);
2496ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2497ef270ab1SKenneth D. Merry 	return 0;
2498ef270ab1SKenneth D. Merry }
2499ef270ab1SKenneth D. Merry 
2500ef270ab1SKenneth D. Merry static int
set_inject_drop_resp(ocs_t * ocs,char * name,char * value)2501ef270ab1SKenneth D. Merry set_inject_drop_resp(ocs_t *ocs, char *name, char *value)
2502ef270ab1SKenneth D. Merry {
2503ef270ab1SKenneth D. Merry 	ocs->err_injection = (ocs_strtoul(value, NULL, 0) == 0 ? NO_ERR_INJECT : INJECT_DROP_RESP);
2504ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2505ef270ab1SKenneth D. Merry 	return 0;
2506ef270ab1SKenneth D. Merry }
2507ef270ab1SKenneth D. Merry 
2508ef270ab1SKenneth D. Merry static int
set_cmd_err_inject(ocs_t * ocs,char * name,char * value)2509ef270ab1SKenneth D. Merry set_cmd_err_inject(ocs_t *ocs, char *name, char *value)
2510ef270ab1SKenneth D. Merry {
2511ef270ab1SKenneth D. Merry 	ocs->cmd_err_inject = ocs_strtoul(value, NULL, 0);
2512ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2513ef270ab1SKenneth D. Merry 	return 0;
2514ef270ab1SKenneth D. Merry }
2515ef270ab1SKenneth D. Merry 
2516ef270ab1SKenneth D. Merry static int
set_cmd_delay_value(ocs_t * ocs,char * name,char * value)2517ef270ab1SKenneth D. Merry set_cmd_delay_value(ocs_t *ocs, char *name, char *value)
2518ef270ab1SKenneth D. Merry {
2519ef270ab1SKenneth D. Merry 	ocs->delay_value_msec = ocs_strtoul(value, NULL, 0);
2520ef270ab1SKenneth D. Merry 	ocs->err_injection = (ocs->delay_value_msec == 0 ? NO_ERR_INJECT : INJECT_DELAY_CMD);
2521ef270ab1SKenneth D. Merry 	ocs_log_debug(ocs, "mgmt set: %s %s\n", name, value);
2522ef270ab1SKenneth D. Merry 	return 0;
2523ef270ab1SKenneth D. Merry }
2524ef270ab1SKenneth D. Merry 
2525ef270ab1SKenneth D. Merry /**
2526ef270ab1SKenneth D. Merry  * @brief parse a WWN from a string into a 64-bit value
2527ef270ab1SKenneth D. Merry  *
2528ef270ab1SKenneth D. Merry  * Given a pointer to a string, parse the string into a 64-bit
2529ef270ab1SKenneth D. Merry  * WWN value.  The format of the string must be xx:xx:xx:xx:xx:xx:xx:xx
2530ef270ab1SKenneth D. Merry  *
2531ef270ab1SKenneth D. Merry  * @param wwn_in pointer to the string to be parsed
2532ef270ab1SKenneth D. Merry  * @param wwn_out pointer to uint64_t in which to put the parsed result
2533ef270ab1SKenneth D. Merry  *
2534ef270ab1SKenneth D. Merry  * @return 0 if successful, non-zero if the WWN is malformed and couldn't be parsed
2535ef270ab1SKenneth D. Merry  */
2536ef270ab1SKenneth D. Merry int
parse_wwn(char * wwn_in,uint64_t * wwn_out)2537ef270ab1SKenneth D. Merry parse_wwn(char *wwn_in, uint64_t *wwn_out)
2538ef270ab1SKenneth D. Merry {
2539ef270ab1SKenneth D. Merry 	uint8_t byte0;
2540ef270ab1SKenneth D. Merry 	uint8_t byte1;
2541ef270ab1SKenneth D. Merry 	uint8_t byte2;
2542ef270ab1SKenneth D. Merry 	uint8_t byte3;
2543ef270ab1SKenneth D. Merry 	uint8_t byte4;
2544ef270ab1SKenneth D. Merry 	uint8_t byte5;
2545ef270ab1SKenneth D. Merry 	uint8_t byte6;
2546ef270ab1SKenneth D. Merry 	uint8_t byte7;
2547ef270ab1SKenneth D. Merry 	int rc;
2548ef270ab1SKenneth D. Merry 
2549ef270ab1SKenneth D. Merry 	rc = ocs_sscanf(wwn_in, "0x%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx",
2550ef270ab1SKenneth D. Merry 				&byte0, &byte1, &byte2, &byte3,
2551ef270ab1SKenneth D. Merry 				&byte4, &byte5, &byte6, &byte7);
2552ef270ab1SKenneth D. Merry 
2553ef270ab1SKenneth D. Merry 	if (rc == 8) {
2554ef270ab1SKenneth D. Merry 		*wwn_out = ((uint64_t)byte0 << 56) |
2555ef270ab1SKenneth D. Merry 				((uint64_t)byte1 << 48) |
2556ef270ab1SKenneth D. Merry 				((uint64_t)byte2 << 40) |
2557ef270ab1SKenneth D. Merry 				((uint64_t)byte3 << 32) |
2558ef270ab1SKenneth D. Merry 				((uint64_t)byte4 << 24) |
2559ef270ab1SKenneth D. Merry 				((uint64_t)byte5 << 16) |
2560ef270ab1SKenneth D. Merry 				((uint64_t)byte6 <<  8) |
2561ef270ab1SKenneth D. Merry 				((uint64_t)byte7);
2562ef270ab1SKenneth D. Merry 		return 0;
2563ef270ab1SKenneth D. Merry 
2564ef270ab1SKenneth D. Merry 	} else {
2565ef270ab1SKenneth D. Merry 		return 1;
2566ef270ab1SKenneth D. Merry 	}
2567ef270ab1SKenneth D. Merry }
2568ef270ab1SKenneth D. Merry 
2569ef270ab1SKenneth D. Merry static char *mode_string(int mode);
2570ef270ab1SKenneth D. Merry 
2571ef270ab1SKenneth D. Merry /**
2572ef270ab1SKenneth D. Merry  * @ingroup mgmt
2573ef270ab1SKenneth D. Merry  * @brief Generate the beginning of a numbered section in a management XML document.
2574ef270ab1SKenneth D. Merry  *
2575ef270ab1SKenneth D. Merry  * @par Description
2576ef270ab1SKenneth D. Merry  * This function begins a section. The XML information is appended to
2577ef270ab1SKenneth D. Merry  * the textbuf. This form of the function is used for sections that might have
2578ef270ab1SKenneth D. Merry  * multiple instances, such as a node or a SLI Port (sport). The index number
2579ef270ab1SKenneth D. Merry  * is appended to the name.
2580ef270ab1SKenneth D. Merry  *
2581ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2582ef270ab1SKenneth D. Merry  * @param name Name of the section.
2583ef270ab1SKenneth D. Merry  * @param index Index number of this instance of the section.
2584ef270ab1SKenneth D. Merry  *
2585ef270ab1SKenneth D. Merry  * @return None.
2586ef270ab1SKenneth D. Merry  */
2587ef270ab1SKenneth D. Merry 
ocs_mgmt_start_section(ocs_textbuf_t * textbuf,const char * name,int index)2588ef270ab1SKenneth D. Merry extern void ocs_mgmt_start_section(ocs_textbuf_t *textbuf, const char *name, int index)
2589ef270ab1SKenneth D. Merry {
2590ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "<%s instance=\"%d\">\n", name, index);
2591ef270ab1SKenneth D. Merry }
2592ef270ab1SKenneth D. Merry 
2593ef270ab1SKenneth D. Merry /**
2594ef270ab1SKenneth D. Merry  * @ingroup mgmt
2595ef270ab1SKenneth D. Merry  * @brief Generate the beginning of an unnumbered section in a management XML document.
2596ef270ab1SKenneth D. Merry  *
2597ef270ab1SKenneth D. Merry  * @par Description
2598ef270ab1SKenneth D. Merry  * This function begins a section. The XML information is appended to
2599ef270ab1SKenneth D. Merry  * the textbuf. This form of the function is used for sections that have
2600ef270ab1SKenneth D. Merry  * a single instance only. Therefore, no index number is needed.
2601ef270ab1SKenneth D. Merry  *
2602ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2603ef270ab1SKenneth D. Merry  * @param name Name of the section.
2604ef270ab1SKenneth D. Merry  *
2605ef270ab1SKenneth D. Merry  * @return None.
2606ef270ab1SKenneth D. Merry  */
2607ef270ab1SKenneth D. Merry 
ocs_mgmt_start_unnumbered_section(ocs_textbuf_t * textbuf,const char * name)2608ef270ab1SKenneth D. Merry extern void ocs_mgmt_start_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
2609ef270ab1SKenneth D. Merry {
2610ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "<%s>\n", name);
2611ef270ab1SKenneth D. Merry }
2612ef270ab1SKenneth D. Merry 
2613ef270ab1SKenneth D. Merry /**
2614ef270ab1SKenneth D. Merry  * @ingroup mgmt
2615ef270ab1SKenneth D. Merry  * @brief Generate the end of a section in a management XML document.
2616ef270ab1SKenneth D. Merry  *
2617ef270ab1SKenneth D. Merry  * @par Description
2618ef270ab1SKenneth D. Merry  * This function ends a section. The XML information is appended to
2619ef270ab1SKenneth D. Merry  * the textbuf.
2620ef270ab1SKenneth D. Merry  *
2621ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2622ef270ab1SKenneth D. Merry  * @param name Name of the section.
2623ef270ab1SKenneth D. Merry  *
2624ef270ab1SKenneth D. Merry  * @return None.
2625ef270ab1SKenneth D. Merry  */
2626ef270ab1SKenneth D. Merry 
ocs_mgmt_end_unnumbered_section(ocs_textbuf_t * textbuf,const char * name)2627ef270ab1SKenneth D. Merry void ocs_mgmt_end_unnumbered_section(ocs_textbuf_t *textbuf, const char *name)
2628ef270ab1SKenneth D. Merry {
2629ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "</%s>\n", name);
2630ef270ab1SKenneth D. Merry }
2631ef270ab1SKenneth D. Merry 
2632ef270ab1SKenneth D. Merry /**
2633ef270ab1SKenneth D. Merry  * @ingroup mgmt
2634ef270ab1SKenneth D. Merry  * @brief Generate the indexed end of a section in a management XML document.
2635ef270ab1SKenneth D. Merry  *
2636ef270ab1SKenneth D. Merry  * @par Description
2637ef270ab1SKenneth D. Merry  * This function ends a section. The XML information is appended to
2638ef270ab1SKenneth D. Merry  * the textbuf.
2639ef270ab1SKenneth D. Merry  *
2640ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2641ef270ab1SKenneth D. Merry  * @param name Name of the section.
2642ef270ab1SKenneth D. Merry  * @param index Index number of this instance of the section.
2643ef270ab1SKenneth D. Merry  *
2644ef270ab1SKenneth D. Merry  * @return None.
2645ef270ab1SKenneth D. Merry  */
2646ef270ab1SKenneth D. Merry 
ocs_mgmt_end_section(ocs_textbuf_t * textbuf,const char * name,int index)2647ef270ab1SKenneth D. Merry void ocs_mgmt_end_section(ocs_textbuf_t *textbuf, const char *name, int index)
2648ef270ab1SKenneth D. Merry {
2649ef270ab1SKenneth D. Merry 
2650ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "</%s>\n", name);
2651ef270ab1SKenneth D. Merry 
2652ef270ab1SKenneth D. Merry }
2653ef270ab1SKenneth D. Merry 
2654ef270ab1SKenneth D. Merry /**
2655ef270ab1SKenneth D. Merry  * @ingroup mgmt
2656ef270ab1SKenneth D. Merry  * @brief Generate a property, with no value, in a management XML document.
2657ef270ab1SKenneth D. Merry  *
2658ef270ab1SKenneth D. Merry  * @par Description
2659ef270ab1SKenneth D. Merry  * This function generates a property name. The XML information is appended to
2660ef270ab1SKenneth D. Merry  * the textbuf. This form of the function is used by the list functions
2661ef270ab1SKenneth D. Merry  * when the property name only (and not the current value) is given.
2662ef270ab1SKenneth D. Merry  *
2663ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2664ef270ab1SKenneth D. Merry  * @param mode Defines whether the property is read(r)/write(w)/executable(x).
2665ef270ab1SKenneth D. Merry  * @param name Name of the property.
2666ef270ab1SKenneth D. Merry  *
2667ef270ab1SKenneth D. Merry  * @return None.
2668ef270ab1SKenneth D. Merry  */
2669ef270ab1SKenneth D. Merry 
ocs_mgmt_emit_property_name(ocs_textbuf_t * textbuf,int mode,const char * name)2670ef270ab1SKenneth D. Merry void ocs_mgmt_emit_property_name(ocs_textbuf_t *textbuf, int mode, const char *name)
2671ef270ab1SKenneth D. Merry {
2672ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "<%s mode=\"%s\"/>\n", name, mode_string(mode));
2673ef270ab1SKenneth D. Merry }
2674ef270ab1SKenneth D. Merry 
2675ef270ab1SKenneth D. Merry /**
2676ef270ab1SKenneth D. Merry  * @ingroup mgmt
2677ef270ab1SKenneth D. Merry  * @brief Generate a property with a string value in a management XML document.
2678ef270ab1SKenneth D. Merry  *
2679ef270ab1SKenneth D. Merry  * @par Description
2680ef270ab1SKenneth D. Merry  * This function generates a property name and a string value.
2681ef270ab1SKenneth D. Merry  * The XML information is appended to the textbuf.
2682ef270ab1SKenneth D. Merry  *
2683ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2684ef270ab1SKenneth D. Merry  * @param mode Defines whether the property is read(r)/write(w)/executable(x).
2685ef270ab1SKenneth D. Merry  * @param name Name of the property.
2686ef270ab1SKenneth D. Merry  * @param value Value of the property.
2687ef270ab1SKenneth D. Merry  *
2688ef270ab1SKenneth D. Merry  * @return None.
2689ef270ab1SKenneth D. Merry  */
2690ef270ab1SKenneth D. Merry 
ocs_mgmt_emit_string(ocs_textbuf_t * textbuf,int mode,const char * name,const char * value)2691ef270ab1SKenneth D. Merry void ocs_mgmt_emit_string(ocs_textbuf_t *textbuf, int mode, const char *name, const char *value)
2692ef270ab1SKenneth D. Merry {
2693ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "<%s mode=\"%s\">%s</%s>\n", name, mode_string(mode), value, name);
2694ef270ab1SKenneth D. Merry }
2695ef270ab1SKenneth D. Merry 
2696ef270ab1SKenneth D. Merry /**
2697ef270ab1SKenneth D. Merry  * @ingroup mgmt
2698ef270ab1SKenneth D. Merry  * @brief Generate a property with an integer value in a management XML document.
2699ef270ab1SKenneth D. Merry  *
2700ef270ab1SKenneth D. Merry  * @par Description
2701ef270ab1SKenneth D. Merry  * This function generates a property name and an integer value.
2702ef270ab1SKenneth D. Merry  * The XML information is appended to the textbuf.
2703ef270ab1SKenneth D. Merry  *
2704ef270ab1SKenneth D. Merry  * @param textbuf Pointer to driver dump text buffer.
2705ef270ab1SKenneth D. Merry  * @param mode Defines whether the property is read(r)/write(w)/executable(x).
2706ef270ab1SKenneth D. Merry  * @param name Name of the property.
2707ef270ab1SKenneth D. Merry  * @param fmt A printf format for formatting the integer value.
2708ef270ab1SKenneth D. Merry  *
2709ef270ab1SKenneth D. Merry  * @return none
2710ef270ab1SKenneth D. Merry  */
2711ef270ab1SKenneth D. Merry 
ocs_mgmt_emit_int(ocs_textbuf_t * textbuf,int mode,const char * name,const char * fmt,...)2712ef270ab1SKenneth D. Merry void ocs_mgmt_emit_int(ocs_textbuf_t *textbuf, int mode, const char *name, const char *fmt, ...)
2713ef270ab1SKenneth D. Merry {
2714ef270ab1SKenneth D. Merry 	va_list ap;
2715ef270ab1SKenneth D. Merry 	char valuebuf[64];
2716ef270ab1SKenneth D. Merry 
2717ef270ab1SKenneth D. Merry 	va_start(ap, fmt);
2718ef270ab1SKenneth D. Merry 	ocs_vsnprintf(valuebuf, sizeof(valuebuf), fmt, ap);
2719ef270ab1SKenneth D. Merry 	va_end(ap);
2720ef270ab1SKenneth D. Merry 
2721ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "<%s mode=\"%s\">%s</%s>\n", name, mode_string(mode), valuebuf, name);
2722ef270ab1SKenneth D. Merry }
2723ef270ab1SKenneth D. Merry 
2724ef270ab1SKenneth D. Merry /**
2725ef270ab1SKenneth D. Merry  * @ingroup mgmt
2726ef270ab1SKenneth D. Merry  * @brief Generate a property with a boolean value in a management XML document.
2727ef270ab1SKenneth D. Merry  *
2728ef270ab1SKenneth D. Merry  * @par Description
2729ef270ab1SKenneth D. Merry  * This function generates a property name and a boolean value.
2730ef270ab1SKenneth D. Merry  * The XML information is appended to the textbuf.
2731ef270ab1SKenneth D. Merry  *
2732ef270ab1SKenneth D. Merry  * @param textbuf Pointer to the driver dump text buffer.
2733ef270ab1SKenneth D. Merry  * @param mode Defines whether the property is read(r)/write(w)/executable(x).
2734ef270ab1SKenneth D. Merry  * @param name Name of the property.
2735ef270ab1SKenneth D. Merry  * @param value Boolean value to be added to the textbuf.
2736ef270ab1SKenneth D. Merry  *
2737ef270ab1SKenneth D. Merry  * @return None.
2738ef270ab1SKenneth D. Merry  */
2739ef270ab1SKenneth D. Merry 
ocs_mgmt_emit_boolean(ocs_textbuf_t * textbuf,int mode,const char * name,int value)2740ef270ab1SKenneth D. Merry void ocs_mgmt_emit_boolean(ocs_textbuf_t *textbuf, int mode, const char *name, int value)
2741ef270ab1SKenneth D. Merry {
2742ef270ab1SKenneth D. Merry 	char *valuebuf = value ? "true" : "false";
2743ef270ab1SKenneth D. Merry 
2744ef270ab1SKenneth D. Merry 	ocs_textbuf_printf(textbuf, "<%s mode=\"%s\">%s</%s>\n", name, mode_string(mode), valuebuf, name);
2745ef270ab1SKenneth D. Merry }
2746ef270ab1SKenneth D. Merry 
mode_string(int mode)2747ef270ab1SKenneth D. Merry static char *mode_string(int mode)
2748ef270ab1SKenneth D. Merry {
2749ef270ab1SKenneth D. Merry 	static char mode_str[4];
2750ef270ab1SKenneth D. Merry 
2751ef270ab1SKenneth D. Merry 	mode_str[0] = '\0';
2752ef270ab1SKenneth D. Merry 	if (mode & MGMT_MODE_RD) {
2753ef270ab1SKenneth D. Merry 		strcat(mode_str, "r");
2754ef270ab1SKenneth D. Merry 	}
2755ef270ab1SKenneth D. Merry 	if (mode & MGMT_MODE_WR) {
2756ef270ab1SKenneth D. Merry 		strcat(mode_str, "w");
2757ef270ab1SKenneth D. Merry 	}
2758ef270ab1SKenneth D. Merry 	if (mode & MGMT_MODE_EX) {
2759ef270ab1SKenneth D. Merry 		strcat(mode_str, "x");
2760ef270ab1SKenneth D. Merry 	}
2761ef270ab1SKenneth D. Merry 
2762ef270ab1SKenneth D. Merry 	return mode_str;
2763ef270ab1SKenneth D. Merry 
2764ef270ab1SKenneth D. Merry }
2765