About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Documentation / target / tcm_mod_builder.py




Custom Search

Based on kernel version 4.1. Page generated on 2015-06-28 12:14 EST.

1	#!/usr/bin/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	#
9	import os, sys
10	import subprocess as sub
11	import string
12	import re
13	import optparse
14	
15	tcm_dir = ""
16	
17	fabric_ops = []
18	fabric_mod_dir = ""
19	fabric_mod_port = ""
20	fabric_mod_init_port = ""
21	
22	def tcm_mod_err(msg):
23		print msg
24		sys.exit(1)
25	
26	def 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	
38	def 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 + "_nacl {\n"
54		buf += "	/* Binary World Wide unique Port Name for FC Initiator Nport */\n"
55		buf += "	u64 nport_wwpn;\n"
56		buf += "	/* ASCII formatted WWPN for FC Initiator Nport */\n"
57		buf += "	char nport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
58		buf += "	/* Returned by " + fabric_mod_name + "_make_nodeacl() */\n"
59		buf += "	struct se_node_acl se_node_acl;\n"
60		buf += "};\n"
61		buf += "\n"
62		buf += "struct " + fabric_mod_name + "_tpg {\n"
63		buf += "	/* FC lport target portal group tag for TCM */\n"
64		buf += "	u16 lport_tpgt;\n"
65		buf += "	/* Pointer back to " + fabric_mod_name + "_lport */\n"
66		buf += "	struct " + fabric_mod_name + "_lport *lport;\n"
67		buf += "	/* Returned by " + fabric_mod_name + "_make_tpg() */\n"
68		buf += "	struct se_portal_group se_tpg;\n"
69		buf += "};\n"
70		buf += "\n"
71		buf += "struct " + fabric_mod_name + "_lport {\n"
72		buf += "	/* SCSI protocol the lport is providing */\n"
73		buf += "	u8 lport_proto_id;\n"
74		buf += "	/* Binary World Wide unique Port Name for FC Target Lport */\n"
75		buf += "	u64 lport_wwpn;\n"
76		buf += "	/* ASCII formatted WWPN for FC Target Lport */\n"
77		buf += "	char lport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
78		buf += "	/* Returned by " + fabric_mod_name + "_make_lport() */\n"
79		buf += "	struct se_wwn lport_wwn;\n"
80		buf += "};\n"
81	
82		ret = p.write(buf)
83		if ret:
84			tcm_mod_err("Unable to write f: " + f)
85	
86		p.close()
87	
88		fabric_mod_port = "lport"
89		fabric_mod_init_port = "nport"
90	
91		return
92	
93	def tcm_mod_build_SAS_include(fabric_mod_dir_var, fabric_mod_name):
94		global fabric_mod_port
95		global fabric_mod_init_port
96		buf = ""
97	
98		f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h"
99		print "Writing file: " + f
100	
101		p = open(f, 'w');
102		if not p:
103			tcm_mod_err("Unable to open file: " + f)
104	
105		buf = "#define " + fabric_mod_name.upper() + "_VERSION  \"v0.1\"\n"
106		buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n"
107		buf += "\n"
108		buf += "struct " + fabric_mod_name + "_nacl {\n"
109		buf += "	/* Binary World Wide unique Port Name for SAS Initiator port */\n"
110		buf += "	u64 iport_wwpn;\n"
111		buf += "	/* ASCII formatted WWPN for Sas Initiator port */\n"
112		buf += "	char iport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
113		buf += "	/* Returned by " + fabric_mod_name + "_make_nodeacl() */\n"
114		buf += "	struct se_node_acl se_node_acl;\n"
115		buf += "};\n\n"
116		buf += "struct " + fabric_mod_name + "_tpg {\n"
117		buf += "	/* SAS port target portal group tag for TCM */\n"
118		buf += "	u16 tport_tpgt;\n"
119		buf += "	/* Pointer back to " + fabric_mod_name + "_tport */\n"
120		buf += "	struct " + fabric_mod_name + "_tport *tport;\n"
121		buf += "	/* Returned by " + fabric_mod_name + "_make_tpg() */\n"
122		buf += "	struct se_portal_group se_tpg;\n"
123		buf += "};\n\n"
124		buf += "struct " + fabric_mod_name + "_tport {\n"
125		buf += "	/* SCSI protocol the tport is providing */\n"
126		buf += "	u8 tport_proto_id;\n"
127		buf += "	/* Binary World Wide unique Port Name for SAS Target port */\n"
128		buf += "	u64 tport_wwpn;\n"
129		buf += "	/* ASCII formatted WWPN for SAS Target port */\n"
130		buf += "	char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
131		buf += "	/* Returned by " + fabric_mod_name + "_make_tport() */\n"
132		buf += "	struct se_wwn tport_wwn;\n"
133		buf += "};\n"
134	
135		ret = p.write(buf)
136		if ret:
137			tcm_mod_err("Unable to write f: " + f)
138	
139		p.close()
140	
141		fabric_mod_port = "tport"
142		fabric_mod_init_port = "iport"
143	
144		return
145	
146	def tcm_mod_build_iSCSI_include(fabric_mod_dir_var, fabric_mod_name):
147		global fabric_mod_port
148		global fabric_mod_init_port
149		buf = ""
150	
151		f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h"
152		print "Writing file: " + f
153	
154		p = open(f, 'w');
155		if not p:
156			tcm_mod_err("Unable to open file: " + f)
157	
158		buf = "#define " + fabric_mod_name.upper() + "_VERSION  \"v0.1\"\n"
159		buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n"
160		buf += "\n"
161		buf += "struct " + fabric_mod_name + "_nacl {\n"
162		buf += "	/* ASCII formatted InitiatorName */\n"
163		buf += "	char iport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
164		buf += "	/* Returned by " + fabric_mod_name + "_make_nodeacl() */\n"
165		buf += "	struct se_node_acl se_node_acl;\n"
166		buf += "};\n\n"
167		buf += "struct " + fabric_mod_name + "_tpg {\n"
168		buf += "	/* iSCSI target portal group tag for TCM */\n"
169		buf += "	u16 tport_tpgt;\n"
170		buf += "	/* Pointer back to " + fabric_mod_name + "_tport */\n"
171		buf += "	struct " + fabric_mod_name + "_tport *tport;\n"
172		buf += "	/* Returned by " + fabric_mod_name + "_make_tpg() */\n"
173		buf += "	struct se_portal_group se_tpg;\n"
174		buf += "};\n\n"
175		buf += "struct " + fabric_mod_name + "_tport {\n"
176		buf += "	/* SCSI protocol the tport is providing */\n"
177		buf += "	u8 tport_proto_id;\n"
178		buf += "	/* ASCII formatted TargetName for IQN */\n"
179		buf += "	char tport_name[" + fabric_mod_name.upper() + "_NAMELEN];\n"
180		buf += "	/* Returned by " + fabric_mod_name + "_make_tport() */\n"
181		buf += "	struct se_wwn tport_wwn;\n"
182		buf += "};\n"
183	
184		ret = p.write(buf)
185		if ret:
186			tcm_mod_err("Unable to write f: " + f)
187	
188		p.close()
189	
190		fabric_mod_port = "tport"
191		fabric_mod_init_port = "iport"
192	
193		return
194	
195	def tcm_mod_build_base_includes(proto_ident, fabric_mod_dir_val, fabric_mod_name):
196	
197		if proto_ident == "FC":
198			tcm_mod_build_FC_include(fabric_mod_dir_val, fabric_mod_name)
199		elif proto_ident == "SAS":
200			tcm_mod_build_SAS_include(fabric_mod_dir_val, fabric_mod_name)
201		elif proto_ident == "iSCSI":
202			tcm_mod_build_iSCSI_include(fabric_mod_dir_val, fabric_mod_name)
203		else:
204			print "Unsupported proto_ident: " + proto_ident
205			sys.exit(1)
206	
207		return
208	
209	def tcm_mod_build_configfs(proto_ident, fabric_mod_dir_var, fabric_mod_name):
210		buf = ""
211	
212		f = fabric_mod_dir_var + "/" + fabric_mod_name + "_configfs.c"
213		print "Writing file: " + f
214	
215	        p = open(f, 'w');
216	        if not p:
217	                tcm_mod_err("Unable to open file: " + f)
218	
219		buf = "#include <linux/module.h>\n"
220		buf += "#include <linux/moduleparam.h>\n"
221		buf += "#include <linux/version.h>\n"
222		buf += "#include <generated/utsrelease.h>\n"
223		buf += "#include <linux/utsname.h>\n"
224		buf += "#include <linux/init.h>\n"
225		buf += "#include <linux/slab.h>\n"
226		buf += "#include <linux/kthread.h>\n"
227		buf += "#include <linux/types.h>\n"
228		buf += "#include <linux/string.h>\n"
229		buf += "#include <linux/configfs.h>\n"
230		buf += "#include <linux/ctype.h>\n"
231		buf += "#include <asm/unaligned.h>\n\n"
232		buf += "#include <target/target_core_base.h>\n"
233		buf += "#include <target/target_core_fabric.h>\n"
234		buf += "#include <target/target_core_fabric_configfs.h>\n"
235		buf += "#include <target/target_core_configfs.h>\n"
236		buf += "#include <target/configfs_macros.h>\n\n"
237		buf += "#include \"" + fabric_mod_name + "_base.h\"\n"
238		buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n"
239	
240		buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops;\n\n"
241	
242		buf += "static struct se_node_acl *" + fabric_mod_name + "_make_nodeacl(\n"
243		buf += "	struct se_portal_group *se_tpg,\n"
244		buf += "	struct config_group *group,\n"
245		buf += "	const char *name)\n"
246		buf += "{\n"
247		buf += "	struct se_node_acl *se_nacl, *se_nacl_new;\n"
248		buf += "	struct " + fabric_mod_name + "_nacl *nacl;\n"
249	
250		if proto_ident == "FC" or proto_ident == "SAS":
251			buf += "	u64 wwpn = 0;\n"
252	
253		buf += "	u32 nexus_depth;\n\n"
254		buf += "	/* " + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
255		buf += "		return ERR_PTR(-EINVAL); */\n"
256		buf += "	se_nacl_new = " + fabric_mod_name + "_alloc_fabric_acl(se_tpg);\n"
257		buf += "	if (!se_nacl_new)\n"
258		buf += "		return ERR_PTR(-ENOMEM);\n"
259		buf += "//#warning FIXME: Hardcoded nexus depth in " + fabric_mod_name + "_make_nodeacl()\n"
260		buf += "	nexus_depth = 1;\n"
261		buf += "	/*\n"
262		buf += "	 * se_nacl_new may be released by core_tpg_add_initiator_node_acl()\n"
263		buf += "	 * when converting a NodeACL from demo mode -> explict\n"
264		buf += "	 */\n"
265		buf += "	se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,\n"
266		buf += "				name, nexus_depth);\n"
267		buf += "	if (IS_ERR(se_nacl)) {\n"
268		buf += "		" + fabric_mod_name + "_release_fabric_acl(se_tpg, se_nacl_new);\n"
269		buf += "		return se_nacl;\n"
270		buf += "	}\n"
271		buf += "	/*\n"
272		buf += "	 * Locate our struct " + fabric_mod_name + "_nacl and set the FC Nport WWPN\n"
273		buf += "	 */\n"
274		buf += "	nacl = container_of(se_nacl, struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
275	
276		if proto_ident == "FC" or proto_ident == "SAS":
277			buf += "	nacl->" + fabric_mod_init_port + "_wwpn = wwpn;\n"
278	
279		buf += "	/* " + fabric_mod_name + "_format_wwn(&nacl->" + fabric_mod_init_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n"
280		buf += "	return se_nacl;\n"
281		buf += "}\n\n"
282		buf += "static void " + fabric_mod_name + "_drop_nodeacl(struct se_node_acl *se_acl)\n"
283		buf += "{\n"
284		buf += "	struct " + fabric_mod_name + "_nacl *nacl = container_of(se_acl,\n"
285		buf += "				struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
286		buf += "	core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1);\n"
287		buf += "	kfree(nacl);\n"
288		buf += "}\n\n"
289	
290		buf += "static struct se_portal_group *" + fabric_mod_name + "_make_tpg(\n"
291		buf += "	struct se_wwn *wwn,\n"
292		buf += "	struct config_group *group,\n"
293		buf += "	const char *name)\n"
294		buf += "{\n"
295		buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + "*" + fabric_mod_port + " = container_of(wwn,\n"
296		buf += "			struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n\n"
297		buf += "	struct " + fabric_mod_name + "_tpg *tpg;\n"
298		buf += "	unsigned long tpgt;\n"
299		buf += "	int ret;\n\n"
300		buf += "	if (strstr(name, \"tpgt_\") != name)\n"
301		buf += "		return ERR_PTR(-EINVAL);\n"
302		buf += "	if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)\n"
303		buf += "		return ERR_PTR(-EINVAL);\n\n"
304		buf += "	tpg = kzalloc(sizeof(struct " + fabric_mod_name + "_tpg), GFP_KERNEL);\n"
305		buf += "	if (!tpg) {\n"
306		buf += "		printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_tpg\");\n"
307		buf += "		return ERR_PTR(-ENOMEM);\n"
308		buf += "	}\n"
309		buf += "	tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n"
310		buf += "	tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n"
311		buf += "	ret = core_tpg_register(&" + fabric_mod_name + "_ops, wwn,\n"
312		buf += "				&tpg->se_tpg, tpg,\n"
313		buf += "				TRANSPORT_TPG_TYPE_NORMAL);\n"
314		buf += "	if (ret < 0) {\n"
315		buf += "		kfree(tpg);\n"
316		buf += "		return NULL;\n"
317		buf += "	}\n"
318		buf += "	return &tpg->se_tpg;\n"
319		buf += "}\n\n"
320		buf += "static void " + fabric_mod_name + "_drop_tpg(struct se_portal_group *se_tpg)\n"
321		buf += "{\n"
322		buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
323		buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n\n"
324		buf += "	core_tpg_deregister(se_tpg);\n"
325		buf += "	kfree(tpg);\n"
326		buf += "}\n\n"
327	
328		buf += "static struct se_wwn *" + fabric_mod_name + "_make_" + fabric_mod_port + "(\n"
329		buf += "	struct target_fabric_configfs *tf,\n"
330		buf += "	struct config_group *group,\n"
331		buf += "	const char *name)\n"
332		buf += "{\n"
333		buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + ";\n"
334	
335		if proto_ident == "FC" or proto_ident == "SAS":
336			buf += "	u64 wwpn = 0;\n\n"
337	
338		buf += "	/* if (" + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
339		buf += "		return ERR_PTR(-EINVAL); */\n\n"
340		buf += "	" + fabric_mod_port + " = kzalloc(sizeof(struct " + fabric_mod_name + "_" + fabric_mod_port + "), GFP_KERNEL);\n"
341		buf += "	if (!" + fabric_mod_port + ") {\n"
342		buf += "		printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_" + fabric_mod_port + "\");\n"
343		buf += "		return ERR_PTR(-ENOMEM);\n"
344		buf += "	}\n"
345	
346		if proto_ident == "FC" or proto_ident == "SAS":
347			buf += "	" + fabric_mod_port + "->" + fabric_mod_port + "_wwpn = wwpn;\n"
348	
349		buf += "	/* " + fabric_mod_name + "_format_wwn(&" + fabric_mod_port + "->" + fabric_mod_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n"
350		buf += "	return &" + fabric_mod_port + "->" + fabric_mod_port + "_wwn;\n"
351		buf += "}\n\n"
352		buf += "static void " + fabric_mod_name + "_drop_" + fabric_mod_port + "(struct se_wwn *wwn)\n"
353		buf += "{\n"
354		buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = container_of(wwn,\n"
355		buf += "				struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n"
356		buf += "	kfree(" + fabric_mod_port + ");\n"
357		buf += "}\n\n"
358		buf += "static ssize_t " + fabric_mod_name + "_wwn_show_attr_version(\n"
359		buf += "	struct target_fabric_configfs *tf,\n"
360		buf += "	char *page)\n"
361		buf += "{\n"
362		buf += "	return sprintf(page, \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
363		buf += "		\"on \"UTS_RELEASE\"\\n\", " + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
364		buf += "		utsname()->machine);\n"
365		buf += "}\n\n"
366		buf += "TF_WWN_ATTR_RO(" + fabric_mod_name + ", version);\n\n"
367		buf += "static struct configfs_attribute *" + fabric_mod_name + "_wwn_attrs[] = {\n"
368		buf += "	&" + fabric_mod_name + "_wwn_version.attr,\n"
369		buf += "	NULL,\n"
370		buf += "};\n\n"
371	
372		buf += "static const struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
373		buf += "	.module				= THIS_MODULE,\n"
374		buf += "	.name				= " + fabric_mod_name + ",\n"
375		buf += "	.get_fabric_proto_ident		= " + fabric_mod_name + "_get_fabric_proto_ident,\n"
376		buf += "	.get_fabric_name		= " + fabric_mod_name + "_get_fabric_name,\n"
377		buf += "	.get_fabric_proto_ident		= " + fabric_mod_name + "_get_fabric_proto_ident,\n"
378		buf += "	.tpg_get_wwn			= " + fabric_mod_name + "_get_fabric_wwn,\n"
379		buf += "	.tpg_get_tag			= " + fabric_mod_name + "_get_tag,\n"
380		buf += "	.tpg_get_default_depth		= " + fabric_mod_name + "_get_default_depth,\n"
381		buf += "	.tpg_get_pr_transport_id	= " + fabric_mod_name + "_get_pr_transport_id,\n"
382		buf += "	.tpg_get_pr_transport_id_len	= " + fabric_mod_name + "_get_pr_transport_id_len,\n"
383		buf += "	.tpg_parse_pr_out_transport_id	= " + fabric_mod_name + "_parse_pr_out_transport_id,\n"
384		buf += "	.tpg_check_demo_mode		= " + fabric_mod_name + "_check_false,\n"
385		buf += "	.tpg_check_demo_mode_cache	= " + fabric_mod_name + "_check_true,\n"
386		buf += "	.tpg_check_demo_mode_write_protect = " + fabric_mod_name + "_check_true,\n"
387		buf += "	.tpg_check_prod_mode_write_protect = " + fabric_mod_name + "_check_false,\n"
388		buf += "	.tpg_alloc_fabric_acl		= " + fabric_mod_name + "_alloc_fabric_acl,\n"
389		buf += "	.tpg_release_fabric_acl		= " + fabric_mod_name + "_release_fabric_acl,\n"
390		buf += "	.tpg_get_inst_index		= " + fabric_mod_name + "_tpg_get_inst_index,\n"
391		buf += "	.release_cmd			= " + fabric_mod_name + "_release_cmd,\n"
392		buf += "	.shutdown_session		= " + fabric_mod_name + "_shutdown_session,\n"
393		buf += "	.close_session			= " + fabric_mod_name + "_close_session,\n"
394		buf += "	.sess_get_index			= " + fabric_mod_name + "_sess_get_index,\n"
395		buf += "	.sess_get_initiator_sid		= NULL,\n"
396		buf += "	.write_pending			= " + fabric_mod_name + "_write_pending,\n"
397		buf += "	.write_pending_status		= " + fabric_mod_name + "_write_pending_status,\n"
398		buf += "	.set_default_node_attributes	= " + fabric_mod_name + "_set_default_node_attrs,\n"
399		buf += "	.get_task_tag			= " + fabric_mod_name + "_get_task_tag,\n"
400		buf += "	.get_cmd_state			= " + fabric_mod_name + "_get_cmd_state,\n"
401		buf += "	.queue_data_in			= " + fabric_mod_name + "_queue_data_in,\n"
402		buf += "	.queue_status			= " + fabric_mod_name + "_queue_status,\n"
403		buf += "	.queue_tm_rsp			= " + fabric_mod_name + "_queue_tm_rsp,\n"
404		buf += "	.aborted_task			= " + fabric_mod_name + "_aborted_task,\n"
405		buf += "	/*\n"
406		buf += "	 * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
407		buf += "	 */\n"
408		buf += "	.fabric_make_wwn		= " + fabric_mod_name + "_make_" + fabric_mod_port + ",\n"
409		buf += "	.fabric_drop_wwn		= " + fabric_mod_name + "_drop_" + fabric_mod_port + ",\n"
410		buf += "	.fabric_make_tpg		= " + fabric_mod_name + "_make_tpg,\n"
411		buf += "	.fabric_drop_tpg		= " + fabric_mod_name + "_drop_tpg,\n"
412		buf += "	.fabric_post_link		= NULL,\n"
413		buf += "	.fabric_pre_unlink		= NULL,\n"
414		buf += "	.fabric_make_np			= NULL,\n"
415		buf += "	.fabric_drop_np			= NULL,\n"
416		buf += "	.fabric_make_nodeacl		= " + fabric_mod_name + "_make_nodeacl,\n"
417		buf += "	.fabric_drop_nodeacl		= " + fabric_mod_name + "_drop_nodeacl,\n"
418		buf += "\n"
419		buf += "	.tfc_wwn_attrs			= " + fabric_mod_name + "_wwn_attrs;\n"
420		buf += "};\n\n"
421	
422		buf += "static int __init " + fabric_mod_name + "_init(void)\n"
423		buf += "{\n"
424		buf += "	return target_register_template(" + fabric_mod_name + "_ops);\n"
425		buf += "};\n\n"
426	
427		buf += "static void __exit " + fabric_mod_name + "_exit(void)\n"
428		buf += "{\n"
429		buf += "	target_unregister_template(" + fabric_mod_name + "_ops);\n"
430		buf += "};\n\n"
431	
432		buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n"
433		buf += "MODULE_LICENSE(\"GPL\");\n"
434		buf += "module_init(" + fabric_mod_name + "_init);\n"
435		buf += "module_exit(" + fabric_mod_name + "_exit);\n"
436	
437		ret = p.write(buf)
438		if ret:
439			tcm_mod_err("Unable to write f: " + f)
440	
441		p.close()
442	
443		return
444	
445	def tcm_mod_scan_fabric_ops(tcm_dir):
446	
447		fabric_ops_api = tcm_dir + "include/target/target_core_fabric.h"
448	
449		print "Using tcm_mod_scan_fabric_ops: " + fabric_ops_api
450		process_fo = 0;
451	
452		p = open(fabric_ops_api, 'r')
453	
454		line = p.readline()
455		while line:
456			if process_fo == 0 and re.search('struct target_core_fabric_ops {', line):
457				line = p.readline()
458				continue
459	
460			if process_fo == 0:
461				process_fo = 1;
462				line = p.readline()
463				# Search for function pointer
464				if not re.search('\(\*', line):
465					continue
466	
467				fabric_ops.append(line.rstrip())
468				continue
469	
470			line = p.readline()
471			# Search for function pointer
472			if not re.search('\(\*', line):
473				continue
474	
475			fabric_ops.append(line.rstrip())
476	
477		p.close()
478		return
479	
480	def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
481		buf = ""
482		bufi = ""
483	
484		f = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.c"
485		print "Writing file: " + f
486	
487		p = open(f, 'w')
488		if not p:
489			tcm_mod_err("Unable to open file: " + f)
490	
491		fi = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.h"
492		print "Writing file: " + fi
493	
494		pi = open(fi, 'w')
495		if not pi:
496			tcm_mod_err("Unable to open file: " + fi)
497	
498		buf = "#include <linux/slab.h>\n"
499		buf += "#include <linux/kthread.h>\n"
500		buf += "#include <linux/types.h>\n"
501		buf += "#include <linux/list.h>\n"
502		buf += "#include <linux/types.h>\n"
503		buf += "#include <linux/string.h>\n"
504		buf += "#include <linux/ctype.h>\n"
505		buf += "#include <asm/unaligned.h>\n"
506		buf += "#include <scsi/scsi.h>\n"
507		buf += "#include <scsi/scsi_host.h>\n"
508		buf += "#include <scsi/scsi_device.h>\n"
509		buf += "#include <scsi/scsi_cmnd.h>\n"
510		buf += "#include <scsi/libfc.h>\n\n"
511		buf += "#include <target/target_core_base.h>\n"
512		buf += "#include <target/target_core_fabric.h>\n"
513		buf += "#include <target/target_core_configfs.h>\n\n"
514		buf += "#include \"" + fabric_mod_name + "_base.h\"\n"
515		buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n"
516	
517		buf += "int " + fabric_mod_name + "_check_true(struct se_portal_group *se_tpg)\n"
518		buf += "{\n"
519		buf += "	return 1;\n"
520		buf += "}\n\n"
521		bufi += "int " + fabric_mod_name + "_check_true(struct se_portal_group *);\n"
522	
523		buf += "int " + fabric_mod_name + "_check_false(struct se_portal_group *se_tpg)\n"
524		buf += "{\n"
525		buf += "	return 0;\n"
526		buf += "}\n\n"
527		bufi += "int " + fabric_mod_name + "_check_false(struct se_portal_group *);\n"
528	
529		total_fabric_ops = len(fabric_ops)
530		i = 0
531	
532		while i < total_fabric_ops:
533			fo = fabric_ops[i]
534			i += 1
535	#		print "fabric_ops: " + fo
536	
537			if re.search('get_fabric_name', fo):
538				buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
539				buf += "{\n"
540				buf += "	return \"" + fabric_mod_name + "\";\n"
541				buf += "}\n\n"
542				bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
543				continue
544	
545			if re.search('get_fabric_proto_ident', fo):
546				buf += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *se_tpg)\n"
547				buf += "{\n"
548				buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
549				buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n"
550				buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
551				buf += "	u8 proto_id;\n\n"
552				buf += "	switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
553				if proto_ident == "FC":
554					buf += "	case SCSI_PROTOCOL_FCP:\n"
555					buf += "	default:\n"
556					buf += "		proto_id = fc_get_fabric_proto_ident(se_tpg);\n"
557					buf += "		break;\n"
558				elif proto_ident == "SAS":
559					buf += "	case SCSI_PROTOCOL_SAS:\n"
560					buf += "	default:\n"
561					buf += "		proto_id = sas_get_fabric_proto_ident(se_tpg);\n"
562					buf += "		break;\n"
563				elif proto_ident == "iSCSI":
564					buf += "	case SCSI_PROTOCOL_ISCSI:\n"
565					buf += "	default:\n"
566					buf += "		proto_id = iscsi_get_fabric_proto_ident(se_tpg);\n"
567					buf += "		break;\n"
568	
569				buf += "	}\n\n"
570				buf += "	return proto_id;\n"
571				buf += "}\n\n"
572				bufi += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *);\n"
573	
574			if re.search('get_wwn', fo):
575				buf += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *se_tpg)\n"
576				buf += "{\n"
577				buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
578				buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n"
579				buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n\n"
580				buf += "	return &" + fabric_mod_port + "->" + fabric_mod_port + "_name[0];\n"
581				buf += "}\n\n"
582				bufi += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *);\n"
583	
584			if re.search('get_tag', fo):
585				buf += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *se_tpg)\n"
586				buf += "{\n"
587				buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
588				buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n"
589				buf += "	return tpg->" + fabric_mod_port + "_tpgt;\n"
590				buf += "}\n\n"
591				bufi += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *);\n"
592	
593			if re.search('get_default_depth', fo):
594				buf += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *se_tpg)\n"
595				buf += "{\n"
596				buf += "	return 1;\n"
597				buf += "}\n\n"
598				bufi += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *);\n"
599	
600			if re.search('get_pr_transport_id\)\(', fo):
601				buf += "u32 " + fabric_mod_name + "_get_pr_transport_id(\n"
602				buf += "	struct se_portal_group *se_tpg,\n"
603				buf += "	struct se_node_acl *se_nacl,\n"
604				buf += "	struct t10_pr_registration *pr_reg,\n"
605				buf += "	int *format_code,\n"
606				buf += "	unsigned char *buf)\n"
607				buf += "{\n"
608				buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
609				buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n"
610				buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
611				buf += "	int ret = 0;\n\n"
612				buf += "	switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
613				if proto_ident == "FC":
614					buf += "	case SCSI_PROTOCOL_FCP:\n"
615					buf += "	default:\n"
616					buf += "		ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
617					buf += "					format_code, buf);\n"
618					buf += "		break;\n"
619				elif proto_ident == "SAS":
620					buf += "	case SCSI_PROTOCOL_SAS:\n"
621					buf += "	default:\n"
622					buf += "		ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
623					buf += "					format_code, buf);\n"
624					buf += "		break;\n"
625				elif proto_ident == "iSCSI":
626					buf += "	case SCSI_PROTOCOL_ISCSI:\n"
627					buf += "	default:\n"
628					buf += "		ret = iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
629					buf += "					format_code, buf);\n"
630					buf += "		break;\n"
631	
632				buf += "	}\n\n"
633				buf += "	return ret;\n"
634				buf += "}\n\n"
635				bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id(struct se_portal_group *,\n"
636				bufi += "			struct se_node_acl *, struct t10_pr_registration *,\n"
637				bufi += "			int *, unsigned char *);\n"
638	
639			if re.search('get_pr_transport_id_len\)\(', fo):
640				buf += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(\n"
641				buf += "	struct se_portal_group *se_tpg,\n"
642				buf += "	struct se_node_acl *se_nacl,\n"
643				buf += "	struct t10_pr_registration *pr_reg,\n"
644				buf += "	int *format_code)\n"
645				buf += "{\n"
646				buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
647				buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n"
648				buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
649				buf += "	int ret = 0;\n\n"
650				buf += "	switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
651				if proto_ident == "FC":
652					buf += "	case SCSI_PROTOCOL_FCP:\n"
653					buf += "	default:\n"
654					buf += "		ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
655					buf += "					format_code);\n"
656					buf += "		break;\n"
657				elif proto_ident == "SAS":
658					buf += "	case SCSI_PROTOCOL_SAS:\n"
659					buf += "	default:\n"
660					buf += "		ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
661					buf += "					format_code);\n"
662					buf += "		break;\n"
663				elif proto_ident == "iSCSI":
664					buf += "	case SCSI_PROTOCOL_ISCSI:\n"
665					buf += "	default:\n"
666					buf += "		ret = iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
667					buf += "					format_code);\n"
668					buf += "		break;\n"
669	
670	
671				buf += "	}\n\n"
672				buf += "	return ret;\n"
673				buf += "}\n\n"
674				bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(struct se_portal_group *,\n"
675				bufi += "			struct se_node_acl *, struct t10_pr_registration *,\n"
676				bufi += "			int *);\n"
677	
678			if re.search('parse_pr_out_transport_id\)\(', fo):
679				buf += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(\n"
680				buf += "	struct se_portal_group *se_tpg,\n"
681				buf += "	const char *buf,\n"
682				buf += "	u32 *out_tid_len,\n"
683				buf += "	char **port_nexus_ptr)\n"
684				buf += "{\n"
685				buf += "	struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
686				buf += "				struct " + fabric_mod_name + "_tpg, se_tpg);\n"
687				buf += "	struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
688				buf += "	char *tid = NULL;\n\n"
689				buf += "	switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
690				if proto_ident == "FC":
691					buf += "	case SCSI_PROTOCOL_FCP:\n"
692					buf += "	default:\n"
693					buf += "		tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
694					buf += "					port_nexus_ptr);\n"
695				elif proto_ident == "SAS":
696					buf += "	case SCSI_PROTOCOL_SAS:\n"
697					buf += "	default:\n"
698					buf += "		tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
699					buf += "					port_nexus_ptr);\n"
700				elif proto_ident == "iSCSI":
701					buf += "	case SCSI_PROTOCOL_ISCSI:\n"
702					buf += "	default:\n"
703					buf += "		tid = iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
704					buf += "					port_nexus_ptr);\n"
705	
706				buf += "	}\n\n"
707				buf += "	return tid;\n"
708				buf += "}\n\n"
709				bufi += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(struct se_portal_group *,\n"
710				bufi +=	"			const char *, u32 *, char **);\n"
711	
712			if re.search('alloc_fabric_acl\)\(', fo):
713				buf += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *se_tpg)\n"
714				buf += "{\n"
715				buf += "	struct " + fabric_mod_name + "_nacl *nacl;\n\n"
716				buf += "	nacl = kzalloc(sizeof(struct " + fabric_mod_name + "_nacl), GFP_KERNEL);\n"
717				buf += "	if (!nacl) {\n"
718				buf += "		printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_nacl\\n\");\n"
719				buf += "		return NULL;\n"
720				buf += "	}\n\n"
721				buf += "	return &nacl->se_node_acl;\n"
722				buf += "}\n\n"
723				bufi += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *);\n"
724	
725			if re.search('release_fabric_acl\)\(', fo):
726				buf += "void " + fabric_mod_name + "_release_fabric_acl(\n"
727				buf += "	struct se_portal_group *se_tpg,\n"
728				buf += "	struct se_node_acl *se_nacl)\n"
729				buf += "{\n"
730				buf += "	struct " + fabric_mod_name + "_nacl *nacl = container_of(se_nacl,\n"
731				buf += "			struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
732				buf += "	kfree(nacl);\n"
733				buf += "}\n\n"
734				bufi += "void " + fabric_mod_name + "_release_fabric_acl(struct se_portal_group *,\n"
735				bufi +=	"			struct se_node_acl *);\n"
736	
737			if re.search('tpg_get_inst_index\)\(', fo):
738				buf += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *se_tpg)\n"
739				buf += "{\n"
740				buf += "	return 1;\n"
741				buf += "}\n\n"
742				bufi += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *);\n"
743	
744			if re.search('\*release_cmd\)\(', fo):
745				buf += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *se_cmd)\n"
746				buf += "{\n"
747				buf += "	return;\n"
748				buf += "}\n\n"
749				bufi += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *);\n"
750	
751			if re.search('shutdown_session\)\(', fo):
752				buf += "int " + fabric_mod_name + "_shutdown_session(struct se_session *se_sess)\n"
753				buf += "{\n"
754				buf += "	return 0;\n"
755				buf += "}\n\n"
756				bufi += "int " + fabric_mod_name + "_shutdown_session(struct se_session *);\n"
757	
758			if re.search('close_session\)\(', fo):
759				buf += "void " + fabric_mod_name + "_close_session(struct se_session *se_sess)\n"
760				buf += "{\n"
761				buf += "	return;\n"
762				buf += "}\n\n"
763				bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
764	
765			if re.search('sess_get_index\)\(', fo):
766				buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
767				buf += "{\n"
768				buf += "	return 0;\n"
769				buf += "}\n\n"
770				bufi += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *);\n"
771	
772			if re.search('write_pending\)\(', fo):
773				buf += "int " + fabric_mod_name + "_write_pending(struct se_cmd *se_cmd)\n"
774				buf += "{\n"
775				buf += "	return 0;\n"
776				buf += "}\n\n"
777				bufi += "int " + fabric_mod_name + "_write_pending(struct se_cmd *);\n"
778	
779			if re.search('write_pending_status\)\(', fo):
780				buf += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *se_cmd)\n"
781				buf += "{\n"
782				buf += "	return 0;\n"
783				buf += "}\n\n"
784				bufi += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *);\n"
785	
786			if re.search('set_default_node_attributes\)\(', fo):
787				buf += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *nacl)\n"
788				buf += "{\n"
789				buf += "	return;\n"
790				buf += "}\n\n"
791				bufi += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *);\n"
792	
793			if re.search('get_task_tag\)\(', fo):
794				buf += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *se_cmd)\n"
795				buf += "{\n"
796				buf += "	return 0;\n"
797				buf += "}\n\n"
798				bufi += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *);\n"
799	
800			if re.search('get_cmd_state\)\(', fo):
801				buf += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *se_cmd)\n"
802				buf += "{\n"
803				buf += "	return 0;\n"
804				buf += "}\n\n"
805				bufi += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *);\n"
806	
807			if re.search('queue_data_in\)\(', fo):
808				buf += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *se_cmd)\n"
809				buf += "{\n"
810				buf += "	return 0;\n"
811				buf += "}\n\n"
812				bufi += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *);\n"
813	
814			if re.search('queue_status\)\(', fo):
815				buf += "int " + fabric_mod_name + "_queue_status(struct se_cmd *se_cmd)\n"
816				buf += "{\n"
817				buf += "	return 0;\n"
818				buf += "}\n\n"
819				bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
820	
821			if re.search('queue_tm_rsp\)\(', fo):
822				buf += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
823				buf += "{\n"
824				buf += "	return;\n"
825				buf += "}\n\n"
826				bufi += "void " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
827	
828			if re.search('aborted_task\)\(', fo):
829				buf += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *se_cmd)\n"
830				buf += "{\n"
831				buf += "	return;\n"
832				buf += "}\n\n"
833				bufi += "void " + fabric_mod_name + "_aborted_task(struct se_cmd *);\n"
834	
835		ret = p.write(buf)
836		if ret:
837			tcm_mod_err("Unable to write f: " + f)
838	
839		p.close()
840	
841		ret = pi.write(bufi)
842		if ret:
843			tcm_mod_err("Unable to write fi: " + fi)
844	
845		pi.close()
846		return
847	
848	def tcm_mod_build_kbuild(fabric_mod_dir_var, fabric_mod_name):
849	
850		buf = ""
851		f = fabric_mod_dir_var + "/Makefile"
852		print "Writing file: " + f
853	
854		p = open(f, 'w')
855		if not p:
856			tcm_mod_err("Unable to open file: " + f)
857	
858		buf += fabric_mod_name + "-objs			:= " + fabric_mod_name + "_fabric.o \\\n"
859		buf += "					   " + fabric_mod_name + "_configfs.o\n"
860		buf += "obj-$(CONFIG_" + fabric_mod_name.upper() + ")		+= " + fabric_mod_name + ".o\n"
861	
862		ret = p.write(buf)
863		if ret:
864			tcm_mod_err("Unable to write f: " + f)
865	
866		p.close()
867		return
868	
869	def tcm_mod_build_kconfig(fabric_mod_dir_var, fabric_mod_name):
870	
871		buf = ""
872		f = fabric_mod_dir_var + "/Kconfig"
873		print "Writing file: " + f
874	
875		p = open(f, 'w')
876		if not p:
877			tcm_mod_err("Unable to open file: " + f)
878	
879		buf = "config " + fabric_mod_name.upper() + "\n"
880		buf += "	tristate \"" + fabric_mod_name.upper() + " fabric module\"\n"
881		buf += "	depends on TARGET_CORE && CONFIGFS_FS\n"
882		buf += "	default n\n"
883		buf += "	---help---\n"
884		buf += "	Say Y here to enable the " + fabric_mod_name.upper() + " fabric module\n"
885	
886		ret = p.write(buf)
887		if ret:
888			tcm_mod_err("Unable to write f: " + f)
889	
890		p.close()
891		return
892	
893	def tcm_mod_add_kbuild(tcm_dir, fabric_mod_name):
894		buf = "obj-$(CONFIG_" + fabric_mod_name.upper() + ")	+= " + fabric_mod_name.lower() + "/\n"
895		kbuild = tcm_dir + "/drivers/target/Makefile"
896	
897		f = open(kbuild, 'a')
898		f.write(buf)
899		f.close()
900		return
901	
902	def tcm_mod_add_kconfig(tcm_dir, fabric_mod_name):
903		buf = "source \"drivers/target/" + fabric_mod_name.lower() + "/Kconfig\"\n"
904		kconfig = tcm_dir + "/drivers/target/Kconfig"
905	
906		f = open(kconfig, 'a')
907		f.write(buf)
908		f.close()
909		return
910	
911	def main(modname, proto_ident):
912	#	proto_ident = "FC"
913	#	proto_ident = "SAS"
914	#	proto_ident = "iSCSI"
915	
916		tcm_dir = os.getcwd();
917		tcm_dir += "/../../"
918		print "tcm_dir: " + tcm_dir
919		fabric_mod_name = modname
920		fabric_mod_dir = tcm_dir + "drivers/target/" + fabric_mod_name
921		print "Set fabric_mod_name: " + fabric_mod_name
922		print "Set fabric_mod_dir: " + fabric_mod_dir
923		print "Using proto_ident: " + proto_ident
924	
925		if proto_ident != "FC" and proto_ident != "SAS" and proto_ident != "iSCSI":
926			print "Unsupported proto_ident: " + proto_ident
927			sys.exit(1)
928	
929		ret = tcm_mod_create_module_subdir(fabric_mod_dir)
930		if ret:
931			print "tcm_mod_create_module_subdir() failed because module already exists!"
932			sys.exit(1)
933	
934		tcm_mod_build_base_includes(proto_ident, fabric_mod_dir, fabric_mod_name)
935		tcm_mod_scan_fabric_ops(tcm_dir)
936		tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir, fabric_mod_name)
937		tcm_mod_build_configfs(proto_ident, fabric_mod_dir, fabric_mod_name)
938		tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name)
939		tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name)
940	
941		input = raw_input("Would you like to add " + fabric_mod_name + " to drivers/target/Makefile..? [yes,no]: ")
942		if input == "yes" or input == "y":
943			tcm_mod_add_kbuild(tcm_dir, fabric_mod_name)
944	
945		input = raw_input("Would you like to add " + fabric_mod_name + " to drivers/target/Kconfig..? [yes,no]: ")
946		if input == "yes" or input == "y":
947			tcm_mod_add_kconfig(tcm_dir, fabric_mod_name)
948	
949		return
950	
951	parser = optparse.OptionParser()
952	parser.add_option('-m', '--modulename', help='Module name', dest='modname',
953			action='store', nargs=1, type='string')
954	parser.add_option('-p', '--protoident', help='Protocol Ident', dest='protoident',
955			action='store', nargs=1, type='string')
956	
957	(opts, args) = parser.parse_args()
958	
959	mandatories = ['modname', 'protoident']
960	for m in mandatories:
961		if not opts.__dict__[m]:
962			print "mandatory option is missing\n"
963			parser.print_help()
964			exit(-1)
965	
966	if __name__ == "__main__":
967	
968		main(str(opts.modname), opts.protoident)
Hide Line Numbers
About Kernel Documentation Linux Kernel Contact Linux Resources Linux Blog

Information is copyright its respective author. All material is available from the Linux Kernel Source distributed under a GPL License. This page is provided as a free service by mjmwired.net.