tcm_mod_builder.py 31 KB

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