cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tcm_mod_builder.py (22505B)


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