Blame fcnsq.c

Packit Service bca4e3
/*
Packit Service bca4e3
 * Copyright(c) 2009 Intel Corporation. All rights reserved.
Packit Service bca4e3
 *
Packit Service bca4e3
 * This program is free software; you can redistribute it and/or modify it
Packit Service bca4e3
 * under the terms and conditions of the GNU General Public License,
Packit Service bca4e3
 * version 2, as published by the Free Software Foundation.
Packit Service bca4e3
 *
Packit Service bca4e3
 * This program is distributed in the hope it will be useful, but WITHOUT
Packit Service bca4e3
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit Service bca4e3
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
Packit Service bca4e3
 * more details.
Packit Service bca4e3
 *
Packit Service bca4e3
 * You should have received a copy of the GNU General Public License along with
Packit Service bca4e3
 * this program; if not, write to the Free Software Foundation, Inc.,
Packit Service bca4e3
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
Packit Service bca4e3
 *
Packit Service bca4e3
 * Maintained at www.Open-FCoE.org
Packit Service bca4e3
 */
Packit Service bca4e3
Packit Service bca4e3
#define _GNU_SOURCE
Packit Service bca4e3
#include <stdio.h>
Packit Service bca4e3
#include <stdint.h>
Packit Service bca4e3
#include <stdlib.h>
Packit Service bca4e3
#include <stdarg.h>
Packit Service bca4e3
#include <stdbool.h>
Packit Service bca4e3
#include <unistd.h>
Packit Service bca4e3
#include <inttypes.h>
Packit Service bca4e3
#include <string.h>
Packit Service bca4e3
#include <errno.h>
Packit Service bca4e3
#include <fcntl.h>
Packit Service bca4e3
#include <getopt.h>
Packit Service bca4e3
#include <arpa/inet.h>
Packit Service bca4e3
#include <sys/types.h>
Packit Service bca4e3
#include <sys/ioctl.h>
Packit Service bca4e3
#include <sys/stat.h>
Packit Service bca4e3
#include <linux/types.h>
Packit Service bca4e3
typedef __u8 u8;
Packit Service bca4e3
typedef __u16 u16;
Packit Service bca4e3
typedef __u32 u32;
Packit Service bca4e3
typedef __u64 u64;
Packit Service bca4e3
#include <linux/bsg.h>
Packit Service bca4e3
#include <scsi/sg.h>
Packit Service bca4e3
#include "fc_gs.h"
Packit Service bca4e3
#include "fc_ns.h"
Packit Service bca4e3
#include "scsi_bsg_fc.h"
Packit Service bca4e3
Packit Service bca4e3
static bool quiet = false;
Packit Service bca4e3
Packit Service bca4e3
__attribute__((__format__(__printf__, 2, 3)))
Packit Service bca4e3
static int print_result(const char *prefix, const char *format, ...)
Packit Service bca4e3
{
Packit Service bca4e3
	va_list ap;
Packit Service bca4e3
	int rc;
Packit Service bca4e3
Packit Service bca4e3
	va_start(ap, format);
Packit Service bca4e3
	if (!quiet)
Packit Service bca4e3
		printf("%s: ", prefix);
Packit Service bca4e3
	rc = vprintf(format, ap);
Packit Service bca4e3
	va_end(ap);
Packit Service bca4e3
	return rc;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
__attribute__((__format__(__printf__, 1, 2)))
Packit Service bca4e3
static int print_err(const char *format, ...)
Packit Service bca4e3
{
Packit Service bca4e3
	va_list ap;
Packit Service bca4e3
	int rc;
Packit Service bca4e3
Packit Service bca4e3
	if (quiet)
Packit Service bca4e3
		return 0;
Packit Service bca4e3
	va_start(ap, format);
Packit Service bca4e3
	rc = vprintf(format, ap);
Packit Service bca4e3
	va_end(ap);
Packit Service bca4e3
	return rc;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
#define ntoh24(n) (u32) ((n)[0] << 16 | (n)[1] << 8  | (n)[2])
Packit Service bca4e3
#define hton24(h) { (h) >> 16 & 0xff, (h) >> 8 & 0xff, (h) & 0xff }
Packit Service bca4e3
Packit Service bca4e3
static u64 ntohll(u64 netll)
Packit Service bca4e3
{
Packit Service bca4e3
	u8 *_netll = (u8 *)&netll;
Packit Service bca4e3
	return	(u64) _netll[0] << (7 * 8) |
Packit Service bca4e3
		(u64) _netll[1] << (6 * 8) |
Packit Service bca4e3
		(u64) _netll[2] << (5 * 8) |
Packit Service bca4e3
		(u64) _netll[3] << (4 * 8) |
Packit Service bca4e3
		(u64) _netll[4] << (3 * 8) |
Packit Service bca4e3
		(u64) _netll[5] << (2 * 8) |
Packit Service bca4e3
		(u64) _netll[6] << (1 * 8) |
Packit Service bca4e3
		(u64) _netll[7];
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
static u64 htonll(u64 hostll)
Packit Service bca4e3
{
Packit Service bca4e3
	u64 netll;
Packit Service bca4e3
	u8 *_netll = (u8 *)&netll;
Packit Service bca4e3
	_netll[0] = hostll >> (7 * 8) & 0xff;
Packit Service bca4e3
	_netll[1] = hostll >> (6 * 8) & 0xff;
Packit Service bca4e3
	_netll[2] = hostll >> (5 * 8) & 0xff;
Packit Service bca4e3
	_netll[3] = hostll >> (4 * 8) & 0xff;
Packit Service bca4e3
	_netll[4] = hostll >> (3 * 8) & 0xff;
Packit Service bca4e3
	_netll[5] = hostll >> (2 * 8) & 0xff;
Packit Service bca4e3
	_netll[6] = hostll >> (1 * 8) & 0xff;
Packit Service bca4e3
	_netll[7] = hostll & 0xff;
Packit Service bca4e3
	return netll;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
static char* rjt_reason[] = {
Packit Service bca4e3
	[1] = "Invalid command code",
Packit Service bca4e3
	[2] = "Invalid version level",
Packit Service bca4e3
	[3] = "Logical error",
Packit Service bca4e3
	[4] = "Invalid CT_IU size",
Packit Service bca4e3
	[5] = "Logical busy",
Packit Service bca4e3
	[7] = "Protocol error",
Packit Service bca4e3
	[9] = "Unable to perform command request",
Packit Service bca4e3
	[0xB] = "Command not supported",
Packit Service bca4e3
	[0xD] = "Server not available",
Packit Service bca4e3
	[0xE] = "Session could not be established",
Packit Service bca4e3
};
Packit Service bca4e3
Packit Service bca4e3
static char* rjt_explan[] = {
Packit Service bca4e3
	[0] = "No additional explanation",
Packit Service bca4e3
	[1] = "Port Identifier not registered",
Packit Service bca4e3
	[2] = "Port Name not registered",
Packit Service bca4e3
	[3] = "Node Name not registered",
Packit Service bca4e3
	[4] = "Class of Service not registered",
Packit Service bca4e3
	[6] = "Initial Process Associator not registered",
Packit Service bca4e3
	[7] = "FC-4 Types not registered",
Packit Service bca4e3
	[8] = "Symbolic Port Name not registered",
Packit Service bca4e3
	[9] = "Symbolic Node Name not registered",
Packit Service bca4e3
	[0xA] = "Port Type not registered",
Packit Service bca4e3
	[0xC] = "Fabric Port Name not registered",
Packit Service bca4e3
	[0xD] = "Hard Address not registered",
Packit Service bca4e3
	[0xF] = "FC-4 Features not registered",
Packit Service bca4e3
	[0x10] = "Access denied",
Packit Service bca4e3
	[0x11] = "Unacceptable Port Identifier",
Packit Service bca4e3
	[0x12] = "Data base empty",
Packit Service bca4e3
	[0x13] = "No object registered in the specified scope",
Packit Service bca4e3
	[0x14] = "Domain ID not present",
Packit Service bca4e3
	[0x15] = "Port number not present",
Packit Service bca4e3
	[0x16] = "No device attached",
Packit Service bca4e3
	[0xf0] = "Authorization Exception",
Packit Service bca4e3
	[0xf1] = "Authentication Exception",
Packit Service bca4e3
	[0xf2] = "Data base full",
Packit Service bca4e3
	[0xf3] = "Data base empty",
Packit Service bca4e3
	[0xf4] = "Processing request",
Packit Service bca4e3
	[0xf5] = "Unable to verify connection",
Packit Service bca4e3
	[0xf6] = "Devices not in a common zone",
Packit Service bca4e3
};
Packit Service bca4e3
Packit Service bca4e3
static u16 ct_rjt(u8 reason, u8 explan) {
Packit Service bca4e3
	return (u16) reason << 8 | explan;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
static u8 ct_rjt_reason(u16 rjt) {
Packit Service bca4e3
	return (u8)(rjt >> 8);
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
static u8 ct_rjt_explan(u16 rjt) {
Packit Service bca4e3
	return (u8) rjt & 0xff;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
static int ns_query(int bsg, void *req, int req_len, void *resp, int resp_len)
Packit Service bca4e3
{
Packit Service bca4e3
	char sense[96];
Packit Service bca4e3
Packit Service bca4e3
	struct fc_bsg_request cdb = {
Packit Service bca4e3
		.msgcode 	= FC_BSG_HST_CT,
Packit Service bca4e3
		.rqst_data.h_ct	= {
Packit Service bca4e3
			.port_id = hton24(0xfffffc),
Packit Service bca4e3
		}
Packit Service bca4e3
	};
Packit Service bca4e3
Packit Service bca4e3
	struct sg_io_v4 sgio = {
Packit Service bca4e3
		.guard			= 'Q',
Packit Service bca4e3
		.protocol		= BSG_PROTOCOL_SCSI,
Packit Service bca4e3
		.subprotocol		= BSG_SUB_PROTOCOL_SCSI_TRANSPORT,
Packit Service bca4e3
		.request_len		= sizeof(cdb),
Packit Service bca4e3
		.request		= (uintptr_t) &cdb,
Packit Service bca4e3
		.dout_xfer_len		= req_len,
Packit Service bca4e3
		.dout_xferp		= (uintptr_t) req,
Packit Service bca4e3
		.din_xfer_len		= resp_len,
Packit Service bca4e3
		.din_xferp		= (uintptr_t) resp,
Packit Service bca4e3
		.max_response_len	= sizeof(sense),
Packit Service bca4e3
		.response		= (uintptr_t) &sense,
Packit Service bca4e3
		.timeout		= 1000,
Packit Service bca4e3
	};
Packit Service bca4e3
Packit Service bca4e3
	return ioctl(bsg, SG_IO, &sgio);
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
static u16 gn_id(int bsg, u32 fcid, u16 cmd, u64 *wwn)
Packit Service bca4e3
{
Packit Service bca4e3
	struct {
Packit Service bca4e3
		struct fc_ct_hdr hdr;
Packit Service bca4e3
		u64 wwn;
Packit Service bca4e3
	} __attribute__((__packed__)) gn_resp;
Packit Service bca4e3
Packit Service bca4e3
	struct {
Packit Service bca4e3
		struct fc_ct_hdr hdr;
Packit Service bca4e3
		u8 resv;
Packit Service bca4e3
		u8 port_id[3];
Packit Service bca4e3
	} __attribute__((__packed__)) gn = {
Packit Service bca4e3
		.hdr = {
Packit Service bca4e3
			.ct_rev		= FC_CT_REV,
Packit Service bca4e3
			.ct_fs_type	= FC_FST_DIR,
Packit Service bca4e3
			.ct_fs_subtype	= FC_NS_SUBTYPE,
Packit Service bca4e3
			.ct_cmd		= htons(cmd),
Packit Service bca4e3
			.ct_mr_size	= htons(sizeof(gn_resp)),
Packit Service bca4e3
			.ct_vendor	= 0,
Packit Service bca4e3
		},
Packit Service bca4e3
		.port_id = hton24(fcid),
Packit Service bca4e3
	};
Packit Service bca4e3
Packit Service bca4e3
	if (ns_query(bsg, &gn, sizeof(gn), &gn_resp, sizeof(gn_resp)) < 0)
Packit Service bca4e3
		return ~0;
Packit Service bca4e3
	if (gn_resp.hdr.ct_cmd != htons(FC_FS_ACC))
Packit Service bca4e3
		return ct_rjt(gn_resp.hdr.ct_reason, gn_resp.hdr.ct_explan);
Packit Service bca4e3
	*wwn = ntohll(gn_resp.wwn);
Packit Service bca4e3
	return 0;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
#define FC_NS_GPN_ID	0x0112
Packit Service bca4e3
static int gpn_id(int bsg, u32 fcid)
Packit Service bca4e3
{
Packit Service bca4e3
	u64 wwpn;
Packit Service bca4e3
	u16 rjt;
Packit Service bca4e3
Packit Service bca4e3
	rjt = gn_id(bsg, fcid, FC_NS_GPN_ID, &wwpn);
Packit Service bca4e3
	if (rjt)
Packit Service bca4e3
		goto fail;
Packit Service bca4e3
	print_result("Port Name", "%16.16jx\n", (uintmax_t)wwpn);
Packit Service bca4e3
	return 0;
Packit Service bca4e3
fail:
Packit Service bca4e3
	if (rjt == (u16) ~0)
Packit Service bca4e3
		print_err("%s ioctl failed: %s\n", __func__, strerror(errno));
Packit Service bca4e3
	else
Packit Service bca4e3
		print_err("%s command failed: %s, %s\n", __func__,
Packit Service bca4e3
			  rjt_reason[ct_rjt_reason(rjt)],
Packit Service bca4e3
			  rjt_explan[ct_rjt_explan(rjt)]);
Packit Service bca4e3
	return rjt;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
#define FC_NS_GNN_ID	0x0113
Packit Service bca4e3
static int gnn_id(int bsg, u32 fcid)
Packit Service bca4e3
{
Packit Service bca4e3
	u64 wwnn;
Packit Service bca4e3
	u16 rjt;
Packit Service bca4e3
Packit Service bca4e3
	rjt = gn_id(bsg, fcid, FC_NS_GNN_ID, &wwnn);
Packit Service bca4e3
	if (rjt)
Packit Service bca4e3
		goto fail;
Packit Service bca4e3
	print_result("Node Name", "%16.16jx\n", (uintmax_t)wwnn);
Packit Service bca4e3
	return 0;
Packit Service bca4e3
fail:
Packit Service bca4e3
	if (rjt == (u16) ~0)
Packit Service bca4e3
		print_err("%s ioctl failed: %s\n", __func__, strerror(errno));
Packit Service bca4e3
	else
Packit Service bca4e3
		print_err("%s command failed: %s, %s\n", __func__,
Packit Service bca4e3
			  rjt_reason[ct_rjt_reason(rjt)],
Packit Service bca4e3
			  rjt_explan[ct_rjt_explan(rjt)]);
Packit Service bca4e3
	return rjt;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
#define FC_NS_GSPN_ID	0x0118
Packit Service bca4e3
static int gspn_id(int bsg, u32 fcid)
Packit Service bca4e3
{
Packit Service bca4e3
	struct {
Packit Service bca4e3
		struct fc_ct_hdr hdr;
Packit Service bca4e3
		u8 len;
Packit Service bca4e3
		char name[255];
Packit Service bca4e3
	} __attribute__((__packed__)) gspn_resp;
Packit Service bca4e3
Packit Service bca4e3
	struct {
Packit Service bca4e3
		struct fc_ct_hdr hdr;
Packit Service bca4e3
		u8 resv;
Packit Service bca4e3
		u8 port_id[3];
Packit Service bca4e3
	} __attribute__((__packed__)) gspn = {
Packit Service bca4e3
		.hdr = {
Packit Service bca4e3
			.ct_rev		= FC_CT_REV,
Packit Service bca4e3
			.ct_fs_type	= FC_FST_DIR,
Packit Service bca4e3
			.ct_fs_subtype	= FC_NS_SUBTYPE,
Packit Service bca4e3
			.ct_cmd		= htons(FC_NS_GSPN_ID),
Packit Service bca4e3
			.ct_mr_size	= htons(sizeof(gspn_resp)),
Packit Service bca4e3
			.ct_vendor	= 0,
Packit Service bca4e3
		},
Packit Service bca4e3
		.port_id = hton24(fcid),
Packit Service bca4e3
	};
Packit Service bca4e3
Packit Service bca4e3
	if (ns_query(bsg, &gspn, sizeof(gspn), &gspn_resp, sizeof(gspn_resp)) < 0) {
Packit Service bca4e3
		print_err("%s ioctl failed: %s\n", __func__, strerror(errno));
Packit Service bca4e3
		return ~0;
Packit Service bca4e3
	}
Packit Service bca4e3
	if (gspn_resp.hdr.ct_cmd != htons(FC_FS_ACC)) {
Packit Service bca4e3
		print_err("%s command failed: %s, %s\n", __func__,
Packit Service bca4e3
			  rjt_reason[gspn_resp.hdr.ct_reason],
Packit Service bca4e3
			  rjt_explan[gspn_resp.hdr.ct_explan]);
Packit Service bca4e3
		return ct_rjt(gspn_resp.hdr.ct_reason, gspn_resp.hdr.ct_explan);
Packit Service bca4e3
	}
Packit Service bca4e3
	print_result("Symbolic Port Name", "%s\n", gspn_resp.name);
Packit Service bca4e3
	return 0;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
#define FC_NS_GSNN_NN	0x0139
Packit Service bca4e3
static int gsnn_nn(int bsg, u64 wwnn)
Packit Service bca4e3
{
Packit Service bca4e3
	struct {
Packit Service bca4e3
		struct fc_ct_hdr hdr;
Packit Service bca4e3
		u8 len;
Packit Service bca4e3
		char name[255];
Packit Service bca4e3
	} __attribute__((__packed__)) gsnn_resp;
Packit Service bca4e3
Packit Service bca4e3
	struct {
Packit Service bca4e3
		struct fc_ct_hdr hdr;
Packit Service bca4e3
		u64 wwnn;
Packit Service bca4e3
	} __attribute__((__packed__)) gsnn = {
Packit Service bca4e3
		.hdr = {
Packit Service bca4e3
			.ct_rev		= FC_CT_REV,
Packit Service bca4e3
			.ct_fs_type	= FC_FST_DIR,
Packit Service bca4e3
			.ct_fs_subtype	= FC_NS_SUBTYPE,
Packit Service bca4e3
			.ct_cmd		= htons(FC_NS_GSNN_NN),
Packit Service bca4e3
			.ct_mr_size	= htons(sizeof(gsnn_resp)),
Packit Service bca4e3
			.ct_vendor	= 0,
Packit Service bca4e3
		},
Packit Service bca4e3
		.wwnn = htonll(wwnn),
Packit Service bca4e3
	};
Packit Service bca4e3
Packit Service bca4e3
	if (ns_query(bsg, &gsnn, sizeof(gsnn), &gsnn_resp, sizeof(gsnn_resp)) < 0) {
Packit Service bca4e3
		print_err("%s ioctl failed: %s\n", __func__, strerror(errno));
Packit Service bca4e3
		return ~0;
Packit Service bca4e3
	}
Packit Service bca4e3
	if (gsnn_resp.hdr.ct_cmd != htons(FC_FS_ACC)) {
Packit Service bca4e3
		print_err("%s command failed: %s, %s\n", __func__,
Packit Service bca4e3
			  rjt_reason[gsnn_resp.hdr.ct_reason],
Packit Service bca4e3
			  rjt_explan[gsnn_resp.hdr.ct_explan]);
Packit Service bca4e3
		return ct_rjt(gsnn_resp.hdr.ct_reason, gsnn_resp.hdr.ct_explan);
Packit Service bca4e3
	}
Packit Service bca4e3
	print_result("Symbolic Node Name", "%s\n", gsnn_resp.name);
Packit Service bca4e3
	return 0;
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
enum commands {
Packit Service bca4e3
	NONE = 0,
Packit Service bca4e3
	GPN_ID,
Packit Service bca4e3
	GNN_ID,
Packit Service bca4e3
	GSPN_ID,
Packit Service bca4e3
	GSNN_NN,
Packit Service bca4e3
};
Packit Service bca4e3
Packit Service bca4e3
static const struct option options[] = {
Packit Service bca4e3
	{ "gpn", required_argument, NULL, GPN_ID },
Packit Service bca4e3
	{ "gnn", required_argument, NULL, GNN_ID },
Packit Service bca4e3
	{ "gspn", required_argument, NULL, GSPN_ID },
Packit Service bca4e3
	{ "gsnn", required_argument, NULL, GSNN_NN },
Packit Service bca4e3
	{ "quiet", no_argument, NULL, 'q' },
Packit Service bca4e3
	{ NULL, 0, NULL, 0 },
Packit Service bca4e3
};
Packit Service bca4e3
Packit Service bca4e3
static void help(int status)
Packit Service bca4e3
{
Packit Service bca4e3
	printf(
Packit Service bca4e3
		"Usage: fcnsq <host#> <command> [options]\n"
Packit Service bca4e3
		"Commands:\n"
Packit Service bca4e3
		"  --gpn  <port id>\n"
Packit Service bca4e3
		"  --gnn  <port id>\n"
Packit Service bca4e3
		"  --gspn <port id>\n"
Packit Service bca4e3
		"  --gsnn <world wide node name>\n"
Packit Service bca4e3
		"Options:\n"
Packit Service bca4e3
		"  --quiet|-q	print minimal results on success, and no error messages\n"
Packit Service bca4e3
		"\n"
Packit Service bca4e3
		"Port IDs and World Wide Names must be specified in hexadecimal.\n"
Packit Service bca4e3
		);
Packit Service bca4e3
	exit(status);
Packit Service bca4e3
}
Packit Service bca4e3
Packit Service bca4e3
int main(int argc, char *argv[])
Packit Service bca4e3
{
Packit Service bca4e3
	char *bsg;
Packit Service bca4e3
	int bsg_dev;
Packit Service bca4e3
	u32 port_id = 0;
Packit Service bca4e3
	u64 wwnn = 0;
Packit Service bca4e3
	int rc = 0;
Packit Service bca4e3
	enum commands cmd = 0;
Packit Service bca4e3
	signed char c;
Packit Service bca4e3
	uintmax_t wwnn_tmp = 0;
Packit Service bca4e3
Packit Service bca4e3
	while(1) {
Packit Service bca4e3
		c = getopt_long_only(argc, argv, "", options, NULL);
Packit Service bca4e3
		if (c < 0)
Packit Service bca4e3
			break;
Packit Service bca4e3
		switch(c) {
Packit Service bca4e3
		case '?':
Packit Service bca4e3
			help(-1);
Packit Service bca4e3
			break;
Packit Service bca4e3
		case 'q':
Packit Service bca4e3
			quiet = true;
Packit Service bca4e3
			break;
Packit Service bca4e3
		case GPN_ID:
Packit Service bca4e3
		case GNN_ID:
Packit Service bca4e3
		case GSPN_ID:
Packit Service bca4e3
			if (cmd)
Packit Service bca4e3
				help(-1);
Packit Service bca4e3
			cmd = c;
Packit Service bca4e3
			if (sscanf(optarg, "%x", &port_id) != 1)
Packit Service bca4e3
				help(-1);
Packit Service bca4e3
			break;
Packit Service bca4e3
		case GSNN_NN:
Packit Service bca4e3
			if (cmd)
Packit Service bca4e3
				help(-1);
Packit Service bca4e3
			cmd = c;
Packit Service bca4e3
			if (sscanf(optarg, "%jx", &wwnn_tmp) == 1)
Packit Service bca4e3
				wwnn = (u64)wwnn_tmp;
Packit Service bca4e3
			else
Packit Service bca4e3
				help(-1);
Packit Service bca4e3
			break;
Packit Service bca4e3
		}
Packit Service bca4e3
	}
Packit Service bca4e3
Packit Service bca4e3
	if (cmd == NONE)
Packit Service bca4e3
		help(-1);
Packit Service bca4e3
Packit Service bca4e3
	if (asprintf(&bsg, "/dev/bsg/fc_%s", argv[optind]) < 0) {
Packit Service bca4e3
		if (!quiet)
Packit Service bca4e3
			perror(NULL);
Packit Service bca4e3
		return -1;
Packit Service bca4e3
	}
Packit Service bca4e3
	bsg_dev = open(bsg, O_RDWR);
Packit Service bca4e3
	if (bsg_dev < 0) {
Packit Service bca4e3
		if (!quiet)
Packit Service bca4e3
			perror(bsg);
Packit Service bca4e3
		return -1;
Packit Service bca4e3
	}
Packit Service bca4e3
	switch (cmd) {
Packit Service bca4e3
	case GPN_ID:
Packit Service bca4e3
		rc = gpn_id(bsg_dev, port_id);
Packit Service bca4e3
		break;
Packit Service bca4e3
	case GNN_ID:
Packit Service bca4e3
		rc = gnn_id(bsg_dev, port_id);
Packit Service bca4e3
		break;
Packit Service bca4e3
	case GSPN_ID:
Packit Service bca4e3
		rc = gspn_id(bsg_dev, port_id);
Packit Service bca4e3
		break;
Packit Service bca4e3
	case GSNN_NN:
Packit Service bca4e3
		rc = gsnn_nn(bsg_dev, wwnn);
Packit Service bca4e3
		break;
Packit Service bca4e3
	default:
Packit Service bca4e3
		help(-1);
Packit Service bca4e3
		break;
Packit Service bca4e3
	};
Packit Service bca4e3
	close(bsg_dev);
Packit Service bca4e3
	free(bsg);
Packit Service bca4e3
	return rc;
Packit Service bca4e3
}
Packit Service bca4e3