comm: add -Wall
[unleashed.git] / usr / src / cmd / luxadm / x86_adm.c
bloba53b2b92fe024593420135a9defa8a1b8aca6765
1 /*
2 * CDDL HEADER START
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.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <hbaapi.h>
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <string.h>
34 #include <sys/fibre-channel/fcio.h>
35 #include <sys/fibre-channel/impl/fc_error.h>
36 #include <sys/scsi/adapters/scsi_vhci.h>
37 #include "common.h"
38 #include "errorcodes.h"
39 #include <locale.h>
41 /* The i18n catalog */
42 nl_catd l_catd;
44 void
45 i18n_catopen() {
46 static int fileopen = 0;
48 if (setlocale(LC_ALL, "") == NULL) {
49 (void) fprintf(stderr,
50 "Cannot operate in the locale requested. "
51 "Continuing in the default C locale\n");
53 if (!fileopen) {
54 l_catd = catopen("a5k_g_fc_i18n_cat", NL_CAT_LOCALE);
55 if (l_catd == (nl_catd)-1) {
56 return;
58 fileopen = 1;
60 return;
65 * Given an error number, this functions
66 * calls the get_errString() to print a
67 * corresponding error message to the stderr.
68 * get_errString() always returns an error
69 * message, even in case of undefined error number.
70 * So, there is no need to check for a NULL pointer
71 * while printing the error message to the stdout.
73 * RETURNS: N/A
76 void
77 print_errString(int errnum, char *devpath)
80 char *errStr;
82 errStr = get_errString(errnum);
84 if (devpath == NULL) {
85 (void) fprintf(stderr,
86 "%s \n\n", errStr);
87 } else {
88 (void) fprintf(stderr,
89 "%s - %s.\n\n", errStr, devpath);
92 /* free the allocated memory for error string */
93 if (errStr != NULL)
94 (void) free(errStr);
97 static void terminate() {
98 fprintf(stdout, MSGSTR(2506, "Unsupported"));
99 fprintf(stdout, "\n");
100 exit(1);
103 /*ARGSUSED*/
104 int adm_display_config(char **a) {
105 terminate();
106 return (1);
109 /*ARGSUSED*/
110 void adm_download(char **a, char *b) {
111 terminate();
114 /*ARGSUSED*/
115 void up_encl_name(char **a, int b) {
116 terminate();
119 void adm_failover(char **argv) {
120 int path_index = 0, err = 0, fd;
121 char path_class[MAXNAMELEN];
122 char client_path[MAXPATHLEN];
123 char *path_phys = NULL, *trailingMinor;
124 sv_switch_to_cntlr_iocdata_t iocsc;
126 (void) memset(path_class, 0, sizeof (path_class));
127 (void) strcpy(path_class, argv[path_index++]);
128 if ((strcmp(path_class, "primary") != 0) &&
129 (strcmp(path_class, "secondary") != 0)) {
130 (void) fprintf(stderr,
131 MSGSTR(2300, "Incorrect pathclass\n"));
132 exit(-1);
135 if ((fd = open("/devices/scsi_vhci:devctl", O_RDWR)) < 0) {
136 print_errString(L_OPEN_PATH_FAIL, "/devices/scsi_vhci:devctl");
137 exit(-1);
140 iocsc.client = client_path;
141 iocsc.class = path_class;
143 while (argv[path_index] != NULL) {
144 path_phys =
145 get_slash_devices_from_osDevName(argv[path_index++],
146 STANDARD_DEVNAME_HANDLING);
147 if ((path_phys == NULL) ||
148 (strstr(path_phys, "/devices/scsi_vhci") == NULL)) {
149 (void) fprintf(stderr,
150 MSGSTR(2301, "Incorrect pathname\n"));
151 close(fd);
152 exit(-1);
155 strcpy(iocsc.client, path_phys + strlen("/devices"));
157 /* Now chop off the trailing ":xxx" portion if present */
158 if ((trailingMinor = strrchr(iocsc.client, ':')) != NULL) {
159 trailingMinor[0] = '\0';
162 if (ioctl(fd, SCSI_VHCI_SWITCH_TO_CNTLR, &iocsc) != 0) {
163 switch (errno) {
164 case EALREADY:
165 err = L_SCSI_VHCI_ALREADY_ACTIVE;
166 break;
167 case ENXIO:
168 err = L_INVALID_PATH;
169 break;
170 case EIO:
171 err = L_SCSI_VHCI_NO_STANDBY;
172 break;
173 case ENOTSUP:
174 err = L_SCSI_VHCI_FAILOVER_NOTSUP;
175 break;
176 case EBUSY:
177 err = L_SCSI_VHCI_FAILOVER_BUSY;
178 break;
179 case EFAULT:
180 default:
181 err = L_SCSI_VHCI_ERROR;
185 if (err != 0) {
186 close(fd);
187 print_errString(err, path_phys);
188 exit(-1);
192 close(fd);
195 /*ARGSUSED*/
196 int adm_inquiry(char **a) {
197 terminate();
198 return (1);
201 /*ARGSUSED*/
202 void pho_probe() {
203 terminate();
206 /*ARGSUSED*/
207 void non_encl_probe() {
208 terminate();
211 /*ARGSUSED*/
212 void adm_led(char **a, int b) {
213 terminate();
216 /*ARGSUSED*/
217 void up_password(char **a) {
218 terminate();
221 /*ARGSUSED*/
222 int adm_reserve(char *path) {
223 terminate();
224 return (1);
227 /*ARGSUSED*/
228 int adm_release(char *path) {
229 terminate();
230 return (1);
233 /*ARGSUSED*/
234 int adm_start(char **a) {
235 terminate();
236 return (1);
239 /*ARGSUSED*/
240 int adm_stop(char **a) {
241 terminate();
242 return (1);
245 /*ARGSUSED*/
246 int adm_power_off(char **a, int b) {
247 terminate();
248 return (1);
252 adm_forcelip(char **argv)
254 int path_index = 0, fd;
255 uint64_t wwn;
256 fcio_t fcio;
257 HBA_HANDLE handle;
258 HBA_ADAPTERATTRIBUTES hbaAttrs;
259 HBA_PORTATTRIBUTES portAttrs;
260 HBA_FCPTARGETMAPPINGV2 *map;
261 HBA_STATUS status;
262 int count, adapterIndex, portIndex, mapIndex;
263 char name[256];
264 int matched, ret = 0, wwnCompare = 0, ntries;
265 char *physical = NULL, *slash_OSDeviceName = NULL;
267 if ((status = loadLibrary())) {
268 /* loadLibrary print out error msg */
269 return (ret++);
271 for (path_index = 0; argv[path_index] != NULL; path_index++) {
273 if (is_wwn(argv[path_index])) {
274 (void) sscanf(argv[path_index], "%016llx", &wwn);
275 wwnCompare = 1;
276 } else if (!is_path(argv[path_index])) {
277 print_errString(L_INVALID_PATH, argv[path_index]);
278 ret++;
279 continue;
281 if (!wwnCompare) {
282 /* Convert the paths to phsyical paths */
283 physical = get_slash_devices_from_osDevName(argv[path_index],
284 STANDARD_DEVNAME_HANDLING);
285 if (!physical) {
286 print_errString(L_INVALID_PATH, argv[path_index]);
287 ret++;
288 continue;
292 count = getNumberOfAdapters();
294 matched = 0;
295 for (adapterIndex = 0; adapterIndex < count; adapterIndex ++) {
296 status = HBA_GetAdapterName(adapterIndex, (char *)&name);
297 if (status != HBA_STATUS_OK) {
298 /* May have been DR'd */
299 continue;
301 handle = HBA_OpenAdapter(name);
302 if (handle == 0) {
303 /* May have been DR'd */
304 continue;
307 if (getAdapterAttrs(handle, name, &hbaAttrs)) {
308 /* Should never happen */
309 HBA_CloseAdapter(handle);
310 continue;
313 /* Loop over all HBA Ports */
314 for (portIndex = 0; portIndex < hbaAttrs.NumberOfPorts;
315 portIndex++) {
316 if (getAdapterPortAttrs(handle, name, portIndex,
317 &portAttrs)) {
318 continue;
321 matched = 0;
322 if (is_wwn(argv[path_index])) {
323 if (wwn == wwnConversion(
324 portAttrs.NodeWWN.wwn) ||
325 wwn == wwnConversion(
326 portAttrs.PortWWN.wwn)) {
327 matched = 1;
329 } else {
330 slash_OSDeviceName = get_slash_devices_from_osDevName(
331 portAttrs.OSDeviceName, STANDARD_DEVNAME_HANDLING);
332 if (!slash_OSDeviceName) {
333 continue;
334 } else {
335 if (strncmp(physical, slash_OSDeviceName,
336 strlen(slash_OSDeviceName) -
337 strlen(strrchr(slash_OSDeviceName, ':')))
338 == 0) {
339 matched = 1;
341 free(slash_OSDeviceName);
345 if (!matched) {
346 if (!fetch_mappings(handle, portAttrs.PortWWN, &map)) {
348 * matchr_mapping checks the arg
349 * so we pass argv here.
351 mapIndex = match_mappings(argv[path_index], map);
352 if (mapIndex >= 0) {
353 matched = 1;
355 } else {
356 continue;
360 if (matched) {
361 if ((fd = open(portAttrs.OSDeviceName,
362 O_RDONLY | O_EXCL)) == -1) {
363 print_errString(L_OPEN_PATH_FAIL,
364 portAttrs.OSDeviceName);
365 return (ret++);
368 fcio.fcio_cmd = FCIO_RESET_LINK;
369 fcio.fcio_xfer = FCIO_XFER_WRITE;
371 * Reset the local loop here (fcio_ibuf = 0).
372 * Reset a remote loop on the Fabric by
373 * passing its node wwn (fcio_len = sizeof(nwwn)
374 * and fcio_ibuf = (caddr_t)&nwwn) to the port driver.
376 (void) memset(&wwn, 0, sizeof (wwn));
377 fcio.fcio_ilen = sizeof (wwn);
378 fcio.fcio_ibuf = (caddr_t)&wwn;
380 for (ntries = 0; ntries < RETRY_FCIO_IOCTL; ntries++) {
381 errno = 0;
382 if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
384 * When port is offlined, qlc
385 * returns the FC_OFFLINE error and errno
386 * is set to EIO.
387 * We do want to ignore this error,
388 * especially when an enclosure is
389 * removed from the loop.
391 if (fcio.fcio_errno == FC_OFFLINE)
392 break;
393 if ((errno == EAGAIN) &&
394 (ntries+1 < RETRY_FCIO_IOCTL)) {
395 /* wait WAIT_FCIO_IOCTL */
396 (void) usleep(WAIT_FCIO_IOCTL);
397 continue;
399 I_DPRINTF("FCIO ioctl failed.\n"
400 "Error: %s. fc_error = %d (0x%x)\n",
401 strerror(errno), fcio.fcio_errno,
402 fcio.fcio_errno);
403 close(fd);
404 print_errString(L_FCIO_FORCE_LIP_FAIL,
405 portAttrs.OSDeviceName);
406 return (ret++);
407 } else {
408 break; /* ioctl succeeds. */
411 close(fd);
412 if (ntries == RETRY_FCIO_IOCTL) {
413 print_errString(L_FCIO_FORCE_LIP_FAIL,
414 portAttrs.OSDeviceName);
415 return (ret++);
418 if (matched)
419 break; /* for HBA port for loop */
421 if (matched) /* HBA adapter for loop */
422 break;
425 if (!matched) {
426 print_errString(L_INVALID_PATH, argv[path_index]);
427 ret++;
430 HBA_FreeLibrary();
431 return (ret);
434 /*ARGSUSED*/
435 void adm_bypass_enable(char **argv, int bypass_flag) {
436 terminate();
439 /*ARGSUSED*/
440 int adm_port_offline_online(char **a, int b) {
441 terminate();
442 return (1);
445 /*ARGSUSED*/
446 void display_link_status(char **a) {
447 terminate();
450 /*ARGSUSED*/
451 void dump_map(char **argv) {
452 terminate();
455 /*ARGSUSED*/
456 int adm_display_port(int a) {
457 terminate();
458 return (1);
461 /*ARGSUSED*/
462 int adm_port_loopback(char *a, int b) {
463 terminate();
464 return (1);
467 /*ARGSUSED*/
468 int hotplug_e(int todo, char **argv, int verbose_flag, int force_flag) {
469 terminate();
470 return (1);
473 /*ARGSUSED*/
475 setboot(unsigned int yes, unsigned int verbose, char *fname)
477 terminate();
478 return (1);
481 /*ARGSUSED*/
482 int hotplug(int todo, char **argv, int verbose_flag, int force_flag) {
483 terminate();
484 return (1);
487 /*ARGSUSED*/
488 int adm_check_file(char **argv, int flag) {
489 terminate();
490 return (1);
493 /*ARGSUSED*/
494 int sysdump(int verbose) {
495 terminate();
496 return (1);
499 /*ARGSUSED*/
500 int fcal_update(unsigned int verbose, char *file) {
501 terminate();
502 return (1);
505 /*ARGSUSED*/
506 int q_qlgc_update(unsigned int verbose, char *file) {
507 terminate();
508 return (1);
511 /*ARGSUSED*/
512 int emulex_update(char *file) {
513 terminate();
514 return (1);
517 /*ARGSUSED*/
518 int emulex_fcode_reader(int fcode_fd, char *pattern, char *pattern_value,
519 uint32_t pattern_value_size) {
520 terminate();
521 return (1);
524 /*ARGSUSED*/
525 void dump(char **argv) {
526 terminate();
529 /*ARGSUSED*/
530 int h_insertSena_fcdev() {
531 terminate();
532 return (1);