aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/linux/configfs.h97
-rw-r--r--include/linux/usb/gadget_configfs.h19
-rw-r--r--include/target/configfs_macros.h147
-rw-r--r--include/target/target_core_base.h60
-rw-r--r--include/target/target_core_fabric_configfs.h122
5 files changed, 86 insertions, 359 deletions
diff --git a/include/linux/configfs.h b/include/linux/configfs.h
index 63a36e89d0eb..a8a335b7fce0 100644
--- a/include/linux/configfs.h
+++ b/include/linux/configfs.h
@@ -125,86 +125,33 @@ struct configfs_attribute {
125 const char *ca_name; 125 const char *ca_name;
126 struct module *ca_owner; 126 struct module *ca_owner;
127 umode_t ca_mode; 127 umode_t ca_mode;
128 ssize_t (*show)(struct config_item *, char *);
129 ssize_t (*store)(struct config_item *, const char *, size_t);
128}; 130};
129 131
130/* 132#define CONFIGFS_ATTR(_pfx, _name) \
131 * Users often need to create attribute structures for their configurable 133static struct configfs_attribute _pfx##attr_##_name = { \
132 * attributes, containing a configfs_attribute member and function pointers 134 .ca_name = __stringify(_name), \
133 * for the show() and store() operations on that attribute. If they don't 135 .ca_mode = S_IRUGO | S_IWUSR, \
134 * need anything else on the extended attribute structure, they can use 136 .ca_owner = THIS_MODULE, \
135 * this macro to define it The argument _item is the name of the 137 .show = _pfx##_name##_show, \
136 * config_item structure. 138 .store = _pfx##_name##_store, \
137 */
138#define CONFIGFS_ATTR_STRUCT(_item) \
139struct _item##_attribute { \
140 struct configfs_attribute attr; \
141 ssize_t (*show)(struct _item *, char *); \
142 ssize_t (*store)(struct _item *, const char *, size_t); \
143} 139}
144 140
145/* 141#define CONFIGFS_ATTR_RO(_pfx, _name) \
146 * With the extended attribute structure, users can use this macro 142static struct configfs_attribute _pfx##attr_##_name = { \
147 * (similar to sysfs' __ATTR) to make defining attributes easier. 143 .ca_name = __stringify(_name), \
148 * An example: 144 .ca_mode = S_IRUGO, \
149 * #define MYITEM_ATTR(_name, _mode, _show, _store) \ 145 .ca_owner = THIS_MODULE, \
150 * struct myitem_attribute childless_attr_##_name = \ 146 .show = _pfx##_name##_show, \
151 * __CONFIGFS_ATTR(_name, _mode, _show, _store)
152 */
153#define __CONFIGFS_ATTR(_name, _mode, _show, _store) \
154{ \
155 .attr = { \
156 .ca_name = __stringify(_name), \
157 .ca_mode = _mode, \
158 .ca_owner = THIS_MODULE, \
159 }, \
160 .show = _show, \
161 .store = _store, \
162}
163/* Here is a readonly version, only requiring a show() operation */
164#define __CONFIGFS_ATTR_RO(_name, _show) \
165{ \
166 .attr = { \
167 .ca_name = __stringify(_name), \
168 .ca_mode = 0444, \
169 .ca_owner = THIS_MODULE, \
170 }, \
171 .show = _show, \
172} 147}
173 148
174/* 149#define CONFIGFS_ATTR_WO(_pfx, _name) \
175 * With these extended attributes, the simple show_attribute() and 150static struct configfs_attribute _pfx##attr_##_name = { \
176 * store_attribute() operations need to call the show() and store() of the 151 .ca_name = __stringify(_name), \
177 * attributes. This is a common pattern, so we provide a macro to define 152 .ca_mode = S_IWUSR, \
178 * them. The argument _item is the name of the config_item structure. 153 .ca_owner = THIS_MODULE, \
179 * This macro expects the attributes to be named "struct <name>_attribute" 154 .store = _pfx##_name##_store, \
180 * and the function to_<name>() to exist;
181 */
182#define CONFIGFS_ATTR_OPS(_item) \
183static ssize_t _item##_attr_show(struct config_item *item, \
184 struct configfs_attribute *attr, \
185 char *page) \
186{ \
187 struct _item *_item = to_##_item(item); \
188 struct _item##_attribute *_item##_attr = \
189 container_of(attr, struct _item##_attribute, attr); \
190 ssize_t ret = 0; \
191 \
192 if (_item##_attr->show) \
193 ret = _item##_attr->show(_item, page); \
194 return ret; \
195} \
196static ssize_t _item##_attr_store(struct config_item *item, \
197 struct configfs_attribute *attr, \
198 const char *page, size_t count) \
199{ \
200 struct _item *_item = to_##_item(item); \
201 struct _item##_attribute *_item##_attr = \
202 container_of(attr, struct _item##_attribute, attr); \
203 ssize_t ret = -EINVAL; \
204 \
205 if (_item##_attr->store) \
206 ret = _item##_attr->store(_item, page, count); \
207 return ret; \
208} 155}
209 156
210/* 157/*
@@ -223,8 +170,6 @@ static ssize_t _item##_attr_store(struct config_item *item, \
223 */ 170 */
224struct configfs_item_operations { 171struct configfs_item_operations {
225 void (*release)(struct config_item *); 172 void (*release)(struct config_item *);
226 ssize_t (*show_attribute)(struct config_item *, struct configfs_attribute *,char *);
227 ssize_t (*store_attribute)(struct config_item *,struct configfs_attribute *,const char *, size_t);
228 int (*allow_link)(struct config_item *src, struct config_item *target); 173 int (*allow_link)(struct config_item *src, struct config_item *target);
229 int (*drop_link)(struct config_item *src, struct config_item *target); 174 int (*drop_link)(struct config_item *src, struct config_item *target);
230}; 175};
diff --git a/include/linux/usb/gadget_configfs.h b/include/linux/usb/gadget_configfs.h
index d74c0ae989d5..c36e95730de1 100644
--- a/include/linux/usb/gadget_configfs.h
+++ b/include/linux/usb/gadget_configfs.h
@@ -7,9 +7,10 @@ int check_user_usb_string(const char *name,
7 struct usb_gadget_strings *stringtab_dev); 7 struct usb_gadget_strings *stringtab_dev);
8 8
9#define GS_STRINGS_W(__struct, __name) \ 9#define GS_STRINGS_W(__struct, __name) \
10 static ssize_t __struct##_##__name##_store(struct __struct *gs, \ 10static ssize_t __struct##_##__name##_store(struct config_item *item, \
11 const char *page, size_t len) \ 11 const char *page, size_t len) \
12{ \ 12{ \
13 struct __struct *gs = to_##__struct(item); \
13 int ret; \ 14 int ret; \
14 \ 15 \
15 ret = usb_string_copy(page, &gs->__name); \ 16 ret = usb_string_copy(page, &gs->__name); \
@@ -19,30 +20,20 @@ int check_user_usb_string(const char *name,
19} 20}
20 21
21#define GS_STRINGS_R(__struct, __name) \ 22#define GS_STRINGS_R(__struct, __name) \
22 static ssize_t __struct##_##__name##_show(struct __struct *gs, \ 23static ssize_t __struct##_##__name##_show(struct config_item *item, char *page) \
23 char *page) \
24{ \ 24{ \
25 struct __struct *gs = to_##__struct(item); \
25 return sprintf(page, "%s\n", gs->__name ?: ""); \ 26 return sprintf(page, "%s\n", gs->__name ?: ""); \
26} 27}
27 28
28#define GS_STRING_ITEM_ATTR(struct_name, name) \
29 static struct struct_name##_attribute struct_name##_##name = \
30 __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \
31 struct_name##_##name##_show, \
32 struct_name##_##name##_store)
33
34#define GS_STRINGS_RW(struct_name, _name) \ 29#define GS_STRINGS_RW(struct_name, _name) \
35 GS_STRINGS_R(struct_name, _name) \ 30 GS_STRINGS_R(struct_name, _name) \
36 GS_STRINGS_W(struct_name, _name) \ 31 GS_STRINGS_W(struct_name, _name) \
37 GS_STRING_ITEM_ATTR(struct_name, _name) 32 CONFIGFS_ATTR(struct_name##_, _name)
38 33
39#define USB_CONFIG_STRING_RW_OPS(struct_in) \ 34#define USB_CONFIG_STRING_RW_OPS(struct_in) \
40 CONFIGFS_ATTR_OPS(struct_in); \
41 \
42static struct configfs_item_operations struct_in##_langid_item_ops = { \ 35static struct configfs_item_operations struct_in##_langid_item_ops = { \
43 .release = struct_in##_attr_release, \ 36 .release = struct_in##_attr_release, \
44 .show_attribute = struct_in##_attr_show, \
45 .store_attribute = struct_in##_attr_store, \
46}; \ 37}; \
47 \ 38 \
48static struct config_item_type struct_in##_langid_type = { \ 39static struct config_item_type struct_in##_langid_type = { \
diff --git a/include/target/configfs_macros.h b/include/target/configfs_macros.h
deleted file mode 100644
index a0fc85bbe2da..000000000000
--- a/include/target/configfs_macros.h
+++ /dev/null
@@ -1,147 +0,0 @@
1/* -*- mode: c; c-basic-offset: 8; -*-
2 * vim: noexpandtab sw=8 ts=8 sts=0:
3 *
4 * configfs_macros.h - extends macros for configfs
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA.
20 *
21 * Based on sysfs:
22 * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
23 *
24 * Based on kobject.h:
25 * Copyright (c) 2002-2003 Patrick Mochel
26 * Copyright (c) 2002-2003 Open Source Development Labs
27 *
28 * configfs Copyright (C) 2005 Oracle. All rights reserved.
29 *
30 * Added CONFIGFS_EATTR() macros from original configfs.h macros
31 * Copright (C) 2008-2009 Nicholas A. Bellinger <nab@linux-iscsi.org>
32 *
33 * Please read Documentation/filesystems/configfs/configfs.txt before using
34 * the configfs interface, ESPECIALLY the parts about reference counts and
35 * item destructors.
36 */
37
38#ifndef _CONFIGFS_MACROS_H_
39#define _CONFIGFS_MACROS_H_
40
41#include <linux/configfs.h>
42
43/*
44 * Users often need to create attribute structures for their configurable
45 * attributes, containing a configfs_attribute member and function pointers
46 * for the show() and store() operations on that attribute. If they don't
47 * need anything else on the extended attribute structure, they can use
48 * this macro to define it. The argument _name isends up as
49 * 'struct _name_attribute, as well as names of to CONFIGFS_ATTR_OPS() below.
50 * The argument _item is the name of the structure containing the
51 * struct config_item or struct config_group structure members
52 */
53#define CONFIGFS_EATTR_STRUCT(_name, _item) \
54struct _name##_attribute { \
55 struct configfs_attribute attr; \
56 ssize_t (*show)(struct _item *, char *); \
57 ssize_t (*store)(struct _item *, const char *, size_t); \
58}
59
60/*
61 * With the extended attribute structure, users can use this macro
62 * (similar to sysfs' __ATTR) to make defining attributes easier.
63 * An example:
64 * #define MYITEM_EATTR(_name, _mode, _show, _store) \
65 * struct myitem_attribute childless_attr_##_name = \
66 * __CONFIGFS_EATTR(_name, _mode, _show, _store)
67 */
68#define __CONFIGFS_EATTR(_name, _mode, _show, _store) \
69{ \
70 .attr = { \
71 .ca_name = __stringify(_name), \
72 .ca_mode = _mode, \
73 .ca_owner = THIS_MODULE, \
74 }, \
75 .show = _show, \
76 .store = _store, \
77}
78/* Here is a readonly version, only requiring a show() operation */
79#define __CONFIGFS_EATTR_RO(_name, _show) \
80{ \
81 .attr = { \
82 .ca_name = __stringify(_name), \
83 .ca_mode = 0444, \
84 .ca_owner = THIS_MODULE, \
85 }, \
86 .show = _show, \
87}
88
89/*
90 * With these extended attributes, the simple show_attribute() and
91 * store_attribute() operations need to call the show() and store() of the
92 * attributes. This is a common pattern, so we provide a macro to define
93 * them. The argument _name is the name of the attribute defined by
94 * CONFIGFS_ATTR_STRUCT(). The argument _item is the name of the structure
95 * containing the struct config_item or struct config_group structure member.
96 * The argument _item_member is the actual name of the struct config_* struct
97 * in your _item structure. Meaning my_structure->some_config_group.
98 * ^^_item^^^^^ ^^_item_member^^^
99 * This macro expects the attributes to be named "struct <name>_attribute".
100 */
101#define CONFIGFS_EATTR_OPS_TO_FUNC(_name, _item, _item_member) \
102static struct _item *to_##_name(struct config_item *ci) \
103{ \
104 return (ci) ? container_of(to_config_group(ci), struct _item, \
105 _item_member) : NULL; \
106}
107
108#define CONFIGFS_EATTR_OPS_SHOW(_name, _item) \
109static ssize_t _name##_attr_show(struct config_item *item, \
110 struct configfs_attribute *attr, \
111 char *page) \
112{ \
113 struct _item *_item = to_##_name(item); \
114 struct _name##_attribute * _name##_attr = \
115 container_of(attr, struct _name##_attribute, attr); \
116 ssize_t ret = 0; \
117 \
118 if (_name##_attr->show) \
119 ret = _name##_attr->show(_item, page); \
120 return ret; \
121}
122
123#define CONFIGFS_EATTR_OPS_STORE(_name, _item) \
124static ssize_t _name##_attr_store(struct config_item *item, \
125 struct configfs_attribute *attr, \
126 const char *page, size_t count) \
127{ \
128 struct _item *_item = to_##_name(item); \
129 struct _name##_attribute * _name##_attr = \
130 container_of(attr, struct _name##_attribute, attr); \
131 ssize_t ret = -EINVAL; \
132 \
133 if (_name##_attr->store) \
134 ret = _name##_attr->store(_item, page, count); \
135 return ret; \
136}
137
138#define CONFIGFS_EATTR_OPS(_name, _item, _item_member) \
139 CONFIGFS_EATTR_OPS_TO_FUNC(_name, _item, _item_member); \
140 CONFIGFS_EATTR_OPS_SHOW(_name, _item); \
141 CONFIGFS_EATTR_OPS_STORE(_name, _item);
142
143#define CONFIGFS_EATTR_OPS_RO(_name, _item, _item_member) \
144 CONFIGFS_EATTR_OPS_TO_FUNC(_name, _item, _item_member); \
145 CONFIGFS_EATTR_OPS_SHOW(_name, _item);
146
147#endif /* _CONFIGFS_MACROS_H_ */
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 5f48754dc36a..0a2c74008e53 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -563,6 +563,36 @@ struct se_node_acl {
563 struct kref acl_kref; 563 struct kref acl_kref;
564}; 564};
565 565
566static inline struct se_node_acl *acl_to_nacl(struct config_item *item)
567{
568 return container_of(to_config_group(item), struct se_node_acl,
569 acl_group);
570}
571
572static inline struct se_node_acl *attrib_to_nacl(struct config_item *item)
573{
574 return container_of(to_config_group(item), struct se_node_acl,
575 acl_attrib_group);
576}
577
578static inline struct se_node_acl *auth_to_nacl(struct config_item *item)
579{
580 return container_of(to_config_group(item), struct se_node_acl,
581 acl_auth_group);
582}
583
584static inline struct se_node_acl *param_to_nacl(struct config_item *item)
585{
586 return container_of(to_config_group(item), struct se_node_acl,
587 acl_param_group);
588}
589
590static inline struct se_node_acl *fabric_stat_to_nacl(struct config_item *item)
591{
592 return container_of(to_config_group(item), struct se_node_acl,
593 acl_fabric_stat_group);
594}
595
566struct se_session { 596struct se_session {
567 unsigned sess_tearing_down:1; 597 unsigned sess_tearing_down:1;
568 u64 sess_bin_isid; 598 u64 sess_bin_isid;
@@ -821,6 +851,12 @@ struct se_tpg_np {
821 struct config_group tpg_np_group; 851 struct config_group tpg_np_group;
822}; 852};
823 853
854static inline struct se_tpg_np *to_tpg_np(struct config_item *item)
855{
856 return container_of(to_config_group(item), struct se_tpg_np,
857 tpg_np_group);
858}
859
824struct se_portal_group { 860struct se_portal_group {
825 /* 861 /*
826 * PROTOCOL IDENTIFIER value per SPC4, 7.5.1. 862 * PROTOCOL IDENTIFIER value per SPC4, 7.5.1.
@@ -857,6 +893,30 @@ struct se_portal_group {
857 struct config_group tpg_param_group; 893 struct config_group tpg_param_group;
858}; 894};
859 895
896static inline struct se_portal_group *to_tpg(struct config_item *item)
897{
898 return container_of(to_config_group(item), struct se_portal_group,
899 tpg_group);
900}
901
902static inline struct se_portal_group *attrib_to_tpg(struct config_item *item)
903{
904 return container_of(to_config_group(item), struct se_portal_group,
905 tpg_attrib_group);
906}
907
908static inline struct se_portal_group *auth_to_tpg(struct config_item *item)
909{
910 return container_of(to_config_group(item), struct se_portal_group,
911 tpg_auth_group);
912}
913
914static inline struct se_portal_group *param_to_tpg(struct config_item *item)
915{
916 return container_of(to_config_group(item), struct se_portal_group,
917 tpg_param_group);
918}
919
860struct se_wwn { 920struct se_wwn {
861 struct target_fabric_configfs *wwn_tf; 921 struct target_fabric_configfs *wwn_tf;
862 struct config_group wwn_group; 922 struct config_group wwn_group;
diff --git a/include/target/target_core_fabric_configfs.h b/include/target/target_core_fabric_configfs.h
deleted file mode 100644
index 7a0649c09e79..000000000000
--- a/include/target/target_core_fabric_configfs.h
+++ /dev/null
@@ -1,122 +0,0 @@
1/*
2 * Used for tfc_wwn_cit attributes
3 */
4
5#include <target/configfs_macros.h>
6
7CONFIGFS_EATTR_STRUCT(target_fabric_nacl_attrib, se_node_acl);
8#define TF_NACL_ATTRIB_ATTR(_fabric, _name, _mode) \
9static struct target_fabric_nacl_attrib_attribute _fabric##_nacl_attrib_##_name = \
10 __CONFIGFS_EATTR(_name, _mode, \
11 _fabric##_nacl_attrib_show_##_name, \
12 _fabric##_nacl_attrib_store_##_name);
13
14CONFIGFS_EATTR_STRUCT(target_fabric_nacl_auth, se_node_acl);
15#define TF_NACL_AUTH_ATTR(_fabric, _name, _mode) \
16static struct target_fabric_nacl_auth_attribute _fabric##_nacl_auth_##_name = \
17 __CONFIGFS_EATTR(_name, _mode, \
18 _fabric##_nacl_auth_show_##_name, \
19 _fabric##_nacl_auth_store_##_name);
20
21#define TF_NACL_AUTH_ATTR_RO(_fabric, _name) \
22static struct target_fabric_nacl_auth_attribute _fabric##_nacl_auth_##_name = \
23 __CONFIGFS_EATTR_RO(_name, \
24 _fabric##_nacl_auth_show_##_name);
25
26CONFIGFS_EATTR_STRUCT(target_fabric_nacl_param, se_node_acl);
27#define TF_NACL_PARAM_ATTR(_fabric, _name, _mode) \
28static struct target_fabric_nacl_param_attribute _fabric##_nacl_param_##_name = \
29 __CONFIGFS_EATTR(_name, _mode, \
30 _fabric##_nacl_param_show_##_name, \
31 _fabric##_nacl_param_store_##_name);
32
33#define TF_NACL_PARAM_ATTR_RO(_fabric, _name) \
34static struct target_fabric_nacl_param_attribute _fabric##_nacl_param_##_name = \
35 __CONFIGFS_EATTR_RO(_name, \
36 _fabric##_nacl_param_show_##_name);
37
38
39CONFIGFS_EATTR_STRUCT(target_fabric_nacl_base, se_node_acl);
40#define TF_NACL_BASE_ATTR(_fabric, _name, _mode) \
41static struct target_fabric_nacl_base_attribute _fabric##_nacl_##_name = \
42 __CONFIGFS_EATTR(_name, _mode, \
43 _fabric##_nacl_show_##_name, \
44 _fabric##_nacl_store_##_name);
45
46#define TF_NACL_BASE_ATTR_RO(_fabric, _name) \
47static struct target_fabric_nacl_base_attribute _fabric##_nacl_##_name = \
48 __CONFIGFS_EATTR_RO(_name, \
49 _fabric##_nacl_show_##_name);
50
51CONFIGFS_EATTR_STRUCT(target_fabric_np_base, se_tpg_np);
52#define TF_NP_BASE_ATTR(_fabric, _name, _mode) \
53static struct target_fabric_np_base_attribute _fabric##_np_##_name = \
54 __CONFIGFS_EATTR(_name, _mode, \
55 _fabric##_np_show_##_name, \
56 _fabric##_np_store_##_name);
57
58CONFIGFS_EATTR_STRUCT(target_fabric_tpg_attrib, se_portal_group);
59#define TF_TPG_ATTRIB_ATTR(_fabric, _name, _mode) \
60static struct target_fabric_tpg_attrib_attribute _fabric##_tpg_attrib_##_name = \
61 __CONFIGFS_EATTR(_name, _mode, \
62 _fabric##_tpg_attrib_show_##_name, \
63 _fabric##_tpg_attrib_store_##_name);
64
65CONFIGFS_EATTR_STRUCT(target_fabric_tpg_auth, se_portal_group);
66#define TF_TPG_AUTH_ATTR(_fabric, _name, _mode) \
67static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \
68 __CONFIGFS_EATTR(_name, _mode, \
69 _fabric##_tpg_auth_show_##_name, \
70 _fabric##_tpg_auth_store_##_name);
71
72#define TF_TPG_AUTH_ATTR_RO(_fabric, _name) \
73static struct target_fabric_tpg_auth_attribute _fabric##_tpg_auth_##_name = \
74 __CONFIGFS_EATTR_RO(_name, \
75 _fabric##_tpg_auth_show_##_name);
76
77CONFIGFS_EATTR_STRUCT(target_fabric_tpg_param, se_portal_group);
78#define TF_TPG_PARAM_ATTR(_fabric, _name, _mode) \
79static struct target_fabric_tpg_param_attribute _fabric##_tpg_param_##_name = \
80 __CONFIGFS_EATTR(_name, _mode, \
81 _fabric##_tpg_param_show_##_name, \
82 _fabric##_tpg_param_store_##_name);
83
84
85CONFIGFS_EATTR_STRUCT(target_fabric_tpg, se_portal_group);
86#define TF_TPG_BASE_ATTR(_fabric, _name, _mode) \
87static struct target_fabric_tpg_attribute _fabric##_tpg_##_name = \
88 __CONFIGFS_EATTR(_name, _mode, \
89 _fabric##_tpg_show_##_name, \
90 _fabric##_tpg_store_##_name);
91
92
93#define TF_TPG_BASE_ATTR_RO(_fabric, _name) \
94static struct target_fabric_tpg_attribute _fabric##_tpg_##_name = \
95 __CONFIGFS_EATTR_RO(_name, \
96 _fabric##_tpg_show_##_name);
97
98CONFIGFS_EATTR_STRUCT(target_fabric_wwn, target_fabric_configfs);
99#define TF_WWN_ATTR(_fabric, _name, _mode) \
100static struct target_fabric_wwn_attribute _fabric##_wwn_##_name = \
101 __CONFIGFS_EATTR(_name, _mode, \
102 _fabric##_wwn_show_attr_##_name, \
103 _fabric##_wwn_store_attr_##_name);
104
105#define TF_WWN_ATTR_RO(_fabric, _name) \
106static struct target_fabric_wwn_attribute _fabric##_wwn_##_name = \
107 __CONFIGFS_EATTR_RO(_name, \
108 _fabric##_wwn_show_attr_##_name);
109
110CONFIGFS_EATTR_STRUCT(target_fabric_discovery, target_fabric_configfs);
111#define TF_DISC_ATTR(_fabric, _name, _mode) \
112static struct target_fabric_discovery_attribute _fabric##_disc_##_name = \
113 __CONFIGFS_EATTR(_name, _mode, \
114 _fabric##_disc_show_##_name, \
115 _fabric##_disc_store_##_name);
116
117#define TF_DISC_ATTR_RO(_fabric, _name) \
118static struct target_fabric_discovery_attribute _fabric##_disc_##_name = \
119 __CONFIGFS_EATTR_RO(_name, \
120 _fabric##_disc_show_##_name);
121
122extern int target_fabric_setup_cits(struct target_fabric_configfs *);