aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/DocBook/80211.tmpl21
-rw-r--r--Documentation/filesystems/Locking2
-rwxr-xr-xDocumentation/target/tcm_mod_builder.py1094
-rw-r--r--Documentation/target/tcm_mod_builder.txt145
4 files changed, 1256 insertions, 6 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl
index 03641a08e275..8906648f962b 100644
--- a/Documentation/DocBook/80211.tmpl
+++ b/Documentation/DocBook/80211.tmpl
@@ -268,10 +268,6 @@
268!Finclude/net/mac80211.h ieee80211_ops 268!Finclude/net/mac80211.h ieee80211_ops
269!Finclude/net/mac80211.h ieee80211_alloc_hw 269!Finclude/net/mac80211.h ieee80211_alloc_hw
270!Finclude/net/mac80211.h ieee80211_register_hw 270!Finclude/net/mac80211.h ieee80211_register_hw
271!Finclude/net/mac80211.h ieee80211_get_tx_led_name
272!Finclude/net/mac80211.h ieee80211_get_rx_led_name
273!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
274!Finclude/net/mac80211.h ieee80211_get_radio_led_name
275!Finclude/net/mac80211.h ieee80211_unregister_hw 271!Finclude/net/mac80211.h ieee80211_unregister_hw
276!Finclude/net/mac80211.h ieee80211_free_hw 272!Finclude/net/mac80211.h ieee80211_free_hw
277 </chapter> 273 </chapter>
@@ -382,6 +378,23 @@
382 </para> 378 </para>
383 </partintro> 379 </partintro>
384 380
381 <chapter id="led-support">
382 <title>LED support</title>
383 <para>
384 Mac80211 supports various ways of blinking LEDs. Wherever possible,
385 device LEDs should be exposed as LED class devices and hooked up to
386 the appropriate trigger, which will then be triggered appropriately
387 by mac80211.
388 </para>
389!Finclude/net/mac80211.h ieee80211_get_tx_led_name
390!Finclude/net/mac80211.h ieee80211_get_rx_led_name
391!Finclude/net/mac80211.h ieee80211_get_assoc_led_name
392!Finclude/net/mac80211.h ieee80211_get_radio_led_name
393!Finclude/net/mac80211.h ieee80211_tpt_blink
394!Finclude/net/mac80211.h ieee80211_tpt_led_trigger_flags
395!Finclude/net/mac80211.h ieee80211_create_tpt_led_trigger
396 </chapter>
397
385 <chapter id="hardware-crypto-offload"> 398 <chapter id="hardware-crypto-offload">
386 <title>Hardware crypto acceleration</title> 399 <title>Hardware crypto acceleration</title>
387!Pinclude/net/mac80211.h Hardware crypto acceleration 400!Pinclude/net/mac80211.h Hardware crypto acceleration
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 39707748ed2d..651d5237c155 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -347,7 +347,6 @@ prototypes:
347 int (*fl_grant)(struct file_lock *, struct file_lock *, int); 347 int (*fl_grant)(struct file_lock *, struct file_lock *, int);
348 void (*fl_release_private)(struct file_lock *); 348 void (*fl_release_private)(struct file_lock *);
349 void (*fl_break)(struct file_lock *); /* break_lease callback */ 349 void (*fl_break)(struct file_lock *); /* break_lease callback */
350 int (*fl_mylease)(struct file_lock *, struct file_lock *);
351 int (*fl_change)(struct file_lock **, int); 350 int (*fl_change)(struct file_lock **, int);
352 351
353locking rules: 352locking rules:
@@ -357,7 +356,6 @@ fl_notify: yes no
357fl_grant: no no 356fl_grant: no no
358fl_release_private: maybe no 357fl_release_private: maybe no
359fl_break: yes no 358fl_break: yes no
360fl_mylease: yes no
361fl_change yes no 359fl_change yes no
362 360
363--------------------------- buffer_head ----------------------------------- 361--------------------------- buffer_head -----------------------------------
diff --git a/Documentation/target/tcm_mod_builder.py b/Documentation/target/tcm_mod_builder.py
new file mode 100755
index 000000000000..dbeb8a0d7175
--- /dev/null
+++ b/Documentation/target/tcm_mod_builder.py
@@ -0,0 +1,1094 @@
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#
9import os, sys
10import subprocess as sub
11import string
12import re
13import optparse
14
15tcm_dir = ""
16
17fabric_ops = []
18fabric_mod_dir = ""
19fabric_mod_port = ""
20fabric_mod_init_port = ""
21
22def tcm_mod_err(msg):
23 print msg
24 sys.exit(1)
25
26def tcm_mod_create_module_subdir(fabric_mod_dir_var):
27
28 if os.path.isdir(fabric_mod_dir_var) == True:
29 return 1
30
31 print "Creating fabric_mod_dir: " + fabric_mod_dir_var
32 ret = os.mkdir(fabric_mod_dir_var)
33 if ret:
34 tcm_mod_err("Unable to mkdir " + fabric_mod_dir_var)
35
36 return
37
38def tcm_mod_build_FC_include(fabric_mod_dir_var, fabric_mod_name):
39 global fabric_mod_port
40 global fabric_mod_init_port
41 buf = ""
42
43 f = fabric_mod_dir_var + "/" + fabric_mod_name + "_base.h"
44 print "Writing file: " + f
45
46 p = open(f, 'w');
47 if not p:
48 tcm_mod_err("Unable to open file: " + f)
49
50 buf = "#define " + fabric_mod_name.upper() + "_VERSION \"v0.1\"\n"
51 buf += "#define " + fabric_mod_name.upper() + "_NAMELEN 32\n"
52 buf += "\n"
53 buf += "struct " + fabric_mod_name + "_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
93def 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
146def 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
195def 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
209def 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_transport.h>\n"
234 buf += "#include <target/target_core_fabric_ops.h>\n"
235 buf += "#include <target/target_core_fabric_configfs.h>\n"
236 buf += "#include <target/target_core_fabric_lib.h>\n"
237 buf += "#include <target/target_core_device.h>\n"
238 buf += "#include <target/target_core_tpg.h>\n"
239 buf += "#include <target/target_core_configfs.h>\n"
240 buf += "#include <target/target_core_base.h>\n"
241 buf += "#include <target/configfs_macros.h>\n\n"
242 buf += "#include <" + fabric_mod_name + "_base.h>\n"
243 buf += "#include <" + fabric_mod_name + "_fabric.h>\n\n"
244
245 buf += "/* Local pointer to allocated TCM configfs fabric module */\n"
246 buf += "struct target_fabric_configfs *" + fabric_mod_name + "_fabric_configfs;\n\n"
247
248 buf += "static struct se_node_acl *" + fabric_mod_name + "_make_nodeacl(\n"
249 buf += " struct se_portal_group *se_tpg,\n"
250 buf += " struct config_group *group,\n"
251 buf += " const char *name)\n"
252 buf += "{\n"
253 buf += " struct se_node_acl *se_nacl, *se_nacl_new;\n"
254 buf += " struct " + fabric_mod_name + "_nacl *nacl;\n"
255
256 if proto_ident == "FC" or proto_ident == "SAS":
257 buf += " u64 wwpn = 0;\n"
258
259 buf += " u32 nexus_depth;\n\n"
260 buf += " /* " + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
261 buf += " return ERR_PTR(-EINVAL); */\n"
262 buf += " se_nacl_new = " + fabric_mod_name + "_alloc_fabric_acl(se_tpg);\n"
263 buf += " if (!(se_nacl_new))\n"
264 buf += " return ERR_PTR(-ENOMEM);\n"
265 buf += "//#warning FIXME: Hardcoded nexus depth in " + fabric_mod_name + "_make_nodeacl()\n"
266 buf += " nexus_depth = 1;\n"
267 buf += " /*\n"
268 buf += " * se_nacl_new may be released by core_tpg_add_initiator_node_acl()\n"
269 buf += " * when converting a NodeACL from demo mode -> explict\n"
270 buf += " */\n"
271 buf += " se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new,\n"
272 buf += " name, nexus_depth);\n"
273 buf += " if (IS_ERR(se_nacl)) {\n"
274 buf += " " + fabric_mod_name + "_release_fabric_acl(se_tpg, se_nacl_new);\n"
275 buf += " return se_nacl;\n"
276 buf += " }\n"
277 buf += " /*\n"
278 buf += " * Locate our struct " + fabric_mod_name + "_nacl and set the FC Nport WWPN\n"
279 buf += " */\n"
280 buf += " nacl = container_of(se_nacl, struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
281
282 if proto_ident == "FC" or proto_ident == "SAS":
283 buf += " nacl->" + fabric_mod_init_port + "_wwpn = wwpn;\n"
284
285 buf += " /* " + fabric_mod_name + "_format_wwn(&nacl->" + fabric_mod_init_port + "_name[0], " + fabric_mod_name.upper() + "_NAMELEN, wwpn); */\n\n"
286 buf += " return se_nacl;\n"
287 buf += "}\n\n"
288 buf += "static void " + fabric_mod_name + "_drop_nodeacl(struct se_node_acl *se_acl)\n"
289 buf += "{\n"
290 buf += " struct " + fabric_mod_name + "_nacl *nacl = container_of(se_acl,\n"
291 buf += " struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
292 buf += " kfree(nacl);\n"
293 buf += "}\n\n"
294
295 buf += "static struct se_portal_group *" + fabric_mod_name + "_make_tpg(\n"
296 buf += " struct se_wwn *wwn,\n"
297 buf += " struct config_group *group,\n"
298 buf += " const char *name)\n"
299 buf += "{\n"
300 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + "*" + fabric_mod_port + " = container_of(wwn,\n"
301 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n\n"
302 buf += " struct " + fabric_mod_name + "_tpg *tpg;\n"
303 buf += " unsigned long tpgt;\n"
304 buf += " int ret;\n\n"
305 buf += " if (strstr(name, \"tpgt_\") != name)\n"
306 buf += " return ERR_PTR(-EINVAL);\n"
307 buf += " if (strict_strtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX)\n"
308 buf += " return ERR_PTR(-EINVAL);\n\n"
309 buf += " tpg = kzalloc(sizeof(struct " + fabric_mod_name + "_tpg), GFP_KERNEL);\n"
310 buf += " if (!(tpg)) {\n"
311 buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_tpg\");\n"
312 buf += " return ERR_PTR(-ENOMEM);\n"
313 buf += " }\n"
314 buf += " tpg->" + fabric_mod_port + " = " + fabric_mod_port + ";\n"
315 buf += " tpg->" + fabric_mod_port + "_tpgt = tpgt;\n\n"
316 buf += " ret = core_tpg_register(&" + fabric_mod_name + "_fabric_configfs->tf_ops, wwn,\n"
317 buf += " &tpg->se_tpg, (void *)tpg,\n"
318 buf += " TRANSPORT_TPG_TYPE_NORMAL);\n"
319 buf += " if (ret < 0) {\n"
320 buf += " kfree(tpg);\n"
321 buf += " return NULL;\n"
322 buf += " }\n"
323 buf += " return &tpg->se_tpg;\n"
324 buf += "}\n\n"
325 buf += "static void " + fabric_mod_name + "_drop_tpg(struct se_portal_group *se_tpg)\n"
326 buf += "{\n"
327 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
328 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n\n"
329 buf += " core_tpg_deregister(se_tpg);\n"
330 buf += " kfree(tpg);\n"
331 buf += "}\n\n"
332
333 buf += "static struct se_wwn *" + fabric_mod_name + "_make_" + fabric_mod_port + "(\n"
334 buf += " struct target_fabric_configfs *tf,\n"
335 buf += " struct config_group *group,\n"
336 buf += " const char *name)\n"
337 buf += "{\n"
338 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + ";\n"
339
340 if proto_ident == "FC" or proto_ident == "SAS":
341 buf += " u64 wwpn = 0;\n\n"
342
343 buf += " /* if (" + fabric_mod_name + "_parse_wwn(name, &wwpn, 1) < 0)\n"
344 buf += " return ERR_PTR(-EINVAL); */\n\n"
345 buf += " " + fabric_mod_port + " = kzalloc(sizeof(struct " + fabric_mod_name + "_" + fabric_mod_port + "), GFP_KERNEL);\n"
346 buf += " if (!(" + fabric_mod_port + ")) {\n"
347 buf += " printk(KERN_ERR \"Unable to allocate struct " + fabric_mod_name + "_" + fabric_mod_port + "\");\n"
348 buf += " return ERR_PTR(-ENOMEM);\n"
349 buf += " }\n"
350
351 if proto_ident == "FC" or proto_ident == "SAS":
352 buf += " " + fabric_mod_port + "->" + fabric_mod_port + "_wwpn = wwpn;\n"
353
354 buf += " /* " + fabric_mod_name + "_format_wwn(&" + fabric_mod_port + "->" + fabric_mod_port + "_name[0], " + fabric_mod_name.upper() + "__NAMELEN, wwpn); */\n\n"
355 buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_wwn;\n"
356 buf += "}\n\n"
357 buf += "static void " + fabric_mod_name + "_drop_" + fabric_mod_port + "(struct se_wwn *wwn)\n"
358 buf += "{\n"
359 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = container_of(wwn,\n"
360 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + ", " + fabric_mod_port + "_wwn);\n"
361 buf += " kfree(" + fabric_mod_port + ");\n"
362 buf += "}\n\n"
363 buf += "static ssize_t " + fabric_mod_name + "_wwn_show_attr_version(\n"
364 buf += " struct target_fabric_configfs *tf,\n"
365 buf += " char *page)\n"
366 buf += "{\n"
367 buf += " return sprintf(page, \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
368 buf += " \"on \"UTS_RELEASE\"\\n\", " + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
369 buf += " utsname()->machine);\n"
370 buf += "}\n\n"
371 buf += "TF_WWN_ATTR_RO(" + fabric_mod_name + ", version);\n\n"
372 buf += "static struct configfs_attribute *" + fabric_mod_name + "_wwn_attrs[] = {\n"
373 buf += " &" + fabric_mod_name + "_wwn_version.attr,\n"
374 buf += " NULL,\n"
375 buf += "};\n\n"
376
377 buf += "static struct target_core_fabric_ops " + fabric_mod_name + "_ops = {\n"
378 buf += " .get_fabric_name = " + fabric_mod_name + "_get_fabric_name,\n"
379 buf += " .get_fabric_proto_ident = " + fabric_mod_name + "_get_fabric_proto_ident,\n"
380 buf += " .tpg_get_wwn = " + fabric_mod_name + "_get_fabric_wwn,\n"
381 buf += " .tpg_get_tag = " + fabric_mod_name + "_get_tag,\n"
382 buf += " .tpg_get_default_depth = " + fabric_mod_name + "_get_default_depth,\n"
383 buf += " .tpg_get_pr_transport_id = " + fabric_mod_name + "_get_pr_transport_id,\n"
384 buf += " .tpg_get_pr_transport_id_len = " + fabric_mod_name + "_get_pr_transport_id_len,\n"
385 buf += " .tpg_parse_pr_out_transport_id = " + fabric_mod_name + "_parse_pr_out_transport_id,\n"
386 buf += " .tpg_check_demo_mode = " + fabric_mod_name + "_check_false,\n"
387 buf += " .tpg_check_demo_mode_cache = " + fabric_mod_name + "_check_true,\n"
388 buf += " .tpg_check_demo_mode_write_protect = " + fabric_mod_name + "_check_true,\n"
389 buf += " .tpg_check_prod_mode_write_protect = " + fabric_mod_name + "_check_false,\n"
390 buf += " .tpg_alloc_fabric_acl = " + fabric_mod_name + "_alloc_fabric_acl,\n"
391 buf += " .tpg_release_fabric_acl = " + fabric_mod_name + "_release_fabric_acl,\n"
392 buf += " .tpg_get_inst_index = " + fabric_mod_name + "_tpg_get_inst_index,\n"
393 buf += " .release_cmd_to_pool = " + fabric_mod_name + "_release_cmd,\n"
394 buf += " .release_cmd_direct = " + fabric_mod_name + "_release_cmd,\n"
395 buf += " .shutdown_session = " + fabric_mod_name + "_shutdown_session,\n"
396 buf += " .close_session = " + fabric_mod_name + "_close_session,\n"
397 buf += " .stop_session = " + fabric_mod_name + "_stop_session,\n"
398 buf += " .fall_back_to_erl0 = " + fabric_mod_name + "_reset_nexus,\n"
399 buf += " .sess_logged_in = " + fabric_mod_name + "_sess_logged_in,\n"
400 buf += " .sess_get_index = " + fabric_mod_name + "_sess_get_index,\n"
401 buf += " .sess_get_initiator_sid = NULL,\n"
402 buf += " .write_pending = " + fabric_mod_name + "_write_pending,\n"
403 buf += " .write_pending_status = " + fabric_mod_name + "_write_pending_status,\n"
404 buf += " .set_default_node_attributes = " + fabric_mod_name + "_set_default_node_attrs,\n"
405 buf += " .get_task_tag = " + fabric_mod_name + "_get_task_tag,\n"
406 buf += " .get_cmd_state = " + fabric_mod_name + "_get_cmd_state,\n"
407 buf += " .new_cmd_failure = " + fabric_mod_name + "_new_cmd_failure,\n"
408 buf += " .queue_data_in = " + fabric_mod_name + "_queue_data_in,\n"
409 buf += " .queue_status = " + fabric_mod_name + "_queue_status,\n"
410 buf += " .queue_tm_rsp = " + fabric_mod_name + "_queue_tm_rsp,\n"
411 buf += " .get_fabric_sense_len = " + fabric_mod_name + "_get_fabric_sense_len,\n"
412 buf += " .set_fabric_sense_len = " + fabric_mod_name + "_set_fabric_sense_len,\n"
413 buf += " .is_state_remove = " + fabric_mod_name + "_is_state_remove,\n"
414 buf += " .pack_lun = " + fabric_mod_name + "_pack_lun,\n"
415 buf += " /*\n"
416 buf += " * Setup function pointers for generic logic in target_core_fabric_configfs.c\n"
417 buf += " */\n"
418 buf += " .fabric_make_wwn = " + fabric_mod_name + "_make_" + fabric_mod_port + ",\n"
419 buf += " .fabric_drop_wwn = " + fabric_mod_name + "_drop_" + fabric_mod_port + ",\n"
420 buf += " .fabric_make_tpg = " + fabric_mod_name + "_make_tpg,\n"
421 buf += " .fabric_drop_tpg = " + fabric_mod_name + "_drop_tpg,\n"
422 buf += " .fabric_post_link = NULL,\n"
423 buf += " .fabric_pre_unlink = NULL,\n"
424 buf += " .fabric_make_np = NULL,\n"
425 buf += " .fabric_drop_np = NULL,\n"
426 buf += " .fabric_make_nodeacl = " + fabric_mod_name + "_make_nodeacl,\n"
427 buf += " .fabric_drop_nodeacl = " + fabric_mod_name + "_drop_nodeacl,\n"
428 buf += "};\n\n"
429
430 buf += "static int " + fabric_mod_name + "_register_configfs(void)\n"
431 buf += "{\n"
432 buf += " struct target_fabric_configfs *fabric;\n"
433 buf += " int ret;\n\n"
434 buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + " fabric module %s on %s/%s\"\n"
435 buf += " \" on \"UTS_RELEASE\"\\n\"," + fabric_mod_name.upper() + "_VERSION, utsname()->sysname,\n"
436 buf += " utsname()->machine);\n"
437 buf += " /*\n"
438 buf += " * Register the top level struct config_item_type with TCM core\n"
439 buf += " */\n"
440 buf += " fabric = target_fabric_configfs_init(THIS_MODULE, \"" + fabric_mod_name[4:] + "\");\n"
441 buf += " if (!(fabric)) {\n"
442 buf += " printk(KERN_ERR \"target_fabric_configfs_init() failed\\n\");\n"
443 buf += " return -ENOMEM;\n"
444 buf += " }\n"
445 buf += " /*\n"
446 buf += " * Setup fabric->tf_ops from our local " + fabric_mod_name + "_ops\n"
447 buf += " */\n"
448 buf += " fabric->tf_ops = " + fabric_mod_name + "_ops;\n"
449 buf += " /*\n"
450 buf += " * Setup default attribute lists for various fabric->tf_cit_tmpl\n"
451 buf += " */\n"
452 buf += " TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = " + fabric_mod_name + "_wwn_attrs;\n"
453 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = NULL;\n"
454 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;\n"
455 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;\n"
456 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;\n"
457 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL;\n"
458 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;\n"
459 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;\n"
460 buf += " TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;\n"
461 buf += " /*\n"
462 buf += " * Register the fabric for use within TCM\n"
463 buf += " */\n"
464 buf += " ret = target_fabric_configfs_register(fabric);\n"
465 buf += " if (ret < 0) {\n"
466 buf += " printk(KERN_ERR \"target_fabric_configfs_register() failed\"\n"
467 buf += " \" for " + fabric_mod_name.upper() + "\\n\");\n"
468 buf += " return ret;\n"
469 buf += " }\n"
470 buf += " /*\n"
471 buf += " * Setup our local pointer to *fabric\n"
472 buf += " */\n"
473 buf += " " + fabric_mod_name + "_fabric_configfs = fabric;\n"
474 buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Set fabric -> " + fabric_mod_name + "_fabric_configfs\\n\");\n"
475 buf += " return 0;\n"
476 buf += "};\n\n"
477 buf += "static void " + fabric_mod_name + "_deregister_configfs(void)\n"
478 buf += "{\n"
479 buf += " if (!(" + fabric_mod_name + "_fabric_configfs))\n"
480 buf += " return;\n\n"
481 buf += " target_fabric_configfs_deregister(" + fabric_mod_name + "_fabric_configfs);\n"
482 buf += " " + fabric_mod_name + "_fabric_configfs = NULL;\n"
483 buf += " printk(KERN_INFO \"" + fabric_mod_name.upper() + "[0] - Cleared " + fabric_mod_name + "_fabric_configfs\\n\");\n"
484 buf += "};\n\n"
485
486 buf += "static int __init " + fabric_mod_name + "_init(void)\n"
487 buf += "{\n"
488 buf += " int ret;\n\n"
489 buf += " ret = " + fabric_mod_name + "_register_configfs();\n"
490 buf += " if (ret < 0)\n"
491 buf += " return ret;\n\n"
492 buf += " return 0;\n"
493 buf += "};\n\n"
494 buf += "static void " + fabric_mod_name + "_exit(void)\n"
495 buf += "{\n"
496 buf += " " + fabric_mod_name + "_deregister_configfs();\n"
497 buf += "};\n\n"
498
499 buf += "#ifdef MODULE\n"
500 buf += "MODULE_DESCRIPTION(\"" + fabric_mod_name.upper() + " series fabric driver\");\n"
501 buf += "MODULE_LICENSE(\"GPL\");\n"
502 buf += "module_init(" + fabric_mod_name + "_init);\n"
503 buf += "module_exit(" + fabric_mod_name + "_exit);\n"
504 buf += "#endif\n"
505
506 ret = p.write(buf)
507 if ret:
508 tcm_mod_err("Unable to write f: " + f)
509
510 p.close()
511
512 return
513
514def tcm_mod_scan_fabric_ops(tcm_dir):
515
516 fabric_ops_api = tcm_dir + "include/target/target_core_fabric_ops.h"
517
518 print "Using tcm_mod_scan_fabric_ops: " + fabric_ops_api
519 process_fo = 0;
520
521 p = open(fabric_ops_api, 'r')
522
523 line = p.readline()
524 while line:
525 if process_fo == 0 and re.search('struct target_core_fabric_ops {', line):
526 line = p.readline()
527 continue
528
529 if process_fo == 0:
530 process_fo = 1;
531 line = p.readline()
532 # Search for function pointer
533 if not re.search('\(\*', line):
534 continue
535
536 fabric_ops.append(line.rstrip())
537 continue
538
539 line = p.readline()
540 # Search for function pointer
541 if not re.search('\(\*', line):
542 continue
543
544 fabric_ops.append(line.rstrip())
545
546 p.close()
547 return
548
549def tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir_var, fabric_mod_name):
550 buf = ""
551 bufi = ""
552
553 f = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.c"
554 print "Writing file: " + f
555
556 p = open(f, 'w')
557 if not p:
558 tcm_mod_err("Unable to open file: " + f)
559
560 fi = fabric_mod_dir_var + "/" + fabric_mod_name + "_fabric.h"
561 print "Writing file: " + fi
562
563 pi = open(fi, 'w')
564 if not pi:
565 tcm_mod_err("Unable to open file: " + fi)
566
567 buf = "#include <linux/slab.h>\n"
568 buf += "#include <linux/kthread.h>\n"
569 buf += "#include <linux/types.h>\n"
570 buf += "#include <linux/list.h>\n"
571 buf += "#include <linux/types.h>\n"
572 buf += "#include <linux/string.h>\n"
573 buf += "#include <linux/ctype.h>\n"
574 buf += "#include <asm/unaligned.h>\n"
575 buf += "#include <scsi/scsi.h>\n"
576 buf += "#include <scsi/scsi_host.h>\n"
577 buf += "#include <scsi/scsi_device.h>\n"
578 buf += "#include <scsi/scsi_cmnd.h>\n"
579 buf += "#include <scsi/libfc.h>\n\n"
580 buf += "#include <target/target_core_base.h>\n"
581 buf += "#include <target/target_core_transport.h>\n"
582 buf += "#include <target/target_core_fabric_ops.h>\n"
583 buf += "#include <target/target_core_fabric_lib.h>\n"
584 buf += "#include <target/target_core_device.h>\n"
585 buf += "#include <target/target_core_tpg.h>\n"
586 buf += "#include <target/target_core_configfs.h>\n"
587 buf += "#include <" + fabric_mod_name + "_base.h>\n"
588 buf += "#include <" + fabric_mod_name + "_fabric.h>\n\n"
589
590 buf += "int " + fabric_mod_name + "_check_true(struct se_portal_group *se_tpg)\n"
591 buf += "{\n"
592 buf += " return 1;\n"
593 buf += "}\n\n"
594 bufi += "int " + fabric_mod_name + "_check_true(struct se_portal_group *);\n"
595
596 buf += "int " + fabric_mod_name + "_check_false(struct se_portal_group *se_tpg)\n"
597 buf += "{\n"
598 buf += " return 0;\n"
599 buf += "}\n\n"
600 bufi += "int " + fabric_mod_name + "_check_false(struct se_portal_group *);\n"
601
602 total_fabric_ops = len(fabric_ops)
603 i = 0
604
605 while i < total_fabric_ops:
606 fo = fabric_ops[i]
607 i += 1
608# print "fabric_ops: " + fo
609
610 if re.search('get_fabric_name', fo):
611 buf += "char *" + fabric_mod_name + "_get_fabric_name(void)\n"
612 buf += "{\n"
613 buf += " return \"" + fabric_mod_name[4:] + "\";\n"
614 buf += "}\n\n"
615 bufi += "char *" + fabric_mod_name + "_get_fabric_name(void);\n"
616 continue
617
618 if re.search('get_fabric_proto_ident', fo):
619 buf += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *se_tpg)\n"
620 buf += "{\n"
621 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
622 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
623 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
624 buf += " u8 proto_id;\n\n"
625 buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
626 if proto_ident == "FC":
627 buf += " case SCSI_PROTOCOL_FCP:\n"
628 buf += " default:\n"
629 buf += " proto_id = fc_get_fabric_proto_ident(se_tpg);\n"
630 buf += " break;\n"
631 elif proto_ident == "SAS":
632 buf += " case SCSI_PROTOCOL_SAS:\n"
633 buf += " default:\n"
634 buf += " proto_id = sas_get_fabric_proto_ident(se_tpg);\n"
635 buf += " break;\n"
636 elif proto_ident == "iSCSI":
637 buf += " case SCSI_PROTOCOL_ISCSI:\n"
638 buf += " default:\n"
639 buf += " proto_id = iscsi_get_fabric_proto_ident(se_tpg);\n"
640 buf += " break;\n"
641
642 buf += " }\n\n"
643 buf += " return proto_id;\n"
644 buf += "}\n\n"
645 bufi += "u8 " + fabric_mod_name + "_get_fabric_proto_ident(struct se_portal_group *);\n"
646
647 if re.search('get_wwn', fo):
648 buf += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *se_tpg)\n"
649 buf += "{\n"
650 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
651 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
652 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n\n"
653 buf += " return &" + fabric_mod_port + "->" + fabric_mod_port + "_name[0];\n"
654 buf += "}\n\n"
655 bufi += "char *" + fabric_mod_name + "_get_fabric_wwn(struct se_portal_group *);\n"
656
657 if re.search('get_tag', fo):
658 buf += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *se_tpg)\n"
659 buf += "{\n"
660 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
661 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
662 buf += " return tpg->" + fabric_mod_port + "_tpgt;\n"
663 buf += "}\n\n"
664 bufi += "u16 " + fabric_mod_name + "_get_tag(struct se_portal_group *);\n"
665
666 if re.search('get_default_depth', fo):
667 buf += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *se_tpg)\n"
668 buf += "{\n"
669 buf += " return 1;\n"
670 buf += "}\n\n"
671 bufi += "u32 " + fabric_mod_name + "_get_default_depth(struct se_portal_group *);\n"
672
673 if re.search('get_pr_transport_id\)\(', fo):
674 buf += "u32 " + fabric_mod_name + "_get_pr_transport_id(\n"
675 buf += " struct se_portal_group *se_tpg,\n"
676 buf += " struct se_node_acl *se_nacl,\n"
677 buf += " struct t10_pr_registration *pr_reg,\n"
678 buf += " int *format_code,\n"
679 buf += " unsigned char *buf)\n"
680 buf += "{\n"
681 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
682 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
683 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
684 buf += " int ret = 0;\n\n"
685 buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
686 if proto_ident == "FC":
687 buf += " case SCSI_PROTOCOL_FCP:\n"
688 buf += " default:\n"
689 buf += " ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
690 buf += " format_code, buf);\n"
691 buf += " break;\n"
692 elif proto_ident == "SAS":
693 buf += " case SCSI_PROTOCOL_SAS:\n"
694 buf += " default:\n"
695 buf += " ret = sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
696 buf += " format_code, buf);\n"
697 buf += " break;\n"
698 elif proto_ident == "iSCSI":
699 buf += " case SCSI_PROTOCOL_ISCSI:\n"
700 buf += " default:\n"
701 buf += " ret = iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg,\n"
702 buf += " format_code, buf);\n"
703 buf += " break;\n"
704
705 buf += " }\n\n"
706 buf += " return ret;\n"
707 buf += "}\n\n"
708 bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id(struct se_portal_group *,\n"
709 bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
710 bufi += " int *, unsigned char *);\n"
711
712 if re.search('get_pr_transport_id_len\)\(', fo):
713 buf += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(\n"
714 buf += " struct se_portal_group *se_tpg,\n"
715 buf += " struct se_node_acl *se_nacl,\n"
716 buf += " struct t10_pr_registration *pr_reg,\n"
717 buf += " int *format_code)\n"
718 buf += "{\n"
719 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
720 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
721 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
722 buf += " int ret = 0;\n\n"
723 buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
724 if proto_ident == "FC":
725 buf += " case SCSI_PROTOCOL_FCP:\n"
726 buf += " default:\n"
727 buf += " ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
728 buf += " format_code);\n"
729 buf += " break;\n"
730 elif proto_ident == "SAS":
731 buf += " case SCSI_PROTOCOL_SAS:\n"
732 buf += " default:\n"
733 buf += " ret = sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
734 buf += " format_code);\n"
735 buf += " break;\n"
736 elif proto_ident == "iSCSI":
737 buf += " case SCSI_PROTOCOL_ISCSI:\n"
738 buf += " default:\n"
739 buf += " ret = iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg,\n"
740 buf += " format_code);\n"
741 buf += " break;\n"
742
743
744 buf += " }\n\n"
745 buf += " return ret;\n"
746 buf += "}\n\n"
747 bufi += "u32 " + fabric_mod_name + "_get_pr_transport_id_len(struct se_portal_group *,\n"
748 bufi += " struct se_node_acl *, struct t10_pr_registration *,\n"
749 bufi += " int *);\n"
750
751 if re.search('parse_pr_out_transport_id\)\(', fo):
752 buf += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(\n"
753 buf += " struct se_portal_group *se_tpg,\n"
754 buf += " const char *buf,\n"
755 buf += " u32 *out_tid_len,\n"
756 buf += " char **port_nexus_ptr)\n"
757 buf += "{\n"
758 buf += " struct " + fabric_mod_name + "_tpg *tpg = container_of(se_tpg,\n"
759 buf += " struct " + fabric_mod_name + "_tpg, se_tpg);\n"
760 buf += " struct " + fabric_mod_name + "_" + fabric_mod_port + " *" + fabric_mod_port + " = tpg->" + fabric_mod_port + ";\n"
761 buf += " char *tid = NULL;\n\n"
762 buf += " switch (" + fabric_mod_port + "->" + fabric_mod_port + "_proto_id) {\n"
763 if proto_ident == "FC":
764 buf += " case SCSI_PROTOCOL_FCP:\n"
765 buf += " default:\n"
766 buf += " tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
767 buf += " port_nexus_ptr);\n"
768 elif proto_ident == "SAS":
769 buf += " case SCSI_PROTOCOL_SAS:\n"
770 buf += " default:\n"
771 buf += " tid = sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
772 buf += " port_nexus_ptr);\n"
773 elif proto_ident == "iSCSI":
774 buf += " case SCSI_PROTOCOL_ISCSI:\n"
775 buf += " default:\n"
776 buf += " tid = iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len,\n"
777 buf += " port_nexus_ptr);\n"
778
779 buf += " }\n\n"
780 buf += " return tid;\n"
781 buf += "}\n\n"
782 bufi += "char *" + fabric_mod_name + "_parse_pr_out_transport_id(struct se_portal_group *,\n"
783 bufi += " const char *, u32 *, char **);\n"
784
785 if re.search('alloc_fabric_acl\)\(', fo):
786 buf += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *se_tpg)\n"
787 buf += "{\n"
788 buf += " struct " + fabric_mod_name + "_nacl *nacl;\n\n"
789 buf += " nacl = kzalloc(sizeof(struct " + fabric_mod_name + "_nacl), GFP_KERNEL);\n"
790 buf += " if (!(nacl)) {\n"
791 buf += " printk(KERN_ERR \"Unable to alocate struct " + fabric_mod_name + "_nacl\\n\");\n"
792 buf += " return NULL;\n"
793 buf += " }\n\n"
794 buf += " return &nacl->se_node_acl;\n"
795 buf += "}\n\n"
796 bufi += "struct se_node_acl *" + fabric_mod_name + "_alloc_fabric_acl(struct se_portal_group *);\n"
797
798 if re.search('release_fabric_acl\)\(', fo):
799 buf += "void " + fabric_mod_name + "_release_fabric_acl(\n"
800 buf += " struct se_portal_group *se_tpg,\n"
801 buf += " struct se_node_acl *se_nacl)\n"
802 buf += "{\n"
803 buf += " struct " + fabric_mod_name + "_nacl *nacl = container_of(se_nacl,\n"
804 buf += " struct " + fabric_mod_name + "_nacl, se_node_acl);\n"
805 buf += " kfree(nacl);\n"
806 buf += "}\n\n"
807 bufi += "void " + fabric_mod_name + "_release_fabric_acl(struct se_portal_group *,\n"
808 bufi += " struct se_node_acl *);\n"
809
810 if re.search('tpg_get_inst_index\)\(', fo):
811 buf += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *se_tpg)\n"
812 buf += "{\n"
813 buf += " return 1;\n"
814 buf += "}\n\n"
815 bufi += "u32 " + fabric_mod_name + "_tpg_get_inst_index(struct se_portal_group *);\n"
816
817 if re.search('release_cmd_to_pool', fo):
818 buf += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *se_cmd)\n"
819 buf += "{\n"
820 buf += " return;\n"
821 buf += "}\n\n"
822 bufi += "void " + fabric_mod_name + "_release_cmd(struct se_cmd *);\n"
823
824 if re.search('shutdown_session\)\(', fo):
825 buf += "int " + fabric_mod_name + "_shutdown_session(struct se_session *se_sess)\n"
826 buf += "{\n"
827 buf += " return 0;\n"
828 buf += "}\n\n"
829 bufi += "int " + fabric_mod_name + "_shutdown_session(struct se_session *);\n"
830
831 if re.search('close_session\)\(', fo):
832 buf += "void " + fabric_mod_name + "_close_session(struct se_session *se_sess)\n"
833 buf += "{\n"
834 buf += " return;\n"
835 buf += "}\n\n"
836 bufi += "void " + fabric_mod_name + "_close_session(struct se_session *);\n"
837
838 if re.search('stop_session\)\(', fo):
839 buf += "void " + fabric_mod_name + "_stop_session(struct se_session *se_sess, int sess_sleep , int conn_sleep)\n"
840 buf += "{\n"
841 buf += " return;\n"
842 buf += "}\n\n"
843 bufi += "void " + fabric_mod_name + "_stop_session(struct se_session *, int, int);\n"
844
845 if re.search('fall_back_to_erl0\)\(', fo):
846 buf += "void " + fabric_mod_name + "_reset_nexus(struct se_session *se_sess)\n"
847 buf += "{\n"
848 buf += " return;\n"
849 buf += "}\n\n"
850 bufi += "void " + fabric_mod_name + "_reset_nexus(struct se_session *);\n"
851
852 if re.search('sess_logged_in\)\(', fo):
853 buf += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *se_sess)\n"
854 buf += "{\n"
855 buf += " return 0;\n"
856 buf += "}\n\n"
857 bufi += "int " + fabric_mod_name + "_sess_logged_in(struct se_session *);\n"
858
859 if re.search('sess_get_index\)\(', fo):
860 buf += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *se_sess)\n"
861 buf += "{\n"
862 buf += " return 0;\n"
863 buf += "}\n\n"
864 bufi += "u32 " + fabric_mod_name + "_sess_get_index(struct se_session *);\n"
865
866 if re.search('write_pending\)\(', fo):
867 buf += "int " + fabric_mod_name + "_write_pending(struct se_cmd *se_cmd)\n"
868 buf += "{\n"
869 buf += " return 0;\n"
870 buf += "}\n\n"
871 bufi += "int " + fabric_mod_name + "_write_pending(struct se_cmd *);\n"
872
873 if re.search('write_pending_status\)\(', fo):
874 buf += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *se_cmd)\n"
875 buf += "{\n"
876 buf += " return 0;\n"
877 buf += "}\n\n"
878 bufi += "int " + fabric_mod_name + "_write_pending_status(struct se_cmd *);\n"
879
880 if re.search('set_default_node_attributes\)\(', fo):
881 buf += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *nacl)\n"
882 buf += "{\n"
883 buf += " return;\n"
884 buf += "}\n\n"
885 bufi += "void " + fabric_mod_name + "_set_default_node_attrs(struct se_node_acl *);\n"
886
887 if re.search('get_task_tag\)\(', fo):
888 buf += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *se_cmd)\n"
889 buf += "{\n"
890 buf += " return 0;\n"
891 buf += "}\n\n"
892 bufi += "u32 " + fabric_mod_name + "_get_task_tag(struct se_cmd *);\n"
893
894 if re.search('get_cmd_state\)\(', fo):
895 buf += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *se_cmd)\n"
896 buf += "{\n"
897 buf += " return 0;\n"
898 buf += "}\n\n"
899 bufi += "int " + fabric_mod_name + "_get_cmd_state(struct se_cmd *);\n"
900
901 if re.search('new_cmd_failure\)\(', fo):
902 buf += "void " + fabric_mod_name + "_new_cmd_failure(struct se_cmd *se_cmd)\n"
903 buf += "{\n"
904 buf += " return;\n"
905 buf += "}\n\n"
906 bufi += "void " + fabric_mod_name + "_new_cmd_failure(struct se_cmd *);\n"
907
908 if re.search('queue_data_in\)\(', fo):
909 buf += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *se_cmd)\n"
910 buf += "{\n"
911 buf += " return 0;\n"
912 buf += "}\n\n"
913 bufi += "int " + fabric_mod_name + "_queue_data_in(struct se_cmd *);\n"
914
915 if re.search('queue_status\)\(', fo):
916 buf += "int " + fabric_mod_name + "_queue_status(struct se_cmd *se_cmd)\n"
917 buf += "{\n"
918 buf += " return 0;\n"
919 buf += "}\n\n"
920 bufi += "int " + fabric_mod_name + "_queue_status(struct se_cmd *);\n"
921
922 if re.search('queue_tm_rsp\)\(', fo):
923 buf += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *se_cmd)\n"
924 buf += "{\n"
925 buf += " return 0;\n"
926 buf += "}\n\n"
927 bufi += "int " + fabric_mod_name + "_queue_tm_rsp(struct se_cmd *);\n"
928
929 if re.search('get_fabric_sense_len\)\(', fo):
930 buf += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void)\n"
931 buf += "{\n"
932 buf += " return 0;\n"
933 buf += "}\n\n"
934 bufi += "u16 " + fabric_mod_name + "_get_fabric_sense_len(void);\n"
935
936 if re.search('set_fabric_sense_len\)\(', fo):
937 buf += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_length)\n"
938 buf += "{\n"
939 buf += " return 0;\n"
940 buf += "}\n\n"
941 bufi += "u16 " + fabric_mod_name + "_set_fabric_sense_len(struct se_cmd *, u32);\n"
942
943 if re.search('is_state_remove\)\(', fo):
944 buf += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *se_cmd)\n"
945 buf += "{\n"
946 buf += " return 0;\n"
947 buf += "}\n\n"
948 bufi += "int " + fabric_mod_name + "_is_state_remove(struct se_cmd *);\n"
949
950 if re.search('pack_lun\)\(', fo):
951 buf += "u64 " + fabric_mod_name + "_pack_lun(unsigned int lun)\n"
952 buf += "{\n"
953 buf += " WARN_ON(lun >= 256);\n"
954 buf += " /* Caller wants this byte-swapped */\n"
955 buf += " return cpu_to_le64((lun & 0xff) << 8);\n"
956 buf += "}\n\n"
957 bufi += "u64 " + fabric_mod_name + "_pack_lun(unsigned int);\n"
958
959
960 ret = p.write(buf)
961 if ret:
962 tcm_mod_err("Unable to write f: " + f)
963
964 p.close()
965
966 ret = pi.write(bufi)
967 if ret:
968 tcm_mod_err("Unable to write fi: " + fi)
969
970 pi.close()
971 return
972
973def tcm_mod_build_kbuild(fabric_mod_dir_var, fabric_mod_name):
974
975 buf = ""
976 f = fabric_mod_dir_var + "/Kbuild"
977 print "Writing file: " + f
978
979 p = open(f, 'w')
980 if not p:
981 tcm_mod_err("Unable to open file: " + f)
982
983 buf = "EXTRA_CFLAGS += -I$(srctree)/drivers/target/ -I$(srctree)/include/ -I$(srctree)/drivers/scsi/ -I$(srctree)/include/scsi/ -I$(srctree)/drivers/target/" + fabric_mod_name + "\n\n"
984 buf += fabric_mod_name + "-objs := " + fabric_mod_name + "_fabric.o \\\n"
985 buf += " " + fabric_mod_name + "_configfs.o\n"
986 buf += "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name + ".o\n"
987
988 ret = p.write(buf)
989 if ret:
990 tcm_mod_err("Unable to write f: " + f)
991
992 p.close()
993 return
994
995def tcm_mod_build_kconfig(fabric_mod_dir_var, fabric_mod_name):
996
997 buf = ""
998 f = fabric_mod_dir_var + "/Kconfig"
999 print "Writing file: " + f
1000
1001 p = open(f, 'w')
1002 if not p:
1003 tcm_mod_err("Unable to open file: " + f)
1004
1005 buf = "config " + fabric_mod_name.upper() + "\n"
1006 buf += " tristate \"" + fabric_mod_name.upper() + " fabric module\"\n"
1007 buf += " depends on TARGET_CORE && CONFIGFS_FS\n"
1008 buf += " default n\n"
1009 buf += " ---help---\n"
1010 buf += " Say Y here to enable the " + fabric_mod_name.upper() + " fabric module\n"
1011
1012 ret = p.write(buf)
1013 if ret:
1014 tcm_mod_err("Unable to write f: " + f)
1015
1016 p.close()
1017 return
1018
1019def tcm_mod_add_kbuild(tcm_dir, fabric_mod_name):
1020 buf = "obj-$(CONFIG_" + fabric_mod_name.upper() + ") += " + fabric_mod_name.lower() + "/\n"
1021 kbuild = tcm_dir + "/drivers/target/Kbuild"
1022
1023 f = open(kbuild, 'a')
1024 f.write(buf)
1025 f.close()
1026 return
1027
1028def tcm_mod_add_kconfig(tcm_dir, fabric_mod_name):
1029 buf = "source \"drivers/target/" + fabric_mod_name.lower() + "/Kconfig\"\n"
1030 kconfig = tcm_dir + "/drivers/target/Kconfig"
1031
1032 f = open(kconfig, 'a')
1033 f.write(buf)
1034 f.close()
1035 return
1036
1037def main(modname, proto_ident):
1038# proto_ident = "FC"
1039# proto_ident = "SAS"
1040# proto_ident = "iSCSI"
1041
1042 tcm_dir = os.getcwd();
1043 tcm_dir += "/../../"
1044 print "tcm_dir: " + tcm_dir
1045 fabric_mod_name = modname
1046 fabric_mod_dir = tcm_dir + "drivers/target/" + fabric_mod_name
1047 print "Set fabric_mod_name: " + fabric_mod_name
1048 print "Set fabric_mod_dir: " + fabric_mod_dir
1049 print "Using proto_ident: " + proto_ident
1050
1051 if proto_ident != "FC" and proto_ident != "SAS" and proto_ident != "iSCSI":
1052 print "Unsupported proto_ident: " + proto_ident
1053 sys.exit(1)
1054
1055 ret = tcm_mod_create_module_subdir(fabric_mod_dir)
1056 if ret:
1057 print "tcm_mod_create_module_subdir() failed because module already exists!"
1058 sys.exit(1)
1059
1060 tcm_mod_build_base_includes(proto_ident, fabric_mod_dir, fabric_mod_name)
1061 tcm_mod_scan_fabric_ops(tcm_dir)
1062 tcm_mod_dump_fabric_ops(proto_ident, fabric_mod_dir, fabric_mod_name)
1063 tcm_mod_build_configfs(proto_ident, fabric_mod_dir, fabric_mod_name)
1064 tcm_mod_build_kbuild(fabric_mod_dir, fabric_mod_name)
1065 tcm_mod_build_kconfig(fabric_mod_dir, fabric_mod_name)
1066
1067 input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Kbuild..? [yes,no]: ")
1068 if input == "yes" or input == "y":
1069 tcm_mod_add_kbuild(tcm_dir, fabric_mod_name)
1070
1071 input = raw_input("Would you like to add " + fabric_mod_name + "to drivers/target/Kconfig..? [yes,no]: ")
1072 if input == "yes" or input == "y":
1073 tcm_mod_add_kconfig(tcm_dir, fabric_mod_name)
1074
1075 return
1076
1077parser = optparse.OptionParser()
1078parser.add_option('-m', '--modulename', help='Module name', dest='modname',
1079 action='store', nargs=1, type='string')
1080parser.add_option('-p', '--protoident', help='Protocol Ident', dest='protoident',
1081 action='store', nargs=1, type='string')
1082
1083(opts, args) = parser.parse_args()
1084
1085mandatories = ['modname', 'protoident']
1086for m in mandatories:
1087 if not opts.__dict__[m]:
1088 print "mandatory option is missing\n"
1089 parser.print_help()
1090 exit(-1)
1091
1092if __name__ == "__main__":
1093
1094 main(str(opts.modname), opts.protoident)
diff --git a/Documentation/target/tcm_mod_builder.txt b/Documentation/target/tcm_mod_builder.txt
new file mode 100644
index 000000000000..84533d8e747f
--- /dev/null
+++ b/Documentation/target/tcm_mod_builder.txt
@@ -0,0 +1,145 @@
1>>>>>>>>>> The TCM v4 fabric module script generator <<<<<<<<<<
2
3Greetings all,
4
5This document is intended to be a mini-HOWTO for using the tcm_mod_builder.py
6script to generate a brand new functional TCM v4 fabric .ko module of your very own,
7that once built can be immediately be loaded to start access the new TCM/ConfigFS
8fabric skeleton, by simply using:
9
10 modprobe $TCM_NEW_MOD
11 mkdir -p /sys/kernel/config/target/$TCM_NEW_MOD
12
13This script will create a new drivers/target/$TCM_NEW_MOD/, and will do the following
14
15 *) Generate new API callers for drivers/target/target_core_fabric_configs.c logic
16 ->make_nodeacl(), ->drop_nodeacl(), ->make_tpg(), ->drop_tpg()
17 ->make_wwn(), ->drop_wwn(). These are created into $TCM_NEW_MOD/$TCM_NEW_MOD_configfs.c
18 *) Generate basic infrastructure for loading/unloading LKMs and TCM/ConfigFS fabric module
19 using a skeleton struct target_core_fabric_ops API template.
20 *) Based on user defined T10 Proto_Ident for the new fabric module being built,
21 the TransportID / Initiator and Target WWPN related handlers for
22 SPC-3 persistent reservation are automatically generated in $TCM_NEW_MOD/$TCM_NEW_MOD_fabric.c
23 using drivers/target/target_core_fabric_lib.c logic.
24 *) NOP API calls for all other Data I/O path and fabric dependent attribute logic
25 in $TCM_NEW_MOD/$TCM_NEW_MOD_fabric.c
26
27tcm_mod_builder.py depends upon the mandatory '-p $PROTO_IDENT' and '-m
28$FABRIC_MOD_name' parameters, and actually running the script looks like:
29
30target:/mnt/sdb/lio-core-2.6.git/Documentation/target# python tcm_mod_builder.py -p iSCSI -m tcm_nab5000
31tcm_dir: /mnt/sdb/lio-core-2.6.git/Documentation/target/../../
32Set fabric_mod_name: tcm_nab5000
33Set fabric_mod_dir:
34/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000
35Using proto_ident: iSCSI
36Creating fabric_mod_dir:
37/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000
38Writing file:
39/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_base.h
40Using tcm_mod_scan_fabric_ops:
41/mnt/sdb/lio-core-2.6.git/Documentation/target/../../include/target/target_core_fabric_ops.h
42Writing file:
43/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_fabric.c
44Writing file:
45/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_fabric.h
46Writing file:
47/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/tcm_nab5000_configfs.c
48Writing file:
49/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/Kbuild
50Writing file:
51/mnt/sdb/lio-core-2.6.git/Documentation/target/../../drivers/target/tcm_nab5000/Kconfig
52Would you like to add tcm_nab5000to drivers/target/Kbuild..? [yes,no]: yes
53Would you like to add tcm_nab5000to drivers/target/Kconfig..? [yes,no]: yes
54
55At the end of tcm_mod_builder.py. the script will ask to add the following
56line to drivers/target/Kbuild:
57
58 obj-$(CONFIG_TCM_NAB5000) += tcm_nab5000/
59
60and the same for drivers/target/Kconfig:
61
62 source "drivers/target/tcm_nab5000/Kconfig"
63
64*) Run 'make menuconfig' and select the new CONFIG_TCM_NAB5000 item:
65
66 <M> TCM_NAB5000 fabric module
67
68*) Build using 'make modules', once completed you will have:
69
70target:/mnt/sdb/lio-core-2.6.git# ls -la drivers/target/tcm_nab5000/
71total 1348
72drwxr-xr-x 2 root root 4096 2010-10-05 03:23 .
73drwxr-xr-x 9 root root 4096 2010-10-05 03:22 ..
74-rw-r--r-- 1 root root 282 2010-10-05 03:22 Kbuild
75-rw-r--r-- 1 root root 171 2010-10-05 03:22 Kconfig
76-rw-r--r-- 1 root root 49 2010-10-05 03:23 modules.order
77-rw-r--r-- 1 root root 738 2010-10-05 03:22 tcm_nab5000_base.h
78-rw-r--r-- 1 root root 9096 2010-10-05 03:22 tcm_nab5000_configfs.c
79-rw-r--r-- 1 root root 191200 2010-10-05 03:23 tcm_nab5000_configfs.o
80-rw-r--r-- 1 root root 40504 2010-10-05 03:23 .tcm_nab5000_configfs.o.cmd
81-rw-r--r-- 1 root root 5414 2010-10-05 03:22 tcm_nab5000_fabric.c
82-rw-r--r-- 1 root root 2016 2010-10-05 03:22 tcm_nab5000_fabric.h
83-rw-r--r-- 1 root root 190932 2010-10-05 03:23 tcm_nab5000_fabric.o
84-rw-r--r-- 1 root root 40713 2010-10-05 03:23 .tcm_nab5000_fabric.o.cmd
85-rw-r--r-- 1 root root 401861 2010-10-05 03:23 tcm_nab5000.ko
86-rw-r--r-- 1 root root 265 2010-10-05 03:23 .tcm_nab5000.ko.cmd
87-rw-r--r-- 1 root root 459 2010-10-05 03:23 tcm_nab5000.mod.c
88-rw-r--r-- 1 root root 23896 2010-10-05 03:23 tcm_nab5000.mod.o
89-rw-r--r-- 1 root root 22655 2010-10-05 03:23 .tcm_nab5000.mod.o.cmd
90-rw-r--r-- 1 root root 379022 2010-10-05 03:23 tcm_nab5000.o
91-rw-r--r-- 1 root root 211 2010-10-05 03:23 .tcm_nab5000.o.cmd
92
93*) Load the new module, create a lun_0 configfs group, and add new TCM Core
94 IBLOCK backstore symlink to port:
95
96target:/mnt/sdb/lio-core-2.6.git# insmod drivers/target/tcm_nab5000.ko
97target:/mnt/sdb/lio-core-2.6.git# mkdir -p /sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0
98target:/mnt/sdb/lio-core-2.6.git# cd /sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0/
99target:/sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0# ln -s /sys/kernel/config/target/core/iblock_0/lvm_test0 nab5000_port
100
101target:/sys/kernel/config/target/nab5000/iqn.foo/tpgt_1/lun/lun_0# cd -
102target:/mnt/sdb/lio-core-2.6.git# tree /sys/kernel/config/target/nab5000/
103/sys/kernel/config/target/nab5000/
104|-- discovery_auth
105|-- iqn.foo
106| `-- tpgt_1
107| |-- acls
108| |-- attrib
109| |-- lun
110| | `-- lun_0
111| | |-- alua_tg_pt_gp
112| | |-- alua_tg_pt_offline
113| | |-- alua_tg_pt_status
114| | |-- alua_tg_pt_write_md
115| | `-- nab5000_port -> ../../../../../../target/core/iblock_0/lvm_test0
116| |-- np
117| `-- param
118`-- version
119
120target:/mnt/sdb/lio-core-2.6.git# lsmod
121Module Size Used by
122tcm_nab5000 3935 4
123iscsi_target_mod 193211 0
124target_core_stgt 8090 0
125target_core_pscsi 11122 1
126target_core_file 9172 2
127target_core_iblock 9280 1
128target_core_mod 228575 31
129tcm_nab5000,iscsi_target_mod,target_core_stgt,target_core_pscsi,target_core_file,target_core_iblock
130libfc 73681 0
131scsi_debug 56265 0
132scsi_tgt 8666 1 target_core_stgt
133configfs 20644 2 target_core_mod
134
135----------------------------------------------------------------------
136
137Future TODO items:
138
139 *) Add more T10 proto_idents
140 *) Make tcm_mod_dump_fabric_ops() smarter and generate function pointer
141 defs directly from include/target/target_core_fabric_ops.h:struct target_core_fabric_ops
142 structure members.
143
144October 5th, 2010
145Nicholas A. Bellinger <nab@linux-iscsi.org>