1*4882a593Smuzhiyun#!/usr/bin/env python 2*4882a593Smuzhiyun# The TCM v4 multi-protocol fabric module generation script for drivers/target/$NEW_MOD 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# Copyright (c) 2010 Rising Tide Systems 5*4882a593Smuzhiyun# Copyright (c) 2010 Linux-iSCSI.org 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# Author: nab@kernel.org 8*4882a593Smuzhiyun# 9*4882a593Smuzhiyunimport os, sys 10*4882a593Smuzhiyunimport subprocess as sub 11*4882a593Smuzhiyunimport string 12*4882a593Smuzhiyunimport re 13*4882a593Smuzhiyunimport optparse 14*4882a593Smuzhiyun 15*4882a593Smuzhiyuntcm_dir = "" 16*4882a593Smuzhiyun 17*4882a593Smuzhiyunfabric_ops = [] 18*4882a593Smuzhiyunfabric_mod_dir = "" 19*4882a593Smuzhiyunfabric_mod_port = "" 20*4882a593Smuzhiyunfabric_mod_init_port = "" 21*4882a593Smuzhiyun 22*4882a593Smuzhiyundef tcm_mod_err(msg): 23*4882a593Smuzhiyun print msg 24*4882a593Smuzhiyun sys.exit(1) 25*4882a593Smuzhiyun 26*4882a593Smuzhiyundef tcm_mod_create_module_subdir(fabric_mod_dir_var): 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun if os.path.isdir(fabric_mod_dir_var) == True: 29*4882a593Smuzhiyun return 1 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun print "Creating fabric_mod_dir: " + fabric_mod_dir_var 32*4882a593Smuzhiyun ret = os.mkdir(fabric_mod_dir_var) 33*4882a593Smuzhiyun if ret: 34*4882a593Smuzhiyun tcm_mod_err("Unable to mkdir " + fabric_mod_dir_var) 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun return 37*4882a593Smuzhiyun 38*4882a593Smuzhiyundef tcm_mod_build_FC_include(fabric_mod_dir_var, fabric_mod_name): 39*4882a593Smuzhiyun global fabric_mod_port 40*4882a593Smuzhiyun global fabric_mod_init_port 41*4882a593Smuzhiyun buf = "" 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h" 44*4882a593Smuzhiyun print "Writing file: " + f 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun p = open(f, 'w'); 47*4882a593Smuzhiyun if not p: 48*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n" 51*4882a593Smuzhiyun buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n" 52*4882a593Smuzhiyun buf += "\n" 53*4882a593Smuzhiyun buf += "struct " + fabric_mod_name + "_tpg {\n" 54*4882a593Smuzhiyun buf += " /* FC lport target portal group tag for TCM */\n" 55*4882a593Smuzhiyun buf += " u16 lport_tpgt;\n" 56*4882a593Smuzhiyun buf += " /* Pointer back to " + fabric_mod_name + "_lport */\n" 57*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_lport *lport;\n" 58*4882a593Smuzhiyun buf += " /* Returned by " + fabric_mod_name + "_make_tpg() */\n" 59*4882a593Smuzhiyun buf += " struct se_portal_group se_tpg;\n" 60*4882a593Smuzhiyun buf += "};\n" 61*4882a593Smuzhiyun buf += "\n" 62*4882a593Smuzhiyun buf += "struct " + fabric_mod_name + "_lport {\n" 63*4882a593Smuzhiyun buf += " /* Binary World Wide unique Port Name for FC Target Lport */\n" 64*4882a593Smuzhiyun buf += " u64 lport_wwpn;\n" 65*4882a593Smuzhiyun buf += " /* ASCII formatted WWPN for FC Target Lport */\n" 66*4882a593Smuzhiyun buf += " char lport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n" 67*4882a593Smuzhiyun buf += " /* Returned by " + fabric_mod_name + "_make_lport() */\n" 68*4882a593Smuzhiyun buf += " struct se_wwn lport_wwn;\n" 69*4882a593Smuzhiyun buf += "};\n" 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun ret = p.write(buf) 72*4882a593Smuzhiyun if ret: 73*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun p.close() 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun fabric_mod_port = "lport" 78*4882a593Smuzhiyun fabric_mod_init_port = "nport" 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun return 81*4882a593Smuzhiyun 82*4882a593Smuzhiyundef tcm_mod_build_SAS_include(fabric_mod_dir_var, fabric_mod_name): 83*4882a593Smuzhiyun global fabric_mod_port 84*4882a593Smuzhiyun global fabric_mod_init_port 85*4882a593Smuzhiyun buf = "" 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h" 88*4882a593Smuzhiyun print "Writing file: " + f 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun p = open(f, 'w'); 91*4882a593Smuzhiyun if not p: 92*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n" 95*4882a593Smuzhiyun buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n" 96*4882a593Smuzhiyun buf += "\n" 97*4882a593Smuzhiyun buf += "struct " + fabric_mod_name + "_tpg {\n" 98*4882a593Smuzhiyun buf += " /* SAS port target portal group tag for TCM */\n" 99*4882a593Smuzhiyun buf += " u16 tport_tpgt;\n" 100*4882a593Smuzhiyun buf += " /* Pointer back to " + fabric_mod_name + "_tport */\n" 101*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tport *tport;\n" 102*4882a593Smuzhiyun buf += " /* Returned by " + fabric_mod_name + "_make_tpg() */\n" 103*4882a593Smuzhiyun buf += " struct se_portal_group se_tpg;\n" 104*4882a593Smuzhiyun buf += "};\n\n" 105*4882a593Smuzhiyun buf += "struct " + fabric_mod_name + "_tport {\n" 106*4882a593Smuzhiyun buf += " /* Binary World Wide unique Port Name for SAS Target port */\n" 107*4882a593Smuzhiyun buf += " u64 tport_wwpn;\n" 108*4882a593Smuzhiyun buf += " /* ASCII formatted WWPN for SAS Target port */\n" 109*4882a593Smuzhiyun buf += " char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n" 110*4882a593Smuzhiyun buf += " /* Returned by " + fabric_mod_name + "_make_tport() */\n" 111*4882a593Smuzhiyun buf += " struct se_wwn tport_wwn;\n" 112*4882a593Smuzhiyun buf += "};\n" 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun ret = p.write(buf) 115*4882a593Smuzhiyun if ret: 116*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun p.close() 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun fabric_mod_port = "tport" 121*4882a593Smuzhiyun fabric_mod_init_port = "iport" 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun return 124*4882a593Smuzhiyun 125*4882a593Smuzhiyundef tcm_mod_build_iSCSI_include(fabric_mod_dir_var, fabric_mod_name): 126*4882a593Smuzhiyun global fabric_mod_port 127*4882a593Smuzhiyun global fabric_mod_init_port 128*4882a593Smuzhiyun buf = "" 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h" 131*4882a593Smuzhiyun print "Writing file: " + f 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun p = open(f, 'w'); 134*4882a593Smuzhiyun if not p: 135*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n" 138*4882a593Smuzhiyun buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n" 139*4882a593Smuzhiyun buf += "\n" 140*4882a593Smuzhiyun buf += "struct " + fabric_mod_name + "_tpg {\n" 141*4882a593Smuzhiyun buf += " /* iSCSI target portal group tag for TCM */\n" 142*4882a593Smuzhiyun buf += " u16 tport_tpgt;\n" 143*4882a593Smuzhiyun buf += " /* Pointer back to " + fabric_mod_name + "_tport */\n" 144*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tport *tport;\n" 145*4882a593Smuzhiyun buf += " /* Returned by " + fabric_mod_name + "_make_tpg() */\n" 146*4882a593Smuzhiyun buf += " struct se_portal_group se_tpg;\n" 147*4882a593Smuzhiyun buf += "};\n\n" 148*4882a593Smuzhiyun buf += "struct " + fabric_mod_name + "_tport {\n" 149*4882a593Smuzhiyun buf += " /* ASCII formatted TargetName for IQN */\n" 150*4882a593Smuzhiyun buf += " char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n" 151*4882a593Smuzhiyun buf += " /* Returned by " + fabric_mod_name + "_make_tport() */\n" 152*4882a593Smuzhiyun buf += " struct se_wwn tport_wwn;\n" 153*4882a593Smuzhiyun buf += "};\n" 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun ret = p.write(buf) 156*4882a593Smuzhiyun if ret: 157*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun p.close() 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun fabric_mod_port = "tport" 162*4882a593Smuzhiyun fabric_mod_init_port = "iport" 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun return 165*4882a593Smuzhiyun 166*4882a593Smuzhiyundef tcm_mod_build_base_includes(proto_ident, fabric_mod_dir_val, fabric_mod_name): 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun if proto_ident == "FC": 169*4882a593Smuzhiyun tcm_mod_build_FC_include(fabric_mod_dir_val, fabric_mod_name) 170*4882a593Smuzhiyun elif proto_ident == "SAS": 171*4882a593Smuzhiyun tcm_mod_build_SAS_include(fabric_mod_dir_val, fabric_mod_name) 172*4882a593Smuzhiyun elif proto_ident == "iSCSI": 173*4882a593Smuzhiyun tcm_mod_build_iSCSI_include(fabric_mod_dir_val, fabric_mod_name) 174*4882a593Smuzhiyun else: 175*4882a593Smuzhiyun print "Unsupported proto_ident: " + proto_ident 176*4882a593Smuzhiyun sys.exit(1) 177*4882a593Smuzhiyun 178*4882a593Smuzhiyun return 179*4882a593Smuzhiyun 180*4882a593Smuzhiyundef tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name): 181*4882a593Smuzhiyun buf = "" 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun f = fabric_mod_dir_var + "/" + fabric_mod_name + "_configfs.c" 184*4882a593Smuzhiyun print "Writing file: " + f 185*4882a593Smuzhiyun 186*4882a593Smuzhiyun p = open(f, 'w'); 187*4882a593Smuzhiyun if not p: 188*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun buf = "#include <linux/module.h>\n" 191*4882a593Smuzhiyun buf += "#include <linux/moduleparam.h>\n" 192*4882a593Smuzhiyun buf += "#include <linux/version.h>\n" 193*4882a593Smuzhiyun buf += "#include <generated/utsrelease.h>\n" 194*4882a593Smuzhiyun buf += "#include <linux/utsname.h>\n" 195*4882a593Smuzhiyun buf += "#include <linux/init.h>\n" 196*4882a593Smuzhiyun buf += "#include <linux/slab.h>\n" 197*4882a593Smuzhiyun buf += "#include <linux/kthread.h>\n" 198*4882a593Smuzhiyun buf += "#include <linux/types.h>\n" 199*4882a593Smuzhiyun buf += "#include <linux/string.h>\n" 200*4882a593Smuzhiyun buf += "#include <linux/configfs.h>\n" 201*4882a593Smuzhiyun buf += "#include <linux/ctype.h>\n" 202*4882a593Smuzhiyun buf += "#include <asm/unaligned.h>\n" 203*4882a593Smuzhiyun buf += "#include <scsi/scsi_proto.h>\n\n" 204*4882a593Smuzhiyun buf += "#include <target/target_core_base.h>\n" 205*4882a593Smuzhiyun buf += "#include <target/target_core_fabric.h>\n" 206*4882a593Smuzhiyun buf += "#include \"" + fabric_mod_name + "_base.h\"\n" 207*4882a593Smuzhiyun buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n" 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops;\n\n" 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun buf += "static struct se_portal_group *" + fabric_mod_name + "_make_tpg(\n" 212*4882a593Smuzhiyun buf += " struct se_wwn *wwn,\n" 213*4882a593Smuzhiyun buf += " struct config_group *group,\n" 214*4882a593Smuzhiyun buf += " const char *name)\n" 215*4882a593Smuzhiyun buf += "{\n" 216*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + "*" + fabric_mod_port + " = container_of(wwn,\n" 217*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n\n" 218*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg *tpg;\n" 219*4882a593Smuzhiyun buf += " unsigned long tpgt;\n" 220*4882a593Smuzhiyun buf += " int ret;\n\n" 221*4882a593Smuzhiyun buf += " if (strstr(name, \"tpgt_\") != name)\n" 222*4882a593Smuzhiyun buf += " return ERR_PTR(-EINVAL);\n" 223*4882a593Smuzhiyun buf += " if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)\n" 224*4882a593Smuzhiyun buf += " return ERR_PTR(-EINVAL);\n\n" 225*4882a593Smuzhiyun buf += " tpg = kzalloc(sizeof(struct " + fabric_mod_name + "_tpg), GFP_KERNEL);\n" 226*4882a593Smuzhiyun buf += " if (!tpg) {\n" 227*4882a593Smuzhiyun buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_tpg\");\n" 228*4882a593Smuzhiyun buf += " return ERR_PTR(-ENOMEM);\n" 229*4882a593Smuzhiyun buf += " }\n" 230*4882a593Smuzhiyun buf += " tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n" 231*4882a593Smuzhiyun buf += " tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n" 232*4882a593Smuzhiyun 233*4882a593Smuzhiyun if proto_ident == "FC": 234*4882a593Smuzhiyun buf += " ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_FCP);\n" 235*4882a593Smuzhiyun elif proto_ident == "SAS": 236*4882a593Smuzhiyun buf += " ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_SAS);\n" 237*4882a593Smuzhiyun elif proto_ident == "iSCSI": 238*4882a593Smuzhiyun buf += " ret = core_tpg_register(wwn, &tpg->se_tpg, SCSI_PROTOCOL_ISCSI);\n" 239*4882a593Smuzhiyun 240*4882a593Smuzhiyun buf += " if (ret < 0) {\n" 241*4882a593Smuzhiyun buf += " kfree(tpg);\n" 242*4882a593Smuzhiyun buf += " return NULL;\n" 243*4882a593Smuzhiyun buf += " }\n" 244*4882a593Smuzhiyun buf += " return &tpg->se_tpg;\n" 245*4882a593Smuzhiyun buf += "}\n\n" 246*4882a593Smuzhiyun buf += "static void " + fabric_mod_name + "_drop_tpg(struct se_portal_group *se_tpg)\n" 247*4882a593Smuzhiyun buf += "{\n" 248*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n" 249*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n\n" 250*4882a593Smuzhiyun buf += " core_tpg_deregister(se_tpg);\n" 251*4882a593Smuzhiyun buf += " kfree(tpg);\n" 252*4882a593Smuzhiyun buf += "}\n\n" 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun buf += "static struct se_wwn *" + fabric_mod_name + "_make_" + fabric_mod_port + "(\n" 255*4882a593Smuzhiyun buf += " struct target_fabric_configfs *tf,\n" 256*4882a593Smuzhiyun buf += " struct config_group *group,\n" 257*4882a593Smuzhiyun buf += " const char *name)\n" 258*4882a593Smuzhiyun buf += "{\n" 259*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + ";\n" 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun if proto_ident == "FC" or proto_ident == "SAS": 262*4882a593Smuzhiyun buf += " u64 wwpn = 0;\n\n" 263*4882a593Smuzhiyun 264*4882a593Smuzhiyun buf += " /* if (" + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n" 265*4882a593Smuzhiyun buf += " return ERR_PTR(-EINVAL); */\n\n" 266*4882a593Smuzhiyun buf += " " + fabric_mod_port + " = kzalloc(sizeof(struct " + fabric_mod_name + "_" + fabric_mod_port + "), GFP_KERNEL);\n" 267*4882a593Smuzhiyun buf += " if (!" + fabric_mod_port + ") {\n" 268*4882a593Smuzhiyun buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_" + fabric_mod_port + "\");\n" 269*4882a593Smuzhiyun buf += " return ERR_PTR(-ENOMEM);\n" 270*4882a593Smuzhiyun buf += " }\n" 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun if proto_ident == "FC" or proto_ident == "SAS": 273*4882a593Smuzhiyun buf += " " + fabric_mod_port + "->" + fabric_mod_port + "_wwpn = wwpn;\n" 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun buf += " /* " + fabric_mod_name + "_format_wwn(&" + fabric_mod_port + "->" + fabric_mod_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n" 276*4882a593Smuzhiyun buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_wwn;\n" 277*4882a593Smuzhiyun buf += "}\n\n" 278*4882a593Smuzhiyun buf += "static void " + fabric_mod_name + "_drop_" + fabric_mod_port + "(struct se_wwn *wwn)\n" 279*4882a593Smuzhiyun buf += "{\n" 280*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = container_of(wwn,\n" 281*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n" 282*4882a593Smuzhiyun buf += " kfree(" + fabric_mod_port + ");\n" 283*4882a593Smuzhiyun buf += "}\n\n" 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n" 286*4882a593Smuzhiyun buf += " .module = THIS_MODULE,\n" 287*4882a593Smuzhiyun buf += " .name = \"" + fabric_mod_name + "\",\n" 288*4882a593Smuzhiyun buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n" 289*4882a593Smuzhiyun buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n" 290*4882a593Smuzhiyun buf += " .tpg_get_tag = " + fabric_mod_name + "_get_tag,\n" 291*4882a593Smuzhiyun buf += " .tpg_check_demo_mode = " + fabric_mod_name + "_check_false,\n" 292*4882a593Smuzhiyun buf += " .tpg_check_demo_mode_cache = " + fabric_mod_name + "_check_true,\n" 293*4882a593Smuzhiyun buf += " .tpg_check_demo_mode_write_protect = " + fabric_mod_name + "_check_true,\n" 294*4882a593Smuzhiyun buf += " .tpg_check_prod_mode_write_protect = " + fabric_mod_name + "_check_false,\n" 295*4882a593Smuzhiyun buf += " .tpg_get_inst_index = " + fabric_mod_name + "_tpg_get_inst_index,\n" 296*4882a593Smuzhiyun buf += " .release_cmd = " + fabric_mod_name + "_release_cmd,\n" 297*4882a593Smuzhiyun buf += " .sess_get_index = " + fabric_mod_name + "_sess_get_index,\n" 298*4882a593Smuzhiyun buf += " .sess_get_initiator_sid = NULL,\n" 299*4882a593Smuzhiyun buf += " .write_pending = " + fabric_mod_name + "_write_pending,\n" 300*4882a593Smuzhiyun buf += " .set_default_node_attributes = " + fabric_mod_name + "_set_default_node_attrs,\n" 301*4882a593Smuzhiyun buf += " .get_cmd_state = " + fabric_mod_name + "_get_cmd_state,\n" 302*4882a593Smuzhiyun buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n" 303*4882a593Smuzhiyun buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n" 304*4882a593Smuzhiyun buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n" 305*4882a593Smuzhiyun buf += " .aborted_task = " + fabric_mod_name + "_aborted_task,\n" 306*4882a593Smuzhiyun buf += " /*\n" 307*4882a593Smuzhiyun buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n" 308*4882a593Smuzhiyun buf += " */\n" 309*4882a593Smuzhiyun buf += " .fabric_make_wwn = " + fabric_mod_name + "_make_" + fabric_mod_port + ",\n" 310*4882a593Smuzhiyun buf += " .fabric_drop_wwn = " + fabric_mod_name + "_drop_" + fabric_mod_port + ",\n" 311*4882a593Smuzhiyun buf += " .fabric_make_tpg = " + fabric_mod_name + "_make_tpg,\n" 312*4882a593Smuzhiyun buf += " .fabric_drop_tpg = " + fabric_mod_name + "_drop_tpg,\n" 313*4882a593Smuzhiyun buf += "};\n\n" 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun buf += "static int __init " + fabric_mod_name + "_init(void)\n" 316*4882a593Smuzhiyun buf += "{\n" 317*4882a593Smuzhiyun buf += " return target_register_template(&" + fabric_mod_name + "_ops);\n" 318*4882a593Smuzhiyun buf += "};\n\n" 319*4882a593Smuzhiyun 320*4882a593Smuzhiyun buf += "static void __exit " + fabric_mod_name + "_exit(void)\n" 321*4882a593Smuzhiyun buf += "{\n" 322*4882a593Smuzhiyun buf += " target_unregister_template(&" + fabric_mod_name + "_ops);\n" 323*4882a593Smuzhiyun buf += "};\n\n" 324*4882a593Smuzhiyun 325*4882a593Smuzhiyun buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n" 326*4882a593Smuzhiyun buf += "MODULE_LICENSE(\"GPL\");\n" 327*4882a593Smuzhiyun buf += "module_init(" + fabric_mod_name + "_init);\n" 328*4882a593Smuzhiyun buf += "module_exit(" + fabric_mod_name + "_exit);\n" 329*4882a593Smuzhiyun 330*4882a593Smuzhiyun ret = p.write(buf) 331*4882a593Smuzhiyun if ret: 332*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 333*4882a593Smuzhiyun 334*4882a593Smuzhiyun p.close() 335*4882a593Smuzhiyun 336*4882a593Smuzhiyun return 337*4882a593Smuzhiyun 338*4882a593Smuzhiyundef tcm_mod_scan_fabric_ops(tcm_dir): 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun fabric_ops_api = tcm_dir + "include/target/target_core_fabric.h" 341*4882a593Smuzhiyun 342*4882a593Smuzhiyun print "Using tcm_mod_scan_fabric_ops: " + fabric_ops_api 343*4882a593Smuzhiyun process_fo = 0; 344*4882a593Smuzhiyun 345*4882a593Smuzhiyun p = open(fabric_ops_api, 'r') 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun line = p.readline() 348*4882a593Smuzhiyun while line: 349*4882a593Smuzhiyun if process_fo == 0 and re.search('struct target_core_fabric_ops {', line): 350*4882a593Smuzhiyun line = p.readline() 351*4882a593Smuzhiyun continue 352*4882a593Smuzhiyun 353*4882a593Smuzhiyun if process_fo == 0: 354*4882a593Smuzhiyun process_fo = 1; 355*4882a593Smuzhiyun line = p.readline() 356*4882a593Smuzhiyun # Search for function pointer 357*4882a593Smuzhiyun if not re.search('\(\*', line): 358*4882a593Smuzhiyun continue 359*4882a593Smuzhiyun 360*4882a593Smuzhiyun fabric_ops.append(line.rstrip()) 361*4882a593Smuzhiyun continue 362*4882a593Smuzhiyun 363*4882a593Smuzhiyun line = p.readline() 364*4882a593Smuzhiyun # Search for function pointer 365*4882a593Smuzhiyun if not re.search('\(\*', line): 366*4882a593Smuzhiyun continue 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun fabric_ops.append(line.rstrip()) 369*4882a593Smuzhiyun 370*4882a593Smuzhiyun p.close() 371*4882a593Smuzhiyun return 372*4882a593Smuzhiyun 373*4882a593Smuzhiyundef tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name): 374*4882a593Smuzhiyun buf = "" 375*4882a593Smuzhiyun bufi = "" 376*4882a593Smuzhiyun 377*4882a593Smuzhiyun f = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.c" 378*4882a593Smuzhiyun print "Writing file: " + f 379*4882a593Smuzhiyun 380*4882a593Smuzhiyun p = open(f, 'w') 381*4882a593Smuzhiyun if not p: 382*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 383*4882a593Smuzhiyun 384*4882a593Smuzhiyun fi = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.h" 385*4882a593Smuzhiyun print "Writing file: " + fi 386*4882a593Smuzhiyun 387*4882a593Smuzhiyun pi = open(fi, 'w') 388*4882a593Smuzhiyun if not pi: 389*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + fi) 390*4882a593Smuzhiyun 391*4882a593Smuzhiyun buf = "#include <linux/slab.h>\n" 392*4882a593Smuzhiyun buf += "#include <linux/kthread.h>\n" 393*4882a593Smuzhiyun buf += "#include <linux/types.h>\n" 394*4882a593Smuzhiyun buf += "#include <linux/list.h>\n" 395*4882a593Smuzhiyun buf += "#include <linux/types.h>\n" 396*4882a593Smuzhiyun buf += "#include <linux/string.h>\n" 397*4882a593Smuzhiyun buf += "#include <linux/ctype.h>\n" 398*4882a593Smuzhiyun buf += "#include <asm/unaligned.h>\n" 399*4882a593Smuzhiyun buf += "#include <scsi/scsi_common.h>\n" 400*4882a593Smuzhiyun buf += "#include <scsi/scsi_proto.h>\n" 401*4882a593Smuzhiyun buf += "#include <target/target_core_base.h>\n" 402*4882a593Smuzhiyun buf += "#include <target/target_core_fabric.h>\n" 403*4882a593Smuzhiyun buf += "#include \"" + fabric_mod_name + "_base.h\"\n" 404*4882a593Smuzhiyun buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n" 405*4882a593Smuzhiyun 406*4882a593Smuzhiyun buf += "int " + fabric_mod_name + "_check_true(struct se_portal_group *se_tpg)\n" 407*4882a593Smuzhiyun buf += "{\n" 408*4882a593Smuzhiyun buf += " return 1;\n" 409*4882a593Smuzhiyun buf += "}\n\n" 410*4882a593Smuzhiyun bufi += "int " + fabric_mod_name + "_check_true(struct se_portal_group *);\n" 411*4882a593Smuzhiyun 412*4882a593Smuzhiyun buf += "int " + fabric_mod_name + "_check_false(struct se_portal_group *se_tpg)\n" 413*4882a593Smuzhiyun buf += "{\n" 414*4882a593Smuzhiyun buf += " return 0;\n" 415*4882a593Smuzhiyun buf += "}\n\n" 416*4882a593Smuzhiyun bufi += "int " + fabric_mod_name + "_check_false(struct se_portal_group *);\n" 417*4882a593Smuzhiyun 418*4882a593Smuzhiyun total_fabric_ops = len(fabric_ops) 419*4882a593Smuzhiyun i = 0 420*4882a593Smuzhiyun 421*4882a593Smuzhiyun while i < total_fabric_ops: 422*4882a593Smuzhiyun fo = fabric_ops[i] 423*4882a593Smuzhiyun i += 1 424*4882a593Smuzhiyun# print "fabric_ops: " + fo 425*4882a593Smuzhiyun 426*4882a593Smuzhiyun if re.search('get_fabric_name', fo): 427*4882a593Smuzhiyun buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n" 428*4882a593Smuzhiyun buf += "{\n" 429*4882a593Smuzhiyun buf += " return \"" + fabric_mod_name + "\";\n" 430*4882a593Smuzhiyun buf += "}\n\n" 431*4882a593Smuzhiyun bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n" 432*4882a593Smuzhiyun continue 433*4882a593Smuzhiyun 434*4882a593Smuzhiyun if re.search('get_wwn', fo): 435*4882a593Smuzhiyun buf += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *se_tpg)\n" 436*4882a593Smuzhiyun buf += "{\n" 437*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n" 438*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n" 439*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n\n" 440*4882a593Smuzhiyun buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_name[0];\n" 441*4882a593Smuzhiyun buf += "}\n\n" 442*4882a593Smuzhiyun bufi += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *);\n" 443*4882a593Smuzhiyun 444*4882a593Smuzhiyun if re.search('get_tag', fo): 445*4882a593Smuzhiyun buf += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *se_tpg)\n" 446*4882a593Smuzhiyun buf += "{\n" 447*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n" 448*4882a593Smuzhiyun buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n" 449*4882a593Smuzhiyun buf += " return tpg->" + fabric_mod_port + "_tpgt;\n" 450*4882a593Smuzhiyun buf += "}\n\n" 451*4882a593Smuzhiyun bufi += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *);\n" 452*4882a593Smuzhiyun 453*4882a593Smuzhiyun if re.search('tpg_get_inst_index\)\(', fo): 454*4882a593Smuzhiyun buf += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *se_tpg)\n" 455*4882a593Smuzhiyun buf += "{\n" 456*4882a593Smuzhiyun buf += " return 1;\n" 457*4882a593Smuzhiyun buf += "}\n\n" 458*4882a593Smuzhiyun bufi += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *);\n" 459*4882a593Smuzhiyun 460*4882a593Smuzhiyun if re.search('\*release_cmd\)\(', fo): 461*4882a593Smuzhiyun buf += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *se_cmd)\n" 462*4882a593Smuzhiyun buf += "{\n" 463*4882a593Smuzhiyun buf += " return;\n" 464*4882a593Smuzhiyun buf += "}\n\n" 465*4882a593Smuzhiyun bufi += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *);\n" 466*4882a593Smuzhiyun 467*4882a593Smuzhiyun if re.search('sess_get_index\)\(', fo): 468*4882a593Smuzhiyun buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n" 469*4882a593Smuzhiyun buf += "{\n" 470*4882a593Smuzhiyun buf += " return 0;\n" 471*4882a593Smuzhiyun buf += "}\n\n" 472*4882a593Smuzhiyun bufi += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *);\n" 473*4882a593Smuzhiyun 474*4882a593Smuzhiyun if re.search('write_pending\)\(', fo): 475*4882a593Smuzhiyun buf += "int " + fabric_mod_name + "_write_pending(struct se_cmd *se_cmd)\n" 476*4882a593Smuzhiyun buf += "{\n" 477*4882a593Smuzhiyun buf += " return 0;\n" 478*4882a593Smuzhiyun buf += "}\n\n" 479*4882a593Smuzhiyun bufi += "int " + fabric_mod_name + "_write_pending(struct se_cmd *);\n" 480*4882a593Smuzhiyun 481*4882a593Smuzhiyun if re.search('set_default_node_attributes\)\(', fo): 482*4882a593Smuzhiyun buf += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *nacl)\n" 483*4882a593Smuzhiyun buf += "{\n" 484*4882a593Smuzhiyun buf += " return;\n" 485*4882a593Smuzhiyun buf += "}\n\n" 486*4882a593Smuzhiyun bufi += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *);\n" 487*4882a593Smuzhiyun 488*4882a593Smuzhiyun if re.search('get_cmd_state\)\(', fo): 489*4882a593Smuzhiyun buf += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *se_cmd)\n" 490*4882a593Smuzhiyun buf += "{\n" 491*4882a593Smuzhiyun buf += " return 0;\n" 492*4882a593Smuzhiyun buf += "}\n\n" 493*4882a593Smuzhiyun bufi += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *);\n" 494*4882a593Smuzhiyun 495*4882a593Smuzhiyun if re.search('queue_data_in\)\(', fo): 496*4882a593Smuzhiyun buf += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *se_cmd)\n" 497*4882a593Smuzhiyun buf += "{\n" 498*4882a593Smuzhiyun buf += " return 0;\n" 499*4882a593Smuzhiyun buf += "}\n\n" 500*4882a593Smuzhiyun bufi += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *);\n" 501*4882a593Smuzhiyun 502*4882a593Smuzhiyun if re.search('queue_status\)\(', fo): 503*4882a593Smuzhiyun buf += "int " + fabric_mod_name + "_queue_status(struct se_cmd *se_cmd)\n" 504*4882a593Smuzhiyun buf += "{\n" 505*4882a593Smuzhiyun buf += " return 0;\n" 506*4882a593Smuzhiyun buf += "}\n\n" 507*4882a593Smuzhiyun bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n" 508*4882a593Smuzhiyun 509*4882a593Smuzhiyun if re.search('queue_tm_rsp\)\(', fo): 510*4882a593Smuzhiyun buf += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n" 511*4882a593Smuzhiyun buf += "{\n" 512*4882a593Smuzhiyun buf += " return;\n" 513*4882a593Smuzhiyun buf += "}\n\n" 514*4882a593Smuzhiyun bufi += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n" 515*4882a593Smuzhiyun 516*4882a593Smuzhiyun if re.search('aborted_task\)\(', fo): 517*4882a593Smuzhiyun buf += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *se_cmd)\n" 518*4882a593Smuzhiyun buf += "{\n" 519*4882a593Smuzhiyun buf += " return;\n" 520*4882a593Smuzhiyun buf += "}\n\n" 521*4882a593Smuzhiyun bufi += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *);\n" 522*4882a593Smuzhiyun 523*4882a593Smuzhiyun ret = p.write(buf) 524*4882a593Smuzhiyun if ret: 525*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 526*4882a593Smuzhiyun 527*4882a593Smuzhiyun p.close() 528*4882a593Smuzhiyun 529*4882a593Smuzhiyun ret = pi.write(bufi) 530*4882a593Smuzhiyun if ret: 531*4882a593Smuzhiyun tcm_mod_err("Unable to write fi: " + fi) 532*4882a593Smuzhiyun 533*4882a593Smuzhiyun pi.close() 534*4882a593Smuzhiyun return 535*4882a593Smuzhiyun 536*4882a593Smuzhiyundef tcm_mod_build_kbuild(fabric_mod_dir_var, fabric_mod_name): 537*4882a593Smuzhiyun 538*4882a593Smuzhiyun buf = "" 539*4882a593Smuzhiyun f = fabric_mod_dir_var + "/Makefile" 540*4882a593Smuzhiyun print "Writing file: " + f 541*4882a593Smuzhiyun 542*4882a593Smuzhiyun p = open(f, 'w') 543*4882a593Smuzhiyun if not p: 544*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 545*4882a593Smuzhiyun 546*4882a593Smuzhiyun buf += fabric_mod_name + "-objs := " + fabric_mod_name + "_fabric.o \\\n" 547*4882a593Smuzhiyun buf += " " + fabric_mod_name + "_configfs.o\n" 548*4882a593Smuzhiyun buf += "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name + ".o\n" 549*4882a593Smuzhiyun 550*4882a593Smuzhiyun ret = p.write(buf) 551*4882a593Smuzhiyun if ret: 552*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 553*4882a593Smuzhiyun 554*4882a593Smuzhiyun p.close() 555*4882a593Smuzhiyun return 556*4882a593Smuzhiyun 557*4882a593Smuzhiyundef tcm_mod_build_kconfig(fabric_mod_dir_var, fabric_mod_name): 558*4882a593Smuzhiyun 559*4882a593Smuzhiyun buf = "" 560*4882a593Smuzhiyun f = fabric_mod_dir_var + "/Kconfig" 561*4882a593Smuzhiyun print "Writing file: " + f 562*4882a593Smuzhiyun 563*4882a593Smuzhiyun p = open(f, 'w') 564*4882a593Smuzhiyun if not p: 565*4882a593Smuzhiyun tcm_mod_err("Unable to open file: " + f) 566*4882a593Smuzhiyun 567*4882a593Smuzhiyun buf = "config " + fabric_mod_name.upper() + "\n" 568*4882a593Smuzhiyun buf += " tristate \"" + fabric_mod_name.upper() + " fabric module\"\n" 569*4882a593Smuzhiyun buf += " depends on TARGET_CORE && CONFIGFS_FS\n" 570*4882a593Smuzhiyun buf += " default n\n" 571*4882a593Smuzhiyun buf += " help\n" 572*4882a593Smuzhiyun buf += " Say Y here to enable the " + fabric_mod_name.upper() + " fabric module\n" 573*4882a593Smuzhiyun 574*4882a593Smuzhiyun ret = p.write(buf) 575*4882a593Smuzhiyun if ret: 576*4882a593Smuzhiyun tcm_mod_err("Unable to write f: " + f) 577*4882a593Smuzhiyun 578*4882a593Smuzhiyun p.close() 579*4882a593Smuzhiyun return 580*4882a593Smuzhiyun 581*4882a593Smuzhiyundef tcm_mod_add_kbuild(tcm_dir, fabric_mod_name): 582*4882a593Smuzhiyun buf = "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name.lower() + "/\n" 583*4882a593Smuzhiyun kbuild = tcm_dir + "/drivers/target/Makefile" 584*4882a593Smuzhiyun 585*4882a593Smuzhiyun f = open(kbuild, 'a') 586*4882a593Smuzhiyun f.write(buf) 587*4882a593Smuzhiyun f.close() 588*4882a593Smuzhiyun return 589*4882a593Smuzhiyun 590*4882a593Smuzhiyundef tcm_mod_add_kconfig(tcm_dir, fabric_mod_name): 591*4882a593Smuzhiyun buf = "source \"drivers/target/" + fabric_mod_name.lower() + "/Kconfig\"\n" 592*4882a593Smuzhiyun kconfig = tcm_dir + "/drivers/target/Kconfig" 593*4882a593Smuzhiyun 594*4882a593Smuzhiyun f = open(kconfig, 'a') 595*4882a593Smuzhiyun f.write(buf) 596*4882a593Smuzhiyun f.close() 597*4882a593Smuzhiyun return 598*4882a593Smuzhiyun 599*4882a593Smuzhiyundef main(modname, proto_ident): 600*4882a593Smuzhiyun# proto_ident = "FC" 601*4882a593Smuzhiyun# proto_ident = "SAS" 602*4882a593Smuzhiyun# proto_ident = "iSCSI" 603*4882a593Smuzhiyun 604*4882a593Smuzhiyun tcm_dir = os.getcwd(); 605*4882a593Smuzhiyun tcm_dir += "/../../" 606*4882a593Smuzhiyun print "tcm_dir: " + tcm_dir 607*4882a593Smuzhiyun fabric_mod_name = modname 608*4882a593Smuzhiyun fabric_mod_dir = tcm_dir + "drivers/target/" + fabric_mod_name 609*4882a593Smuzhiyun print "Set fabric_mod_name: " + fabric_mod_name 610*4882a593Smuzhiyun print "Set fabric_mod_dir: " + fabric_mod_dir 611*4882a593Smuzhiyun print "Using proto_ident: " + proto_ident 612*4882a593Smuzhiyun 613*4882a593Smuzhiyun if proto_ident != "FC" and proto_ident != "SAS" and proto_ident != "iSCSI": 614*4882a593Smuzhiyun print "Unsupported proto_ident: " + proto_ident 615*4882a593Smuzhiyun sys.exit(1) 616*4882a593Smuzhiyun 617*4882a593Smuzhiyun ret = tcm_mod_create_module_subdir(fabric_mod_dir) 618*4882a593Smuzhiyun if ret: 619*4882a593Smuzhiyun print "tcm_mod_create_module_subdir() failed because module already exists!" 620*4882a593Smuzhiyun sys.exit(1) 621*4882a593Smuzhiyun 622*4882a593Smuzhiyun tcm_mod_build_base_includes(proto_ident, fabric_mod_dir, fabric_mod_name) 623*4882a593Smuzhiyun tcm_mod_scan_fabric_ops(tcm_dir) 624*4882a593Smuzhiyun tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir, fabric_mod_name) 625*4882a593Smuzhiyun tcm_mod_build_configfs(proto_ident, fabric_mod_dir, fabric_mod_name) 626*4882a593Smuzhiyun tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name) 627*4882a593Smuzhiyun tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name) 628*4882a593Smuzhiyun 629*4882a593Smuzhiyun input = raw_input("Would you like to add " + fabric_mod_name + " to drivers/target/Makefile..? [yes,no]: ") 630*4882a593Smuzhiyun if input == "yes" or input == "y": 631*4882a593Smuzhiyun tcm_mod_add_kbuild(tcm_dir, fabric_mod_name) 632*4882a593Smuzhiyun 633*4882a593Smuzhiyun input = raw_input("Would you like to add " + fabric_mod_name + " to drivers/target/Kconfig..? [yes,no]: ") 634*4882a593Smuzhiyun if input == "yes" or input == "y": 635*4882a593Smuzhiyun tcm_mod_add_kconfig(tcm_dir, fabric_mod_name) 636*4882a593Smuzhiyun 637*4882a593Smuzhiyun return 638*4882a593Smuzhiyun 639*4882a593Smuzhiyunparser = optparse.OptionParser() 640*4882a593Smuzhiyunparser.add_option('-m', '--modulename', help='Module name', dest='modname', 641*4882a593Smuzhiyun action='store', nargs=1, type='string') 642*4882a593Smuzhiyunparser.add_option('-p', '--protoident', help='Protocol Ident', dest='protoident', 643*4882a593Smuzhiyun action='store', nargs=1, type='string') 644*4882a593Smuzhiyun 645*4882a593Smuzhiyun(opts, args) = parser.parse_args() 646*4882a593Smuzhiyun 647*4882a593Smuzhiyunmandatories = ['modname', 'protoident'] 648*4882a593Smuzhiyunfor m in mandatories: 649*4882a593Smuzhiyun if not opts.__dict__[m]: 650*4882a593Smuzhiyun print "mandatory option is missing\n" 651*4882a593Smuzhiyun parser.print_help() 652*4882a593Smuzhiyun exit(-1) 653*4882a593Smuzhiyun 654*4882a593Smuzhiyunif __name__ == "__main__": 655*4882a593Smuzhiyun 656*4882a593Smuzhiyun main(str(opts.modname), opts.protoident) 657