|
|
1.1 root 1: /*
2: * Copyright (C) 2010 Michael Brown <[email protected]>.
3: *
4: * This program is free software; you can redistribute it and/or
5: * modify it under the terms of the GNU General Public License as
6: * published by the Free Software Foundation; either version 2 of the
7: * License, or any later version.
8: *
9: * This program is distributed in the hope that it will be useful, but
10: * WITHOUT ANY WARRANTY; without even the implied warranty of
11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12: * General Public License for more details.
13: *
14: * You should have received a copy of the GNU General Public License
15: * along with this program; if not, write to the Free Software
16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17: */
18:
19: FILE_LICENCE ( GPL2_OR_LATER );
20:
21: #include <stdio.h>
22: #include <errno.h>
23: #include <getopt.h>
24: #include <strings.h>
25: #include <ipxe/fc.h>
26: #include <ipxe/fcels.h>
27: #include <ipxe/command.h>
28: #include <ipxe/parseopt.h>
29: #include <ipxe/tables.h>
30: #include <usr/fcmgmt.h>
31:
32: /** @file
33: *
34: * Fibre Channel management commands
35: *
36: */
37:
38: /**
39: * Parse Fibre Channel port name
40: *
41: * @v text Text
42: * @ret port Fibre Channel port
43: * @ret rc Return status code
44: */
45: static int parse_fc_port ( const char *text, struct fc_port **port ) {
46:
47: /* Sanity check */
48: assert ( text != NULL );
49:
50: /* Find Fibre Channel port */
51: *port = fc_port_find ( text );
52: if ( ! *port ) {
53: printf ( "\"%s\": no such port\n", text );
54: return -ENODEV;
55: }
56:
57: return 0;
58: }
59:
60: /**
61: * Parse Fibre Channel port ID
62: *
63: * @v text Text
64: * @ret port_id Fibre Channel port ID
65: * @ret rc Return status code
66: */
67: static int parse_fc_port_id ( const char *text, struct fc_port_id *port_id ) {
68: int rc;
69:
70: /* Sanity check */
71: assert ( text != NULL );
72:
73: /* Parse port ID */
74: if ( ( rc = fc_id_aton ( text, port_id ) ) != 0 ) {
75: printf ( "\"%s\": invalid port ID\n", text );
76: return -EINVAL;
77: }
78:
79: return 0;
80: }
81:
82: /**
83: * Parse Fibre Channel ELS handler name
84: *
85: * @v text Text
86: * @ret handler Fibre Channel ELS handler
87: * @ret rc Return status code
88: */
89: static int parse_fc_els_handler ( const char *text,
90: struct fc_els_handler **handler ) {
91:
92: for_each_table_entry ( (*handler), FC_ELS_HANDLERS ) {
93: if ( strcasecmp ( (*handler)->name, text ) == 0 )
94: return 0;
95: }
96:
97: printf ( "\"%s\": unrecognised ELS\n", text );
98: return -ENOENT;
99: }
100:
101: /** "fcstat" options */
102: struct fcstat_options {};
103:
104: /** "fcstat" option list */
105: static struct option_descriptor fcstat_opts[] = {};
106:
107: /** "fcstat" command descriptor */
108: static struct command_descriptor fcstat_cmd =
109: COMMAND_DESC ( struct fcstat_options, fcstat_opts, 0, 0, "" );
110:
111: /**
112: * The "fcstat" command
113: *
114: * @v argc Argument count
115: * @v argv Argument list
116: * @ret rc Return status code
117: */
118: static int fcstat_exec ( int argc, char **argv ) {
119: struct fcstat_options opts;
120: struct fc_port *port;
121: struct fc_peer *peer;
122: int rc;
123:
124: /* Parse options */
125: if ( ( rc = parse_options ( argc, argv, &fcstat_cmd, &opts ) ) != 0 )
126: return rc;
127:
128: list_for_each_entry ( port, &fc_ports, list )
129: fcportstat ( port );
130: list_for_each_entry ( peer, &fc_peers, list )
131: fcpeerstat ( peer );
132:
133: return 0;
134: }
135:
136: /** "fcels" options */
137: struct fcels_options {
138: /** Fibre Channel port */
139: struct fc_port *port;
140: /** Fibre Channel peer port ID */
141: struct fc_port_id peer_port_id;
142: };
143:
144: /** "fcels" option list */
145: static struct option_descriptor fcels_opts[] = {
146: OPTION_DESC ( "port", 'p', required_argument,
147: struct fcels_options, port, parse_fc_port ),
148: OPTION_DESC ( "id", 'i', required_argument,
149: struct fcels_options, peer_port_id, parse_fc_port_id ),
150: };
151:
152: /** "fcels" command descriptor */
153: static struct command_descriptor fcels_cmd =
154: COMMAND_DESC ( struct fcels_options, fcels_opts, 1, 1,
155: "[--port <port>] [--id <peer port id>] <request>" );
156:
157: /**
158: * The "fcels" command
159: *
160: * @v argc Argument count
161: * @v argv Argument list
162: * @ret rc Return status code
163: */
164: static int fcels_exec ( int argc, char **argv ) {
165: struct fcels_options opts;
166: struct fc_els_handler *handler;
167: struct fc_port_id *id;
168: int rc;
169:
170: /* Parse options */
171: if ( ( rc = parse_options ( argc, argv, &fcels_cmd, &opts ) ) != 0 )
172: return rc;
173:
174: /* Parse ELS handler */
175: if ( ( rc = parse_fc_els_handler ( argv[optind], &handler ) ) != 0 )
176: return rc;
177:
178: /* Use first port if no port specified */
179: if ( ! opts.port ) {
180: opts.port = list_first_entry ( &fc_ports, struct fc_port,
181: list );
182: if ( ! opts.port ) {
183: printf ( "No ports\n" );
184: return -ENODEV;
185: }
186: }
187:
188: /* Use link peer port ID if no peer port ID specified */
189: id = &opts.peer_port_id;
190: if ( memcmp ( id, &fc_empty_port_id, sizeof ( *id ) ) == 0 ) {
191: if ( fc_link_ok ( &opts.port->link ) &&
192: ! ( opts.port->flags & FC_PORT_HAS_FABRIC ) ) {
193: id = &opts.port->ptp_link_port_id;
194: } else {
195: id = &fc_f_port_id;
196: }
197: }
198:
199: /** Issue ELS */
200: if ( ( rc = fcels ( opts.port, id, handler ) ) != 0 )
201: return rc;
202:
203: return 0;
204: }
205:
206: /** Fibre Channel management commands */
207: struct command fcmgmt_commands[] __command = {
208: {
209: .name = "fcstat",
210: .exec = fcstat_exec,
211: },
212: {
213: .name = "fcels",
214: .exec = fcels_exec,
215: },
216: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.