1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at
9 * http://www.opensource.org/licenses/cddl1.txt.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004-2012 Emulex. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2020 RackTop Systems, Inc.
26 */
27
28 #include <emlxs.h>
29
30 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31 EMLXS_MSG_DEF(EMLXS_DFC_C);
32
33 static int32_t emlxs_dfc_get_rev(emlxs_hba_t *hba, dfc_t *dfc,
34 int32_t mode);
35 static int32_t emlxs_dfc_get_hbainfo(emlxs_hba_t *hba, dfc_t *dfc,
36 int32_t mode);
37 static int32_t emlxs_dfc_get_hbastats(emlxs_hba_t *hba, dfc_t *dfc,
38 int32_t mode);
39 static int32_t emlxs_dfc_get_drvstats(emlxs_hba_t *hba, dfc_t *dfc,
40 int32_t mode);
41 static int32_t emlxs_dfc_set_diag(emlxs_hba_t *hba, dfc_t *dfc,
42 int32_t mode);
43 static int32_t emlxs_dfc_send_mbox(emlxs_hba_t *hba, dfc_t *dfc,
44 int32_t mode);
45 static int32_t emlxs_dfc_read_pci(emlxs_hba_t *hba, dfc_t *dfc,
46 int32_t mode);
47 static int32_t emlxs_dfc_write_pci(emlxs_hba_t *hba, dfc_t *dfc,
48 int32_t mode);
49 static int32_t emlxs_dfc_get_cfg(emlxs_hba_t *hba, dfc_t *dfc,
50 int32_t mode);
51 static int32_t emlxs_dfc_set_cfg(emlxs_hba_t *hba, dfc_t *dfc,
52 int32_t mode);
53 static int32_t emlxs_dfc_send_menlo(emlxs_hba_t *hba, dfc_t *dfc,
54 int32_t mode);
55 static int32_t emlxs_dfc_send_ct(emlxs_hba_t *hba, dfc_t *dfc,
56 int32_t mode);
57 static int32_t emlxs_dfc_send_ct_rsp(emlxs_hba_t *hba, dfc_t *dfc,
58 int32_t mode);
59 static int32_t emlxs_dfc_write_flash(emlxs_hba_t *hba, dfc_t *dfc,
60 int32_t mode);
61 static int32_t emlxs_dfc_read_flash(emlxs_hba_t *hba, dfc_t *dfc,
62 int32_t mode);
63 static int32_t emlxs_dfc_send_els(emlxs_hba_t *hba, dfc_t *dfc,
64 int32_t mode);
65 static int32_t emlxs_dfc_loopback_test(emlxs_hba_t *hba, dfc_t *dfc,
66 int32_t mode);
67 static int32_t emlxs_dfc_reset_port(emlxs_hba_t *hba, dfc_t *dfc,
68 int32_t mode);
69 static int32_t emlxs_dfc_get_dump_region(emlxs_hba_t *hba, dfc_t *dfc,
70 int32_t mode);
71 static int32_t emlxs_dfc_loopback_mode(emlxs_hba_t *hba, dfc_t *dfc,
72 int32_t mode);
73 static int32_t emlxs_dfc_get_ioinfo(emlxs_hba_t *hba, dfc_t *dfc,
74 int32_t mode);
75 static int32_t emlxs_dfc_get_linkinfo(emlxs_hba_t *hba, dfc_t *dfc,
76 int32_t mode);
77 static int32_t emlxs_dfc_read_mem(emlxs_hba_t *hba, dfc_t *dfc,
78 int32_t mode);
79 static int32_t emlxs_dfc_write_mem(emlxs_hba_t *hba, dfc_t *dfc,
80 int32_t mode);
81 static int32_t emlxs_dfc_write_ctlreg(emlxs_hba_t *hba, dfc_t *dfc,
82 int32_t mode);
83 static int32_t emlxs_dfc_read_ctlreg(emlxs_hba_t *hba, dfc_t *dfc,
84 int32_t mode);
85 static int32_t emlxs_dfc_get_event(emlxs_hba_t *hba, dfc_t *dfc,
86 int32_t mode);
87 static int32_t emlxs_dfc_set_event(emlxs_hba_t *hba, dfc_t *dfc,
88 int32_t mode);
89 static int32_t emlxs_dfc_get_eventinfo(emlxs_hba_t *hba, dfc_t *dfc,
90 int32_t mode);
91 static int32_t emlxs_dfc_get_nodeinfo(emlxs_hba_t *hba, dfc_t *dfc,
92 int32_t mode);
93
94 #ifdef SFCT_SUPPORT
95 static int32_t emlxs_dfc_get_fctstat(emlxs_hba_t *hba, dfc_t *dfc,
96 int32_t mode);
97 #endif /* SFCT_SUPPORT */
98
99 static int32_t emlxs_dfc_create_vport(emlxs_hba_t *hba, dfc_t *dfc,
100 int32_t mode);
101 static int32_t emlxs_dfc_destroy_vport(emlxs_hba_t *hba, dfc_t *dfc,
102 int32_t mode);
103 static int32_t emlxs_dfc_get_vportinfo(emlxs_hba_t *hba, dfc_t *dfc,
104 int32_t mode);
105 static int32_t emlxs_dfc_npiv_resource(emlxs_hba_t *hba, dfc_t *dfc,
106 int32_t mode);
107 static int32_t emlxs_dfc_npiv_test(emlxs_hba_t *hba, dfc_t *dfc,
108 int32_t mode);
109 static emlxs_port_t *emlxs_vport_find_wwpn(emlxs_hba_t *hba, uint8_t *wwpn);
110
111 #ifdef DHCHAP_SUPPORT
112 static int32_t emlxs_dfc_init_auth(emlxs_hba_t *hba, dfc_t *dfc,
113 int32_t mode);
114 static int32_t emlxs_dfc_get_auth_cfg(emlxs_hba_t *hba, dfc_t *dfc,
115 int32_t mode);
116 static int32_t emlxs_dfc_set_auth_cfg(emlxs_hba_t *hba, dfc_t *dfc,
117 int32_t mode);
118 static int32_t emlxs_dfc_get_auth_pwd(emlxs_hba_t *hba, dfc_t *dfc,
119 int32_t mode);
120 static int32_t emlxs_dfc_set_auth_pwd(emlxs_hba_t *hba, dfc_t *dfc,
121 int32_t mode);
122 static int32_t emlxs_dfc_get_auth_status(emlxs_hba_t *hba, dfc_t *dfc,
123 int32_t mode);
124 static int32_t emlxs_dfc_get_auth_cfg_table(emlxs_hba_t *hba,
125 dfc_t *dfc, int32_t mode);
126 static int32_t emlxs_dfc_get_auth_key_table(emlxs_hba_t *hba,
127 dfc_t *dfc, int32_t mode);
128 #endif /* DHCHAP_SUPPORT */
129
130 #ifdef SAN_DIAG_SUPPORT
131 static int32_t emlxs_dfc_sd_set_bucket(emlxs_hba_t *hba, dfc_t *dfc,
132 int32_t mode);
133 static int32_t emlxs_dfc_sd_destroy_bucket(emlxs_hba_t *hba,
134 dfc_t *dfc, int32_t mode);
135 static int32_t emlxs_dfc_sd_get_bucket(emlxs_hba_t *hba, dfc_t *dfc,
136 int32_t mode);
137 static int32_t emlxs_dfc_sd_start_collection(emlxs_hba_t *hba,
138 dfc_t *dfc, int32_t mode);
139 static int32_t emlxs_dfc_sd_stop_collection(emlxs_hba_t *hba,
140 dfc_t *dfc, int32_t mode);
141 static int32_t emlxs_dfc_sd_reset_collection(emlxs_hba_t *hba,
142 dfc_t *dfc, int32_t mode);
143 static int32_t emlxs_dfc_sd_get_data(emlxs_hba_t *hba, dfc_t *dfc,
144 int32_t mode);
145 static int32_t emlxs_dfc_sd_set_event(emlxs_hba_t *hba, dfc_t *dfc,
146 int32_t mode);
147 static int32_t emlxs_dfc_sd_get_event(emlxs_hba_t *hba, dfc_t *dfc,
148 int32_t mode);
149 #endif /* SAN_DIAG_SUPPORT */
150
151 static int32_t emlxs_dfc_send_scsi_fcp(emlxs_hba_t *hba, dfc_t *dfc,
152 int32_t mode);
153 #ifdef FCIO_SUPPORT
154 static int32_t emlxs_fcio_manage(emlxs_hba_t *hba, dfc_t *dfc,
155 int32_t mode);
156 static int32_t emlxs_fcio_get_num_devs(emlxs_port_t *port,
157 fcio_t *fcio, int32_t mode);
158 static int32_t emlxs_fcio_get_dev_list(emlxs_port_t *port,
159 fcio_t *fcio, int32_t mode);
160 static int32_t emlxs_fcio_get_sym_pname(emlxs_port_t *port,
161 fcio_t *fcio, int32_t mode);
162 static int32_t emlxs_fcio_get_sym_nname(emlxs_port_t *port,
163 fcio_t *fcio, int32_t mode);
164 static int32_t emlxs_fcio_unsupported(emlxs_port_t *port,
165 fcio_t *fcio, int32_t mode);
166 static int32_t emlxs_fcio_get_logi_params(emlxs_port_t *port,
167 fcio_t *fcio, int32_t mode);
168 static int32_t emlxs_fcio_get_state(emlxs_port_t *port,
169 fcio_t *fcio, int32_t mode);
170 static int32_t emlxs_fcio_get_fcode_rev(emlxs_port_t *port,
171 fcio_t *fcio, int32_t mode);
172 static int32_t emlxs_fcio_get_fw_rev(emlxs_port_t *port,
173 fcio_t *fcio, int32_t mode);
174 static int32_t emlxs_fcio_get_dump_size(emlxs_port_t *port,
175 fcio_t *fcio, int32_t mode);
176 static int32_t emlxs_fcio_force_dump(emlxs_port_t *port,
177 fcio_t *fcio, int32_t mode);
178 static int32_t emlxs_fcio_get_dump(emlxs_port_t *port,
179 fcio_t *fcio, int32_t mode);
180 static int32_t emlxs_fcio_get_topology(emlxs_port_t *port,
181 fcio_t *fcio, int32_t mode);
182 static int32_t emlxs_fcio_reset_link(emlxs_port_t *port,
183 fcio_t *fcio, int32_t mode);
184 static int32_t emlxs_fcio_reset_hard(emlxs_port_t *port,
185 fcio_t *fcio, int32_t mode);
186 static int32_t emlxs_fcio_diag(emlxs_port_t *port,
187 fcio_t *fcio, int32_t mode);
188 static int32_t emlxs_fcio_download_fw(emlxs_port_t *port,
189 fcio_t *fcio, int32_t mode);
190 static int32_t emlxs_fcio_get_host_params(emlxs_port_t *port,
191 fcio_t *fcio, int32_t mode);
192 static int32_t emlxs_fcio_get_link_status(emlxs_port_t *port,
193 fcio_t *fcio, int32_t mode);
194 static int32_t emlxs_fcio_download_fcode(emlxs_port_t *port,
195 fcio_t *fcio, int32_t mode);
196 static int32_t emlxs_fcio_get_node_id(emlxs_port_t *port,
197 fcio_t *fcio, int32_t mode);
198 static int32_t emlxs_fcio_set_node_id(emlxs_port_t *port,
199 fcio_t *fcio, int32_t mode);
200 static int32_t emlxs_fcio_get_adapter_attrs(emlxs_port_t *port,
201 fcio_t *fcio, int32_t mode);
202 static int32_t emlxs_fcio_get_other_adapter_ports(emlxs_port_t *port,
203 fcio_t *fcio, int32_t mode);
204 static int32_t emlxs_fcio_get_adapter_port_attrs(emlxs_port_t *port,
205 fcio_t *fcio, int32_t mode);
206 static int32_t emlxs_fcio_get_disc_port_attrs(emlxs_port_t *port,
207 fcio_t *fcio, int32_t mode);
208 static int32_t emlxs_fcio_get_port_attrs(emlxs_port_t *port,
209 fcio_t *fcio, int32_t mode);
210 #endif /* FCIO_SUPPORT */
211
212 static int32_t emlxs_dfc_get_persist_linkdown(emlxs_hba_t *hba,
213 dfc_t *dfc, int32_t mode);
214 static int32_t emlxs_dfc_set_persist_linkdown(emlxs_hba_t *hba,
215 dfc_t *dfc, int32_t mode);
216
217 /* SLI-4 ioctls */
218 static int32_t emlxs_dfc_get_fcflist(emlxs_hba_t *hba, dfc_t *dfc,
219 int32_t mode);
220 static int32_t emlxs_dfc_send_mbox4(emlxs_hba_t *hba, dfc_t *dfc,
221 int32_t mode);
222 static int emlxs_dfc_rd_be_fcf(emlxs_hba_t *hba, dfc_t *dfc,
223 int32_t mode);
224 static int emlxs_dfc_set_be_dcbx(emlxs_hba_t *hba, dfc_t *dfc,
225 int32_t mode);
226 static int emlxs_dfc_get_be_dcbx(emlxs_hba_t *hba, dfc_t *dfc,
227 int32_t mode);
228 static int emlxs_dfc_get_qos(emlxs_hba_t *hba, dfc_t *dfc,
229 int32_t mode);
230
231 uint32_t emlxs_loopback_tmo = 60;
232
233 typedef struct
234 {
235 uint32_t code;
236 char string[32];
237 int (*func)(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode);
238 } emlxs_dfc_table_t;
239
240 emlxs_dfc_table_t emlxs_dfc_table[] = {
241 {EMLXS_GET_HBAINFO, "GET_HBAINFO", emlxs_dfc_get_hbainfo},
242 {EMLXS_GET_REV, "GET_REV", emlxs_dfc_get_rev},
243 {EMLXS_SET_DIAG, "SET_DIAG", emlxs_dfc_set_diag},
244 {EMLXS_SEND_MBOX, "SEND_MBOX", emlxs_dfc_send_mbox},
245 {EMLXS_READ_PCI, "READ_PCI", emlxs_dfc_read_pci},
246 {EMLXS_WRITE_PCI, "WRITE_PCI", emlxs_dfc_write_pci},
247 {EMLXS_GET_CFG, "GET_CFG", emlxs_dfc_get_cfg},
248 {EMLXS_SET_CFG, "SET_CFG", emlxs_dfc_set_cfg},
249 {EMLXS_SEND_CT, "SEND_CT", emlxs_dfc_send_ct},
250 {EMLXS_SEND_CT_RSP, "SEND_CT_RSP", emlxs_dfc_send_ct_rsp},
251 {EMLXS_WRITE_FLASH, "WRITE_FLASH", emlxs_dfc_write_flash},
252 {EMLXS_READ_FLASH, "READ_FLASH", emlxs_dfc_read_flash},
253 {EMLXS_SEND_ELS, "SEND_ELS", emlxs_dfc_send_els},
254 {EMLXS_LOOPBACK_TEST, "LOOPBACK_TEST", emlxs_dfc_loopback_test},
255 {EMLXS_RESET_PORT, "RESET_PORT", emlxs_dfc_reset_port},
256 {EMLXS_GET_DUMPREGION, "GET_DUMPREGION", emlxs_dfc_get_dump_region},
257 {EMLXS_LOOPBACK_MODE, "LOOPBACK_MODE", emlxs_dfc_loopback_mode},
258 {EMLXS_GET_IOINFO, "GET_IOINFO", emlxs_dfc_get_ioinfo},
259 {EMLXS_GET_LINKINFO, "GET_LINKINFO", emlxs_dfc_get_linkinfo},
260 {EMLXS_GET_NODEINFO, "GET_NODEINFO", emlxs_dfc_get_nodeinfo},
261 {EMLXS_READ_MEM, "READ_MEM", emlxs_dfc_read_mem},
262 {EMLXS_WRITE_MEM, "WRITE_MEM", emlxs_dfc_write_mem},
263 {EMLXS_WRITE_CTLREG, "WRITE_CTLREG", emlxs_dfc_write_ctlreg},
264 {EMLXS_READ_CTLREG, "READ_CTLREG", emlxs_dfc_read_ctlreg},
265 {EMLXS_SEND_SCSI, "SEND_SCSI", emlxs_dfc_send_scsi_fcp},
266 {EMLXS_GET_EVENT, "GET_EVENT", emlxs_dfc_get_event},
267 {EMLXS_SET_EVENT, "SET_EVENT", emlxs_dfc_set_event},
268 {EMLXS_GET_EVENTINFO, "GET_EVENTINFO", emlxs_dfc_get_eventinfo},
269 {EMLXS_GET_HBASTATS, "GET_HBASTATS", emlxs_dfc_get_hbastats},
270 {EMLXS_GET_DRVSTATS, "GET_DRVSTATS", emlxs_dfc_get_drvstats},
271 {EMLXS_CREATE_VPORT, "CREATE_VPORT", emlxs_dfc_create_vport},
272 {EMLXS_DESTROY_VPORT, "DESTROY_VPORT", emlxs_dfc_destroy_vport},
273 {EMLXS_GET_VPORTINFO, "GET_VPORTINFO", emlxs_dfc_get_vportinfo},
274 {EMLXS_NPIV_RESOURCE, "NPIV_RESOURCE", emlxs_dfc_npiv_resource},
275 {EMLXS_NPIV_TEST, "NPIV_TEST", emlxs_dfc_npiv_test},
276 {EMLXS_GET_PERSIST_LINKDOWN, "GET_PERSIST_LINKDOWN",
277 emlxs_dfc_get_persist_linkdown},
278 {EMLXS_SET_PERSIST_LINKDOWN, "SET_PERSIST_LINKDOWN",
279 emlxs_dfc_set_persist_linkdown},
280 {EMLXS_GET_FCOE_FCFLIST, "GET_FCOE_FCFLIST", emlxs_dfc_get_fcflist},
281 {EMLXS_SEND_MBOX4, "SEND_MBOX4", emlxs_dfc_send_mbox4},
282 {EMLXS_RD_BE_FCF, "RD_BE_FCF", emlxs_dfc_rd_be_fcf},
283 {EMLXS_SET_BE_DCBX, "SET_BE_DCBX", emlxs_dfc_set_be_dcbx},
284 {EMLXS_GET_BE_DCBX, "GET_BE_DCBX", emlxs_dfc_get_be_dcbx},
285 {EMLXS_GET_QOS, "GET_QOS", emlxs_dfc_get_qos},
286 #ifdef MENLO_SUPPORT
287 {EMLXS_SEND_MENLO, "SEND_MENLO", emlxs_dfc_send_menlo},
288 #endif /* MENLO_SUPPORT */
289 #ifdef DHCHAP_SUPPORT
290 {EMLXS_INIT_AUTH, "INIT_AUTH", emlxs_dfc_init_auth},
291 {EMLXS_GET_AUTH_CFG, "GET_AUTH_CFG", emlxs_dfc_get_auth_cfg},
292 {EMLXS_SET_AUTH_CFG, "SET_AUTH_CFG", emlxs_dfc_set_auth_cfg},
293 {EMLXS_GET_AUTH_PASSWORD, "GET_AUTH_PASSWORD", emlxs_dfc_get_auth_pwd},
294 {EMLXS_SET_AUTH_PASSWORD, "SET_AUTH_PASSWORD", emlxs_dfc_set_auth_pwd},
295 {EMLXS_GET_AUTH_STATUS, "GET_AUTH_STATUS", emlxs_dfc_get_auth_status},
296 {EMLXS_GET_AUTH_CFG_TABLE, "GET_AUTH_CFG_TABLE",
297 emlxs_dfc_get_auth_cfg_table},
298 {EMLXS_GET_AUTH_KEY_TABLE, "GET_AUTH_KEY_TABLE",
299 emlxs_dfc_get_auth_key_table},
300 #endif /* DHCHAP_SUPPORT */
301 #ifdef FCIO_SUPPORT
302 {EMLXS_FCIO_CMD, "FCIO_CMD", emlxs_fcio_manage},
303 #endif /* FCIO_SUPPORT */
304 #ifdef SFCT_SUPPORT
305 {EMLXS_GET_FCTSTAT, "GET_FCTSTAT", emlxs_dfc_get_fctstat},
306 #endif /* SFCT_SUPPORT */
307 #ifdef SAN_DIAG_SUPPORT
308 {EMLXS_SD_SET_BUCKET, "SD_SET_BUCKET", emlxs_dfc_sd_set_bucket},
309 {EMLXS_SD_DESTROY_BUCKET, "SD_DESTROY_BUCKET",
310 emlxs_dfc_sd_destroy_bucket},
311 {EMLXS_SD_GET_BUCKET, "SD_GET_BUCKET", emlxs_dfc_sd_get_bucket},
312 {EMLXS_SD_START_DATA_COLLECTION, "SD_START_DATA_COLLECTION",
313 emlxs_dfc_sd_start_collection},
314 {EMLXS_SD_STOP_DATA_COLLECTION, "SD_STOP_DATA_COLLECTION",
315 emlxs_dfc_sd_stop_collection},
316 {EMLXS_SD_RESET_DATA_COLLECTION, "SD_RESET_DATA_COLLECTION",
317 emlxs_dfc_sd_reset_collection},
318 {EMLXS_SD_GET_DATA, "SD_GET_DATA", emlxs_dfc_sd_get_data},
319 {EMLXS_SD_SET_EVENT, "SD_SET_EVENT", emlxs_dfc_sd_set_event},
320 {EMLXS_SD_GET_EVENT, "SD_GET_EVENT", emlxs_dfc_sd_get_event},
321 #endif /* SAN_DIAG_SUPPORT */
322 }; /* emlxs_dfc_table */
323
324
325 emlxs_table_t emlxs_dfc_event_table[] = {
326 {FC_REG_LINK_EVENT, "LINK_EVENT"},
327 {FC_REG_RSCN_EVENT, "RSCN_EVENT"},
328 {FC_REG_CT_EVENT, "CT_EVENT"},
329 {FC_REG_DUMP_EVENT, "DUMP_EVENT"},
330 {FC_REG_TEMP_EVENT, "TEMP_EVENT"},
331 {FC_REG_VPORTRSCN_EVENT, "VPORTRSCN_EVENT"},
332 {FC_REG_FCOE_EVENT, "FCOE_EVENT"},
333
334 }; /* emlxs_dfc_event_table */
335
336
337 #ifdef SAN_DIAG_SUPPORT
338 kmutex_t emlxs_sd_bucket_mutex;
339 sd_bucket_info_t emlxs_sd_bucket;
340 #endif /* SAN_DIAG_SUPPORT */
341
342 extern char *
emlxs_dfc_xlate(uint16_t cmd)343 emlxs_dfc_xlate(uint16_t cmd)
344 {
345 static char buffer[32];
346 uint32_t i;
347 uint32_t count;
348
349 count = sizeof (emlxs_dfc_table) / sizeof (emlxs_dfc_table_t);
350 for (i = 0; i < count; i++) {
351 if (cmd == emlxs_dfc_table[i].code) {
352 return (emlxs_dfc_table[i].string);
353 }
354 }
355
356 (void) snprintf(buffer, sizeof (buffer), "Cmd=0x%x", cmd);
357 return (buffer);
358
359 } /* emlxs_dfc_xlate() */
360
361
362 static int
emlxs_dfc_func(emlxs_hba_t * hba,dfc_t * dfc,int32_t mode)363 emlxs_dfc_func(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode)
364 {
365 emlxs_port_t *port = &PPORT;
366 uint32_t i;
367 uint32_t count;
368 int rval;
369
370 count = sizeof (emlxs_dfc_table) / sizeof (emlxs_dfc_table_t);
371 for (i = 0; i < count; i++) {
372 if (dfc->cmd == emlxs_dfc_table[i].code) {
373 if ((dfc->cmd != EMLXS_FCIO_CMD) ||
374 (dfc->data1 != FCIO_DIAG) ||
375 (dfc->data2 != EMLXS_LOG_GET)) {
376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
377 "%s requested.",
378 emlxs_dfc_table[i].string);
379 }
380
381 rval = emlxs_dfc_table[i].func(hba, dfc, mode);
382 return (rval);
383 }
384 }
385
386 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
387 "Unknown DFC command. (0x%x)", dfc->cmd);
388
389 return (DFC_ARG_INVALID);
390
391 } /* emlxs_dfc_func() */
392
393
394 extern char *
emlxs_dfc_event_xlate(uint32_t event)395 emlxs_dfc_event_xlate(uint32_t event)
396 {
397 static char buffer[32];
398 uint32_t i;
399 uint32_t count;
400
401 count = sizeof (emlxs_dfc_event_table) / sizeof (emlxs_table_t);
402 for (i = 0; i < count; i++) {
403 if (event == emlxs_dfc_event_table[i].code) {
404 return (emlxs_dfc_event_table[i].string);
405 }
406 }
407
408 (void) snprintf(buffer, sizeof (buffer), "Event=0x%x", event);
409 return (buffer);
410
411 } /* emlxs_dfc_event_xlate() */
412
413
414 static int32_t
emlxs_dfc_copyin(emlxs_hba_t * hba,void * arg,dfc_t * dfc1,dfc_t * dfc2,int32_t mode)415 emlxs_dfc_copyin(emlxs_hba_t *hba, void *arg, dfc_t *dfc1, dfc_t *dfc2,
416 int32_t mode)
417 {
418 emlxs_port_t *port = &PPORT;
419 int rval = 0;
420 uint32_t use32 = 0;
421
422 #ifdef _MULTI_DATAMODEL
423 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
424 use32 = 1;
425 }
426 #endif /* _MULTI_DATAMODEL */
427
428 if (use32) {
429 dfc32_t dfc32;
430
431 if (ddi_copyin((void *)arg, (void *)&dfc32,
432 sizeof (dfc32_t), mode)) {
433 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
434 "ddi_copyin32 failed.");
435
436 rval = DFC_COPYIN_ERROR;
437 goto done;
438 }
439
440 dfc1->cmd = dfc32.cmd;
441 dfc1->flag = dfc32.flag;
442 dfc1->buf1 = (void *)((uintptr_t)dfc32.buf1);
443 dfc1->buf1_size = dfc32.buf1_size;
444 dfc1->data1 = dfc32.data1;
445 dfc1->buf2 = (void *)((uintptr_t)dfc32.buf2);
446 dfc1->buf2_size = dfc32.buf2_size;
447 dfc1->data2 = dfc32.data2;
448 dfc1->buf3 = (void *)((uintptr_t)dfc32.buf3);
449 dfc1->buf3_size = dfc32.buf3_size;
450 dfc1->data3 = dfc32.data3;
451 dfc1->buf4 = (void *)((uintptr_t)dfc32.buf4);
452 dfc1->buf4_size = dfc32.buf4_size;
453 dfc1->data4 = dfc32.data4;
454
455 } else {
456 if (ddi_copyin((void *)arg, (void *)dfc1, sizeof (dfc_t),
457 mode)) {
458 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
459 "ddi_copyin failed.");
460
461 rval = DFC_COPYIN_ERROR;
462 goto done;
463 }
464 }
465
466 /* Map dfc1 to dfc2 */
467 dfc2->cmd = dfc1->cmd;
468 dfc2->flag = dfc1->flag;
469 dfc2->data1 = dfc1->data1;
470 dfc2->data2 = dfc1->data2;
471 dfc2->data3 = dfc1->data3;
472 dfc2->data4 = dfc1->data4;
473 dfc2->buf1 = 0;
474 dfc2->buf1_size = 0;
475 dfc2->buf2 = 0;
476 dfc2->buf2_size = 0;
477 dfc2->buf3 = 0;
478 dfc2->buf3_size = 0;
479 dfc2->buf4 = 0;
480 dfc2->buf4_size = 0;
481
482 /* Copyin data buffers */
483 if (dfc1->buf1_size && dfc1->buf1) {
484 dfc2->buf1_size = dfc1->buf1_size;
485 dfc2->buf1 = kmem_zalloc(dfc1->buf1_size, KM_SLEEP);
486
487 if (ddi_copyin(dfc1->buf1, dfc2->buf1, dfc1->buf1_size,
488 mode)) {
489 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
490 "%s: buf1 ddi_copyin failed. (size=%d)",
491 emlxs_dfc_xlate(dfc1->cmd),
492 dfc1->buf1_size);
493
494 rval = DFC_COPYIN_ERROR;
495 goto done;
496 }
497 }
498
499 if (dfc1->buf2_size && dfc1->buf2) {
500 dfc2->buf2_size = dfc1->buf2_size;
501 dfc2->buf2 = kmem_zalloc(dfc1->buf2_size, KM_SLEEP);
502
503 if (ddi_copyin(dfc1->buf2, dfc2->buf2, dfc1->buf2_size,
504 mode)) {
505 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
506 "%s: buf2 ddi_copyin failed. (size=%d)",
507 emlxs_dfc_xlate(dfc1->cmd),
508 dfc1->buf2_size);
509
510 rval = DFC_COPYIN_ERROR;
511 goto done;
512 }
513 }
514
515 if (dfc1->buf3_size && dfc1->buf3) {
516 dfc2->buf3_size = dfc1->buf3_size;
517 dfc2->buf3 = kmem_zalloc(dfc1->buf3_size, KM_SLEEP);
518
519 if (ddi_copyin(dfc1->buf3, dfc2->buf3, dfc1->buf3_size,
520 mode)) {
521 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
522 "%s buf3 ddi_copyin failed. (size=%d)",
523 emlxs_dfc_xlate(dfc1->cmd),
524 dfc1->buf3_size);
525
526 rval = DFC_COPYIN_ERROR;
527 goto done;
528 }
529 }
530
531 if (dfc1->buf4_size && dfc1->buf4) {
532 dfc2->buf4_size = dfc1->buf4_size;
533 dfc2->buf4 = kmem_zalloc(dfc1->buf4_size, KM_SLEEP);
534
535 if (ddi_copyin(dfc1->buf4, dfc2->buf4, dfc1->buf4_size,
536 mode)) {
537 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
538 "%s: buf4 ddi_copyin failed. (size=%d)",
539 emlxs_dfc_xlate(dfc1->cmd),
540 dfc1->buf4_size);
541
542 rval = DFC_COPYIN_ERROR;
543 goto done;
544 }
545 }
546
547 done:
548 return (rval);
549
550 } /* emlxs_dfc_copyin() */
551
552
553 static int32_t
emlxs_dfc_copyout(emlxs_hba_t * hba,void * arg,dfc_t * dfc2,dfc_t * dfc1,int32_t mode)554 emlxs_dfc_copyout(emlxs_hba_t *hba, void *arg, dfc_t *dfc2, dfc_t *dfc1,
555 int32_t mode)
556 {
557 emlxs_port_t *port = &PPORT;
558 int rval = 0;
559 uint32_t use32 = 0;
560
561 #ifdef _MULTI_DATAMODEL
562 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
563 use32 = 1;
564 }
565 #endif /* _MULTI_DATAMODEL */
566
567 /* Copyout data buffers */
568 if (dfc2->buf1) {
569 if (ddi_copyout(dfc2->buf1, dfc1->buf1, dfc1->buf1_size,
570 mode)) {
571 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
572 "%s: buf1 ddi_copyout failed. (size=%d)",
573 emlxs_dfc_xlate(dfc2->cmd),
574 dfc2->buf1_size);
575
576 rval = DFC_COPYOUT_ERROR;
577 }
578 kmem_free(dfc2->buf1, dfc2->buf1_size);
579 dfc2->buf1 = 0;
580 }
581
582 if (dfc2->buf2) {
583 if (ddi_copyout(dfc2->buf2, dfc1->buf2, dfc1->buf2_size,
584 mode)) {
585 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
586 "%s: buf2 ddi_copyout failed. (size=%d)",
587 emlxs_dfc_xlate(dfc2->cmd),
588 dfc2->buf2_size);
589
590 rval = DFC_COPYOUT_ERROR;
591 }
592 kmem_free(dfc2->buf2, dfc2->buf2_size);
593 dfc2->buf2 = 0;
594 }
595
596 if (dfc2->buf3) {
597 if (ddi_copyout(dfc2->buf3, dfc1->buf3, dfc1->buf3_size,
598 mode)) {
599 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
600 "%s buf3 ddi_copyout failed. (size=%d)",
601 emlxs_dfc_xlate(dfc2->cmd),
602 dfc2->buf3_size);
603
604 rval = DFC_COPYOUT_ERROR;
605 }
606 kmem_free(dfc2->buf3, dfc2->buf3_size);
607 dfc2->buf3 = 0;
608 }
609
610 if (dfc2->buf4) {
611 if (ddi_copyout(dfc2->buf4, dfc1->buf4, dfc1->buf4_size,
612 mode)) {
613 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
614 "%s: buf4 ddi_copyout failed. (size=%d)",
615 emlxs_dfc_xlate(dfc2->cmd),
616 dfc2->buf4_size);
617
618 rval = DFC_COPYOUT_ERROR;
619 }
620 kmem_free(dfc2->buf4, dfc2->buf4_size);
621 dfc2->buf4 = 0;
622 }
623
624 if (use32) {
625 dfc32_t dfc32;
626
627 dfc32.cmd = dfc1->cmd;
628 dfc32.flag = dfc1->flag;
629 dfc32.buf1 = (uint32_t)((uintptr_t)dfc1->buf1);
630 dfc32.buf1_size = dfc1->buf1_size;
631 dfc32.data1 = dfc1->data1;
632 dfc32.buf2 = (uint32_t)((uintptr_t)dfc1->buf2);
633 dfc32.buf2_size = dfc1->buf2_size;
634 dfc32.data2 = dfc1->data2;
635 dfc32.buf3 = (uint32_t)((uintptr_t)dfc1->buf3);
636 dfc32.buf3_size = dfc1->buf3_size;
637 dfc32.data3 = dfc1->data3;
638 dfc32.buf4 = (uint32_t)((uintptr_t)dfc1->buf4);
639 dfc32.buf4_size = dfc1->buf4_size;
640 dfc32.data4 = dfc1->data4;
641
642 if (ddi_copyout((void *)&dfc32, (void *)arg,
643 sizeof (dfc32_t), mode)) {
644 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
645 "ddi_copyout32 failed.");
646
647 rval = DFC_COPYOUT_ERROR;
648 goto done;
649 }
650 } else {
651 if (ddi_copyout((void *)dfc1, (void *)arg, sizeof (dfc_t),
652 mode)) {
653 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
654 "ddi_copyout failed.");
655
656 rval = DFC_COPYOUT_ERROR;
657 goto done;
658 }
659 }
660
661 done:
662 return (rval);
663
664 } /* emlxs_dfc_copyout() */
665
666
667 extern int32_t
emlxs_dfc_manage(emlxs_hba_t * hba,void * arg,int32_t mode)668 emlxs_dfc_manage(emlxs_hba_t *hba, void *arg, int32_t mode)
669 {
670 dfc_t dfc1;
671 dfc_t dfc2;
672 int rval = 0;
673
674 /* This copies arg data to dfc1 space, */
675 /* then creates local dfc2 buffers */
676 rval = emlxs_dfc_copyin(hba, arg, &dfc1, &dfc2, mode);
677
678 if (rval) {
679 return (rval);
680 }
681
682 rval = emlxs_dfc_func(hba, &dfc2, mode);
683
684 if (rval) {
685 return (rval);
686 }
687
688 /* This copies dfc2 local buffers back to dfc1 addresses */
689 rval = emlxs_dfc_copyout(hba, arg, &dfc2, &dfc1, mode);
690
691 return (rval);
692
693 } /* emlxs_dfc_manage() */
694
695
696 #ifdef FCIO_SUPPORT
697 typedef struct
698 {
699 uint32_t code;
700 char string[32];
701 int (*func)(emlxs_port_t *port, fcio_t *fcio, int32_t mode);
702 } emlxs_fcio_table_t;
703
704 emlxs_fcio_table_t emlxs_fcio_table[] = {
705 {FCIO_GET_NUM_DEVS, "GET_NUM_DEVS", emlxs_fcio_get_num_devs},
706 {FCIO_GET_DEV_LIST, "GET_DEV_LIST", emlxs_fcio_get_dev_list},
707 {FCIO_GET_SYM_PNAME, "GET_SYM_PNAME", emlxs_fcio_get_sym_pname},
708 {FCIO_GET_SYM_NNAME, "GET_SYM_NNAME", emlxs_fcio_get_sym_nname},
709 {FCIO_SET_SYM_PNAME, "SET_SYM_PNAME", emlxs_fcio_unsupported},
710 {FCIO_SET_SYM_NNAME, "SET_SYM_NNAME", emlxs_fcio_unsupported},
711 {FCIO_GET_LOGI_PARAMS, "GET_LOGI_PARAMS", emlxs_fcio_get_logi_params},
712 {FCIO_DEV_LOGIN, "DEV_LOGIN", emlxs_fcio_unsupported},
713 {FCIO_DEV_LOGOUT, "DEV_LOGOUT", emlxs_fcio_unsupported},
714 {FCIO_GET_STATE, "GET_STATE", emlxs_fcio_get_state},
715 {FCIO_DEV_REMOVE, "DEV_REMOVE", emlxs_fcio_unsupported},
716 {FCIO_GET_FCODE_REV, "GET_FCODE_REV", emlxs_fcio_get_fcode_rev},
717 {FCIO_GET_FW_REV, "GET_FW_REV", emlxs_fcio_get_fw_rev},
718 {FCIO_GET_DUMP_SIZE, "GET_DUMP_SIZE", emlxs_fcio_get_dump_size},
719 {FCIO_FORCE_DUMP, "FORCE_DUMP", emlxs_fcio_force_dump},
720 {FCIO_GET_DUMP, "GET_DUMP", emlxs_fcio_get_dump},
721 {FCIO_GET_TOPOLOGY, "GET_TOPOLOGY", emlxs_fcio_get_topology},
722 {FCIO_RESET_LINK, "RESET_LINK", emlxs_fcio_reset_link},
723 {FCIO_RESET_HARD, "RESET_HARD", emlxs_fcio_reset_hard},
724 {FCIO_RESET_HARD_CORE, "RESET_HARD_CORE", emlxs_fcio_reset_hard},
725 {FCIO_DIAG, "DIAG", emlxs_fcio_diag},
726 {FCIO_NS, "NS", emlxs_fcio_unsupported},
727 {FCIO_DOWNLOAD_FW, "DOWNLOAD_FW", emlxs_fcio_download_fw},
728 {FCIO_GET_HOST_PARAMS, "GET_HOST_PARAMS", emlxs_fcio_get_host_params},
729 {FCIO_LINK_STATUS, "LINK_STATUS", emlxs_fcio_get_link_status},
730 {FCIO_DOWNLOAD_FCODE, "DOWNLOAD_FCODE", emlxs_fcio_download_fcode},
731 {FCIO_GET_NODE_ID, "GET_NODE_ID", emlxs_fcio_get_node_id},
732 {FCIO_SET_NODE_ID, "SET_NODE_ID", emlxs_fcio_set_node_id},
733 {FCIO_SEND_NODE_ID, "SEND_NODE_ID", emlxs_fcio_unsupported},
734 /* {FCIO_GET_P2P_INFO, "GET_P2P_INFO", emlxs_fcio_get_p2p_info}, */
735 {FCIO_GET_ADAPTER_ATTRIBUTES, "GET_ADAPTER_ATTRIBUTES",
736 emlxs_fcio_get_adapter_attrs},
737 {FCIO_GET_OTHER_ADAPTER_PORTS, "GET_OTHER_ADAPTER_PORTS",
738 emlxs_fcio_get_other_adapter_ports},
739 {FCIO_GET_ADAPTER_PORT_ATTRIBUTES, "GET_ADAPTER_PORT_ATTRIBUTES",
740 emlxs_fcio_get_adapter_port_attrs},
741 {FCIO_GET_DISCOVERED_PORT_ATTRIBUTES, "GET_DISCOVERED_PORT_ATTRIBUTES",
742 emlxs_fcio_get_disc_port_attrs},
743 {FCIO_GET_PORT_ATTRIBUTES, "GET_PORT_ATTRIBUTES",
744 emlxs_fcio_get_port_attrs},
745 {FCIO_GET_ADAPTER_PORT_STATS, "GET_ADAPTER_PORT_STATS",
746 emlxs_fcio_unsupported},
747 }; /* emlxs_fcio_table */
748
749
750 extern char *
emlxs_fcio_xlate(uint16_t cmd)751 emlxs_fcio_xlate(uint16_t cmd)
752 {
753 static char buffer[32];
754 uint32_t i;
755 uint32_t count;
756
757 count = sizeof (emlxs_fcio_table) / sizeof (emlxs_fcio_table_t);
758 for (i = 0; i < count; i++) {
759 if (cmd == emlxs_fcio_table[i].code) {
760 return (emlxs_fcio_table[i].string);
761 }
762 }
763
764 (void) snprintf(buffer, sizeof (buffer), "Cmd=0x%x", cmd);
765 return (buffer);
766
767 } /* emlxs_fcio_xlate() */
768
769
770 static int
emlxs_fcio_func(emlxs_port_t * port,fcio_t * fcio,int32_t mode)771 emlxs_fcio_func(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
772 {
773 uint32_t i;
774 uint32_t count;
775 int rval;
776
777 count = sizeof (emlxs_fcio_table) / sizeof (emlxs_fcio_table_t);
778 for (i = 0; i < count; i++) {
779 if (fcio->fcio_cmd == emlxs_fcio_table[i].code) {
780 if ((fcio->fcio_cmd != FCIO_DIAG) ||
781 (fcio->fcio_cmd_flags != EMLXS_LOG_GET)) {
782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
783 "%s requested.",
784 emlxs_fcio_table[i].string);
785 }
786
787 rval = emlxs_fcio_table[i].func(port, fcio, mode);
788 return (rval);
789 }
790 }
791
792 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
793 "Unknown FCIO command. (0x%x)", fcio->fcio_cmd);
794
795 return (EFAULT);
796
797 } /* emlxs_fcio_func() */
798
799
800 /* This is used by FCT ports to mimic SFS ports for FCIO support */
801 /*ARGSUSED*/
802 extern int32_t
emlxs_fcio_manage(emlxs_hba_t * hba,dfc_t * dfc,int32_t mode)803 emlxs_fcio_manage(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode)
804 {
805 emlxs_port_t *port = &PPORT;
806 int32_t rval = 0;
807 fcio_t fcio;
808 uint32_t vpi;
809
810 /* Map DFC to FCIO */
811 vpi = (dfc->data4 < MAX_VPORTS)? dfc->data4:0;
812 port = &VPORT(vpi);
813
814 bzero(&fcio, sizeof (fcio_t));
815 fcio.fcio_flags = dfc->flag;
816 fcio.fcio_cmd = dfc->data1;
817 fcio.fcio_cmd_flags = dfc->data2;
818 fcio.fcio_xfer = dfc->data3;
819
820 if (dfc->buf1_size && dfc->buf1) {
821 fcio.fcio_ilen = dfc->buf1_size;
822 fcio.fcio_ibuf = dfc->buf1;
823 }
824
825 if (dfc->buf2_size && dfc->buf2) {
826 fcio.fcio_olen = dfc->buf2_size;
827 fcio.fcio_obuf = dfc->buf2;
828 }
829
830 if (dfc->buf3_size && dfc->buf3) {
831 fcio.fcio_alen = dfc->buf3_size;
832 fcio.fcio_abuf = dfc->buf3;
833 }
834
835 if (!dfc->buf4 || (dfc->buf4_size < sizeof (uint32_t))) {
836 EMLXS_MSGF(EMLXS_CONTEXT,
837 &emlxs_dfc_error_msg,
838 "%s: %s: buf4 invalid. (buf4=%p size=%d)",
839 emlxs_dfc_xlate(dfc->cmd), emlxs_fcio_xlate(dfc->data1),
840 dfc->buf4, dfc->buf4_size);
841
842 rval = EFAULT;
843 goto done;
844 }
845
846 rval = emlxs_fcio_func(port, &fcio, mode);
847
848 /* Map FCIO to DFC */
849 dfc->flag = fcio.fcio_flags;
850 dfc->data1 = fcio.fcio_cmd;
851 dfc->data2 = fcio.fcio_cmd_flags;
852 dfc->data3 = fcio.fcio_xfer;
853
854 done:
855 /* Set fcio_errno if needed */
856 if ((rval != 0) && (fcio.fcio_errno == 0)) {
857 fcio.fcio_errno = FC_FAILURE;
858 }
859
860 bcopy((void *)&fcio.fcio_errno, (void *)dfc->buf4, sizeof (uint32_t));
861
862 return (rval);
863
864 } /* emlxs_fcio_manage() */
865
866
867 /*ARGSUSED*/
868 static int32_t
emlxs_fcio_diag(emlxs_port_t * port,fcio_t * fcio,int32_t mode)869 emlxs_fcio_diag(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
870 {
871 fc_fca_pm_t pm;
872 int32_t rval = 0;
873
874 bzero((caddr_t)&pm, sizeof (fc_fca_pm_t));
875
876 pm.pm_cmd_len = fcio->fcio_ilen;
877 pm.pm_cmd_buf = fcio->fcio_ibuf;
878 pm.pm_data_len = fcio->fcio_alen;
879 pm.pm_data_buf = fcio->fcio_abuf;
880 pm.pm_stat_len = fcio->fcio_olen;
881 pm.pm_stat_buf = fcio->fcio_obuf;
882 pm.pm_cmd_code = FC_PORT_DIAG;
883 pm.pm_cmd_flags = fcio->fcio_cmd_flags;
884
885 rval = emlxs_fca_port_manage(port, &pm);
886
887 if (rval != FC_SUCCESS) {
888 fcio->fcio_errno = rval;
889
890 if (rval == FC_INVALID_REQUEST) {
891 rval = ENOTTY;
892 } else {
893 rval = EIO;
894 }
895 }
896 if (fcio->fcio_olen > pm.pm_stat_len) {
897 fcio->fcio_olen = pm.pm_stat_len;
898 }
899
900 return (rval);
901
902 } /* emlxs_fcio_diag() */
903
904
905 #ifndef _MULTI_DATAMODEL
906 /* ARGSUSED */
907 #endif
908 static int32_t
emlxs_fcio_get_host_params(emlxs_port_t * port,fcio_t * fcio,int32_t mode)909 emlxs_fcio_get_host_params(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
910 {
911 emlxs_hba_t *hba = HBA;
912 int32_t rval = 0;
913 uint32_t use32 = 0;
914 emlxs_config_t *cfg = &CFG;
915
916 #ifdef _MULTI_DATAMODEL
917 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
918 use32 = 1;
919 }
920 #endif /* _MULTI_DATAMODEL */
921
922 if (use32) {
923 fc_port_dev32_t *port_dev;
924 uint32_t i;
925
926 if (fcio->fcio_xfer != FCIO_XFER_READ ||
927 fcio->fcio_olen != sizeof (fc_port_dev32_t)) {
928 rval = EINVAL;
929 goto done;
930 }
931
932 port_dev = (fc_port_dev32_t *)fcio->fcio_obuf;
933
934 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
935 "fcio_get_host_params: fct_flags=%x ulp_statec=%x",
936 port->fct_flags, port->ulp_statec);
937
938 if ((port->mode == MODE_TARGET) &&
939 (port->fct_port) &&
940 (port->fct_flags & FCT_STATE_PORT_ONLINE)) {
941 port_dev->dev_state = port->ulp_statec;
942 port_dev->dev_did.port_id = port->did;
943
944 if (hba->topology == TOPOLOGY_LOOP) {
945 for (i = 0; i < port->alpa_map[0]; i++) {
946 if (port->alpa_map[i + 1] == port->did) {
947 port_dev->dev_did.priv_lilp_posit =
948 (uint8_t)(i & 0xff);
949 goto done;
950 }
951 }
952 }
953
954 } else {
955 port_dev->dev_state = FC_STATE_OFFLINE;
956 port_dev->dev_did.port_id = 0;
957 }
958
959 port_dev->dev_hard_addr.hard_addr =
960 cfg[CFG_ASSIGN_ALPA].current;
961
962 bcopy((caddr_t)&port->wwpn,
963 (caddr_t)&port_dev->dev_pwwn, 8);
964 bcopy((caddr_t)&port->wwnn,
965 (caddr_t)&port_dev->dev_nwwn, 8);
966
967 port_dev->dev_type[0] = LE_SWAP32(0x00000120);
968 port_dev->dev_type[1] = LE_SWAP32(0x00000001);
969
970 } else {
971
972 fc_port_dev_t *port_dev;
973 uint32_t i;
974
975 if (fcio->fcio_xfer != FCIO_XFER_READ ||
976 fcio->fcio_olen != sizeof (fc_port_dev_t)) {
977 rval = EINVAL;
978 goto done;
979 }
980
981 port_dev = (fc_port_dev_t *)fcio->fcio_obuf;
982
983 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
984 "fcio_get_host_params: fct_flags=%x ulp_statec=%x",
985 port->fct_flags, port->ulp_statec);
986
987 if ((port->mode == MODE_TARGET) &&
988 (port->fct_port) &&
989 (port->fct_flags & FCT_STATE_PORT_ONLINE)) {
990 port_dev->dev_state = port->ulp_statec;
991 port_dev->dev_did.port_id = port->did;
992
993 if (hba->topology == TOPOLOGY_LOOP) {
994 for (i = 0; i < port->alpa_map[0]; i++) {
995 if (port->alpa_map[i + 1] == port->did) {
996 port_dev->dev_did.priv_lilp_posit =
997 (uint8_t)(i & 0xff);
998 goto done;
999 }
1000 }
1001 }
1002
1003 } else {
1004 port_dev->dev_state = FC_STATE_OFFLINE;
1005 port_dev->dev_did.port_id = 0;
1006 }
1007
1008 port_dev->dev_hard_addr.hard_addr =
1009 cfg[CFG_ASSIGN_ALPA].current;
1010
1011 bcopy((caddr_t)&port->wwpn,
1012 (caddr_t)&port_dev->dev_pwwn, 8);
1013 bcopy((caddr_t)&port->wwnn,
1014 (caddr_t)&port_dev->dev_nwwn, 8);
1015
1016 port_dev->dev_type[0] = LE_SWAP32(0x00000120);
1017 port_dev->dev_type[1] = LE_SWAP32(0x00000001);
1018 }
1019
1020 done:
1021 return (rval);
1022
1023 } /* emlxs_fcio_get_host_params() */
1024
1025
1026 /*ARGSUSED*/
1027 static int32_t
emlxs_fcio_reset_link(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1028 emlxs_fcio_reset_link(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1029 {
1030 int32_t rval = 0;
1031 uint8_t null_wwn[8];
1032
1033 if (fcio->fcio_xfer != FCIO_XFER_WRITE ||
1034 fcio->fcio_ilen != 8) {
1035 rval = EINVAL;
1036 goto done;
1037 }
1038
1039 if (port->mode != MODE_TARGET) {
1040 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
1041 "fcio_reset_link failed. Port is not in target mode.");
1042
1043 fcio->fcio_errno = FC_FAILURE;
1044 rval = EIO;
1045 goto done;
1046 }
1047
1048 bzero(null_wwn, 8);
1049
1050 if (bcmp((uint8_t *)fcio->fcio_ibuf, null_wwn, 8) == 0) {
1051 rval = emlxs_fca_reset(port, FC_FCA_LINK_RESET);
1052
1053 if (rval != FC_SUCCESS) {
1054 fcio->fcio_errno = rval;
1055 rval = EIO;
1056 }
1057 } else {
1058 rval = ENOTSUP;
1059 }
1060
1061 done:
1062 return (rval);
1063
1064 } /* emlxs_fcio_reset_link() */
1065
1066
1067 /*ARGSUSED*/
1068 static int32_t
emlxs_fcio_reset_hard(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1069 emlxs_fcio_reset_hard(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1070 {
1071 int32_t rval = 0;
1072
1073 if (port->mode != MODE_TARGET) {
1074 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
1075 "fcio_reset_hard failed. Port is not in target mode.");
1076
1077 fcio->fcio_errno = FC_FAILURE;
1078 rval = EIO;
1079 goto done;
1080 }
1081
1082 rval = emlxs_reset(port, FC_FCA_RESET);
1083
1084 if (rval != FC_SUCCESS) {
1085 fcio->fcio_errno = rval;
1086 rval = EIO;
1087 }
1088
1089 done:
1090 return (rval);
1091
1092 } /* emlxs_fcio_reset_hard() */
1093
1094
1095 /*ARGSUSED*/
1096 static int32_t
emlxs_fcio_download_fw(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1097 emlxs_fcio_download_fw(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1098 {
1099 int32_t rval = 0;
1100 fc_fca_pm_t pm;
1101
1102 if (fcio->fcio_xfer != FCIO_XFER_WRITE ||
1103 fcio->fcio_ilen == 0) {
1104 rval = EINVAL;
1105 goto done;
1106 }
1107
1108 bzero((caddr_t)&pm, sizeof (pm));
1109
1110 pm.pm_cmd_flags = FC_FCA_PM_WRITE;
1111 pm.pm_cmd_code = FC_PORT_DOWNLOAD_FW;
1112 pm.pm_data_len = fcio->fcio_ilen;
1113 pm.pm_data_buf = fcio->fcio_ibuf;
1114
1115 rval = emlxs_fca_port_manage(port, &pm);
1116
1117 if ((rval != FC_SUCCESS) && (rval != EMLXS_REBOOT_REQUIRED)) {
1118 fcio->fcio_errno = rval;
1119 rval = EIO;
1120 }
1121
1122 done:
1123 return (rval);
1124
1125 } /* emlxs_fcio_download_fw() */
1126
1127
1128 /*ARGSUSED*/
1129 static int32_t
emlxs_fcio_get_fw_rev(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1130 emlxs_fcio_get_fw_rev(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1131 {
1132 int32_t rval = 0;
1133 fc_fca_pm_t pm;
1134
1135 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1136 fcio->fcio_olen < FC_FW_REV_SIZE) {
1137 rval = EINVAL;
1138 goto done;
1139 }
1140
1141 bzero((caddr_t)&pm, sizeof (pm));
1142
1143 pm.pm_cmd_flags = FC_FCA_PM_READ;
1144 pm.pm_cmd_code = FC_PORT_GET_FW_REV;
1145 pm.pm_data_len = fcio->fcio_olen;
1146 pm.pm_data_buf = fcio->fcio_obuf;
1147
1148 rval = emlxs_fca_port_manage(port, &pm);
1149
1150 if (rval != FC_SUCCESS) {
1151 fcio->fcio_errno = rval;
1152 rval = EIO;
1153 }
1154
1155 done:
1156 return (rval);
1157
1158 } /* emlxs_fcio_get_fw_rev() */
1159
1160
1161 /*ARGSUSED*/
1162 static int32_t
emlxs_fcio_get_fcode_rev(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1163 emlxs_fcio_get_fcode_rev(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1164 {
1165 int32_t rval = 0;
1166 fc_fca_pm_t pm;
1167
1168 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1169 fcio->fcio_olen < FC_FCODE_REV_SIZE) {
1170 rval = EINVAL;
1171 goto done;
1172 }
1173
1174 bzero((caddr_t)&pm, sizeof (pm));
1175
1176 pm.pm_cmd_flags = FC_FCA_PM_READ;
1177 pm.pm_cmd_code = FC_PORT_GET_FCODE_REV;
1178 pm.pm_data_len = fcio->fcio_olen;
1179 pm.pm_data_buf = fcio->fcio_obuf;
1180
1181 rval = emlxs_fca_port_manage(port, &pm);
1182
1183 if (rval != FC_SUCCESS) {
1184 fcio->fcio_errno = rval;
1185 rval = EIO;
1186 }
1187
1188 done:
1189 return (rval);
1190
1191 } /* emlxs_fcio_get_fcode_rev() */
1192
1193
1194 /*ARGSUSED*/
1195 static int32_t
emlxs_fcio_download_fcode(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1196 emlxs_fcio_download_fcode(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1197 {
1198 int32_t rval = 0;
1199 fc_fca_pm_t pm;
1200
1201 if (fcio->fcio_xfer != FCIO_XFER_WRITE ||
1202 fcio->fcio_ilen == 0) {
1203 rval = EINVAL;
1204 goto done;
1205 }
1206
1207 bzero((caddr_t)&pm, sizeof (pm));
1208
1209 pm.pm_cmd_flags = FC_FCA_PM_WRITE;
1210 pm.pm_cmd_code = FC_PORT_DOWNLOAD_FCODE;
1211 pm.pm_data_len = fcio->fcio_ilen;
1212 pm.pm_data_buf = fcio->fcio_ibuf;
1213
1214 rval = emlxs_fca_port_manage(port, &pm);
1215
1216 if (rval != FC_SUCCESS) {
1217 fcio->fcio_errno = rval;
1218 rval = EIO;
1219 }
1220
1221 done:
1222 return (rval);
1223
1224 } /* emlxs_fcio_download_fcode() */
1225
1226
1227 #ifndef _MULTI_DATAMODEL
1228 /* ARGSUSED */
1229 #endif
1230 static int32_t
emlxs_fcio_get_adapter_attrs(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1231 emlxs_fcio_get_adapter_attrs(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1232 {
1233 emlxs_hba_t *hba = HBA;
1234 int32_t rval = 0;
1235 uint32_t use32 = 0;
1236 emlxs_vpd_t *vpd = &VPD;
1237
1238 #ifdef _MULTI_DATAMODEL
1239 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1240 use32 = 1;
1241 }
1242 #endif /* _MULTI_DATAMODEL */
1243
1244 if (use32) {
1245 fc_hba_adapter_attributes32_t *hba_attrs;
1246
1247 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1248 fcio->fcio_olen <
1249 sizeof (fc_hba_adapter_attributes32_t)) {
1250 rval = EINVAL;
1251 goto done;
1252 }
1253
1254 hba_attrs =
1255 (fc_hba_adapter_attributes32_t *)fcio->fcio_obuf;
1256
1257 hba_attrs->version = FC_HBA_ADAPTER_ATTRIBUTES_VERSION;
1258 (void) strncpy(hba_attrs->Manufacturer,
1259 hba->model_info.manufacturer,
1260 (sizeof (hba_attrs->Manufacturer)-1));
1261 (void) strncpy(hba_attrs->SerialNumber, vpd->serial_num,
1262 (sizeof (hba_attrs->SerialNumber)-1));
1263 (void) strncpy(hba_attrs->Model, hba->model_info.model,
1264 (sizeof (hba_attrs->Model)-1));
1265 (void) strncpy(hba_attrs->ModelDescription,
1266 hba->model_info.model_desc,
1267 (sizeof (hba_attrs->ModelDescription)-1));
1268 bcopy((caddr_t)&port->wwnn,
1269 (caddr_t)&hba_attrs->NodeWWN, 8);
1270 (void) strncpy((caddr_t)hba_attrs->NodeSymbolicName,
1271 (caddr_t)port->snn,
1272 (sizeof (hba_attrs->NodeSymbolicName)-1));
1273 (void) snprintf(hba_attrs->HardwareVersion,
1274 (sizeof (hba_attrs->HardwareVersion)-1),
1275 "%x", vpd->biuRev);
1276 (void) snprintf(hba_attrs->DriverVersion,
1277 (sizeof (hba_attrs->DriverVersion)-1),
1278 "%s (%s)", emlxs_version, emlxs_revision);
1279 (void) strncpy(hba_attrs->OptionROMVersion,
1280 vpd->fcode_version,
1281 (sizeof (hba_attrs->OptionROMVersion)-1));
1282 (void) snprintf(hba_attrs->FirmwareVersion,
1283 (sizeof (hba_attrs->FirmwareVersion)-1),
1284 "%s (%s)", vpd->fw_version, vpd->fw_label);
1285 (void) strncpy(hba_attrs->DriverName, DRIVER_NAME,
1286 (sizeof (hba_attrs->DriverName)-1));
1287 hba_attrs->VendorSpecificID =
1288 (hba->model_info.device_id << 16) |
1289 hba->model_info.vendor_id;
1290 hba_attrs->NumberOfPorts = hba->num_of_ports;
1291 } else {
1292 fc_hba_adapter_attributes_t *hba_attrs;
1293
1294 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1295 fcio->fcio_olen <
1296 sizeof (fc_hba_adapter_attributes_t)) {
1297 rval = EINVAL;
1298 goto done;
1299 }
1300
1301 hba_attrs =
1302 (fc_hba_adapter_attributes_t *)fcio->fcio_obuf;
1303
1304 hba_attrs->version = FC_HBA_ADAPTER_ATTRIBUTES_VERSION;
1305 (void) strncpy(hba_attrs->Manufacturer,
1306 hba->model_info.manufacturer,
1307 (sizeof (hba_attrs->Manufacturer)-1));
1308 (void) strncpy(hba_attrs->SerialNumber, vpd->serial_num,
1309 (sizeof (hba_attrs->SerialNumber)-1));
1310 (void) strncpy(hba_attrs->Model, hba->model_info.model,
1311 (sizeof (hba_attrs->Model)-1));
1312 (void) strncpy(hba_attrs->ModelDescription,
1313 hba->model_info.model_desc,
1314 (sizeof (hba_attrs->ModelDescription)-1));
1315 bcopy((caddr_t)&port->wwnn,
1316 (caddr_t)&hba_attrs->NodeWWN, 8);
1317 (void) strncpy((caddr_t)hba_attrs->NodeSymbolicName,
1318 (caddr_t)port->snn,
1319 (sizeof (hba_attrs->NodeSymbolicName)-1));
1320 (void) snprintf(hba_attrs->HardwareVersion,
1321 (sizeof (hba_attrs->HardwareVersion)-1),
1322 "%x", vpd->biuRev);
1323 (void) snprintf(hba_attrs->DriverVersion,
1324 (sizeof (hba_attrs->DriverVersion)-1),
1325 "%s (%s)", emlxs_version, emlxs_revision);
1326 (void) strncpy(hba_attrs->OptionROMVersion,
1327 vpd->fcode_version,
1328 (sizeof (hba_attrs->OptionROMVersion)-1));
1329 (void) snprintf(hba_attrs->FirmwareVersion,
1330 (sizeof (hba_attrs->FirmwareVersion)-1),
1331 "%s (%s)", vpd->fw_version, vpd->fw_label);
1332 (void) strncpy(hba_attrs->DriverName, DRIVER_NAME,
1333 (sizeof (hba_attrs->DriverName)-1));
1334 hba_attrs->VendorSpecificID =
1335 (hba->model_info.device_id << 16) |
1336 hba->model_info.vendor_id;
1337 hba_attrs->NumberOfPorts = hba->num_of_ports;
1338 }
1339
1340 done:
1341 return (rval);
1342
1343 } /* emlxs_fcio_get_adapter_attrs() */
1344
1345
1346 #ifndef _MULTI_DATAMODEL
1347 /* ARGSUSED */
1348 #endif
1349 static int32_t
emlxs_fcio_get_adapter_port_attrs(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1350 emlxs_fcio_get_adapter_port_attrs(emlxs_port_t *port, fcio_t *fcio,
1351 int32_t mode)
1352 {
1353 emlxs_hba_t *hba = HBA;
1354 int32_t rval = 0;
1355 uint32_t use32 = 0;
1356 emlxs_vpd_t *vpd = &VPD;
1357
1358 #ifdef _MULTI_DATAMODEL
1359 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1360 use32 = 1;
1361 }
1362 #endif /* _MULTI_DATAMODEL */
1363
1364 if (use32) {
1365 fc_hba_port_attributes32_t *port_attrs;
1366 uint32_t value1;
1367 uint32_t value2;
1368
1369 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1370 fcio->fcio_olen <
1371 sizeof (fc_hba_port_attributes32_t)) {
1372 rval = EINVAL;
1373 goto done;
1374 }
1375
1376 port_attrs =
1377 (fc_hba_port_attributes32_t *)fcio->fcio_obuf;
1378
1379 port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
1380 port_attrs->lastChange = 0;
1381 port_attrs->fp_minor = 0;
1382 bcopy((caddr_t)&port->wwnn,
1383 (caddr_t)&port_attrs->NodeWWN, 8);
1384 bcopy((caddr_t)&port->wwpn,
1385 (caddr_t)&port_attrs->PortWWN, 8);
1386
1387 if ((port->mode != MODE_TARGET) ||
1388 (port->ulp_statec == FC_STATE_OFFLINE)) {
1389 /* port_attrs->PortFcId */
1390 /* port_attrs->PortType */
1391 /* port_attrs->PortSpeed */
1392 /* port_attrs->FabricName */
1393 port_attrs->PortState =
1394 FC_HBA_PORTSTATE_OFFLINE;
1395 } else {
1396 port_attrs->PortFcId = port->did;
1397 port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE;
1398
1399 if (hba->topology == TOPOLOGY_LOOP) {
1400 if (hba->flag & FC_FABRIC_ATTACHED) {
1401 port_attrs->PortType =
1402 FC_HBA_PORTTYPE_NLPORT;
1403 } else {
1404 port_attrs->PortType =
1405 FC_HBA_PORTTYPE_LPORT;
1406 }
1407
1408 } else {
1409 if (hba->flag & FC_PT_TO_PT) {
1410 port_attrs->PortType =
1411 FC_HBA_PORTTYPE_PTP;
1412 } else {
1413 port_attrs->PortType =
1414 FC_HBA_PORTTYPE_NPORT;
1415 }
1416 }
1417
1418 if (hba->flag & FC_FABRIC_ATTACHED) {
1419 bcopy(&port->fabric_sparam.portName,
1420 (caddr_t)&port_attrs->FabricName,
1421 sizeof (port_attrs->FabricName));
1422 }
1423
1424 switch (hba->linkspeed) {
1425 case 0:
1426 port_attrs->PortSpeed =
1427 HBA_PORTSPEED_1GBIT;
1428 break;
1429 case LA_1GHZ_LINK:
1430 port_attrs->PortSpeed =
1431 HBA_PORTSPEED_1GBIT;
1432 break;
1433 case LA_2GHZ_LINK:
1434 port_attrs->PortSpeed =
1435 HBA_PORTSPEED_2GBIT;
1436 break;
1437 case LA_4GHZ_LINK:
1438 port_attrs->PortSpeed =
1439 HBA_PORTSPEED_4GBIT;
1440 break;
1441 case LA_8GHZ_LINK:
1442 port_attrs->PortSpeed =
1443 HBA_PORTSPEED_8GBIT;
1444 break;
1445 case LA_10GHZ_LINK:
1446 port_attrs->PortSpeed =
1447 HBA_PORTSPEED_10GBIT;
1448 break;
1449 case LA_16GHZ_LINK:
1450 port_attrs->PortSpeed =
1451 HBA_PORTSPEED_16GBIT;
1452 break;
1453 case LA_32GHZ_LINK:
1454 port_attrs->PortSpeed =
1455 HBA_PORTSPEED_32GBIT;
1456 break;
1457 default:
1458 port_attrs->PortSpeed =
1459 HBA_PORTSPEED_UNKNOWN;
1460 }
1461
1462 port_attrs->NumberofDiscoveredPorts =
1463 emlxs_nport_count(port);
1464 }
1465
1466 port_attrs->PortSupportedClassofService =
1467 LE_SWAP32(FC_NS_CLASS3);
1468 (void) strncpy((caddr_t)port_attrs->PortSymbolicName,
1469 (caddr_t)port->spn,
1470 (sizeof (port_attrs->PortSymbolicName)-1));
1471
1472 /* Set the hba speed limit */
1473 if (vpd->link_speed & LMT_32GB_CAPABLE) {
1474 port_attrs->PortSupportedSpeed |=
1475 FC_HBA_PORTSPEED_32GBIT;
1476 }
1477 if (vpd->link_speed & LMT_16GB_CAPABLE) {
1478 port_attrs->PortSupportedSpeed |=
1479 FC_HBA_PORTSPEED_16GBIT;
1480 }
1481 if (vpd->link_speed & LMT_10GB_CAPABLE) {
1482 port_attrs->PortSupportedSpeed |=
1483 FC_HBA_PORTSPEED_10GBIT;
1484 }
1485 if (vpd->link_speed & LMT_8GB_CAPABLE) {
1486 port_attrs->PortSupportedSpeed |=
1487 FC_HBA_PORTSPEED_8GBIT;
1488 }
1489 if (vpd->link_speed & LMT_4GB_CAPABLE) {
1490 port_attrs->PortSupportedSpeed |=
1491 FC_HBA_PORTSPEED_4GBIT;
1492 }
1493 if (vpd->link_speed & LMT_2GB_CAPABLE) {
1494 port_attrs->PortSupportedSpeed |=
1495 FC_HBA_PORTSPEED_2GBIT;
1496 }
1497 if (vpd->link_speed & LMT_1GB_CAPABLE) {
1498 port_attrs->PortSupportedSpeed |=
1499 FC_HBA_PORTSPEED_1GBIT;
1500 }
1501
1502 value1 = 0x00000120;
1503 value2 = 0x00000001;
1504
1505 bcopy((caddr_t)&value1,
1506 (caddr_t)&port_attrs->PortSupportedFc4Types[0], 4);
1507 bcopy((caddr_t)&value2,
1508 (caddr_t)&port_attrs->PortSupportedFc4Types[4], 4);
1509
1510 bcopy((caddr_t)&value1,
1511 (caddr_t)&port_attrs->PortActiveFc4Types[0], 4);
1512 bcopy((caddr_t)&value2,
1513 (caddr_t)&port_attrs->PortActiveFc4Types[4], 4);
1514
1515 port_attrs->PortMaxFrameSize = FF_FRAME_SIZE;
1516
1517 } else {
1518
1519 fc_hba_port_attributes_t *port_attrs;
1520 uint32_t value1;
1521 uint32_t value2;
1522
1523 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1524 fcio->fcio_olen <
1525 sizeof (fc_hba_port_attributes_t)) {
1526 rval = EINVAL;
1527 goto done;
1528 }
1529
1530 port_attrs =
1531 (fc_hba_port_attributes_t *)fcio->fcio_obuf;
1532
1533 port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
1534 port_attrs->lastChange = 0;
1535 port_attrs->fp_minor = 0;
1536 bcopy((caddr_t)&port->wwnn,
1537 (caddr_t)&port_attrs->NodeWWN, 8);
1538 bcopy((caddr_t)&port->wwpn,
1539 (caddr_t)&port_attrs->PortWWN, 8);
1540
1541 if (port->mode != MODE_TARGET ||
1542 (port->ulp_statec == FC_STATE_OFFLINE)) {
1543 /* port_attrs->PortFcId */
1544 /* port_attrs->PortType */
1545 /* port_attrs->PortSpeed */
1546 /* port_attrs->FabricName */
1547 port_attrs->PortState =
1548 FC_HBA_PORTSTATE_OFFLINE;
1549 } else {
1550 port_attrs->PortFcId = port->did;
1551 port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE;
1552
1553 if (hba->topology == TOPOLOGY_LOOP) {
1554 if (hba->flag & FC_FABRIC_ATTACHED) {
1555 port_attrs->PortType =
1556 FC_HBA_PORTTYPE_NLPORT;
1557 } else {
1558 port_attrs->PortType =
1559 FC_HBA_PORTTYPE_LPORT;
1560 }
1561
1562 } else {
1563 if (hba->flag & FC_PT_TO_PT) {
1564 port_attrs->PortType =
1565 FC_HBA_PORTTYPE_PTP;
1566 } else {
1567 port_attrs->PortType =
1568 FC_HBA_PORTTYPE_NPORT;
1569 }
1570 }
1571
1572 if (hba->flag & FC_FABRIC_ATTACHED) {
1573 bcopy(&port->fabric_sparam.portName,
1574 (caddr_t)&port_attrs->FabricName,
1575 sizeof (port_attrs->FabricName));
1576 }
1577
1578 switch (hba->linkspeed) {
1579 case 0:
1580 port_attrs->PortSpeed =
1581 HBA_PORTSPEED_1GBIT;
1582 break;
1583 case LA_1GHZ_LINK:
1584 port_attrs->PortSpeed =
1585 HBA_PORTSPEED_1GBIT;
1586 break;
1587 case LA_2GHZ_LINK:
1588 port_attrs->PortSpeed =
1589 HBA_PORTSPEED_2GBIT;
1590 break;
1591 case LA_4GHZ_LINK:
1592 port_attrs->PortSpeed =
1593 HBA_PORTSPEED_4GBIT;
1594 break;
1595 case LA_8GHZ_LINK:
1596 port_attrs->PortSpeed =
1597 HBA_PORTSPEED_8GBIT;
1598 break;
1599 case LA_10GHZ_LINK:
1600 port_attrs->PortSpeed =
1601 HBA_PORTSPEED_10GBIT;
1602 break;
1603 case LA_16GHZ_LINK:
1604 port_attrs->PortSpeed =
1605 HBA_PORTSPEED_16GBIT;
1606 break;
1607 case LA_32GHZ_LINK:
1608 port_attrs->PortSpeed =
1609 HBA_PORTSPEED_32GBIT;
1610 break;
1611 default:
1612 port_attrs->PortSpeed =
1613 HBA_PORTSPEED_UNKNOWN;
1614 }
1615
1616 port_attrs->NumberofDiscoveredPorts =
1617 emlxs_nport_count(port);
1618 }
1619
1620 port_attrs->PortSupportedClassofService =
1621 LE_SWAP32(FC_NS_CLASS3);
1622 (void) strncpy((caddr_t)port_attrs->PortSymbolicName,
1623 (caddr_t)port->spn,
1624 (sizeof (port_attrs->PortSymbolicName)-1));
1625
1626 /* Set the hba speed limit */
1627 if (vpd->link_speed & LMT_32GB_CAPABLE) {
1628 port_attrs->PortSupportedSpeed |=
1629 FC_HBA_PORTSPEED_32GBIT;
1630 }
1631 if (vpd->link_speed & LMT_16GB_CAPABLE) {
1632 port_attrs->PortSupportedSpeed |=
1633 FC_HBA_PORTSPEED_16GBIT;
1634 }
1635 if (vpd->link_speed & LMT_10GB_CAPABLE) {
1636 port_attrs->PortSupportedSpeed |=
1637 FC_HBA_PORTSPEED_10GBIT;
1638 }
1639 if (vpd->link_speed & LMT_8GB_CAPABLE) {
1640 port_attrs->PortSupportedSpeed |=
1641 FC_HBA_PORTSPEED_8GBIT;
1642 }
1643 if (vpd->link_speed & LMT_4GB_CAPABLE) {
1644 port_attrs->PortSupportedSpeed |=
1645 FC_HBA_PORTSPEED_4GBIT;
1646 }
1647 if (vpd->link_speed & LMT_2GB_CAPABLE) {
1648 port_attrs->PortSupportedSpeed |=
1649 FC_HBA_PORTSPEED_2GBIT;
1650 }
1651 if (vpd->link_speed & LMT_1GB_CAPABLE) {
1652 port_attrs->PortSupportedSpeed |=
1653 FC_HBA_PORTSPEED_1GBIT;
1654 }
1655
1656 value1 = 0x00000120;
1657 value2 = 0x00000001;
1658
1659 bcopy((caddr_t)&value1,
1660 (caddr_t)&port_attrs->PortSupportedFc4Types[0], 4);
1661 bcopy((caddr_t)&value2,
1662 (caddr_t)&port_attrs->PortSupportedFc4Types[4], 4);
1663
1664 bcopy((caddr_t)&value1,
1665 (caddr_t)&port_attrs->PortActiveFc4Types[0], 4);
1666 bcopy((caddr_t)&value2,
1667 (caddr_t)&port_attrs->PortActiveFc4Types[4], 4);
1668
1669 port_attrs->PortMaxFrameSize = FF_FRAME_SIZE;
1670 }
1671
1672 done:
1673 return (rval);
1674
1675 } /* emlxs_fcio_get_adapter_port_attrs() */
1676
1677
1678 /*ARGSUSED*/
1679 static int32_t
emlxs_fcio_get_node_id(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1680 emlxs_fcio_get_node_id(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1681 {
1682 int32_t rval = 0;
1683 fc_fca_pm_t pm;
1684
1685 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1686 fcio->fcio_olen < sizeof (fc_rnid_t)) {
1687 rval = EINVAL;
1688 goto done;
1689 }
1690
1691 bzero((caddr_t)&pm, sizeof (pm));
1692
1693 pm.pm_cmd_flags = FC_FCA_PM_READ;
1694 pm.pm_cmd_code = FC_PORT_GET_NODE_ID;
1695 pm.pm_data_len = fcio->fcio_olen;
1696 pm.pm_data_buf = fcio->fcio_obuf;
1697
1698 rval = emlxs_fca_port_manage(port, &pm);
1699
1700 if (rval != FC_SUCCESS) {
1701 fcio->fcio_errno = rval;
1702 rval = EIO;
1703 }
1704
1705 done:
1706 return (rval);
1707
1708 } /* emlxs_fcio_get_node_id() */
1709
1710
1711 /*ARGSUSED*/
1712 static int32_t
emlxs_fcio_set_node_id(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1713 emlxs_fcio_set_node_id(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1714 {
1715 int32_t rval = 0;
1716 fc_fca_pm_t pm;
1717
1718 if (fcio->fcio_xfer != FCIO_XFER_WRITE ||
1719 fcio->fcio_ilen < sizeof (fc_rnid_t)) {
1720 rval = EINVAL;
1721 goto done;
1722 }
1723
1724 bzero((caddr_t)&pm, sizeof (pm));
1725
1726 pm.pm_cmd_flags = FC_FCA_PM_READ;
1727 pm.pm_cmd_code = FC_PORT_SET_NODE_ID;
1728 pm.pm_data_len = fcio->fcio_ilen;
1729 pm.pm_data_buf = fcio->fcio_ibuf;
1730
1731 rval = emlxs_fca_port_manage(port, &pm);
1732
1733 if (rval != FC_SUCCESS) {
1734 fcio->fcio_errno = rval;
1735 rval = EIO;
1736 }
1737
1738 done:
1739 return (rval);
1740
1741 } /* emlxs_fcio_set_node_id() */
1742
1743
1744
1745
1746 /*ARGSUSED*/
1747 static int32_t
emlxs_fcio_get_num_devs(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1748 emlxs_fcio_get_num_devs(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1749 {
1750 int32_t rval = 0;
1751
1752 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1753 fcio->fcio_olen < sizeof (uint32_t)) {
1754 rval = EINVAL;
1755 goto done;
1756 }
1757
1758 if (port->mode == MODE_TARGET) {
1759 *(uint32_t *)fcio->fcio_obuf = emlxs_nport_count(port);
1760 }
1761
1762 done:
1763 return (rval);
1764
1765 } /* emlxs_fcio_get_num_devs() */
1766
1767
1768 #ifndef _MULTI_DATAMODEL
1769 /* ARGSUSED */
1770 #endif
1771 static int32_t
emlxs_fcio_get_dev_list(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1772 emlxs_fcio_get_dev_list(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1773 {
1774 emlxs_hba_t *hba = HBA;
1775 int32_t rval = 0;
1776 uint32_t use32 = 0;
1777
1778 #ifdef _MULTI_DATAMODEL
1779 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
1780 use32 = 1;
1781 }
1782 #endif /* _MULTI_DATAMODEL */
1783
1784 if (use32) {
1785 fc_port_dev32_t *port_dev;
1786 uint32_t max_count;
1787 uint32_t i;
1788 uint32_t j;
1789 emlxs_node_t *nlp;
1790 uint32_t nport_count = 0;
1791
1792 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1793 fcio->fcio_alen < sizeof (uint32_t)) {
1794 rval = EINVAL;
1795 goto done;
1796 }
1797
1798 port_dev = (fc_port_dev32_t *)fcio->fcio_obuf;
1799 max_count = fcio->fcio_olen / sizeof (fc_port_dev32_t);
1800
1801 rw_enter(&port->node_rwlock, RW_READER);
1802
1803 if (port->mode == MODE_TARGET) {
1804 nport_count = emlxs_nport_count(port);
1805 }
1806
1807 *(uint32_t *)fcio->fcio_abuf = nport_count;
1808
1809 if (nport_count == 0) {
1810 rw_exit(&port->node_rwlock);
1811
1812 fcio->fcio_errno = FC_NO_MAP;
1813 rval = EIO;
1814 goto done;
1815 }
1816
1817 if (nport_count > max_count) {
1818 rw_exit(&port->node_rwlock);
1819
1820 fcio->fcio_errno = FC_TOOMANY;
1821 rval = EIO;
1822 goto done;
1823 }
1824
1825 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
1826 nlp = port->node_table[i];
1827 while (nlp != NULL) {
1828 if ((nlp->nlp_DID & 0xFFF000) != 0xFFF000) {
1829 port_dev->dev_dtype = 0;
1830 port_dev->dev_type[0] =
1831 BE_SWAP32(0x00000100);
1832 port_dev->dev_state =
1833 PORT_DEVICE_LOGGED_IN;
1834 port_dev->dev_did.port_id =
1835 nlp->nlp_DID;
1836 port_dev->dev_did.priv_lilp_posit = 0;
1837 port_dev->dev_hard_addr.hard_addr = 0;
1838
1839 if (hba->topology == TOPOLOGY_LOOP) {
1840 for (j = 1; j < port->alpa_map[0]; j++) {
1841 if (nlp->nlp_DID == port->alpa_map[j]) {
1842 port_dev->dev_did.priv_lilp_posit = j-1;
1843 goto done;
1844 }
1845 }
1846 port_dev->dev_hard_addr.hard_addr = nlp->nlp_DID;
1847 }
1848
1849 bcopy((caddr_t)&nlp->nlp_portname,
1850 (caddr_t)&port_dev->dev_pwwn, 8);
1851 bcopy((caddr_t)&nlp->nlp_nodename,
1852 (caddr_t)&port_dev->dev_nwwn, 8);
1853 port_dev++;
1854 }
1855
1856 nlp = (NODELIST *) nlp->nlp_list_next;
1857 }
1858 }
1859 rw_exit(&port->node_rwlock);
1860
1861 } else {
1862
1863 fc_port_dev_t *port_dev;
1864 uint32_t max_count;
1865 uint32_t i;
1866 uint32_t j;
1867 emlxs_node_t *nlp;
1868 uint32_t nport_count = 0;
1869
1870 if (fcio->fcio_xfer != FCIO_XFER_READ ||
1871 fcio->fcio_alen < sizeof (uint32_t)) {
1872 rval = EINVAL;
1873 goto done;
1874 }
1875
1876 port_dev = (fc_port_dev_t *)fcio->fcio_obuf;
1877 max_count = fcio->fcio_olen / sizeof (fc_port_dev_t);
1878
1879 rw_enter(&port->node_rwlock, RW_READER);
1880
1881 if (port->mode == MODE_TARGET) {
1882 nport_count = emlxs_nport_count(port);
1883 }
1884
1885 *(uint32_t *)fcio->fcio_abuf = nport_count;
1886
1887 if (nport_count == 0) {
1888 rw_exit(&port->node_rwlock);
1889
1890 fcio->fcio_errno = FC_NO_MAP;
1891 rval = EIO;
1892 goto done;
1893 }
1894
1895 if (nport_count > max_count) {
1896 rw_exit(&port->node_rwlock);
1897
1898 fcio->fcio_errno = FC_TOOMANY;
1899 rval = EIO;
1900 goto done;
1901 }
1902
1903 for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) {
1904 nlp = port->node_table[i];
1905 while (nlp != NULL) {
1906 if ((nlp->nlp_DID & 0xFFF000) != 0xFFF000) {
1907 port_dev->dev_dtype = 0;
1908 port_dev->dev_type[0] =
1909 BE_SWAP32(0x00000100);
1910 port_dev->dev_state =
1911 PORT_DEVICE_LOGGED_IN;
1912 port_dev->dev_did.port_id =
1913 nlp->nlp_DID;
1914 port_dev->dev_did.priv_lilp_posit = 0;
1915 port_dev->dev_hard_addr.hard_addr = 0;
1916
1917 if (hba->topology == TOPOLOGY_LOOP) {
1918 for (j = 1; j < port->alpa_map[0]; j++) {
1919 if (nlp->nlp_DID == port->alpa_map[j]) {
1920 port_dev->dev_did.priv_lilp_posit = j-1;
1921 goto done;
1922 }
1923 }
1924 port_dev->dev_hard_addr.hard_addr = nlp->nlp_DID;
1925 }
1926
1927 bcopy((caddr_t)&nlp->nlp_portname,
1928 (caddr_t)&port_dev->dev_pwwn, 8);
1929 bcopy((caddr_t)&nlp->nlp_nodename,
1930 (caddr_t)&port_dev->dev_nwwn, 8);
1931 port_dev++;
1932 }
1933
1934 nlp = (NODELIST *) nlp->nlp_list_next;
1935 }
1936 }
1937 rw_exit(&port->node_rwlock);
1938 }
1939
1940 done:
1941 return (rval);
1942
1943 } /* emlxs_fcio_get_dev_list() */
1944
1945
1946 /*ARGSUSED*/
1947 static int32_t
emlxs_fcio_get_logi_params(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1948 emlxs_fcio_get_logi_params(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1949 {
1950 int32_t rval = 0;
1951 uint8_t null_wwn[8];
1952 uint8_t *wwpn;
1953 emlxs_node_t *ndlp;
1954
1955 if (fcio->fcio_ilen != sizeof (la_wwn_t) ||
1956 (fcio->fcio_xfer & FCIO_XFER_READ) == 0 ||
1957 (fcio->fcio_xfer & FCIO_XFER_WRITE) == 0) {
1958 rval = EINVAL;
1959 goto done;
1960 }
1961
1962 bzero(null_wwn, 8);
1963 wwpn = (uint8_t *)fcio->fcio_ibuf;
1964
1965 if ((bcmp((caddr_t)wwpn, (caddr_t)null_wwn, 8) == 0) ||
1966 (bcmp((caddr_t)wwpn, (caddr_t)&port->wwpn, 8) == 0)) {
1967 bcopy((caddr_t)&port->sparam,
1968 (caddr_t)fcio->fcio_obuf, fcio->fcio_olen);
1969 } else {
1970 ndlp = emlxs_node_find_wwpn(port, wwpn, 1);
1971
1972 if (ndlp) {
1973 bcopy((caddr_t)&ndlp->sparm,
1974 (caddr_t)fcio->fcio_obuf,
1975 fcio->fcio_olen);
1976 } else {
1977 rval = ENXIO;
1978 }
1979 }
1980
1981 done:
1982 return (rval);
1983
1984 } /* emlxs_fcio_get_logi_params() */
1985
1986
1987 /*ARGSUSED*/
1988 static int32_t
emlxs_fcio_get_state(emlxs_port_t * port,fcio_t * fcio,int32_t mode)1989 emlxs_fcio_get_state(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
1990 {
1991 int32_t rval = 0;
1992 uint8_t null_wwn[8];
1993 uint32_t *statep;
1994 uint8_t *wwpn;
1995 emlxs_node_t *ndlp;
1996
1997 if (fcio->fcio_ilen != 8 ||
1998 fcio->fcio_olen != 4 ||
1999 (fcio->fcio_xfer & FCIO_XFER_WRITE) == 0 ||
2000 (fcio->fcio_xfer & FCIO_XFER_READ) == 0) {
2001 rval = EINVAL;
2002 goto done;
2003 }
2004
2005 bzero(null_wwn, 8);
2006 wwpn = (uint8_t *)fcio->fcio_ibuf;
2007 statep = (uint32_t *)fcio->fcio_obuf;
2008
2009 if ((bcmp((caddr_t)wwpn, (caddr_t)null_wwn, 8) == 0) ||
2010 (bcmp((caddr_t)wwpn, (caddr_t)&port->wwpn, 8) == 0)) {
2011 *statep = PORT_DEVICE_VALID;
2012 } else {
2013 ndlp = emlxs_node_find_wwpn(port, wwpn, 1);
2014
2015 if (ndlp) {
2016 *statep = PORT_DEVICE_VALID;
2017 } else {
2018 *statep = PORT_DEVICE_INVALID;
2019 }
2020 }
2021
2022 done:
2023 return (rval);
2024
2025 } /* emlxs_fcio_get_state() */
2026
2027
2028 /*ARGSUSED*/
2029 static int32_t
emlxs_fcio_get_topology(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2030 emlxs_fcio_get_topology(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2031 {
2032 emlxs_hba_t *hba = HBA;
2033 int32_t rval = 0;
2034 uint32_t *tp;
2035 emlxs_node_t *ndlp;
2036
2037 if (fcio->fcio_olen != 4 ||
2038 (fcio->fcio_xfer & FCIO_XFER_READ) == 0) {
2039 rval = EINVAL;
2040 goto done;
2041 }
2042
2043 tp = (uint32_t *)fcio->fcio_obuf;
2044
2045 if ((port->mode != MODE_TARGET) ||
2046 (port->ulp_statec == FC_STATE_OFFLINE)) {
2047 *tp = FC_TOP_UNKNOWN;
2048 } else {
2049 ndlp = emlxs_node_find_did(port, FABRIC_DID, 1);
2050
2051 if (hba->topology == TOPOLOGY_LOOP) {
2052 if (ndlp) {
2053 *tp = FC_TOP_PUBLIC_LOOP;
2054 } else {
2055 *tp = FC_TOP_PRIVATE_LOOP;
2056 }
2057 } else {
2058 if (ndlp) {
2059 *tp = FC_TOP_FABRIC;
2060 } else {
2061 *tp = FC_TOP_PT_PT;
2062 }
2063 }
2064 }
2065
2066 done:
2067 return (rval);
2068
2069 } /* emlxs_fcio_get_topology() */
2070
2071
2072 /*ARGSUSED*/
2073 static int32_t
emlxs_fcio_get_link_status(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2074 emlxs_fcio_get_link_status(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2075 {
2076 int32_t rval = 0;
2077 fc_portid_t *portid;
2078 fc_rls_acc_t *rls;
2079 fc_fca_pm_t pm;
2080
2081 if (fcio->fcio_ilen != sizeof (fc_portid_t) ||
2082 fcio->fcio_olen != sizeof (fc_rls_acc_t) ||
2083 fcio->fcio_xfer != FCIO_XFER_RW) {
2084 rval = EINVAL;
2085 goto done;
2086 }
2087
2088 if ((fcio->fcio_cmd_flags != FCIO_CFLAGS_RLS_DEST_FPORT) &&
2089 (fcio->fcio_cmd_flags != FCIO_CFLAGS_RLS_DEST_NPORT)) {
2090 rval = EINVAL;
2091 goto done;
2092 }
2093
2094 portid = (fc_portid_t *)fcio->fcio_ibuf;
2095 rls = (fc_rls_acc_t *)fcio->fcio_obuf;
2096
2097 if (portid->port_id == 0 || portid->port_id == port->did) {
2098 bzero((caddr_t)&pm, sizeof (pm));
2099
2100 pm.pm_cmd_flags = FC_FCA_PM_READ;
2101 pm.pm_cmd_code = FC_PORT_RLS;
2102 pm.pm_data_len = sizeof (fc_rls_acc_t);
2103 pm.pm_data_buf = (caddr_t)rls;
2104
2105 rval = emlxs_fca_port_manage(port, &pm);
2106
2107 if (rval != FC_SUCCESS) {
2108 fcio->fcio_errno = rval;
2109 rval = EIO;
2110 }
2111 } else {
2112 rval = ENOTSUP;
2113 }
2114
2115 done:
2116 return (rval);
2117
2118 } /* emlxs_fcio_get_link_status() */
2119
2120
2121 /*ARGSUSED*/
2122 static int32_t
emlxs_fcio_get_other_adapter_ports(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2123 emlxs_fcio_get_other_adapter_ports(emlxs_port_t *port, fcio_t *fcio,
2124 int32_t mode)
2125 {
2126 emlxs_hba_t *hba = HBA;
2127 int32_t rval = 0;
2128 uint32_t index;
2129 char *path;
2130
2131 if (fcio->fcio_olen < MAXPATHLEN ||
2132 fcio->fcio_ilen != sizeof (uint32_t)) {
2133 rval = EINVAL;
2134 goto done;
2135 }
2136
2137 index = *(uint32_t *)fcio->fcio_ibuf;
2138 path = (char *)fcio->fcio_obuf;
2139
2140 if (index > hba->vpi_max) {
2141 fcio->fcio_errno = FC_BADPORT;
2142 rval = EFAULT;
2143 goto done;
2144 }
2145
2146 (void) ddi_pathname(hba->dip, path);
2147
2148 done:
2149 return (rval);
2150
2151 } /* emlxs_fcio_get_other_adapter_ports() */
2152
2153
2154 /*ARGSUSED*/
2155 static int32_t
emlxs_fcio_get_disc_port_attrs(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2156 emlxs_fcio_get_disc_port_attrs(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2157 {
2158 emlxs_hba_t *hba = HBA;
2159 int32_t rval = 0;
2160 uint32_t index;
2161 emlxs_node_t *ndlp;
2162 uint32_t use32 = 0;
2163
2164 #ifdef _MULTI_DATAMODEL
2165 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
2166 use32 = 1;
2167 }
2168 #endif /* _MULTI_DATAMODEL */
2169
2170 if (use32) {
2171 fc_hba_port_attributes32_t *port_attrs;
2172
2173 if (fcio->fcio_xfer != FCIO_XFER_READ ||
2174 fcio->fcio_ilen < sizeof (uint32_t) ||
2175 fcio->fcio_olen < sizeof (fc_hba_port_attributes32_t)) {
2176 rval = EINVAL;
2177 goto done;
2178 }
2179
2180 index = *(uint32_t *)fcio->fcio_ibuf;
2181 ndlp = emlxs_node_find_index(port, index, 1);
2182
2183 if (!ndlp) {
2184 fcio->fcio_errno = FC_OUTOFBOUNDS;
2185 rval = EINVAL;
2186 goto done;
2187 }
2188
2189 port_attrs = (fc_hba_port_attributes32_t *)fcio->fcio_obuf;
2190
2191 port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
2192 /* port_attrs->lastChange */
2193 /* port_attrs->fp_minor */
2194 bcopy((caddr_t)&ndlp->nlp_nodename,
2195 (caddr_t)&port_attrs->NodeWWN, 8);
2196 bcopy((caddr_t)&ndlp->nlp_portname,
2197 (caddr_t)&port_attrs->PortWWN, 8);
2198
2199 port_attrs->PortSpeed = HBA_PORTSPEED_UNKNOWN;
2200 port_attrs->PortType = FC_HBA_PORTTYPE_UNKNOWN;
2201 port_attrs->PortState = FC_HBA_PORTSTATE_OFFLINE;
2202
2203 if ((port->mode == MODE_TARGET) &&
2204 (hba->state >= FC_LINK_UP)) {
2205 port_attrs->PortFcId = ndlp->nlp_DID;
2206 port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE;
2207
2208 /* no switch */
2209 if (!(hba->flag & FC_FABRIC_ATTACHED)) {
2210 if (hba->topology == TOPOLOGY_LOOP) {
2211 port_attrs->PortType =
2212 FC_HBA_PORTTYPE_LPORT;
2213 } else {
2214 port_attrs->PortType =
2215 FC_HBA_PORTTYPE_PTP;
2216 }
2217
2218 /* We share a common speed */
2219 switch (hba->linkspeed) {
2220 case 0:
2221 port_attrs->PortSpeed =
2222 HBA_PORTSPEED_1GBIT;
2223 break;
2224 case LA_1GHZ_LINK:
2225 port_attrs->PortSpeed =
2226 HBA_PORTSPEED_1GBIT;
2227 break;
2228 case LA_2GHZ_LINK:
2229 port_attrs->PortSpeed =
2230 HBA_PORTSPEED_2GBIT;
2231 break;
2232 case LA_4GHZ_LINK:
2233 port_attrs->PortSpeed =
2234 HBA_PORTSPEED_4GBIT;
2235 break;
2236 case LA_8GHZ_LINK:
2237 port_attrs->PortSpeed =
2238 HBA_PORTSPEED_8GBIT;
2239 break;
2240 case LA_10GHZ_LINK:
2241 port_attrs->PortSpeed =
2242 HBA_PORTSPEED_10GBIT;
2243 break;
2244 case LA_16GHZ_LINK:
2245 port_attrs->PortSpeed =
2246 HBA_PORTSPEED_16GBIT;
2247 break;
2248 case LA_32GHZ_LINK:
2249 port_attrs->PortSpeed =
2250 HBA_PORTSPEED_32GBIT;
2251 break;
2252 }
2253 }
2254 /* public loop */
2255 else if (hba->topology == TOPOLOGY_LOOP) {
2256 /* Check for common area and domain */
2257 if ((ndlp->nlp_DID & 0xFFFF00) ==
2258 (port->did & 0xFFFF00)) {
2259 port_attrs->PortType =
2260 FC_HBA_PORTTYPE_NLPORT;
2261
2262 /* We share a common speed */
2263 switch (hba->linkspeed) {
2264 case 0:
2265 port_attrs->PortSpeed =
2266 HBA_PORTSPEED_1GBIT;
2267 break;
2268 case LA_1GHZ_LINK:
2269 port_attrs->PortSpeed =
2270 HBA_PORTSPEED_1GBIT;
2271 break;
2272 case LA_2GHZ_LINK:
2273 port_attrs->PortSpeed =
2274 HBA_PORTSPEED_2GBIT;
2275 break;
2276 case LA_4GHZ_LINK:
2277 port_attrs->PortSpeed =
2278 HBA_PORTSPEED_4GBIT;
2279 break;
2280 case LA_8GHZ_LINK:
2281 port_attrs->PortSpeed =
2282 HBA_PORTSPEED_8GBIT;
2283 break;
2284 case LA_10GHZ_LINK:
2285 port_attrs->PortSpeed =
2286 HBA_PORTSPEED_10GBIT;
2287 break;
2288 case LA_16GHZ_LINK:
2289 port_attrs->PortSpeed =
2290 HBA_PORTSPEED_16GBIT;
2291 break;
2292 case LA_32GHZ_LINK:
2293 port_attrs->PortSpeed =
2294 HBA_PORTSPEED_32GBIT;
2295 break;
2296 }
2297 }
2298 }
2299 }
2300
2301 port_attrs->PortSupportedClassofService =
2302 LE_SWAP32(FC_NS_CLASS3);
2303 /* port_attrs->PortSymbolicName */
2304 /* port_attrs->PortSupportedSpeed */
2305 /* port_attrs->PortSupportedFc4Types */
2306 /* port_attrs->PortActiveFc4Types */
2307 /* port_attrs->PortMaxFrameSize */
2308 /* port_attrs->NumberofDiscoveredPorts */
2309
2310 } else {
2311 fc_hba_port_attributes_t *port_attrs;
2312
2313 if (fcio->fcio_xfer != FCIO_XFER_READ ||
2314 fcio->fcio_ilen < sizeof (uint32_t) ||
2315 fcio->fcio_olen < sizeof (fc_hba_port_attributes_t)) {
2316 rval = EINVAL;
2317 goto done;
2318 }
2319
2320 index = *(uint32_t *)fcio->fcio_ibuf;
2321 ndlp = emlxs_node_find_index(port, index, 1);
2322
2323 if (!ndlp) {
2324 fcio->fcio_errno = FC_OUTOFBOUNDS;
2325 rval = EINVAL;
2326 goto done;
2327 }
2328
2329 port_attrs = (fc_hba_port_attributes_t *)fcio->fcio_obuf;
2330
2331 port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
2332 /* port_attrs->lastChange */
2333 /* port_attrs->fp_minor */
2334 bcopy((caddr_t)&ndlp->nlp_nodename,
2335 (caddr_t)&port_attrs->NodeWWN, 8);
2336 bcopy((caddr_t)&ndlp->nlp_portname,
2337 (caddr_t)&port_attrs->PortWWN, 8);
2338
2339 port_attrs->PortSpeed = HBA_PORTSPEED_UNKNOWN;
2340 port_attrs->PortType = FC_HBA_PORTTYPE_UNKNOWN;
2341 port_attrs->PortState = FC_HBA_PORTSTATE_OFFLINE;
2342
2343 if ((port->mode == MODE_TARGET) &&
2344 (hba->state >= FC_LINK_UP)) {
2345 port_attrs->PortFcId = ndlp->nlp_DID;
2346 port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE;
2347
2348 /* no switch */
2349 if (!(hba->flag & FC_FABRIC_ATTACHED)) {
2350 if (hba->topology == TOPOLOGY_LOOP) {
2351 port_attrs->PortType =
2352 FC_HBA_PORTTYPE_LPORT;
2353 } else {
2354 port_attrs->PortType =
2355 FC_HBA_PORTTYPE_PTP;
2356 }
2357
2358 /* We share a common speed */
2359 switch (hba->linkspeed) {
2360 case 0:
2361 port_attrs->PortSpeed =
2362 HBA_PORTSPEED_1GBIT;
2363 break;
2364 case LA_1GHZ_LINK:
2365 port_attrs->PortSpeed =
2366 HBA_PORTSPEED_1GBIT;
2367 break;
2368 case LA_2GHZ_LINK:
2369 port_attrs->PortSpeed =
2370 HBA_PORTSPEED_2GBIT;
2371 break;
2372 case LA_4GHZ_LINK:
2373 port_attrs->PortSpeed =
2374 HBA_PORTSPEED_4GBIT;
2375 break;
2376 case LA_8GHZ_LINK:
2377 port_attrs->PortSpeed =
2378 HBA_PORTSPEED_8GBIT;
2379 break;
2380 case LA_10GHZ_LINK:
2381 port_attrs->PortSpeed =
2382 HBA_PORTSPEED_10GBIT;
2383 break;
2384 case LA_16GHZ_LINK:
2385 port_attrs->PortSpeed =
2386 HBA_PORTSPEED_16GBIT;
2387 break;
2388 case LA_32GHZ_LINK:
2389 port_attrs->PortSpeed =
2390 HBA_PORTSPEED_32GBIT;
2391 break;
2392 }
2393 }
2394 /* public loop */
2395 else if (hba->topology == TOPOLOGY_LOOP) {
2396 /* Check for common area and domain */
2397 if ((ndlp->nlp_DID & 0xFFFF00) ==
2398 (port->did & 0xFFFF00)) {
2399 port_attrs->PortType =
2400 FC_HBA_PORTTYPE_NLPORT;
2401
2402 /* We share a common speed */
2403 switch (hba->linkspeed) {
2404 case 0:
2405 port_attrs->PortSpeed =
2406 HBA_PORTSPEED_1GBIT;
2407 break;
2408 case LA_1GHZ_LINK:
2409 port_attrs->PortSpeed =
2410 HBA_PORTSPEED_1GBIT;
2411 break;
2412 case LA_2GHZ_LINK:
2413 port_attrs->PortSpeed =
2414 HBA_PORTSPEED_2GBIT;
2415 break;
2416 case LA_4GHZ_LINK:
2417 port_attrs->PortSpeed =
2418 HBA_PORTSPEED_4GBIT;
2419 break;
2420 case LA_8GHZ_LINK:
2421 port_attrs->PortSpeed =
2422 HBA_PORTSPEED_8GBIT;
2423 break;
2424 case LA_10GHZ_LINK:
2425 port_attrs->PortSpeed =
2426 HBA_PORTSPEED_10GBIT;
2427 break;
2428 case LA_16GHZ_LINK:
2429 port_attrs->PortSpeed =
2430 HBA_PORTSPEED_16GBIT;
2431 break;
2432 case LA_32GHZ_LINK:
2433 port_attrs->PortSpeed =
2434 HBA_PORTSPEED_32GBIT;
2435 break;
2436 }
2437 }
2438 }
2439 }
2440
2441 port_attrs->PortSupportedClassofService =
2442 LE_SWAP32(FC_NS_CLASS3);
2443 /* port_attrs->PortSymbolicName */
2444 /* port_attrs->PortSupportedSpeed */
2445 /* port_attrs->PortSupportedFc4Types */
2446 /* port_attrs->PortActiveFc4Types */
2447 /* port_attrs->PortMaxFrameSize */
2448 /* port_attrs->NumberofDiscoveredPorts */
2449 }
2450
2451 done:
2452 return (rval);
2453
2454 } /* emlxs_fcio_get_disc_port_attrs() */
2455
2456
2457 /*ARGSUSED*/
2458 static int32_t
emlxs_fcio_get_port_attrs(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2459 emlxs_fcio_get_port_attrs(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2460 {
2461 emlxs_hba_t *hba = HBA;
2462 int32_t rval = 0;
2463 emlxs_node_t *ndlp;
2464 uint8_t *wwpn;
2465 uint32_t use32 = 0;
2466
2467 #ifdef _MULTI_DATAMODEL
2468 if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
2469 use32 = 1;
2470 }
2471 #endif /* _MULTI_DATAMODEL */
2472
2473 if (use32) {
2474 fc_hba_port_attributes32_t *port_attrs;
2475
2476 if ((fcio->fcio_xfer != FCIO_XFER_READ) ||
2477 (fcio->fcio_ilen < 8) ||
2478 (fcio->fcio_olen < sizeof (fc_hba_port_attributes32_t))) {
2479 rval = EINVAL;
2480 goto done;
2481 }
2482
2483 wwpn = (uint8_t *)fcio->fcio_ibuf;
2484 ndlp = emlxs_node_find_wwpn(port, wwpn, 1);
2485
2486 if (!ndlp) {
2487 fcio->fcio_errno = FC_NOMAP;
2488 rval = EINVAL;
2489 goto done;
2490 }
2491
2492 /* Filter fabric ports */
2493 if ((ndlp->nlp_DID & 0xFFF000) == 0xFFF000) {
2494 fcio->fcio_errno = FC_NOMAP;
2495 rval = EINVAL;
2496 goto done;
2497 }
2498
2499 port_attrs = (fc_hba_port_attributes32_t *)fcio->fcio_obuf;
2500
2501 port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
2502 /* port_attrs->lastChange */
2503 /* port_attrs->fp_minor */
2504 bcopy((caddr_t)&ndlp->nlp_nodename,
2505 (caddr_t)&port_attrs->NodeWWN, 8);
2506 bcopy((caddr_t)&ndlp->nlp_portname,
2507 (caddr_t)&port_attrs->PortWWN, 8);
2508
2509 port_attrs->PortSpeed = HBA_PORTSPEED_UNKNOWN;
2510 port_attrs->PortType = FC_HBA_PORTTYPE_UNKNOWN;
2511 port_attrs->PortState = FC_HBA_PORTSTATE_OFFLINE;
2512
2513 if ((port->mode == MODE_TARGET) &&
2514 (hba->state >= FC_LINK_UP)) {
2515 port_attrs->PortFcId = ndlp->nlp_DID;
2516 port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE;
2517
2518 /* no switch */
2519 if (!(hba->flag & FC_FABRIC_ATTACHED)) {
2520 if (hba->topology == TOPOLOGY_LOOP) {
2521 port_attrs->PortType =
2522 FC_HBA_PORTTYPE_LPORT;
2523 } else {
2524 port_attrs->PortType =
2525 FC_HBA_PORTTYPE_PTP;
2526 }
2527
2528 /* We share a common speed */
2529 switch (hba->linkspeed) {
2530 case 0:
2531 port_attrs->PortSpeed =
2532 HBA_PORTSPEED_1GBIT;
2533 break;
2534 case LA_1GHZ_LINK:
2535 port_attrs->PortSpeed =
2536 HBA_PORTSPEED_1GBIT;
2537 break;
2538 case LA_2GHZ_LINK:
2539 port_attrs->PortSpeed =
2540 HBA_PORTSPEED_2GBIT;
2541 break;
2542 case LA_4GHZ_LINK:
2543 port_attrs->PortSpeed =
2544 HBA_PORTSPEED_4GBIT;
2545 break;
2546 case LA_8GHZ_LINK:
2547 port_attrs->PortSpeed =
2548 HBA_PORTSPEED_8GBIT;
2549 break;
2550 case LA_10GHZ_LINK:
2551 port_attrs->PortSpeed =
2552 HBA_PORTSPEED_10GBIT;
2553 break;
2554 case LA_16GHZ_LINK:
2555 port_attrs->PortSpeed =
2556 HBA_PORTSPEED_16GBIT;
2557 break;
2558 case LA_32GHZ_LINK:
2559 port_attrs->PortSpeed =
2560 HBA_PORTSPEED_32GBIT;
2561 break;
2562 }
2563 }
2564 /* public loop */
2565 else if (hba->topology == TOPOLOGY_LOOP) {
2566 /* Check for common area and domain */
2567 if ((ndlp->nlp_DID & 0xFFFF00) ==
2568 (port->did & 0xFFFF00)) {
2569 port_attrs->PortType =
2570 FC_HBA_PORTTYPE_NLPORT;
2571
2572 /* We share a common speed */
2573 switch (hba->linkspeed) {
2574 case 0:
2575 port_attrs->PortSpeed =
2576 HBA_PORTSPEED_1GBIT;
2577 break;
2578 case LA_1GHZ_LINK:
2579 port_attrs->PortSpeed =
2580 HBA_PORTSPEED_1GBIT;
2581 break;
2582 case LA_2GHZ_LINK:
2583 port_attrs->PortSpeed =
2584 HBA_PORTSPEED_2GBIT;
2585 break;
2586 case LA_4GHZ_LINK:
2587 port_attrs->PortSpeed =
2588 HBA_PORTSPEED_4GBIT;
2589 break;
2590 case LA_8GHZ_LINK:
2591 port_attrs->PortSpeed =
2592 HBA_PORTSPEED_8GBIT;
2593 break;
2594 case LA_10GHZ_LINK:
2595 port_attrs->PortSpeed =
2596 HBA_PORTSPEED_10GBIT;
2597 break;
2598 case LA_16GHZ_LINK:
2599 port_attrs->PortSpeed =
2600 HBA_PORTSPEED_16GBIT;
2601 break;
2602 case LA_32GHZ_LINK:
2603 port_attrs->PortSpeed =
2604 HBA_PORTSPEED_32GBIT;
2605 break;
2606 }
2607 }
2608 }
2609 }
2610
2611 port_attrs->PortSupportedClassofService =
2612 LE_SWAP32(FC_NS_CLASS3);
2613 /* port_attrs->PortSymbolicName */
2614 /* port_attrs->PortSupportedSpeed */
2615 /* port_attrs->PortSupportedFc4Types */
2616 /* port_attrs->PortActiveFc4Types */
2617 /* port_attrs->PortMaxFrameSize */
2618 /* port_attrs->NumberofDiscoveredPorts */
2619
2620 } else {
2621 fc_hba_port_attributes_t *port_attrs;
2622
2623 if ((fcio->fcio_xfer != FCIO_XFER_READ) ||
2624 (fcio->fcio_ilen < 8) ||
2625 (fcio->fcio_olen < sizeof (fc_hba_port_attributes_t))) {
2626 rval = EINVAL;
2627 goto done;
2628 }
2629
2630 wwpn = (uint8_t *)fcio->fcio_ibuf;
2631 ndlp = emlxs_node_find_wwpn(port, wwpn, 1);
2632
2633 if (!ndlp) {
2634 fcio->fcio_errno = FC_NOMAP;
2635 rval = EINVAL;
2636 goto done;
2637 }
2638
2639 /* Filter fabric ports */
2640 if ((ndlp->nlp_DID & 0xFFF000) == 0xFFF000) {
2641 fcio->fcio_errno = FC_NOMAP;
2642 rval = EINVAL;
2643 goto done;
2644 }
2645
2646 port_attrs = (fc_hba_port_attributes_t *)fcio->fcio_obuf;
2647
2648 port_attrs->version = FC_HBA_PORT_ATTRIBUTES_VERSION;
2649 /* port_attrs->lastChange */
2650 /* port_attrs->fp_minor */
2651 bcopy((caddr_t)&ndlp->nlp_nodename,
2652 (caddr_t)&port_attrs->NodeWWN, 8);
2653 bcopy((caddr_t)&ndlp->nlp_portname,
2654 (caddr_t)&port_attrs->PortWWN, 8);
2655
2656 port_attrs->PortSpeed = HBA_PORTSPEED_UNKNOWN;
2657 port_attrs->PortType = FC_HBA_PORTTYPE_UNKNOWN;
2658 port_attrs->PortState = FC_HBA_PORTSTATE_OFFLINE;
2659
2660 if ((port->mode == MODE_TARGET) &&
2661 (hba->state >= FC_LINK_UP)) {
2662 port_attrs->PortFcId = ndlp->nlp_DID;
2663 port_attrs->PortState = FC_HBA_PORTSTATE_ONLINE;
2664
2665 /* no switch */
2666 if (!(hba->flag & FC_FABRIC_ATTACHED)) {
2667 if (hba->topology == TOPOLOGY_LOOP) {
2668 port_attrs->PortType =
2669 FC_HBA_PORTTYPE_LPORT;
2670 } else {
2671 port_attrs->PortType =
2672 FC_HBA_PORTTYPE_PTP;
2673 }
2674
2675 /* We share a common speed */
2676 switch (hba->linkspeed) {
2677 case 0:
2678 port_attrs->PortSpeed =
2679 HBA_PORTSPEED_1GBIT;
2680 break;
2681 case LA_1GHZ_LINK:
2682 port_attrs->PortSpeed =
2683 HBA_PORTSPEED_1GBIT;
2684 break;
2685 case LA_2GHZ_LINK:
2686 port_attrs->PortSpeed =
2687 HBA_PORTSPEED_2GBIT;
2688 break;
2689 case LA_4GHZ_LINK:
2690 port_attrs->PortSpeed =
2691 HBA_PORTSPEED_4GBIT;
2692 break;
2693 case LA_8GHZ_LINK:
2694 port_attrs->PortSpeed =
2695 HBA_PORTSPEED_8GBIT;
2696 break;
2697 case LA_10GHZ_LINK:
2698 port_attrs->PortSpeed =
2699 HBA_PORTSPEED_10GBIT;
2700 break;
2701 case LA_16GHZ_LINK:
2702 port_attrs->PortSpeed =
2703 HBA_PORTSPEED_16GBIT;
2704 break;
2705 case LA_32GHZ_LINK:
2706 port_attrs->PortSpeed =
2707 HBA_PORTSPEED_32GBIT;
2708 break;
2709 }
2710 }
2711 /* public loop */
2712 else if (hba->topology == TOPOLOGY_LOOP) {
2713 /* Check for common area and domain */
2714 if ((ndlp->nlp_DID & 0xFFFF00) ==
2715 (port->did & 0xFFFF00)) {
2716 port_attrs->PortType =
2717 FC_HBA_PORTTYPE_NLPORT;
2718
2719 /* We share a common speed */
2720 switch (hba->linkspeed) {
2721 case 0:
2722 port_attrs->PortSpeed =
2723 HBA_PORTSPEED_1GBIT;
2724 break;
2725 case LA_1GHZ_LINK:
2726 port_attrs->PortSpeed =
2727 HBA_PORTSPEED_1GBIT;
2728 break;
2729 case LA_2GHZ_LINK:
2730 port_attrs->PortSpeed =
2731 HBA_PORTSPEED_2GBIT;
2732 break;
2733 case LA_4GHZ_LINK:
2734 port_attrs->PortSpeed =
2735 HBA_PORTSPEED_4GBIT;
2736 break;
2737 case LA_8GHZ_LINK:
2738 port_attrs->PortSpeed =
2739 HBA_PORTSPEED_8GBIT;
2740 break;
2741 case LA_10GHZ_LINK:
2742 port_attrs->PortSpeed =
2743 HBA_PORTSPEED_10GBIT;
2744 break;
2745 case LA_16GHZ_LINK:
2746 port_attrs->PortSpeed =
2747 HBA_PORTSPEED_16GBIT;
2748 break;
2749 case LA_32GHZ_LINK:
2750 port_attrs->PortSpeed =
2751 HBA_PORTSPEED_32GBIT;
2752 break;
2753 }
2754 }
2755 }
2756 }
2757
2758 port_attrs->PortSupportedClassofService =
2759 LE_SWAP32(FC_NS_CLASS3);
2760 /* port_attrs->PortSymbolicName */
2761 /* port_attrs->PortSupportedSpeed */
2762 /* port_attrs->PortSupportedFc4Types */
2763 /* port_attrs->PortActiveFc4Types */
2764 /* port_attrs->PortMaxFrameSize */
2765 /* port_attrs->NumberofDiscoveredPorts */
2766 }
2767
2768 done:
2769 return (rval);
2770
2771 } /* emlxs_fcio_get_port_attrs() */
2772
2773
2774 /*ARGSUSED*/
2775 static int32_t
emlxs_fcio_get_sym_pname(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2776 emlxs_fcio_get_sym_pname(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2777 {
2778 int32_t rval = 0;
2779
2780 if (fcio->fcio_olen < (strlen(port->spn)+1) ||
2781 (fcio->fcio_xfer & FCIO_XFER_READ) == 0) {
2782 rval = EINVAL;
2783 goto done;
2784 }
2785
2786 (void) strlcpy((caddr_t)fcio->fcio_obuf, (caddr_t)port->spn,
2787 fcio->fcio_olen);
2788
2789 done:
2790 return (rval);
2791
2792 } /* emlxs_fcio_get_sym_pname() */
2793
2794
2795 /*ARGSUSED*/
2796 static int32_t
emlxs_fcio_get_sym_nname(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2797 emlxs_fcio_get_sym_nname(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2798 {
2799 int32_t rval = 0;
2800
2801 if (fcio->fcio_olen < (strlen(port->snn)+1) ||
2802 (fcio->fcio_xfer & FCIO_XFER_READ) == 0) {
2803 rval = EINVAL;
2804 goto done;
2805 }
2806
2807 (void) strlcpy((caddr_t)fcio->fcio_obuf, (caddr_t)port->snn,
2808 fcio->fcio_olen);
2809
2810 done:
2811 return (rval);
2812
2813 } /* emlxs_fcio_get_sym_nname() */
2814
2815
2816 /*ARGSUSED*/
2817 static int32_t
emlxs_fcio_force_dump(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2818 emlxs_fcio_force_dump(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2819 {
2820 int32_t rval = 0;
2821
2822 if (port->mode != MODE_TARGET) {
2823 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sfs_debug_msg,
2824 "fcio_force_dump failed. Port is not in target mode.");
2825
2826 fcio->fcio_errno = FC_FAILURE;
2827 rval = EIO;
2828 goto done;
2829 }
2830
2831 rval = emlxs_reset(port, FC_FCA_CORE);
2832
2833 if (rval != FC_SUCCESS) {
2834 fcio->fcio_errno = rval;
2835 rval = EIO;
2836 goto done;
2837 }
2838
2839 done:
2840 return (rval);
2841
2842 } /* emlxs_fcio_force_dump() */
2843
2844
2845 /*ARGSUSED*/
2846 static int32_t
emlxs_fcio_get_dump_size(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2847 emlxs_fcio_get_dump_size(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2848 {
2849 int32_t rval = 0;
2850 fc_fca_pm_t pm;
2851
2852 if (fcio->fcio_olen != sizeof (uint32_t) ||
2853 fcio->fcio_xfer != FCIO_XFER_READ) {
2854 rval = EINVAL;
2855 goto done;
2856 }
2857
2858 bzero((caddr_t)&pm, sizeof (fc_fca_pm_t));
2859
2860 pm.pm_data_len = fcio->fcio_olen;
2861 pm.pm_data_buf = fcio->fcio_obuf;
2862 pm.pm_cmd_code = FC_PORT_GET_DUMP_SIZE;
2863 pm.pm_cmd_flags = FC_FCA_PM_READ;
2864
2865 rval = emlxs_fca_port_manage(port, &pm);
2866
2867 if (rval != FC_SUCCESS) {
2868 fcio->fcio_errno = rval;
2869
2870 if (rval == FC_INVALID_REQUEST) {
2871 rval = ENOTTY;
2872 } else {
2873 rval = EIO;
2874 }
2875 }
2876
2877 done:
2878 return (rval);
2879
2880 } /* emlxs_fcio_get_dump_size() */
2881
2882
2883 /*ARGSUSED*/
2884 static int32_t
emlxs_fcio_get_dump(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2885 emlxs_fcio_get_dump(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2886 {
2887 int32_t rval = 0;
2888 fc_fca_pm_t pm;
2889 uint32_t dump_size;
2890
2891 if (fcio->fcio_xfer != FCIO_XFER_READ) {
2892 rval = EINVAL;
2893 goto done;
2894 }
2895
2896 bzero((caddr_t)&pm, sizeof (fc_fca_pm_t));
2897
2898 pm.pm_data_len = sizeof (uint32_t);
2899 pm.pm_data_buf = (caddr_t)&dump_size;
2900 pm.pm_cmd_code = FC_PORT_GET_DUMP_SIZE;
2901 pm.pm_cmd_flags = FC_FCA_PM_READ;
2902
2903 rval = emlxs_fca_port_manage(port, &pm);
2904
2905 if (rval != FC_SUCCESS) {
2906 fcio->fcio_errno = rval;
2907
2908 if (rval == FC_INVALID_REQUEST) {
2909 rval = ENOTTY;
2910 } else {
2911 rval = EIO;
2912 }
2913 goto done;
2914 }
2915
2916 if (fcio->fcio_olen != dump_size) {
2917 fcio->fcio_errno = FC_NOMEM;
2918 rval = EINVAL;
2919 goto done;
2920 }
2921
2922 bzero((caddr_t)&pm, sizeof (fc_fca_pm_t));
2923
2924 pm.pm_data_len = fcio->fcio_olen;
2925 pm.pm_data_buf = fcio->fcio_obuf;
2926 pm.pm_cmd_code = FC_PORT_GET_DUMP;
2927 pm.pm_cmd_flags = FC_FCA_PM_READ;
2928
2929 rval = emlxs_fca_port_manage(port, &pm);
2930
2931 if (rval != FC_SUCCESS) {
2932 fcio->fcio_errno = rval;
2933
2934 if (rval == FC_INVALID_REQUEST) {
2935 rval = ENOTTY;
2936 } else {
2937 rval = EIO;
2938 }
2939 }
2940
2941 done:
2942 return (rval);
2943
2944 } /* emlxs_fcio_get_dump() */
2945
2946
2947 /*ARGSUSED*/
2948 static int32_t
emlxs_fcio_unsupported(emlxs_port_t * port,fcio_t * fcio,int32_t mode)2949 emlxs_fcio_unsupported(emlxs_port_t *port, fcio_t *fcio, int32_t mode)
2950 {
2951 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
2952 "%s: Command not supported.",
2953 emlxs_fcio_xlate(fcio->fcio_cmd));
2954
2955 return (ENOTSUP);
2956
2957 } /* emlxs_fcio_unsupported() */
2958 #endif /* FCIO_SUPPORT */
2959
2960
2961 /*ARGSUSED*/
2962 static int32_t
emlxs_dfc_create_vport(emlxs_hba_t * hba,dfc_t * dfc,int32_t mode)2963 emlxs_dfc_create_vport(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode)
2964 {
2965 emlxs_port_t *port = &PPORT;
2966 emlxs_config_t *cfg = &CFG;
2967 emlxs_port_t *vport;
2968 emlxs_port_t *tport;
2969 dfc_vportinfo_t *dfc_vport;
2970 uint32_t vpi;
2971 uint32_t options;
2972 char name[256];
2973 uint8_t wwn[8];
2974
2975 options = dfc->data1;
2976
2977 if (!dfc->buf1 || !dfc->buf1_size) {
2978 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
2979 "%s: Null buffer1 found.", emlxs_dfc_xlate(dfc->cmd));
2980
2981 return (DFC_ARG_NULL);
2982 }
2983
2984 if (dfc->buf1_size < sizeof (dfc_vportinfo_t)) {
2985 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
2986 "%s: Buffer1 too small. (size=%d)",
2987 emlxs_dfc_xlate(dfc->cmd), dfc->buf1_size);
2988
2989 return (DFC_ARG_TOOSMALL);
2990 }
2991
2992 dfc_vport = (dfc_vportinfo_t *)dfc->buf1;
2993
2994 if (!(options & VPORT_OPT_AUTORETRY)) {
2995 if (!(hba->flag & FC_NPIV_ENABLED)) {
2996 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
2997 "%s: NPIV currently not enabled.",
2998 emlxs_dfc_xlate(dfc->cmd));
2999
3000 return (DFC_NPIV_DISABLED);
3001 }
3002
3003 if (!(hba->flag & FC_NPIV_SUPPORTED)) {
3004 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
3005 "%s: NPIV currently not supported.",
3006 emlxs_dfc_xlate(dfc->cmd));
3007
3008 return (DFC_NPIV_UNSUPPORTED);
3009 }
3010 }
3011
3012 /*
3013 * Only the same WWNN and WWPN can be re-created
3014 */
3015 bzero(wwn, 8);
3016 if (bcmp(wwn, dfc_vport->wwpn, 8) || bcmp(wwn, dfc_vport->wwnn, 8)) {
3017 for (vpi = 1; vpi <= hba->vpi_max; vpi++) {
3018 vport = &VPORT(vpi);
3019
3020 if ((bcmp((caddr_t)&vport->wwnn,
3021 (caddr_t)dfc_vport->wwnn, 8) == 0) &&
3022 (bcmp((caddr_t)&vport->wwpn,
3023 (caddr_t)dfc_vport->wwpn, 8) == 0)) {
3024 if (!(vport->flag & EMLXS_PORT_CONFIG) &&
3025 (vport->flag & EMLXS_PORT_BOUND)) {
3026 dfc_vport->vpi = vpi;
3027 break;
3028 } else {
3029 EMLXS_MSGF(EMLXS_CONTEXT,
3030 &emlxs_dfc_error_msg,
3031 "%s: VPI already in use.",
3032 emlxs_dfc_xlate(