|
|
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.