Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tcm_mod_builder.py
Go to the documentation of this file.
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: [email protected]
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 += "/* Local pointer to allocated TCM configfs fabric module */\n"
241  buf += "struct target_fabric_configfs *" + fabric_mod_name + "_fabric_configfs;\n\n"
242 
243  buf += "static struct se_node_acl *" + fabric_mod_name + "_make_nodeacl(\n"
244  buf += " struct se_portal_group *se_tpg,\n"
245  buf += " struct config_group *group,\n"
246  buf += " const char *name)\n"
247  buf += "{\n"
248  buf += " struct se_node_acl *se_nacl, *se_nacl_new;\n"
249  buf += " struct " + fabric_mod_name + "_nacl *nacl;\n"
250 
251  if proto_ident == "FC" or proto_ident == "SAS":
252  buf += " u64 wwpn = 0;\n"
253 
254  buf += " u32 nexus_depth;\n\n"
255  buf += " /* " + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
256  buf += " return ERR_PTR(-EINVAL); */\n"
257  buf += " se_nacl_new = " + fabric_mod_name + "_alloc_fabric_acl(se_tpg);\n"
258  buf += " if (!se_nacl_new)\n"
259  buf += " return ERR_PTR(-ENOMEM);\n"
260  buf += "//#warning FIXME: Hardcoded nexus depth in " + fabric_mod_name + "_make_nodeacl()\n"
261  buf += " nexus_depth = 1;\n"
262  buf += " /*\n"
263  buf += " * se_nacl_new may be released by core_tpg_add_initiator_node_acl()\n"
264  buf += " * when converting a NodeACL from demo mode -> explict\n"
265  buf += " */\n"
266  buf += " se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,\n"
267  buf += " name, nexus_depth);\n"
268  buf += " if (IS_ERR(se_nacl)) {\n"
269  buf += " " + fabric_mod_name + "_release_fabric_acl(se_tpg, se_nacl_new);\n"
270  buf += " return se_nacl;\n"
271  buf += " }\n"
272  buf += " /*\n"
273  buf += " * Locate our struct " + fabric_mod_name + "_nacl and set the FC Nport WWPN\n"
274  buf += " */\n"
275  buf += " nacl = container_of(se_nacl, struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
276 
277  if proto_ident == "FC" or proto_ident == "SAS":
278  buf += " nacl->" + fabric_mod_init_port + "_wwpn = wwpn;\n"
279 
280  buf += " /* " + fabric_mod_name + "_format_wwn(&nacl->" + fabric_mod_init_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n"
281  buf += " return se_nacl;\n"
282  buf += "}\n\n"
283  buf += "static void " + fabric_mod_name + "_drop_nodeacl(struct se_node_acl *se_acl)\n"
284  buf += "{\n"
285  buf += " struct " + fabric_mod_name + "_nacl *nacl = container_of(se_acl,\n"
286  buf += " struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
287  buf += " core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1);\n"
288  buf += " kfree(nacl);\n"
289  buf += "}\n\n"
290 
291  buf += "static struct se_portal_group *" + fabric_mod_name + "_make_tpg(\n"
292  buf += " struct se_wwn *wwn,\n"
293  buf += " struct config_group *group,\n"
294  buf += " const char *name)\n"
295  buf += "{\n"
296  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + "*" + fabric_mod_port + " = container_of(wwn,\n"
297  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n\n"
298  buf += " struct " + fabric_mod_name + "_tpg *tpg;\n"
299  buf += " unsigned long tpgt;\n"
300  buf += " int ret;\n\n"
301  buf += " if (strstr(name, \"tpgt_\") != name)\n"
302  buf += " return ERR_PTR(-EINVAL);\n"
303  buf += " if (strict_strtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)\n"
304  buf += " return ERR_PTR(-EINVAL);\n\n"
305  buf += " tpg = kzalloc(sizeof(struct " + fabric_mod_name + "_tpg), GFP_KERNEL);\n"
306  buf += " if (!tpg) {\n"
307  buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_tpg\");\n"
308  buf += " return ERR_PTR(-ENOMEM);\n"
309  buf += " }\n"
310  buf += " tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n"
311  buf += " tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n"
312  buf += " ret = core_tpg_register(&" + fabric_mod_name + "_fabric_configfs->tf_ops, wwn,\n"
313  buf += " &tpg->se_tpg, (void *)tpg,\n"
314  buf += " TRANSPORT_TPG_TYPE_NORMAL);\n"
315  buf += " if (ret < 0) {\n"
316  buf += " kfree(tpg);\n"
317  buf += " return NULL;\n"
318  buf += " }\n"
319  buf += " return &tpg->se_tpg;\n"
320  buf += "}\n\n"
321  buf += "static void " + fabric_mod_name + "_drop_tpg(struct se_portal_group *se_tpg)\n"
322  buf += "{\n"
323  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
324  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n\n"
325  buf += " core_tpg_deregister(se_tpg);\n"
326  buf += " kfree(tpg);\n"
327  buf += "}\n\n"
328 
329  buf += "static struct se_wwn *" + fabric_mod_name + "_make_" + fabric_mod_port + "(\n"
330  buf += " struct target_fabric_configfs *tf,\n"
331  buf += " struct config_group *group,\n"
332  buf += " const char *name)\n"
333  buf += "{\n"
334  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + ";\n"
335 
336  if proto_ident == "FC" or proto_ident == "SAS":
337  buf += " u64 wwpn = 0;\n\n"
338 
339  buf += " /* if (" + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
340  buf += " return ERR_PTR(-EINVAL); */\n\n"
341  buf += " " + fabric_mod_port + " = kzalloc(sizeof(struct " + fabric_mod_name + "_" + fabric_mod_port + "), GFP_KERNEL);\n"
342  buf += " if (!" + fabric_mod_port + ") {\n"
343  buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_" + fabric_mod_port + "\");\n"
344  buf += " return ERR_PTR(-ENOMEM);\n"
345  buf += " }\n"
346 
347  if proto_ident == "FC" or proto_ident == "SAS":
348  buf += " " + fabric_mod_port + "->" + fabric_mod_port + "_wwpn = wwpn;\n"
349 
350  buf += " /* " + fabric_mod_name + "_format_wwn(&" + fabric_mod_port + "->" + fabric_mod_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n"
351  buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_wwn;\n"
352  buf += "}\n\n"
353  buf += "static void " + fabric_mod_name + "_drop_" + fabric_mod_port + "(struct se_wwn *wwn)\n"
354  buf += "{\n"
355  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = container_of(wwn,\n"
356  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n"
357  buf += " kfree(" + fabric_mod_port + ");\n"
358  buf += "}\n\n"
359  buf += "static ssize_t " + fabric_mod_name + "_wwn_show_attr_version(\n"
360  buf += " struct target_fabric_configfs *tf,\n"
361  buf += " char *page)\n"
362  buf += "{\n"
363  buf += " return sprintf(page, \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
364  buf += " \"on \"UTS_RELEASE\"\\n\", " + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
365  buf += " utsname()->machine);\n"
366  buf += "}\n\n"
367  buf += "TF_WWN_ATTR_RO(" + fabric_mod_name + ", version);\n\n"
368  buf += "static struct configfs_attribute *" + fabric_mod_name + "_wwn_attrs[] = {\n"
369  buf += " &" + fabric_mod_name + "_wwn_version.attr,\n"
370  buf += " NULL,\n"
371  buf += "};\n\n"
372 
373  buf += "static struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
374  buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n"
375  buf += " .get_fabric_proto_ident = " + fabric_mod_name + "_get_fabric_proto_ident,\n"
376  buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n"
377  buf += " .tpg_get_tag = " + fabric_mod_name + "_get_tag,\n"
378  buf += " .tpg_get_default_depth = " + fabric_mod_name + "_get_default_depth,\n"
379  buf += " .tpg_get_pr_transport_id = " + fabric_mod_name + "_get_pr_transport_id,\n"
380  buf += " .tpg_get_pr_transport_id_len = " + fabric_mod_name + "_get_pr_transport_id_len,\n"
381  buf += " .tpg_parse_pr_out_transport_id = " + fabric_mod_name + "_parse_pr_out_transport_id,\n"
382  buf += " .tpg_check_demo_mode = " + fabric_mod_name + "_check_false,\n"
383  buf += " .tpg_check_demo_mode_cache = " + fabric_mod_name + "_check_true,\n"
384  buf += " .tpg_check_demo_mode_write_protect = " + fabric_mod_name + "_check_true,\n"
385  buf += " .tpg_check_prod_mode_write_protect = " + fabric_mod_name + "_check_false,\n"
386  buf += " .tpg_alloc_fabric_acl = " + fabric_mod_name + "_alloc_fabric_acl,\n"
387  buf += " .tpg_release_fabric_acl = " + fabric_mod_name + "_release_fabric_acl,\n"
388  buf += " .tpg_get_inst_index = " + fabric_mod_name + "_tpg_get_inst_index,\n"
389  buf += " .release_cmd = " + fabric_mod_name + "_release_cmd,\n"
390  buf += " .shutdown_session = " + fabric_mod_name + "_shutdown_session,\n"
391  buf += " .close_session = " + fabric_mod_name + "_close_session,\n"
392  buf += " .stop_session = " + fabric_mod_name + "_stop_session,\n"
393  buf += " .fall_back_to_erl0 = " + fabric_mod_name + "_reset_nexus,\n"
394  buf += " .sess_logged_in = " + fabric_mod_name + "_sess_logged_in,\n"
395  buf += " .sess_get_index = " + fabric_mod_name + "_sess_get_index,\n"
396  buf += " .sess_get_initiator_sid = NULL,\n"
397  buf += " .write_pending = " + fabric_mod_name + "_write_pending,\n"
398  buf += " .write_pending_status = " + fabric_mod_name + "_write_pending_status,\n"
399  buf += " .set_default_node_attributes = " + fabric_mod_name + "_set_default_node_attrs,\n"
400  buf += " .get_task_tag = " + fabric_mod_name + "_get_task_tag,\n"
401  buf += " .get_cmd_state = " + fabric_mod_name + "_get_cmd_state,\n"
402  buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n"
403  buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n"
404  buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n"
405  buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n"
406  buf += " /*\n"
407  buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
408  buf += " */\n"
409  buf += " .fabric_make_wwn = " + fabric_mod_name + "_make_" + fabric_mod_port + ",\n"
410  buf += " .fabric_drop_wwn = " + fabric_mod_name + "_drop_" + fabric_mod_port + ",\n"
411  buf += " .fabric_make_tpg = " + fabric_mod_name + "_make_tpg,\n"
412  buf += " .fabric_drop_tpg = " + fabric_mod_name + "_drop_tpg,\n"
413  buf += " .fabric_post_link = NULL,\n"
414  buf += " .fabric_pre_unlink = NULL,\n"
415  buf += " .fabric_make_np = NULL,\n"
416  buf += " .fabric_drop_np = NULL,\n"
417  buf += " .fabric_make_nodeacl = " + fabric_mod_name + "_make_nodeacl,\n"
418  buf += " .fabric_drop_nodeacl = " + fabric_mod_name + "_drop_nodeacl,\n"
419  buf += "};\n\n"
420 
421  buf += "static int " + fabric_mod_name + "_register_configfs(void)\n"
422  buf += "{\n"
423  buf += " struct target_fabric_configfs *fabric;\n"
424  buf += " int ret;\n\n"
425  buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
426  buf += " \" on \"UTS_RELEASE\"\\n\"," + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
427  buf += " utsname()->machine);\n"
428  buf += " /*\n"
429  buf += " * Register the top level struct config_item_type with TCM core\n"
430  buf += " */\n"
431  buf += " fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name[4:] + "\");\n"
432  buf += " if (IS_ERR(fabric)) {\n"
433  buf += " printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
434  buf += " return PTR_ERR(fabric);\n"
435  buf += " }\n"
436  buf += " /*\n"
437  buf += " * Setup fabric->tf_ops from our local " + fabric_mod_name + "_ops\n"
438  buf += " */\n"
439  buf += " fabric->tf_ops = " + fabric_mod_name + "_ops;\n"
440  buf += " /*\n"
441  buf += " * Setup default attribute lists for various fabric->tf_cit_tmpl\n"
442  buf += " */\n"
443  buf += " TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
444  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = NULL;\n"
445  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;\n"
446  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;\n"
447  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;\n"
448  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;\n"
449  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;\n"
450  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;\n"
451  buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;\n"
452  buf += " /*\n"
453  buf += " * Register the fabric for use within TCM\n"
454  buf += " */\n"
455  buf += " ret = target_fabric_configfs_register(fabric);\n"
456  buf += " if (ret < 0) {\n"
457  buf += " printk(KERN_ERR \"target_fabric_configfs_register() failed\"\n"
458  buf += " \" for " + fabric_mod_name.upper() + "\\n\");\n"
459  buf += " return ret;\n"
460  buf += " }\n"
461  buf += " /*\n"
462  buf += " * Setup our local pointer to *fabric\n"
463  buf += " */\n"
464  buf += " " + fabric_mod_name + "_fabric_configfs = fabric;\n"
465  buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Set fabric -> " + fabric_mod_name + "_fabric_configfs\\n\");\n"
466  buf += " return 0;\n"
467  buf += "};\n\n"
468  buf += "static void __exit " + fabric_mod_name + "_deregister_configfs(void)\n"
469  buf += "{\n"
470  buf += " if (!" + fabric_mod_name + "_fabric_configfs)\n"
471  buf += " return;\n\n"
472  buf += " target_fabric_configfs_deregister(" + fabric_mod_name + "_fabric_configfs);\n"
473  buf += " " + fabric_mod_name + "_fabric_configfs = NULL;\n"
474  buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Cleared " + fabric_mod_name + "_fabric_configfs\\n\");\n"
475  buf += "};\n\n"
476 
477  buf += "static int __init " + fabric_mod_name + "_init(void)\n"
478  buf += "{\n"
479  buf += " int ret;\n\n"
480  buf += " ret = " + fabric_mod_name + "_register_configfs();\n"
481  buf += " if (ret < 0)\n"
482  buf += " return ret;\n\n"
483  buf += " return 0;\n"
484  buf += "};\n\n"
485  buf += "static void __exit " + fabric_mod_name + "_exit(void)\n"
486  buf += "{\n"
487  buf += " " + fabric_mod_name + "_deregister_configfs();\n"
488  buf += "};\n\n"
489 
490  buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n"
491  buf += "MODULE_LICENSE(\"GPL\");\n"
492  buf += "module_init(" + fabric_mod_name + "_init);\n"
493  buf += "module_exit(" + fabric_mod_name + "_exit);\n"
494 
495  ret = p.write(buf)
496  if ret:
497  tcm_mod_err("Unable to write f: " + f)
498 
499  p.close()
500 
501  return
502 
504 
505  fabric_ops_api = tcm_dir + "include/target/target_core_fabric.h"
506 
507  print "Using tcm_mod_scan_fabric_ops: " + fabric_ops_api
508  process_fo = 0;
509 
510  p = open(fabric_ops_api, 'r')
511 
512  line = p.readline()
513  while line:
514  if process_fo == 0 and re.search('struct target_core_fabric_ops {', line):
515  line = p.readline()
516  continue
517 
518  if process_fo == 0:
519  process_fo = 1;
520  line = p.readline()
521  # Search for function pointer
522  if not re.search('\(\*', line):
523  continue
524 
525  fabric_ops.append(line.rstrip())
526  continue
527 
528  line = p.readline()
529  # Search for function pointer
530  if not re.search('\(\*', line):
531  continue
532 
533  fabric_ops.append(line.rstrip())
534 
535  p.close()
536  return
537 
538 def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
539  buf = ""
540  bufi = ""
541 
542  f = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.c"
543  print "Writing file: " + f
544 
545  p = open(f, 'w')
546  if not p:
547  tcm_mod_err("Unable to open file: " + f)
548 
549  fi = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.h"
550  print "Writing file: " + fi
551 
552  pi = open(fi, 'w')
553  if not pi:
554  tcm_mod_err("Unable to open file: " + fi)
555 
556  buf = "#include <linux/slab.h>\n"
557  buf += "#include <linux/kthread.h>\n"
558  buf += "#include <linux/types.h>\n"
559  buf += "#include <linux/list.h>\n"
560  buf += "#include <linux/types.h>\n"
561  buf += "#include <linux/string.h>\n"
562  buf += "#include <linux/ctype.h>\n"
563  buf += "#include <asm/unaligned.h>\n"
564  buf += "#include <scsi/scsi.h>\n"
565  buf += "#include <scsi/scsi_host.h>\n"
566  buf += "#include <scsi/scsi_device.h>\n"
567  buf += "#include <scsi/scsi_cmnd.h>\n"
568  buf += "#include <scsi/libfc.h>\n\n"
569  buf += "#include <target/target_core_base.h>\n"
570  buf += "#include <target/target_core_fabric.h>\n"
571  buf += "#include <target/target_core_configfs.h>\n\n"
572  buf += "#include \"" + fabric_mod_name + "_base.h\"\n"
573  buf += "#include \"" + fabric_mod_name + "_fabric.h\"\n\n"
574 
575  buf += "int " + fabric_mod_name + "_check_true(struct se_portal_group *se_tpg)\n"
576  buf += "{\n"
577  buf += " return 1;\n"
578  buf += "}\n\n"
579  bufi += "int " + fabric_mod_name + "_check_true(struct se_portal_group *);\n"
580 
581  buf += "int " + fabric_mod_name + "_check_false(struct se_portal_group *se_tpg)\n"
582  buf += "{\n"
583  buf += " return 0;\n"
584  buf += "}\n\n"
585  bufi += "int " + fabric_mod_name + "_check_false(struct se_portal_group *);\n"
586 
587  total_fabric_ops = len(fabric_ops)
588  i = 0
589 
590  while i < total_fabric_ops:
591  fo = fabric_ops[i]
592  i += 1
593 # print "fabric_ops: " + fo
594 
595  if re.search('get_fabric_name', fo):
596  buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
597  buf += "{\n"
598  buf += " return \"" + fabric_mod_name[4:] + "\";\n"
599  buf += "}\n\n"
600  bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
601  continue
602 
603  if re.search('get_fabric_proto_ident', fo):
604  buf += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *se_tpg)\n"
605  buf += "{\n"
606  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
607  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
608  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
609  buf += " u8 proto_id;\n\n"
610  buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
611  if proto_ident == "FC":
612  buf += " case SCSI_PROTOCOL_FCP:\n"
613  buf += " default:\n"
614  buf += " proto_id = fc_get_fabric_proto_ident(se_tpg);\n"
615  buf += " break;\n"
616  elif proto_ident == "SAS":
617  buf += " case SCSI_PROTOCOL_SAS:\n"
618  buf += " default:\n"
619  buf += " proto_id = sas_get_fabric_proto_ident(se_tpg);\n"
620  buf += " break;\n"
621  elif proto_ident == "iSCSI":
622  buf += " case SCSI_PROTOCOL_ISCSI:\n"
623  buf += " default:\n"
624  buf += " proto_id = iscsi_get_fabric_proto_ident(se_tpg);\n"
625  buf += " break;\n"
626 
627  buf += " }\n\n"
628  buf += " return proto_id;\n"
629  buf += "}\n\n"
630  bufi += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *);\n"
631 
632  if re.search('get_wwn', fo):
633  buf += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *se_tpg)\n"
634  buf += "{\n"
635  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
636  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
637  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n\n"
638  buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_name[0];\n"
639  buf += "}\n\n"
640  bufi += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *);\n"
641 
642  if re.search('get_tag', fo):
643  buf += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *se_tpg)\n"
644  buf += "{\n"
645  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
646  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
647  buf += " return tpg->" + fabric_mod_port + "_tpgt;\n"
648  buf += "}\n\n"
649  bufi += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *);\n"
650 
651  if re.search('get_default_depth', fo):
652  buf += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *se_tpg)\n"
653  buf += "{\n"
654  buf += " return 1;\n"
655  buf += "}\n\n"
656  bufi += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *);\n"
657 
658  if re.search('get_pr_transport_id\)\(', fo):
659  buf += "u32 " + fabric_mod_name + "_get_pr_transport_id(\n"
660  buf += " struct se_portal_group *se_tpg,\n"
661  buf += " struct se_node_acl *se_nacl,\n"
662  buf += " struct t10_pr_registration *pr_reg,\n"
663  buf += " int *format_code,\n"
664  buf += " unsigned char *buf)\n"
665  buf += "{\n"
666  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
667  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
668  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
669  buf += " int ret = 0;\n\n"
670  buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
671  if proto_ident == "FC":
672  buf += " case SCSI_PROTOCOL_FCP:\n"
673  buf += " default:\n"
674  buf += " ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
675  buf += " format_code, buf);\n"
676  buf += " break;\n"
677  elif proto_ident == "SAS":
678  buf += " case SCSI_PROTOCOL_SAS:\n"
679  buf += " default:\n"
680  buf += " ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
681  buf += " format_code, buf);\n"
682  buf += " break;\n"
683  elif proto_ident == "iSCSI":
684  buf += " case SCSI_PROTOCOL_ISCSI:\n"
685  buf += " default:\n"
686  buf += " ret = iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
687  buf += " format_code, buf);\n"
688  buf += " break;\n"
689 
690  buf += " }\n\n"
691  buf += " return ret;\n"
692  buf += "}\n\n"
693  bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id(struct se_portal_group *,\n"
694  bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
695  bufi += " int *, unsigned char *);\n"
696 
697  if re.search('get_pr_transport_id_len\)\(', fo):
698  buf += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(\n"
699  buf += " struct se_portal_group *se_tpg,\n"
700  buf += " struct se_node_acl *se_nacl,\n"
701  buf += " struct t10_pr_registration *pr_reg,\n"
702  buf += " int *format_code)\n"
703  buf += "{\n"
704  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
705  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
706  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
707  buf += " int ret = 0;\n\n"
708  buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
709  if proto_ident == "FC":
710  buf += " case SCSI_PROTOCOL_FCP:\n"
711  buf += " default:\n"
712  buf += " ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
713  buf += " format_code);\n"
714  buf += " break;\n"
715  elif proto_ident == "SAS":
716  buf += " case SCSI_PROTOCOL_SAS:\n"
717  buf += " default:\n"
718  buf += " ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
719  buf += " format_code);\n"
720  buf += " break;\n"
721  elif proto_ident == "iSCSI":
722  buf += " case SCSI_PROTOCOL_ISCSI:\n"
723  buf += " default:\n"
724  buf += " ret = iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
725  buf += " format_code);\n"
726  buf += " break;\n"
727 
728 
729  buf += " }\n\n"
730  buf += " return ret;\n"
731  buf += "}\n\n"
732  bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(struct se_portal_group *,\n"
733  bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
734  bufi += " int *);\n"
735 
736  if re.search('parse_pr_out_transport_id\)\(', fo):
737  buf += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(\n"
738  buf += " struct se_portal_group *se_tpg,\n"
739  buf += " const char *buf,\n"
740  buf += " u32 *out_tid_len,\n"
741  buf += " char **port_nexus_ptr)\n"
742  buf += "{\n"
743  buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
744  buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
745  buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
746  buf += " char *tid = NULL;\n\n"
747  buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
748  if proto_ident == "FC":
749  buf += " case SCSI_PROTOCOL_FCP:\n"
750  buf += " default:\n"
751  buf += " tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
752  buf += " port_nexus_ptr);\n"
753  elif proto_ident == "SAS":
754  buf += " case SCSI_PROTOCOL_SAS:\n"
755  buf += " default:\n"
756  buf += " tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
757  buf += " port_nexus_ptr);\n"
758  elif proto_ident == "iSCSI":
759  buf += " case SCSI_PROTOCOL_ISCSI:\n"
760  buf += " default:\n"
761  buf += " tid = iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
762  buf += " port_nexus_ptr);\n"
763 
764  buf += " }\n\n"
765  buf += " return tid;\n"
766  buf += "}\n\n"
767  bufi += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(struct se_portal_group *,\n"
768  bufi += " const char *, u32 *, char **);\n"
769 
770  if re.search('alloc_fabric_acl\)\(', fo):
771  buf += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *se_tpg)\n"
772  buf += "{\n"
773  buf += " struct " + fabric_mod_name + "_nacl *nacl;\n\n"
774  buf += " nacl = kzalloc(sizeof(struct " + fabric_mod_name + "_nacl), GFP_KERNEL);\n"
775  buf += " if (!nacl) {\n"
776  buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_nacl\\n\");\n"
777  buf += " return NULL;\n"
778  buf += " }\n\n"
779  buf += " return &nacl->se_node_acl;\n"
780  buf += "}\n\n"
781  bufi += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *);\n"
782 
783  if re.search('release_fabric_acl\)\(', fo):
784  buf += "void " + fabric_mod_name + "_release_fabric_acl(\n"
785  buf += " struct se_portal_group *se_tpg,\n"
786  buf += " struct se_node_acl *se_nacl)\n"
787  buf += "{\n"
788  buf += " struct " + fabric_mod_name + "_nacl *nacl = container_of(se_nacl,\n"
789  buf += " struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
790  buf += " kfree(nacl);\n"
791  buf += "}\n\n"
792  bufi += "void " + fabric_mod_name + "_release_fabric_acl(struct se_portal_group *,\n"
793  bufi += " struct se_node_acl *);\n"
794 
795  if re.search('tpg_get_inst_index\)\(', fo):
796  buf += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *se_tpg)\n"
797  buf += "{\n"
798  buf += " return 1;\n"
799  buf += "}\n\n"
800  bufi += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *);\n"
801 
802  if re.search('\*release_cmd\)\(', fo):
803  buf += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *se_cmd)\n"
804  buf += "{\n"
805  buf += " return;\n"
806  buf += "}\n\n"
807  bufi += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *);\n"
808 
809  if re.search('shutdown_session\)\(', fo):
810  buf += "int " + fabric_mod_name + "_shutdown_session(struct se_session *se_sess)\n"
811  buf += "{\n"
812  buf += " return 0;\n"
813  buf += "}\n\n"
814  bufi += "int " + fabric_mod_name + "_shutdown_session(struct se_session *);\n"
815 
816  if re.search('close_session\)\(', fo):
817  buf += "void " + fabric_mod_name + "_close_session(struct se_session *se_sess)\n"
818  buf += "{\n"
819  buf += " return;\n"
820  buf += "}\n\n"
821  bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
822 
823  if re.search('stop_session\)\(', fo):
824  buf += "void " + fabric_mod_name + "_stop_session(struct se_session *se_sess, int sess_sleep , int conn_sleep)\n"
825  buf += "{\n"
826  buf += " return;\n"
827  buf += "}\n\n"
828  bufi += "void " + fabric_mod_name + "_stop_session(struct se_session *, int, int);\n"
829 
830  if re.search('fall_back_to_erl0\)\(', fo):
831  buf += "void " + fabric_mod_name + "_reset_nexus(struct se_session *se_sess)\n"
832  buf += "{\n"
833  buf += " return;\n"
834  buf += "}\n\n"
835  bufi += "void " + fabric_mod_name + "_reset_nexus(struct se_session *);\n"
836 
837  if re.search('sess_logged_in\)\(', fo):
838  buf += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *se_sess)\n"
839  buf += "{\n"
840  buf += " return 0;\n"
841  buf += "}\n\n"
842  bufi += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *);\n"
843 
844  if re.search('sess_get_index\)\(', fo):
845  buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
846  buf += "{\n"
847  buf += " return 0;\n"
848  buf += "}\n\n"
849  bufi += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *);\n"
850 
851  if re.search('write_pending\)\(', fo):
852  buf += "int " + fabric_mod_name + "_write_pending(struct se_cmd *se_cmd)\n"
853  buf += "{\n"
854  buf += " return 0;\n"
855  buf += "}\n\n"
856  bufi += "int " + fabric_mod_name + "_write_pending(struct se_cmd *);\n"
857 
858  if re.search('write_pending_status\)\(', fo):
859  buf += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *se_cmd)\n"
860  buf += "{\n"
861  buf += " return 0;\n"
862  buf += "}\n\n"
863  bufi += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *);\n"
864 
865  if re.search('set_default_node_attributes\)\(', fo):
866  buf += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *nacl)\n"
867  buf += "{\n"
868  buf += " return;\n"
869  buf += "}\n\n"
870  bufi += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *);\n"
871 
872  if re.search('get_task_tag\)\(', fo):
873  buf += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *se_cmd)\n"
874  buf += "{\n"
875  buf += " return 0;\n"
876  buf += "}\n\n"
877  bufi += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *);\n"
878 
879  if re.search('get_cmd_state\)\(', fo):
880  buf += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *se_cmd)\n"
881  buf += "{\n"
882  buf += " return 0;\n"
883  buf += "}\n\n"
884  bufi += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *);\n"
885 
886  if re.search('queue_data_in\)\(', fo):
887  buf += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *se_cmd)\n"
888  buf += "{\n"
889  buf += " return 0;\n"
890  buf += "}\n\n"
891  bufi += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *);\n"
892 
893  if re.search('queue_status\)\(', fo):
894  buf += "int " + fabric_mod_name + "_queue_status(struct se_cmd *se_cmd)\n"
895  buf += "{\n"
896  buf += " return 0;\n"
897  buf += "}\n\n"
898  bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
899 
900  if re.search('queue_tm_rsp\)\(', fo):
901  buf += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
902  buf += "{\n"
903  buf += " return 0;\n"
904  buf += "}\n\n"
905  bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
906 
907  if re.search('is_state_remove\)\(', fo):
908  buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
909  buf += "{\n"
910  buf += " return 0;\n"
911  buf += "}\n\n"
912  bufi += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *);\n"
913 
914 
915  ret = p.write(buf)
916  if ret:
917  tcm_mod_err("Unable to write f: " + f)
918 
919  p.close()
920 
921  ret = pi.write(bufi)
922  if ret:
923  tcm_mod_err("Unable to write fi: " + fi)
924 
925  pi.close()
926  return
927 
928 def tcm_mod_build_kbuild(fabric_mod_dir_var, fabric_mod_name):
929 
930  buf = ""
931  f = fabric_mod_dir_var + "/Makefile"
932  print "Writing file: " + f
933 
934  p = open(f, 'w')
935  if not p:
936  tcm_mod_err("Unable to open file: " + f)
937 
938  buf += fabric_mod_name + "-objs := " + fabric_mod_name + "_fabric.o \\\n"
939  buf += " " + fabric_mod_name + "_configfs.o\n"
940  buf += "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name + ".o\n"
941 
942  ret = p.write(buf)
943  if ret:
944  tcm_mod_err("Unable to write f: " + f)
945 
946  p.close()
947  return
948 
949 def tcm_mod_build_kconfig(fabric_mod_dir_var, fabric_mod_name):
950 
951  buf = ""
952  f = fabric_mod_dir_var + "/Kconfig"
953  print "Writing file: " + f
954 
955  p = open(f, 'w')
956  if not p:
957  tcm_mod_err("Unable to open file: " + f)
958 
959  buf = "config " + fabric_mod_name.upper() + "\n"
960  buf += " tristate \"" + fabric_mod_name.upper() + " fabric module\"\n"
961  buf += " depends on TARGET_CORE && CONFIGFS_FS\n"
962  buf += " default n\n"
963  buf += " ---help---\n"
964  buf += " Say Y here to enable the " + fabric_mod_name.upper() + " fabric module\n"
965 
966  ret = p.write(buf)
967  if ret:
968  tcm_mod_err("Unable to write f: " + f)
969 
970  p.close()
971  return
972 
973 def tcm_mod_add_kbuild(tcm_dir, fabric_mod_name):
974  buf = "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name.lower() + "/\n"
975  kbuild = tcm_dir + "/drivers/target/Makefile"
976 
977  f = open(kbuild, 'a')
978  f.write(buf)
979  f.close()
980  return
981 
982 def tcm_mod_add_kconfig(tcm_dir, fabric_mod_name):
983  buf = "source \"drivers/target/" + fabric_mod_name.lower() + "/Kconfig\"\n"
984  kconfig = tcm_dir + "/drivers/target/Kconfig"
985 
986  f = open(kconfig, 'a')
987  f.write(buf)
988  f.close()
989  return
990 
991 def main(modname, proto_ident):
992 # proto_ident = "FC"
993 # proto_ident = "SAS"
994 # proto_ident = "iSCSI"
995 
996  tcm_dir = os.getcwd();
997  tcm_dir += "/../../"
998  print "tcm_dir: " + tcm_dir
999  fabric_mod_name = modname
1000  fabric_mod_dir = tcm_dir + "drivers/target/" + fabric_mod_name
1001  print "Set fabric_mod_name: " + fabric_mod_name
1002  print "Set fabric_mod_dir: " + fabric_mod_dir
1003  print "Using proto_ident: " + proto_ident
1004 
1005  if proto_ident != "FC" and proto_ident != "SAS" and proto_ident != "iSCSI":
1006  print "Unsupported proto_ident: " + proto_ident
1007  sys.exit(1)
1008 
1009  ret = tcm_mod_create_module_subdir(fabric_mod_dir)
1010  if ret:
1011  print "tcm_mod_create_module_subdir() failed because module already exists!"
1012  sys.exit(1)
1013 
1014  tcm_mod_build_base_includes(proto_ident, fabric_mod_dir, fabric_mod_name)
1015  tcm_mod_scan_fabric_ops(tcm_dir)
1016  tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir, fabric_mod_name)
1017  tcm_mod_build_configfs(proto_ident, fabric_mod_dir, fabric_mod_name)
1018  tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name)
1019  tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name)
1020 
1021  input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Makefile..? [yes,no]: ")
1022  if input == "yes" or input == "y":
1023  tcm_mod_add_kbuild(tcm_dir, fabric_mod_name)
1024 
1025  input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Kconfig..? [yes,no]: ")
1026  if input == "yes" or input == "y":
1027  tcm_mod_add_kconfig(tcm_dir, fabric_mod_name)
1028 
1029  return
1030 
1031 parser = optparse.OptionParser()
1032 parser.add_option('-m', '--modulename', help='Module name', dest='modname',
1033  action='store', nargs=1, type='string')
1034 parser.add_option('-p', '--protoident', help='Protocol Ident', dest='protoident',
1035  action='store', nargs=1, type='string')
1036 
1037 (opts, args) = parser.parse_args()
1038 
1039 mandatories = ['modname', 'protoident']
1040 for m in mandatories:
1041  if not opts.__dict__[m]:
1042  print "mandatory option is missing\n"
1043  parser.print_help()
1044  exit(-1)
1045 
1046 if __name__ == "__main__":
1047 
1048  main(str(opts.modname), opts.protoident)