Commit | Line | Data |
---|---|---|
12d23384 NB |
1 | /******************************************************************************* |
2 | * Filename: target_core_stat.c | |
3 | * | |
4 | * Copyright (c) 2011 Rising Tide Systems | |
5 | * Copyright (c) 2011 Linux-iSCSI.org | |
6 | * | |
7 | * Modern ConfigFS group context specific statistics based on original | |
8 | * target_core_mib.c code | |
9 | * | |
10 | * Copyright (c) 2006-2007 SBE, Inc. All Rights Reserved. | |
11 | * | |
12 | * Nicholas A. Bellinger <nab@linux-iscsi.org> | |
13 | * | |
14 | * This program is free software; you can redistribute it and/or modify | |
15 | * it under the terms of the GNU General Public License as published by | |
16 | * the Free Software Foundation; either version 2 of the License, or | |
17 | * (at your option) any later version. | |
18 | * | |
19 | * This program is distributed in the hope that it will be useful, | |
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
22 | * GNU General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; if not, write to the Free Software | |
26 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
27 | * | |
28 | ******************************************************************************/ | |
29 | ||
30 | #include <linux/kernel.h> | |
31 | #include <linux/module.h> | |
32 | #include <linux/delay.h> | |
33 | #include <linux/timer.h> | |
34 | #include <linux/string.h> | |
12d23384 NB |
35 | #include <linux/utsname.h> |
36 | #include <linux/proc_fs.h> | |
37 | #include <linux/seq_file.h> | |
38 | #include <linux/blkdev.h> | |
39 | #include <linux/configfs.h> | |
40 | #include <scsi/scsi.h> | |
41 | #include <scsi/scsi_device.h> | |
42 | #include <scsi/scsi_host.h> | |
43 | ||
44 | #include <target/target_core_base.h> | |
c4795fb2 CH |
45 | #include <target/target_core_backend.h> |
46 | #include <target/target_core_fabric.h> | |
12d23384 NB |
47 | #include <target/target_core_configfs.h> |
48 | #include <target/configfs_macros.h> | |
49 | ||
e26d99ae | 50 | #include "target_core_internal.h" |
12d23384 NB |
51 | |
52 | #ifndef INITIAL_JIFFIES | |
53 | #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) | |
54 | #endif | |
55 | ||
56 | #define NONE "None" | |
57 | #define ISPRINT(a) ((a >= ' ') && (a <= '~')) | |
58 | ||
59 | #define SCSI_LU_INDEX 1 | |
60 | #define LU_COUNT 1 | |
61 | ||
62 | /* | |
63 | * SCSI Device Table | |
64 | */ | |
65 | ||
66 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_dev, se_dev_stat_grps); | |
67 | #define DEV_STAT_SCSI_DEV_ATTR(_name, _mode) \ | |
68 | static struct target_stat_scsi_dev_attribute \ | |
69 | target_stat_scsi_dev_##_name = \ | |
70 | __CONFIGFS_EATTR(_name, _mode, \ | |
71 | target_stat_scsi_dev_show_attr_##_name, \ | |
72 | target_stat_scsi_dev_store_attr_##_name); | |
73 | ||
74 | #define DEV_STAT_SCSI_DEV_ATTR_RO(_name) \ | |
75 | static struct target_stat_scsi_dev_attribute \ | |
76 | target_stat_scsi_dev_##_name = \ | |
77 | __CONFIGFS_EATTR_RO(_name, \ | |
78 | target_stat_scsi_dev_show_attr_##_name); | |
79 | ||
80 | static ssize_t target_stat_scsi_dev_show_attr_inst( | |
81 | struct se_dev_stat_grps *sgrps, char *page) | |
82 | { | |
0fd97ccf CH |
83 | struct se_device *dev = |
84 | container_of(sgrps, struct se_device, dev_stat_grps); | |
85 | struct se_hba *hba = dev->se_hba; | |
12d23384 NB |
86 | |
87 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | |
88 | } | |
89 | DEV_STAT_SCSI_DEV_ATTR_RO(inst); | |
90 | ||
91 | static ssize_t target_stat_scsi_dev_show_attr_indx( | |
92 | struct se_dev_stat_grps *sgrps, char *page) | |
93 | { | |
0fd97ccf CH |
94 | struct se_device *dev = |
95 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
96 | |
97 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | |
98 | } | |
99 | DEV_STAT_SCSI_DEV_ATTR_RO(indx); | |
100 | ||
101 | static ssize_t target_stat_scsi_dev_show_attr_role( | |
102 | struct se_dev_stat_grps *sgrps, char *page) | |
103 | { | |
12d23384 NB |
104 | return snprintf(page, PAGE_SIZE, "Target\n"); |
105 | } | |
106 | DEV_STAT_SCSI_DEV_ATTR_RO(role); | |
107 | ||
108 | static ssize_t target_stat_scsi_dev_show_attr_ports( | |
109 | struct se_dev_stat_grps *sgrps, char *page) | |
110 | { | |
0fd97ccf CH |
111 | struct se_device *dev = |
112 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
113 | |
114 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_port_count); | |
115 | } | |
116 | DEV_STAT_SCSI_DEV_ATTR_RO(ports); | |
117 | ||
118 | CONFIGFS_EATTR_OPS(target_stat_scsi_dev, se_dev_stat_grps, scsi_dev_group); | |
119 | ||
120 | static struct configfs_attribute *target_stat_scsi_dev_attrs[] = { | |
121 | &target_stat_scsi_dev_inst.attr, | |
122 | &target_stat_scsi_dev_indx.attr, | |
123 | &target_stat_scsi_dev_role.attr, | |
124 | &target_stat_scsi_dev_ports.attr, | |
125 | NULL, | |
126 | }; | |
127 | ||
128 | static struct configfs_item_operations target_stat_scsi_dev_attrib_ops = { | |
129 | .show_attribute = target_stat_scsi_dev_attr_show, | |
130 | .store_attribute = target_stat_scsi_dev_attr_store, | |
131 | }; | |
132 | ||
133 | static struct config_item_type target_stat_scsi_dev_cit = { | |
134 | .ct_item_ops = &target_stat_scsi_dev_attrib_ops, | |
135 | .ct_attrs = target_stat_scsi_dev_attrs, | |
136 | .ct_owner = THIS_MODULE, | |
137 | }; | |
138 | ||
139 | /* | |
140 | * SCSI Target Device Table | |
141 | */ | |
142 | ||
143 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_tgt_dev, se_dev_stat_grps); | |
144 | #define DEV_STAT_SCSI_TGT_DEV_ATTR(_name, _mode) \ | |
145 | static struct target_stat_scsi_tgt_dev_attribute \ | |
146 | target_stat_scsi_tgt_dev_##_name = \ | |
147 | __CONFIGFS_EATTR(_name, _mode, \ | |
148 | target_stat_scsi_tgt_dev_show_attr_##_name, \ | |
149 | target_stat_scsi_tgt_dev_store_attr_##_name); | |
150 | ||
151 | #define DEV_STAT_SCSI_TGT_DEV_ATTR_RO(_name) \ | |
152 | static struct target_stat_scsi_tgt_dev_attribute \ | |
153 | target_stat_scsi_tgt_dev_##_name = \ | |
154 | __CONFIGFS_EATTR_RO(_name, \ | |
155 | target_stat_scsi_tgt_dev_show_attr_##_name); | |
156 | ||
157 | static ssize_t target_stat_scsi_tgt_dev_show_attr_inst( | |
158 | struct se_dev_stat_grps *sgrps, char *page) | |
159 | { | |
0fd97ccf CH |
160 | struct se_device *dev = |
161 | container_of(sgrps, struct se_device, dev_stat_grps); | |
162 | struct se_hba *hba = dev->se_hba; | |
12d23384 NB |
163 | |
164 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | |
165 | } | |
166 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(inst); | |
167 | ||
168 | static ssize_t target_stat_scsi_tgt_dev_show_attr_indx( | |
169 | struct se_dev_stat_grps *sgrps, char *page) | |
170 | { | |
0fd97ccf CH |
171 | struct se_device *dev = |
172 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
173 | |
174 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | |
175 | } | |
176 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(indx); | |
177 | ||
178 | static ssize_t target_stat_scsi_tgt_dev_show_attr_num_lus( | |
179 | struct se_dev_stat_grps *sgrps, char *page) | |
180 | { | |
12d23384 NB |
181 | return snprintf(page, PAGE_SIZE, "%u\n", LU_COUNT); |
182 | } | |
183 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(num_lus); | |
184 | ||
185 | static ssize_t target_stat_scsi_tgt_dev_show_attr_status( | |
186 | struct se_dev_stat_grps *sgrps, char *page) | |
187 | { | |
0fd97ccf CH |
188 | struct se_device *dev = |
189 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 | 190 | |
0fd97ccf CH |
191 | if (dev->export_count) |
192 | return snprintf(page, PAGE_SIZE, "activated"); | |
193 | else | |
194 | return snprintf(page, PAGE_SIZE, "deactivated"); | |
12d23384 NB |
195 | } |
196 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(status); | |
197 | ||
198 | static ssize_t target_stat_scsi_tgt_dev_show_attr_non_access_lus( | |
199 | struct se_dev_stat_grps *sgrps, char *page) | |
200 | { | |
0fd97ccf CH |
201 | struct se_device *dev = |
202 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
203 | int non_accessible_lus; |
204 | ||
0fd97ccf | 205 | if (dev->export_count) |
12d23384 | 206 | non_accessible_lus = 0; |
0fd97ccf | 207 | else |
12d23384 | 208 | non_accessible_lus = 1; |
12d23384 NB |
209 | |
210 | return snprintf(page, PAGE_SIZE, "%u\n", non_accessible_lus); | |
211 | } | |
212 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(non_access_lus); | |
213 | ||
214 | static ssize_t target_stat_scsi_tgt_dev_show_attr_resets( | |
215 | struct se_dev_stat_grps *sgrps, char *page) | |
216 | { | |
0fd97ccf CH |
217 | struct se_device *dev = |
218 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
219 | |
220 | return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets); | |
221 | } | |
222 | DEV_STAT_SCSI_TGT_DEV_ATTR_RO(resets); | |
223 | ||
224 | ||
225 | CONFIGFS_EATTR_OPS(target_stat_scsi_tgt_dev, se_dev_stat_grps, scsi_tgt_dev_group); | |
226 | ||
227 | static struct configfs_attribute *target_stat_scsi_tgt_dev_attrs[] = { | |
228 | &target_stat_scsi_tgt_dev_inst.attr, | |
229 | &target_stat_scsi_tgt_dev_indx.attr, | |
230 | &target_stat_scsi_tgt_dev_num_lus.attr, | |
231 | &target_stat_scsi_tgt_dev_status.attr, | |
232 | &target_stat_scsi_tgt_dev_non_access_lus.attr, | |
233 | &target_stat_scsi_tgt_dev_resets.attr, | |
234 | NULL, | |
235 | }; | |
236 | ||
237 | static struct configfs_item_operations target_stat_scsi_tgt_dev_attrib_ops = { | |
238 | .show_attribute = target_stat_scsi_tgt_dev_attr_show, | |
239 | .store_attribute = target_stat_scsi_tgt_dev_attr_store, | |
240 | }; | |
241 | ||
242 | static struct config_item_type target_stat_scsi_tgt_dev_cit = { | |
243 | .ct_item_ops = &target_stat_scsi_tgt_dev_attrib_ops, | |
244 | .ct_attrs = target_stat_scsi_tgt_dev_attrs, | |
245 | .ct_owner = THIS_MODULE, | |
246 | }; | |
247 | ||
248 | /* | |
249 | * SCSI Logical Unit Table | |
250 | */ | |
251 | ||
252 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_lu, se_dev_stat_grps); | |
253 | #define DEV_STAT_SCSI_LU_ATTR(_name, _mode) \ | |
254 | static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \ | |
255 | __CONFIGFS_EATTR(_name, _mode, \ | |
256 | target_stat_scsi_lu_show_attr_##_name, \ | |
257 | target_stat_scsi_lu_store_attr_##_name); | |
258 | ||
259 | #define DEV_STAT_SCSI_LU_ATTR_RO(_name) \ | |
260 | static struct target_stat_scsi_lu_attribute target_stat_scsi_lu_##_name = \ | |
261 | __CONFIGFS_EATTR_RO(_name, \ | |
262 | target_stat_scsi_lu_show_attr_##_name); | |
263 | ||
264 | static ssize_t target_stat_scsi_lu_show_attr_inst( | |
265 | struct se_dev_stat_grps *sgrps, char *page) | |
266 | { | |
0fd97ccf CH |
267 | struct se_device *dev = |
268 | container_of(sgrps, struct se_device, dev_stat_grps); | |
269 | struct se_hba *hba = dev->se_hba; | |
12d23384 NB |
270 | |
271 | return snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | |
272 | } | |
273 | DEV_STAT_SCSI_LU_ATTR_RO(inst); | |
274 | ||
275 | static ssize_t target_stat_scsi_lu_show_attr_dev( | |
276 | struct se_dev_stat_grps *sgrps, char *page) | |
277 | { | |
0fd97ccf CH |
278 | struct se_device *dev = |
279 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
280 | |
281 | return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | |
282 | } | |
283 | DEV_STAT_SCSI_LU_ATTR_RO(dev); | |
284 | ||
285 | static ssize_t target_stat_scsi_lu_show_attr_indx( | |
286 | struct se_dev_stat_grps *sgrps, char *page) | |
287 | { | |
12d23384 NB |
288 | return snprintf(page, PAGE_SIZE, "%u\n", SCSI_LU_INDEX); |
289 | } | |
290 | DEV_STAT_SCSI_LU_ATTR_RO(indx); | |
291 | ||
292 | static ssize_t target_stat_scsi_lu_show_attr_lun( | |
293 | struct se_dev_stat_grps *sgrps, char *page) | |
294 | { | |
12d23384 NB |
295 | /* FIXME: scsiLuDefaultLun */ |
296 | return snprintf(page, PAGE_SIZE, "%llu\n", (unsigned long long)0); | |
297 | } | |
298 | DEV_STAT_SCSI_LU_ATTR_RO(lun); | |
299 | ||
300 | static ssize_t target_stat_scsi_lu_show_attr_lu_name( | |
301 | struct se_dev_stat_grps *sgrps, char *page) | |
302 | { | |
0fd97ccf CH |
303 | struct se_device *dev = |
304 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 | 305 | |
12d23384 NB |
306 | /* scsiLuWwnName */ |
307 | return snprintf(page, PAGE_SIZE, "%s\n", | |
0fd97ccf CH |
308 | (strlen(dev->t10_wwn.unit_serial)) ? |
309 | dev->t10_wwn.unit_serial : "None"); | |
12d23384 NB |
310 | } |
311 | DEV_STAT_SCSI_LU_ATTR_RO(lu_name); | |
312 | ||
313 | static ssize_t target_stat_scsi_lu_show_attr_vend( | |
314 | struct se_dev_stat_grps *sgrps, char *page) | |
315 | { | |
0fd97ccf CH |
316 | struct se_device *dev = |
317 | container_of(sgrps, struct se_device, dev_stat_grps); | |
e3d6f909 | 318 | int i; |
0fd97ccf | 319 | char str[sizeof(dev->t10_wwn.vendor)+1]; |
e3d6f909 | 320 | |
12d23384 | 321 | /* scsiLuVendorId */ |
0fd97ccf CH |
322 | for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++) |
323 | str[i] = ISPRINT(dev->t10_wwn.vendor[i]) ? | |
324 | dev->t10_wwn.vendor[i] : ' '; | |
e3d6f909 | 325 | str[i] = '\0'; |
12d23384 NB |
326 | return snprintf(page, PAGE_SIZE, "%s\n", str); |
327 | } | |
328 | DEV_STAT_SCSI_LU_ATTR_RO(vend); | |
329 | ||
330 | static ssize_t target_stat_scsi_lu_show_attr_prod( | |
331 | struct se_dev_stat_grps *sgrps, char *page) | |
332 | { | |
0fd97ccf CH |
333 | struct se_device *dev = |
334 | container_of(sgrps, struct se_device, dev_stat_grps); | |
e3d6f909 | 335 | int i; |
0fd97ccf | 336 | char str[sizeof(dev->t10_wwn.model)+1]; |
12d23384 NB |
337 | |
338 | /* scsiLuProductId */ | |
0fd97ccf CH |
339 | for (i = 0; i < sizeof(dev->t10_wwn.vendor); i++) |
340 | str[i] = ISPRINT(dev->t10_wwn.model[i]) ? | |
341 | dev->t10_wwn.model[i] : ' '; | |
e3d6f909 | 342 | str[i] = '\0'; |
12d23384 NB |
343 | return snprintf(page, PAGE_SIZE, "%s\n", str); |
344 | } | |
345 | DEV_STAT_SCSI_LU_ATTR_RO(prod); | |
346 | ||
347 | static ssize_t target_stat_scsi_lu_show_attr_rev( | |
348 | struct se_dev_stat_grps *sgrps, char *page) | |
349 | { | |
0fd97ccf CH |
350 | struct se_device *dev = |
351 | container_of(sgrps, struct se_device, dev_stat_grps); | |
e3d6f909 | 352 | int i; |
0fd97ccf | 353 | char str[sizeof(dev->t10_wwn.revision)+1]; |
12d23384 NB |
354 | |
355 | /* scsiLuRevisionId */ | |
0fd97ccf CH |
356 | for (i = 0; i < sizeof(dev->t10_wwn.revision); i++) |
357 | str[i] = ISPRINT(dev->t10_wwn.revision[i]) ? | |
358 | dev->t10_wwn.revision[i] : ' '; | |
e3d6f909 | 359 | str[i] = '\0'; |
12d23384 NB |
360 | return snprintf(page, PAGE_SIZE, "%s\n", str); |
361 | } | |
362 | DEV_STAT_SCSI_LU_ATTR_RO(rev); | |
363 | ||
364 | static ssize_t target_stat_scsi_lu_show_attr_dev_type( | |
365 | struct se_dev_stat_grps *sgrps, char *page) | |
366 | { | |
0fd97ccf CH |
367 | struct se_device *dev = |
368 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
369 | |
370 | /* scsiLuPeripheralType */ | |
371 | return snprintf(page, PAGE_SIZE, "%u\n", | |
e3d6f909 | 372 | dev->transport->get_device_type(dev)); |
12d23384 NB |
373 | } |
374 | DEV_STAT_SCSI_LU_ATTR_RO(dev_type); | |
375 | ||
376 | static ssize_t target_stat_scsi_lu_show_attr_status( | |
377 | struct se_dev_stat_grps *sgrps, char *page) | |
378 | { | |
0fd97ccf CH |
379 | struct se_device *dev = |
380 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
381 | |
382 | /* scsiLuStatus */ | |
383 | return snprintf(page, PAGE_SIZE, "%s\n", | |
0fd97ccf | 384 | (dev->export_count) ? "available" : "notavailable"); |
12d23384 NB |
385 | } |
386 | DEV_STAT_SCSI_LU_ATTR_RO(status); | |
387 | ||
388 | static ssize_t target_stat_scsi_lu_show_attr_state_bit( | |
389 | struct se_dev_stat_grps *sgrps, char *page) | |
390 | { | |
12d23384 NB |
391 | /* scsiLuState */ |
392 | return snprintf(page, PAGE_SIZE, "exposed\n"); | |
393 | } | |
394 | DEV_STAT_SCSI_LU_ATTR_RO(state_bit); | |
395 | ||
396 | static ssize_t target_stat_scsi_lu_show_attr_num_cmds( | |
397 | struct se_dev_stat_grps *sgrps, char *page) | |
398 | { | |
0fd97ccf CH |
399 | struct se_device *dev = |
400 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
401 | |
402 | /* scsiLuNumCommands */ | |
403 | return snprintf(page, PAGE_SIZE, "%llu\n", | |
404 | (unsigned long long)dev->num_cmds); | |
405 | } | |
406 | DEV_STAT_SCSI_LU_ATTR_RO(num_cmds); | |
407 | ||
408 | static ssize_t target_stat_scsi_lu_show_attr_read_mbytes( | |
409 | struct se_dev_stat_grps *sgrps, char *page) | |
410 | { | |
0fd97ccf CH |
411 | struct se_device *dev = |
412 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
413 | |
414 | /* scsiLuReadMegaBytes */ | |
415 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->read_bytes >> 20)); | |
416 | } | |
417 | DEV_STAT_SCSI_LU_ATTR_RO(read_mbytes); | |
418 | ||
419 | static ssize_t target_stat_scsi_lu_show_attr_write_mbytes( | |
420 | struct se_dev_stat_grps *sgrps, char *page) | |
421 | { | |
0fd97ccf CH |
422 | struct se_device *dev = |
423 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
424 | |
425 | /* scsiLuWrittenMegaBytes */ | |
426 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(dev->write_bytes >> 20)); | |
427 | } | |
428 | DEV_STAT_SCSI_LU_ATTR_RO(write_mbytes); | |
429 | ||
430 | static ssize_t target_stat_scsi_lu_show_attr_resets( | |
431 | struct se_dev_stat_grps *sgrps, char *page) | |
432 | { | |
0fd97ccf CH |
433 | struct se_device *dev = |
434 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
435 | |
436 | /* scsiLuInResets */ | |
437 | return snprintf(page, PAGE_SIZE, "%u\n", dev->num_resets); | |
438 | } | |
439 | DEV_STAT_SCSI_LU_ATTR_RO(resets); | |
440 | ||
441 | static ssize_t target_stat_scsi_lu_show_attr_full_stat( | |
442 | struct se_dev_stat_grps *sgrps, char *page) | |
443 | { | |
12d23384 NB |
444 | /* FIXME: scsiLuOutTaskSetFullStatus */ |
445 | return snprintf(page, PAGE_SIZE, "%u\n", 0); | |
446 | } | |
447 | DEV_STAT_SCSI_LU_ATTR_RO(full_stat); | |
448 | ||
449 | static ssize_t target_stat_scsi_lu_show_attr_hs_num_cmds( | |
450 | struct se_dev_stat_grps *sgrps, char *page) | |
451 | { | |
12d23384 NB |
452 | /* FIXME: scsiLuHSInCommands */ |
453 | return snprintf(page, PAGE_SIZE, "%u\n", 0); | |
454 | } | |
455 | DEV_STAT_SCSI_LU_ATTR_RO(hs_num_cmds); | |
456 | ||
457 | static ssize_t target_stat_scsi_lu_show_attr_creation_time( | |
458 | struct se_dev_stat_grps *sgrps, char *page) | |
459 | { | |
0fd97ccf CH |
460 | struct se_device *dev = |
461 | container_of(sgrps, struct se_device, dev_stat_grps); | |
12d23384 NB |
462 | |
463 | /* scsiLuCreationTime */ | |
464 | return snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)dev->creation_time - | |
465 | INITIAL_JIFFIES) * 100 / HZ)); | |
466 | } | |
467 | DEV_STAT_SCSI_LU_ATTR_RO(creation_time); | |
468 | ||
469 | CONFIGFS_EATTR_OPS(target_stat_scsi_lu, se_dev_stat_grps, scsi_lu_group); | |
470 | ||
471 | static struct configfs_attribute *target_stat_scsi_lu_attrs[] = { | |
472 | &target_stat_scsi_lu_inst.attr, | |
473 | &target_stat_scsi_lu_dev.attr, | |
474 | &target_stat_scsi_lu_indx.attr, | |
475 | &target_stat_scsi_lu_lun.attr, | |
476 | &target_stat_scsi_lu_lu_name.attr, | |
477 | &target_stat_scsi_lu_vend.attr, | |
478 | &target_stat_scsi_lu_prod.attr, | |
479 | &target_stat_scsi_lu_rev.attr, | |
480 | &target_stat_scsi_lu_dev_type.attr, | |
481 | &target_stat_scsi_lu_status.attr, | |
482 | &target_stat_scsi_lu_state_bit.attr, | |
483 | &target_stat_scsi_lu_num_cmds.attr, | |
484 | &target_stat_scsi_lu_read_mbytes.attr, | |
485 | &target_stat_scsi_lu_write_mbytes.attr, | |
486 | &target_stat_scsi_lu_resets.attr, | |
487 | &target_stat_scsi_lu_full_stat.attr, | |
488 | &target_stat_scsi_lu_hs_num_cmds.attr, | |
489 | &target_stat_scsi_lu_creation_time.attr, | |
490 | NULL, | |
491 | }; | |
492 | ||
493 | static struct configfs_item_operations target_stat_scsi_lu_attrib_ops = { | |
494 | .show_attribute = target_stat_scsi_lu_attr_show, | |
495 | .store_attribute = target_stat_scsi_lu_attr_store, | |
496 | }; | |
497 | ||
498 | static struct config_item_type target_stat_scsi_lu_cit = { | |
499 | .ct_item_ops = &target_stat_scsi_lu_attrib_ops, | |
500 | .ct_attrs = target_stat_scsi_lu_attrs, | |
501 | .ct_owner = THIS_MODULE, | |
502 | }; | |
503 | ||
504 | /* | |
505 | * Called from target_core_configfs.c:target_core_make_subdev() to setup | |
506 | * the target statistics groups + configfs CITs located in target_core_stat.c | |
507 | */ | |
0fd97ccf | 508 | void target_stat_setup_dev_default_groups(struct se_device *dev) |
12d23384 | 509 | { |
0fd97ccf | 510 | struct config_group *dev_stat_grp = &dev->dev_stat_grps.stat_group; |
12d23384 | 511 | |
0fd97ccf | 512 | config_group_init_type_name(&dev->dev_stat_grps.scsi_dev_group, |
12d23384 | 513 | "scsi_dev", &target_stat_scsi_dev_cit); |
0fd97ccf | 514 | config_group_init_type_name(&dev->dev_stat_grps.scsi_tgt_dev_group, |
12d23384 | 515 | "scsi_tgt_dev", &target_stat_scsi_tgt_dev_cit); |
0fd97ccf | 516 | config_group_init_type_name(&dev->dev_stat_grps.scsi_lu_group, |
12d23384 NB |
517 | "scsi_lu", &target_stat_scsi_lu_cit); |
518 | ||
0fd97ccf CH |
519 | dev_stat_grp->default_groups[0] = &dev->dev_stat_grps.scsi_dev_group; |
520 | dev_stat_grp->default_groups[1] = &dev->dev_stat_grps.scsi_tgt_dev_group; | |
521 | dev_stat_grp->default_groups[2] = &dev->dev_stat_grps.scsi_lu_group; | |
12d23384 NB |
522 | dev_stat_grp->default_groups[3] = NULL; |
523 | } | |
524 | ||
525 | /* | |
526 | * SCSI Port Table | |
527 | */ | |
528 | ||
529 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_port, se_port_stat_grps); | |
530 | #define DEV_STAT_SCSI_PORT_ATTR(_name, _mode) \ | |
531 | static struct target_stat_scsi_port_attribute \ | |
532 | target_stat_scsi_port_##_name = \ | |
533 | __CONFIGFS_EATTR(_name, _mode, \ | |
534 | target_stat_scsi_port_show_attr_##_name, \ | |
535 | target_stat_scsi_port_store_attr_##_name); | |
536 | ||
537 | #define DEV_STAT_SCSI_PORT_ATTR_RO(_name) \ | |
538 | static struct target_stat_scsi_port_attribute \ | |
539 | target_stat_scsi_port_##_name = \ | |
540 | __CONFIGFS_EATTR_RO(_name, \ | |
541 | target_stat_scsi_port_show_attr_##_name); | |
542 | ||
543 | static ssize_t target_stat_scsi_port_show_attr_inst( | |
544 | struct se_port_stat_grps *pgrps, char *page) | |
545 | { | |
546 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
547 | struct se_port *sep; | |
548 | struct se_device *dev = lun->lun_se_dev; | |
549 | struct se_hba *hba; | |
550 | ssize_t ret; | |
551 | ||
552 | spin_lock(&lun->lun_sep_lock); | |
553 | sep = lun->lun_sep; | |
554 | if (!sep) { | |
555 | spin_unlock(&lun->lun_sep_lock); | |
556 | return -ENODEV; | |
557 | } | |
558 | hba = dev->se_hba; | |
559 | ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | |
560 | spin_unlock(&lun->lun_sep_lock); | |
561 | return ret; | |
562 | } | |
563 | DEV_STAT_SCSI_PORT_ATTR_RO(inst); | |
564 | ||
565 | static ssize_t target_stat_scsi_port_show_attr_dev( | |
566 | struct se_port_stat_grps *pgrps, char *page) | |
567 | { | |
568 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
569 | struct se_port *sep; | |
570 | struct se_device *dev = lun->lun_se_dev; | |
571 | ssize_t ret; | |
572 | ||
573 | spin_lock(&lun->lun_sep_lock); | |
574 | sep = lun->lun_sep; | |
575 | if (!sep) { | |
576 | spin_unlock(&lun->lun_sep_lock); | |
577 | return -ENODEV; | |
578 | } | |
579 | ret = snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | |
580 | spin_unlock(&lun->lun_sep_lock); | |
581 | return ret; | |
582 | } | |
583 | DEV_STAT_SCSI_PORT_ATTR_RO(dev); | |
584 | ||
585 | static ssize_t target_stat_scsi_port_show_attr_indx( | |
586 | struct se_port_stat_grps *pgrps, char *page) | |
587 | { | |
588 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
589 | struct se_port *sep; | |
590 | ssize_t ret; | |
591 | ||
592 | spin_lock(&lun->lun_sep_lock); | |
593 | sep = lun->lun_sep; | |
594 | if (!sep) { | |
595 | spin_unlock(&lun->lun_sep_lock); | |
596 | return -ENODEV; | |
597 | } | |
598 | ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index); | |
599 | spin_unlock(&lun->lun_sep_lock); | |
600 | return ret; | |
601 | } | |
602 | DEV_STAT_SCSI_PORT_ATTR_RO(indx); | |
603 | ||
604 | static ssize_t target_stat_scsi_port_show_attr_role( | |
605 | struct se_port_stat_grps *pgrps, char *page) | |
606 | { | |
607 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
608 | struct se_device *dev = lun->lun_se_dev; | |
609 | struct se_port *sep; | |
610 | ssize_t ret; | |
611 | ||
612 | if (!dev) | |
613 | return -ENODEV; | |
614 | ||
615 | spin_lock(&lun->lun_sep_lock); | |
616 | sep = lun->lun_sep; | |
617 | if (!sep) { | |
618 | spin_unlock(&lun->lun_sep_lock); | |
619 | return -ENODEV; | |
620 | } | |
621 | ret = snprintf(page, PAGE_SIZE, "%s%u\n", "Device", dev->dev_index); | |
622 | spin_unlock(&lun->lun_sep_lock); | |
623 | return ret; | |
624 | } | |
625 | DEV_STAT_SCSI_PORT_ATTR_RO(role); | |
626 | ||
627 | static ssize_t target_stat_scsi_port_show_attr_busy_count( | |
628 | struct se_port_stat_grps *pgrps, char *page) | |
629 | { | |
630 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
631 | struct se_port *sep; | |
632 | ssize_t ret; | |
633 | ||
634 | spin_lock(&lun->lun_sep_lock); | |
635 | sep = lun->lun_sep; | |
636 | if (!sep) { | |
637 | spin_unlock(&lun->lun_sep_lock); | |
638 | return -ENODEV; | |
639 | } | |
640 | /* FIXME: scsiPortBusyStatuses */ | |
641 | ret = snprintf(page, PAGE_SIZE, "%u\n", 0); | |
642 | spin_unlock(&lun->lun_sep_lock); | |
643 | return ret; | |
644 | } | |
645 | DEV_STAT_SCSI_PORT_ATTR_RO(busy_count); | |
646 | ||
647 | CONFIGFS_EATTR_OPS(target_stat_scsi_port, se_port_stat_grps, scsi_port_group); | |
648 | ||
649 | static struct configfs_attribute *target_stat_scsi_port_attrs[] = { | |
650 | &target_stat_scsi_port_inst.attr, | |
651 | &target_stat_scsi_port_dev.attr, | |
652 | &target_stat_scsi_port_indx.attr, | |
653 | &target_stat_scsi_port_role.attr, | |
654 | &target_stat_scsi_port_busy_count.attr, | |
655 | NULL, | |
656 | }; | |
657 | ||
658 | static struct configfs_item_operations target_stat_scsi_port_attrib_ops = { | |
659 | .show_attribute = target_stat_scsi_port_attr_show, | |
660 | .store_attribute = target_stat_scsi_port_attr_store, | |
661 | }; | |
662 | ||
663 | static struct config_item_type target_stat_scsi_port_cit = { | |
664 | .ct_item_ops = &target_stat_scsi_port_attrib_ops, | |
665 | .ct_attrs = target_stat_scsi_port_attrs, | |
666 | .ct_owner = THIS_MODULE, | |
667 | }; | |
668 | ||
669 | /* | |
670 | * SCSI Target Port Table | |
671 | */ | |
672 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_tgt_port, se_port_stat_grps); | |
673 | #define DEV_STAT_SCSI_TGT_PORT_ATTR(_name, _mode) \ | |
674 | static struct target_stat_scsi_tgt_port_attribute \ | |
675 | target_stat_scsi_tgt_port_##_name = \ | |
676 | __CONFIGFS_EATTR(_name, _mode, \ | |
677 | target_stat_scsi_tgt_port_show_attr_##_name, \ | |
678 | target_stat_scsi_tgt_port_store_attr_##_name); | |
679 | ||
680 | #define DEV_STAT_SCSI_TGT_PORT_ATTR_RO(_name) \ | |
681 | static struct target_stat_scsi_tgt_port_attribute \ | |
682 | target_stat_scsi_tgt_port_##_name = \ | |
683 | __CONFIGFS_EATTR_RO(_name, \ | |
684 | target_stat_scsi_tgt_port_show_attr_##_name); | |
685 | ||
686 | static ssize_t target_stat_scsi_tgt_port_show_attr_inst( | |
687 | struct se_port_stat_grps *pgrps, char *page) | |
688 | { | |
689 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
690 | struct se_device *dev = lun->lun_se_dev; | |
691 | struct se_port *sep; | |
692 | struct se_hba *hba; | |
693 | ssize_t ret; | |
694 | ||
695 | spin_lock(&lun->lun_sep_lock); | |
696 | sep = lun->lun_sep; | |
697 | if (!sep) { | |
698 | spin_unlock(&lun->lun_sep_lock); | |
699 | return -ENODEV; | |
700 | } | |
701 | hba = dev->se_hba; | |
702 | ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | |
703 | spin_unlock(&lun->lun_sep_lock); | |
704 | return ret; | |
705 | } | |
706 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(inst); | |
707 | ||
708 | static ssize_t target_stat_scsi_tgt_port_show_attr_dev( | |
709 | struct se_port_stat_grps *pgrps, char *page) | |
710 | { | |
711 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
712 | struct se_device *dev = lun->lun_se_dev; | |
713 | struct se_port *sep; | |
714 | ssize_t ret; | |
715 | ||
716 | spin_lock(&lun->lun_sep_lock); | |
717 | sep = lun->lun_sep; | |
718 | if (!sep) { | |
719 | spin_unlock(&lun->lun_sep_lock); | |
720 | return -ENODEV; | |
721 | } | |
722 | ret = snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index); | |
723 | spin_unlock(&lun->lun_sep_lock); | |
724 | return ret; | |
725 | } | |
726 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(dev); | |
727 | ||
728 | static ssize_t target_stat_scsi_tgt_port_show_attr_indx( | |
729 | struct se_port_stat_grps *pgrps, char *page) | |
730 | { | |
731 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
732 | struct se_port *sep; | |
733 | ssize_t ret; | |
734 | ||
735 | spin_lock(&lun->lun_sep_lock); | |
736 | sep = lun->lun_sep; | |
737 | if (!sep) { | |
738 | spin_unlock(&lun->lun_sep_lock); | |
739 | return -ENODEV; | |
740 | } | |
741 | ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index); | |
742 | spin_unlock(&lun->lun_sep_lock); | |
743 | return ret; | |
744 | } | |
745 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(indx); | |
746 | ||
747 | static ssize_t target_stat_scsi_tgt_port_show_attr_name( | |
748 | struct se_port_stat_grps *pgrps, char *page) | |
749 | { | |
750 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
751 | struct se_port *sep; | |
752 | struct se_portal_group *tpg; | |
753 | ssize_t ret; | |
754 | ||
755 | spin_lock(&lun->lun_sep_lock); | |
756 | sep = lun->lun_sep; | |
757 | if (!sep) { | |
758 | spin_unlock(&lun->lun_sep_lock); | |
759 | return -ENODEV; | |
760 | } | |
761 | tpg = sep->sep_tpg; | |
762 | ||
763 | ret = snprintf(page, PAGE_SIZE, "%sPort#%u\n", | |
e3d6f909 | 764 | tpg->se_tpg_tfo->get_fabric_name(), sep->sep_index); |
12d23384 NB |
765 | spin_unlock(&lun->lun_sep_lock); |
766 | return ret; | |
767 | } | |
768 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(name); | |
769 | ||
770 | static ssize_t target_stat_scsi_tgt_port_show_attr_port_index( | |
771 | struct se_port_stat_grps *pgrps, char *page) | |
772 | { | |
773 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
774 | struct se_port *sep; | |
775 | struct se_portal_group *tpg; | |
776 | ssize_t ret; | |
777 | ||
778 | spin_lock(&lun->lun_sep_lock); | |
779 | sep = lun->lun_sep; | |
780 | if (!sep) { | |
781 | spin_unlock(&lun->lun_sep_lock); | |
782 | return -ENODEV; | |
783 | } | |
784 | tpg = sep->sep_tpg; | |
785 | ||
786 | ret = snprintf(page, PAGE_SIZE, "%s%s%d\n", | |
e3d6f909 AG |
787 | tpg->se_tpg_tfo->tpg_get_wwn(tpg), "+t+", |
788 | tpg->se_tpg_tfo->tpg_get_tag(tpg)); | |
12d23384 NB |
789 | spin_unlock(&lun->lun_sep_lock); |
790 | return ret; | |
791 | } | |
792 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(port_index); | |
793 | ||
794 | static ssize_t target_stat_scsi_tgt_port_show_attr_in_cmds( | |
795 | struct se_port_stat_grps *pgrps, char *page) | |
796 | { | |
797 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
798 | struct se_port *sep; | |
12d23384 NB |
799 | ssize_t ret; |
800 | ||
801 | spin_lock(&lun->lun_sep_lock); | |
802 | sep = lun->lun_sep; | |
803 | if (!sep) { | |
804 | spin_unlock(&lun->lun_sep_lock); | |
805 | return -ENODEV; | |
806 | } | |
12d23384 NB |
807 | |
808 | ret = snprintf(page, PAGE_SIZE, "%llu\n", sep->sep_stats.cmd_pdus); | |
809 | spin_unlock(&lun->lun_sep_lock); | |
810 | return ret; | |
811 | } | |
812 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(in_cmds); | |
813 | ||
814 | static ssize_t target_stat_scsi_tgt_port_show_attr_write_mbytes( | |
815 | struct se_port_stat_grps *pgrps, char *page) | |
816 | { | |
817 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
818 | struct se_port *sep; | |
12d23384 NB |
819 | ssize_t ret; |
820 | ||
821 | spin_lock(&lun->lun_sep_lock); | |
822 | sep = lun->lun_sep; | |
823 | if (!sep) { | |
824 | spin_unlock(&lun->lun_sep_lock); | |
825 | return -ENODEV; | |
826 | } | |
12d23384 NB |
827 | |
828 | ret = snprintf(page, PAGE_SIZE, "%u\n", | |
829 | (u32)(sep->sep_stats.rx_data_octets >> 20)); | |
830 | spin_unlock(&lun->lun_sep_lock); | |
831 | return ret; | |
832 | } | |
833 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(write_mbytes); | |
834 | ||
835 | static ssize_t target_stat_scsi_tgt_port_show_attr_read_mbytes( | |
836 | struct se_port_stat_grps *pgrps, char *page) | |
837 | { | |
838 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
839 | struct se_port *sep; | |
12d23384 NB |
840 | ssize_t ret; |
841 | ||
842 | spin_lock(&lun->lun_sep_lock); | |
843 | sep = lun->lun_sep; | |
844 | if (!sep) { | |
845 | spin_unlock(&lun->lun_sep_lock); | |
846 | return -ENODEV; | |
847 | } | |
12d23384 NB |
848 | |
849 | ret = snprintf(page, PAGE_SIZE, "%u\n", | |
850 | (u32)(sep->sep_stats.tx_data_octets >> 20)); | |
851 | spin_unlock(&lun->lun_sep_lock); | |
852 | return ret; | |
853 | } | |
854 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(read_mbytes); | |
855 | ||
856 | static ssize_t target_stat_scsi_tgt_port_show_attr_hs_in_cmds( | |
857 | struct se_port_stat_grps *pgrps, char *page) | |
858 | { | |
859 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
860 | struct se_port *sep; | |
12d23384 NB |
861 | ssize_t ret; |
862 | ||
863 | spin_lock(&lun->lun_sep_lock); | |
864 | sep = lun->lun_sep; | |
865 | if (!sep) { | |
866 | spin_unlock(&lun->lun_sep_lock); | |
867 | return -ENODEV; | |
868 | } | |
12d23384 NB |
869 | |
870 | /* FIXME: scsiTgtPortHsInCommands */ | |
871 | ret = snprintf(page, PAGE_SIZE, "%u\n", 0); | |
872 | spin_unlock(&lun->lun_sep_lock); | |
873 | return ret; | |
874 | } | |
875 | DEV_STAT_SCSI_TGT_PORT_ATTR_RO(hs_in_cmds); | |
876 | ||
877 | CONFIGFS_EATTR_OPS(target_stat_scsi_tgt_port, se_port_stat_grps, | |
878 | scsi_tgt_port_group); | |
879 | ||
880 | static struct configfs_attribute *target_stat_scsi_tgt_port_attrs[] = { | |
881 | &target_stat_scsi_tgt_port_inst.attr, | |
882 | &target_stat_scsi_tgt_port_dev.attr, | |
883 | &target_stat_scsi_tgt_port_indx.attr, | |
884 | &target_stat_scsi_tgt_port_name.attr, | |
885 | &target_stat_scsi_tgt_port_port_index.attr, | |
886 | &target_stat_scsi_tgt_port_in_cmds.attr, | |
887 | &target_stat_scsi_tgt_port_write_mbytes.attr, | |
888 | &target_stat_scsi_tgt_port_read_mbytes.attr, | |
889 | &target_stat_scsi_tgt_port_hs_in_cmds.attr, | |
890 | NULL, | |
891 | }; | |
892 | ||
893 | static struct configfs_item_operations target_stat_scsi_tgt_port_attrib_ops = { | |
894 | .show_attribute = target_stat_scsi_tgt_port_attr_show, | |
895 | .store_attribute = target_stat_scsi_tgt_port_attr_store, | |
896 | }; | |
897 | ||
898 | static struct config_item_type target_stat_scsi_tgt_port_cit = { | |
899 | .ct_item_ops = &target_stat_scsi_tgt_port_attrib_ops, | |
900 | .ct_attrs = target_stat_scsi_tgt_port_attrs, | |
901 | .ct_owner = THIS_MODULE, | |
902 | }; | |
903 | ||
904 | /* | |
905 | * SCSI Transport Table | |
906 | o */ | |
907 | ||
908 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_transport, se_port_stat_grps); | |
909 | #define DEV_STAT_SCSI_TRANSPORT_ATTR(_name, _mode) \ | |
910 | static struct target_stat_scsi_transport_attribute \ | |
911 | target_stat_scsi_transport_##_name = \ | |
912 | __CONFIGFS_EATTR(_name, _mode, \ | |
913 | target_stat_scsi_transport_show_attr_##_name, \ | |
914 | target_stat_scsi_transport_store_attr_##_name); | |
915 | ||
916 | #define DEV_STAT_SCSI_TRANSPORT_ATTR_RO(_name) \ | |
917 | static struct target_stat_scsi_transport_attribute \ | |
918 | target_stat_scsi_transport_##_name = \ | |
919 | __CONFIGFS_EATTR_RO(_name, \ | |
920 | target_stat_scsi_transport_show_attr_##_name); | |
921 | ||
922 | static ssize_t target_stat_scsi_transport_show_attr_inst( | |
923 | struct se_port_stat_grps *pgrps, char *page) | |
924 | { | |
925 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
926 | struct se_device *dev = lun->lun_se_dev; | |
927 | struct se_port *sep; | |
928 | struct se_hba *hba; | |
929 | ssize_t ret; | |
930 | ||
931 | spin_lock(&lun->lun_sep_lock); | |
932 | sep = lun->lun_sep; | |
933 | if (!sep) { | |
934 | spin_unlock(&lun->lun_sep_lock); | |
935 | return -ENODEV; | |
936 | } | |
937 | ||
938 | hba = dev->se_hba; | |
939 | ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index); | |
940 | spin_unlock(&lun->lun_sep_lock); | |
941 | return ret; | |
942 | } | |
943 | DEV_STAT_SCSI_TRANSPORT_ATTR_RO(inst); | |
944 | ||
945 | static ssize_t target_stat_scsi_transport_show_attr_device( | |
946 | struct se_port_stat_grps *pgrps, char *page) | |
947 | { | |
948 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
949 | struct se_port *sep; | |
950 | struct se_portal_group *tpg; | |
951 | ssize_t ret; | |
952 | ||
953 | spin_lock(&lun->lun_sep_lock); | |
954 | sep = lun->lun_sep; | |
955 | if (!sep) { | |
956 | spin_unlock(&lun->lun_sep_lock); | |
957 | return -ENODEV; | |
958 | } | |
959 | tpg = sep->sep_tpg; | |
960 | /* scsiTransportType */ | |
961 | ret = snprintf(page, PAGE_SIZE, "scsiTransport%s\n", | |
e3d6f909 | 962 | tpg->se_tpg_tfo->get_fabric_name()); |
12d23384 NB |
963 | spin_unlock(&lun->lun_sep_lock); |
964 | return ret; | |
965 | } | |
966 | DEV_STAT_SCSI_TRANSPORT_ATTR_RO(device); | |
967 | ||
968 | static ssize_t target_stat_scsi_transport_show_attr_indx( | |
969 | struct se_port_stat_grps *pgrps, char *page) | |
970 | { | |
971 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
972 | struct se_port *sep; | |
973 | struct se_portal_group *tpg; | |
974 | ssize_t ret; | |
975 | ||
976 | spin_lock(&lun->lun_sep_lock); | |
977 | sep = lun->lun_sep; | |
978 | if (!sep) { | |
979 | spin_unlock(&lun->lun_sep_lock); | |
980 | return -ENODEV; | |
981 | } | |
982 | tpg = sep->sep_tpg; | |
983 | ret = snprintf(page, PAGE_SIZE, "%u\n", | |
e3d6f909 | 984 | tpg->se_tpg_tfo->tpg_get_inst_index(tpg)); |
12d23384 NB |
985 | spin_unlock(&lun->lun_sep_lock); |
986 | return ret; | |
987 | } | |
988 | DEV_STAT_SCSI_TRANSPORT_ATTR_RO(indx); | |
989 | ||
990 | static ssize_t target_stat_scsi_transport_show_attr_dev_name( | |
991 | struct se_port_stat_grps *pgrps, char *page) | |
992 | { | |
993 | struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps); | |
994 | struct se_device *dev = lun->lun_se_dev; | |
995 | struct se_port *sep; | |
996 | struct se_portal_group *tpg; | |
997 | struct t10_wwn *wwn; | |
998 | ssize_t ret; | |
999 | ||
1000 | spin_lock(&lun->lun_sep_lock); | |
1001 | sep = lun->lun_sep; | |
1002 | if (!sep) { | |
1003 | spin_unlock(&lun->lun_sep_lock); | |
1004 | return -ENODEV; | |
1005 | } | |
1006 | tpg = sep->sep_tpg; | |
0fd97ccf | 1007 | wwn = &dev->t10_wwn; |
12d23384 NB |
1008 | /* scsiTransportDevName */ |
1009 | ret = snprintf(page, PAGE_SIZE, "%s+%s\n", | |
e3d6f909 | 1010 | tpg->se_tpg_tfo->tpg_get_wwn(tpg), |
12d23384 NB |
1011 | (strlen(wwn->unit_serial)) ? wwn->unit_serial : |
1012 | wwn->vendor); | |
1013 | spin_unlock(&lun->lun_sep_lock); | |
1014 | return ret; | |
1015 | } | |
1016 | DEV_STAT_SCSI_TRANSPORT_ATTR_RO(dev_name); | |
1017 | ||
1018 | CONFIGFS_EATTR_OPS(target_stat_scsi_transport, se_port_stat_grps, | |
1019 | scsi_transport_group); | |
1020 | ||
1021 | static struct configfs_attribute *target_stat_scsi_transport_attrs[] = { | |
1022 | &target_stat_scsi_transport_inst.attr, | |
1023 | &target_stat_scsi_transport_device.attr, | |
1024 | &target_stat_scsi_transport_indx.attr, | |
1025 | &target_stat_scsi_transport_dev_name.attr, | |
1026 | NULL, | |
1027 | }; | |
1028 | ||
1029 | static struct configfs_item_operations target_stat_scsi_transport_attrib_ops = { | |
1030 | .show_attribute = target_stat_scsi_transport_attr_show, | |
1031 | .store_attribute = target_stat_scsi_transport_attr_store, | |
1032 | }; | |
1033 | ||
1034 | static struct config_item_type target_stat_scsi_transport_cit = { | |
1035 | .ct_item_ops = &target_stat_scsi_transport_attrib_ops, | |
1036 | .ct_attrs = target_stat_scsi_transport_attrs, | |
1037 | .ct_owner = THIS_MODULE, | |
1038 | }; | |
1039 | ||
1040 | /* | |
1041 | * Called from target_core_fabric_configfs.c:target_fabric_make_lun() to setup | |
1042 | * the target port statistics groups + configfs CITs located in target_core_stat.c | |
1043 | */ | |
1044 | void target_stat_setup_port_default_groups(struct se_lun *lun) | |
1045 | { | |
e3d6f909 | 1046 | struct config_group *port_stat_grp = &lun->port_stat_grps.stat_group; |
12d23384 | 1047 | |
e3d6f909 | 1048 | config_group_init_type_name(&lun->port_stat_grps.scsi_port_group, |
12d23384 | 1049 | "scsi_port", &target_stat_scsi_port_cit); |
e3d6f909 | 1050 | config_group_init_type_name(&lun->port_stat_grps.scsi_tgt_port_group, |
12d23384 | 1051 | "scsi_tgt_port", &target_stat_scsi_tgt_port_cit); |
e3d6f909 | 1052 | config_group_init_type_name(&lun->port_stat_grps.scsi_transport_group, |
12d23384 NB |
1053 | "scsi_transport", &target_stat_scsi_transport_cit); |
1054 | ||
e3d6f909 AG |
1055 | port_stat_grp->default_groups[0] = &lun->port_stat_grps.scsi_port_group; |
1056 | port_stat_grp->default_groups[1] = &lun->port_stat_grps.scsi_tgt_port_group; | |
1057 | port_stat_grp->default_groups[2] = &lun->port_stat_grps.scsi_transport_group; | |
12d23384 NB |
1058 | port_stat_grp->default_groups[3] = NULL; |
1059 | } | |
1060 | ||
1061 | /* | |
1062 | * SCSI Authorized Initiator Table | |
1063 | */ | |
1064 | ||
1065 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_auth_intr, se_ml_stat_grps); | |
1066 | #define DEV_STAT_SCSI_AUTH_INTR_ATTR(_name, _mode) \ | |
1067 | static struct target_stat_scsi_auth_intr_attribute \ | |
1068 | target_stat_scsi_auth_intr_##_name = \ | |
1069 | __CONFIGFS_EATTR(_name, _mode, \ | |
1070 | target_stat_scsi_auth_intr_show_attr_##_name, \ | |
1071 | target_stat_scsi_auth_intr_store_attr_##_name); | |
1072 | ||
1073 | #define DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(_name) \ | |
1074 | static struct target_stat_scsi_auth_intr_attribute \ | |
1075 | target_stat_scsi_auth_intr_##_name = \ | |
1076 | __CONFIGFS_EATTR_RO(_name, \ | |
1077 | target_stat_scsi_auth_intr_show_attr_##_name); | |
1078 | ||
1079 | static ssize_t target_stat_scsi_auth_intr_show_attr_inst( | |
1080 | struct se_ml_stat_grps *lgrps, char *page) | |
1081 | { | |
1082 | struct se_lun_acl *lacl = container_of(lgrps, | |
1083 | struct se_lun_acl, ml_stat_grps); | |
1084 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1085 | struct se_dev_entry *deve; | |
1086 | struct se_portal_group *tpg; | |
1087 | ssize_t ret; | |
1088 | ||
1089 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1090 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1091 | if (!deve->se_lun || !deve->se_lun_acl) { |
1092 | spin_unlock_irq(&nacl->device_list_lock); | |
1093 | return -ENODEV; | |
1094 | } | |
1095 | tpg = nacl->se_tpg; | |
1096 | /* scsiInstIndex */ | |
1097 | ret = snprintf(page, PAGE_SIZE, "%u\n", | |
e3d6f909 | 1098 | tpg->se_tpg_tfo->tpg_get_inst_index(tpg)); |
12d23384 NB |
1099 | spin_unlock_irq(&nacl->device_list_lock); |
1100 | return ret; | |
1101 | } | |
1102 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(inst); | |
1103 | ||
1104 | static ssize_t target_stat_scsi_auth_intr_show_attr_dev( | |
1105 | struct se_ml_stat_grps *lgrps, char *page) | |
1106 | { | |
1107 | struct se_lun_acl *lacl = container_of(lgrps, | |
1108 | struct se_lun_acl, ml_stat_grps); | |
1109 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1110 | struct se_dev_entry *deve; | |
1111 | struct se_lun *lun; | |
12d23384 NB |
1112 | ssize_t ret; |
1113 | ||
1114 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1115 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1116 | if (!deve->se_lun || !deve->se_lun_acl) { |
1117 | spin_unlock_irq(&nacl->device_list_lock); | |
1118 | return -ENODEV; | |
1119 | } | |
12d23384 NB |
1120 | lun = deve->se_lun; |
1121 | /* scsiDeviceIndex */ | |
1122 | ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_se_dev->dev_index); | |
1123 | spin_unlock_irq(&nacl->device_list_lock); | |
1124 | return ret; | |
1125 | } | |
1126 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev); | |
1127 | ||
1128 | static ssize_t target_stat_scsi_auth_intr_show_attr_port( | |
1129 | struct se_ml_stat_grps *lgrps, char *page) | |
1130 | { | |
1131 | struct se_lun_acl *lacl = container_of(lgrps, | |
1132 | struct se_lun_acl, ml_stat_grps); | |
1133 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1134 | struct se_dev_entry *deve; | |
1135 | struct se_portal_group *tpg; | |
1136 | ssize_t ret; | |
1137 | ||
1138 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1139 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1140 | if (!deve->se_lun || !deve->se_lun_acl) { |
1141 | spin_unlock_irq(&nacl->device_list_lock); | |
1142 | return -ENODEV; | |
1143 | } | |
1144 | tpg = nacl->se_tpg; | |
1145 | /* scsiAuthIntrTgtPortIndex */ | |
e3d6f909 | 1146 | ret = snprintf(page, PAGE_SIZE, "%u\n", tpg->se_tpg_tfo->tpg_get_tag(tpg)); |
12d23384 NB |
1147 | spin_unlock_irq(&nacl->device_list_lock); |
1148 | return ret; | |
1149 | } | |
1150 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(port); | |
1151 | ||
1152 | static ssize_t target_stat_scsi_auth_intr_show_attr_indx( | |
1153 | struct se_ml_stat_grps *lgrps, char *page) | |
1154 | { | |
1155 | struct se_lun_acl *lacl = container_of(lgrps, | |
1156 | struct se_lun_acl, ml_stat_grps); | |
1157 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1158 | struct se_dev_entry *deve; | |
1159 | ssize_t ret; | |
1160 | ||
1161 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1162 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1163 | if (!deve->se_lun || !deve->se_lun_acl) { |
1164 | spin_unlock_irq(&nacl->device_list_lock); | |
1165 | return -ENODEV; | |
1166 | } | |
1167 | /* scsiAuthIntrIndex */ | |
1168 | ret = snprintf(page, PAGE_SIZE, "%u\n", nacl->acl_index); | |
1169 | spin_unlock_irq(&nacl->device_list_lock); | |
1170 | return ret; | |
1171 | } | |
1172 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(indx); | |
1173 | ||
1174 | static ssize_t target_stat_scsi_auth_intr_show_attr_dev_or_port( | |
1175 | struct se_ml_stat_grps *lgrps, char *page) | |
1176 | { | |
1177 | struct se_lun_acl *lacl = container_of(lgrps, | |
1178 | struct se_lun_acl, ml_stat_grps); | |
1179 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1180 | struct se_dev_entry *deve; | |
1181 | ssize_t ret; | |
1182 | ||
1183 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1184 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1185 | if (!deve->se_lun || !deve->se_lun_acl) { |
1186 | spin_unlock_irq(&nacl->device_list_lock); | |
1187 | return -ENODEV; | |
1188 | } | |
1189 | /* scsiAuthIntrDevOrPort */ | |
1190 | ret = snprintf(page, PAGE_SIZE, "%u\n", 1); | |
1191 | spin_unlock_irq(&nacl->device_list_lock); | |
1192 | return ret; | |
1193 | } | |
1194 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(dev_or_port); | |
1195 | ||
1196 | static ssize_t target_stat_scsi_auth_intr_show_attr_intr_name( | |
1197 | struct se_ml_stat_grps *lgrps, char *page) | |
1198 | { | |
1199 | struct se_lun_acl *lacl = container_of(lgrps, | |
1200 | struct se_lun_acl, ml_stat_grps); | |
1201 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1202 | struct se_dev_entry *deve; | |
1203 | ssize_t ret; | |
1204 | ||
1205 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1206 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1207 | if (!deve->se_lun || !deve->se_lun_acl) { |
1208 | spin_unlock_irq(&nacl->device_list_lock); | |
1209 | return -ENODEV; | |
1210 | } | |
1211 | /* scsiAuthIntrName */ | |
1212 | ret = snprintf(page, PAGE_SIZE, "%s\n", nacl->initiatorname); | |
1213 | spin_unlock_irq(&nacl->device_list_lock); | |
1214 | return ret; | |
1215 | } | |
1216 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(intr_name); | |
1217 | ||
1218 | static ssize_t target_stat_scsi_auth_intr_show_attr_map_indx( | |
1219 | struct se_ml_stat_grps *lgrps, char *page) | |
1220 | { | |
1221 | struct se_lun_acl *lacl = container_of(lgrps, | |
1222 | struct se_lun_acl, ml_stat_grps); | |
1223 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1224 | struct se_dev_entry *deve; | |
1225 | ssize_t ret; | |
1226 | ||
1227 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1228 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1229 | if (!deve->se_lun || !deve->se_lun_acl) { |
1230 | spin_unlock_irq(&nacl->device_list_lock); | |
1231 | return -ENODEV; | |
1232 | } | |
1233 | /* FIXME: scsiAuthIntrLunMapIndex */ | |
1234 | ret = snprintf(page, PAGE_SIZE, "%u\n", 0); | |
1235 | spin_unlock_irq(&nacl->device_list_lock); | |
1236 | return ret; | |
1237 | } | |
1238 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(map_indx); | |
1239 | ||
1240 | static ssize_t target_stat_scsi_auth_intr_show_attr_att_count( | |
1241 | struct se_ml_stat_grps *lgrps, char *page) | |
1242 | { | |
1243 | struct se_lun_acl *lacl = container_of(lgrps, | |
1244 | struct se_lun_acl, ml_stat_grps); | |
1245 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1246 | struct se_dev_entry *deve; | |
1247 | ssize_t ret; | |
1248 | ||
1249 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1250 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1251 | if (!deve->se_lun || !deve->se_lun_acl) { |
1252 | spin_unlock_irq(&nacl->device_list_lock); | |
1253 | return -ENODEV; | |
1254 | } | |
1255 | /* scsiAuthIntrAttachedTimes */ | |
1256 | ret = snprintf(page, PAGE_SIZE, "%u\n", deve->attach_count); | |
1257 | spin_unlock_irq(&nacl->device_list_lock); | |
1258 | return ret; | |
1259 | } | |
1260 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(att_count); | |
1261 | ||
1262 | static ssize_t target_stat_scsi_auth_intr_show_attr_num_cmds( | |
1263 | struct se_ml_stat_grps *lgrps, char *page) | |
1264 | { | |
1265 | struct se_lun_acl *lacl = container_of(lgrps, | |
1266 | struct se_lun_acl, ml_stat_grps); | |
1267 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1268 | struct se_dev_entry *deve; | |
1269 | ssize_t ret; | |
1270 | ||
1271 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1272 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1273 | if (!deve->se_lun || !deve->se_lun_acl) { |
1274 | spin_unlock_irq(&nacl->device_list_lock); | |
1275 | return -ENODEV; | |
1276 | } | |
1277 | /* scsiAuthIntrOutCommands */ | |
1278 | ret = snprintf(page, PAGE_SIZE, "%u\n", deve->total_cmds); | |
1279 | spin_unlock_irq(&nacl->device_list_lock); | |
1280 | return ret; | |
1281 | } | |
1282 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(num_cmds); | |
1283 | ||
1284 | static ssize_t target_stat_scsi_auth_intr_show_attr_read_mbytes( | |
1285 | struct se_ml_stat_grps *lgrps, char *page) | |
1286 | { | |
1287 | struct se_lun_acl *lacl = container_of(lgrps, | |
1288 | struct se_lun_acl, ml_stat_grps); | |
1289 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1290 | struct se_dev_entry *deve; | |
1291 | ssize_t ret; | |
1292 | ||
1293 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1294 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1295 | if (!deve->se_lun || !deve->se_lun_acl) { |
1296 | spin_unlock_irq(&nacl->device_list_lock); | |
1297 | return -ENODEV; | |
1298 | } | |
1299 | /* scsiAuthIntrReadMegaBytes */ | |
1300 | ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(deve->read_bytes >> 20)); | |
1301 | spin_unlock_irq(&nacl->device_list_lock); | |
1302 | return ret; | |
1303 | } | |
1304 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(read_mbytes); | |
1305 | ||
1306 | static ssize_t target_stat_scsi_auth_intr_show_attr_write_mbytes( | |
1307 | struct se_ml_stat_grps *lgrps, char *page) | |
1308 | { | |
1309 | struct se_lun_acl *lacl = container_of(lgrps, | |
1310 | struct se_lun_acl, ml_stat_grps); | |
1311 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1312 | struct se_dev_entry *deve; | |
1313 | ssize_t ret; | |
1314 | ||
1315 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1316 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1317 | if (!deve->se_lun || !deve->se_lun_acl) { |
1318 | spin_unlock_irq(&nacl->device_list_lock); | |
1319 | return -ENODEV; | |
1320 | } | |
1321 | /* scsiAuthIntrWrittenMegaBytes */ | |
1322 | ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(deve->write_bytes >> 20)); | |
1323 | spin_unlock_irq(&nacl->device_list_lock); | |
1324 | return ret; | |
1325 | } | |
1326 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(write_mbytes); | |
1327 | ||
1328 | static ssize_t target_stat_scsi_auth_intr_show_attr_hs_num_cmds( | |
1329 | struct se_ml_stat_grps *lgrps, char *page) | |
1330 | { | |
1331 | struct se_lun_acl *lacl = container_of(lgrps, | |
1332 | struct se_lun_acl, ml_stat_grps); | |
1333 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1334 | struct se_dev_entry *deve; | |
1335 | ssize_t ret; | |
1336 | ||
1337 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1338 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1339 | if (!deve->se_lun || !deve->se_lun_acl) { |
1340 | spin_unlock_irq(&nacl->device_list_lock); | |
1341 | return -ENODEV; | |
1342 | } | |
1343 | /* FIXME: scsiAuthIntrHSOutCommands */ | |
1344 | ret = snprintf(page, PAGE_SIZE, "%u\n", 0); | |
1345 | spin_unlock_irq(&nacl->device_list_lock); | |
1346 | return ret; | |
1347 | } | |
1348 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(hs_num_cmds); | |
1349 | ||
1350 | static ssize_t target_stat_scsi_auth_intr_show_attr_creation_time( | |
1351 | struct se_ml_stat_grps *lgrps, char *page) | |
1352 | { | |
1353 | struct se_lun_acl *lacl = container_of(lgrps, | |
1354 | struct se_lun_acl, ml_stat_grps); | |
1355 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1356 | struct se_dev_entry *deve; | |
1357 | ssize_t ret; | |
1358 | ||
1359 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1360 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1361 | if (!deve->se_lun || !deve->se_lun_acl) { |
1362 | spin_unlock_irq(&nacl->device_list_lock); | |
1363 | return -ENODEV; | |
1364 | } | |
1365 | /* scsiAuthIntrLastCreation */ | |
1366 | ret = snprintf(page, PAGE_SIZE, "%u\n", (u32)(((u32)deve->creation_time - | |
1367 | INITIAL_JIFFIES) * 100 / HZ)); | |
1368 | spin_unlock_irq(&nacl->device_list_lock); | |
1369 | return ret; | |
1370 | } | |
1371 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(creation_time); | |
1372 | ||
1373 | static ssize_t target_stat_scsi_auth_intr_show_attr_row_status( | |
1374 | struct se_ml_stat_grps *lgrps, char *page) | |
1375 | { | |
1376 | struct se_lun_acl *lacl = container_of(lgrps, | |
1377 | struct se_lun_acl, ml_stat_grps); | |
1378 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1379 | struct se_dev_entry *deve; | |
1380 | ssize_t ret; | |
1381 | ||
1382 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1383 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1384 | if (!deve->se_lun || !deve->se_lun_acl) { |
1385 | spin_unlock_irq(&nacl->device_list_lock); | |
1386 | return -ENODEV; | |
1387 | } | |
1388 | /* FIXME: scsiAuthIntrRowStatus */ | |
1389 | ret = snprintf(page, PAGE_SIZE, "Ready\n"); | |
1390 | spin_unlock_irq(&nacl->device_list_lock); | |
1391 | return ret; | |
1392 | } | |
1393 | DEV_STAT_SCSI_AUTH_INTR_ATTR_RO(row_status); | |
1394 | ||
1395 | CONFIGFS_EATTR_OPS(target_stat_scsi_auth_intr, se_ml_stat_grps, | |
1396 | scsi_auth_intr_group); | |
1397 | ||
1398 | static struct configfs_attribute *target_stat_scsi_auth_intr_attrs[] = { | |
1399 | &target_stat_scsi_auth_intr_inst.attr, | |
1400 | &target_stat_scsi_auth_intr_dev.attr, | |
1401 | &target_stat_scsi_auth_intr_port.attr, | |
1402 | &target_stat_scsi_auth_intr_indx.attr, | |
1403 | &target_stat_scsi_auth_intr_dev_or_port.attr, | |
1404 | &target_stat_scsi_auth_intr_intr_name.attr, | |
1405 | &target_stat_scsi_auth_intr_map_indx.attr, | |
1406 | &target_stat_scsi_auth_intr_att_count.attr, | |
1407 | &target_stat_scsi_auth_intr_num_cmds.attr, | |
1408 | &target_stat_scsi_auth_intr_read_mbytes.attr, | |
1409 | &target_stat_scsi_auth_intr_write_mbytes.attr, | |
1410 | &target_stat_scsi_auth_intr_hs_num_cmds.attr, | |
1411 | &target_stat_scsi_auth_intr_creation_time.attr, | |
1412 | &target_stat_scsi_auth_intr_row_status.attr, | |
1413 | NULL, | |
1414 | }; | |
1415 | ||
1416 | static struct configfs_item_operations target_stat_scsi_auth_intr_attrib_ops = { | |
1417 | .show_attribute = target_stat_scsi_auth_intr_attr_show, | |
1418 | .store_attribute = target_stat_scsi_auth_intr_attr_store, | |
1419 | }; | |
1420 | ||
1421 | static struct config_item_type target_stat_scsi_auth_intr_cit = { | |
1422 | .ct_item_ops = &target_stat_scsi_auth_intr_attrib_ops, | |
1423 | .ct_attrs = target_stat_scsi_auth_intr_attrs, | |
1424 | .ct_owner = THIS_MODULE, | |
1425 | }; | |
1426 | ||
1427 | /* | |
1428 | * SCSI Attached Initiator Port Table | |
1429 | */ | |
1430 | ||
1431 | CONFIGFS_EATTR_STRUCT(target_stat_scsi_att_intr_port, se_ml_stat_grps); | |
1432 | #define DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR(_name, _mode) \ | |
1433 | static struct target_stat_scsi_att_intr_port_attribute \ | |
1434 | target_stat_scsi_att_intr_port_##_name = \ | |
1435 | __CONFIGFS_EATTR(_name, _mode, \ | |
1436 | target_stat_scsi_att_intr_port_show_attr_##_name, \ | |
1437 | target_stat_scsi_att_intr_port_store_attr_##_name); | |
1438 | ||
1439 | #define DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(_name) \ | |
1440 | static struct target_stat_scsi_att_intr_port_attribute \ | |
1441 | target_stat_scsi_att_intr_port_##_name = \ | |
1442 | __CONFIGFS_EATTR_RO(_name, \ | |
1443 | target_stat_scsi_att_intr_port_show_attr_##_name); | |
1444 | ||
1445 | static ssize_t target_stat_scsi_att_intr_port_show_attr_inst( | |
1446 | struct se_ml_stat_grps *lgrps, char *page) | |
1447 | { | |
1448 | struct se_lun_acl *lacl = container_of(lgrps, | |
1449 | struct se_lun_acl, ml_stat_grps); | |
1450 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1451 | struct se_dev_entry *deve; | |
1452 | struct se_portal_group *tpg; | |
1453 | ssize_t ret; | |
1454 | ||
1455 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1456 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1457 | if (!deve->se_lun || !deve->se_lun_acl) { |
1458 | spin_unlock_irq(&nacl->device_list_lock); | |
1459 | return -ENODEV; | |
1460 | } | |
1461 | tpg = nacl->se_tpg; | |
1462 | /* scsiInstIndex */ | |
1463 | ret = snprintf(page, PAGE_SIZE, "%u\n", | |
e3d6f909 | 1464 | tpg->se_tpg_tfo->tpg_get_inst_index(tpg)); |
12d23384 NB |
1465 | spin_unlock_irq(&nacl->device_list_lock); |
1466 | return ret; | |
1467 | } | |
1468 | DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(inst); | |
1469 | ||
1470 | static ssize_t target_stat_scsi_att_intr_port_show_attr_dev( | |
1471 | struct se_ml_stat_grps *lgrps, char *page) | |
1472 | { | |
1473 | struct se_lun_acl *lacl = container_of(lgrps, | |
1474 | struct se_lun_acl, ml_stat_grps); | |
1475 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1476 | struct se_dev_entry *deve; | |
1477 | struct se_lun *lun; | |
12d23384 NB |
1478 | ssize_t ret; |
1479 | ||
1480 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1481 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1482 | if (!deve->se_lun || !deve->se_lun_acl) { |
1483 | spin_unlock_irq(&nacl->device_list_lock); | |
1484 | return -ENODEV; | |
1485 | } | |
12d23384 NB |
1486 | lun = deve->se_lun; |
1487 | /* scsiDeviceIndex */ | |
1488 | ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_se_dev->dev_index); | |
1489 | spin_unlock_irq(&nacl->device_list_lock); | |
1490 | return ret; | |
1491 | } | |
1492 | DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(dev); | |
1493 | ||
1494 | static ssize_t target_stat_scsi_att_intr_port_show_attr_port( | |
1495 | struct se_ml_stat_grps *lgrps, char *page) | |
1496 | { | |
1497 | struct se_lun_acl *lacl = container_of(lgrps, | |
1498 | struct se_lun_acl, ml_stat_grps); | |
1499 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1500 | struct se_dev_entry *deve; | |
1501 | struct se_portal_group *tpg; | |
1502 | ssize_t ret; | |
1503 | ||
1504 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1505 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1506 | if (!deve->se_lun || !deve->se_lun_acl) { |
1507 | spin_unlock_irq(&nacl->device_list_lock); | |
1508 | return -ENODEV; | |
1509 | } | |
1510 | tpg = nacl->se_tpg; | |
1511 | /* scsiPortIndex */ | |
e3d6f909 | 1512 | ret = snprintf(page, PAGE_SIZE, "%u\n", tpg->se_tpg_tfo->tpg_get_tag(tpg)); |
12d23384 NB |
1513 | spin_unlock_irq(&nacl->device_list_lock); |
1514 | return ret; | |
1515 | } | |
1516 | DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port); | |
1517 | ||
1518 | static ssize_t target_stat_scsi_att_intr_port_show_attr_indx( | |
1519 | struct se_ml_stat_grps *lgrps, char *page) | |
1520 | { | |
1521 | struct se_lun_acl *lacl = container_of(lgrps, | |
1522 | struct se_lun_acl, ml_stat_grps); | |
1523 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1524 | struct se_session *se_sess; | |
1525 | struct se_portal_group *tpg; | |
1526 | ssize_t ret; | |
1527 | ||
1528 | spin_lock_irq(&nacl->nacl_sess_lock); | |
1529 | se_sess = nacl->nacl_sess; | |
1530 | if (!se_sess) { | |
1531 | spin_unlock_irq(&nacl->nacl_sess_lock); | |
1532 | return -ENODEV; | |
1533 | } | |
1534 | ||
1535 | tpg = nacl->se_tpg; | |
1536 | /* scsiAttIntrPortIndex */ | |
1537 | ret = snprintf(page, PAGE_SIZE, "%u\n", | |
e3d6f909 | 1538 | tpg->se_tpg_tfo->sess_get_index(se_sess)); |
12d23384 NB |
1539 | spin_unlock_irq(&nacl->nacl_sess_lock); |
1540 | return ret; | |
1541 | } | |
1542 | DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(indx); | |
1543 | ||
1544 | static ssize_t target_stat_scsi_att_intr_port_show_attr_port_auth_indx( | |
1545 | struct se_ml_stat_grps *lgrps, char *page) | |
1546 | { | |
1547 | struct se_lun_acl *lacl = container_of(lgrps, | |
1548 | struct se_lun_acl, ml_stat_grps); | |
1549 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1550 | struct se_dev_entry *deve; | |
1551 | ssize_t ret; | |
1552 | ||
1553 | spin_lock_irq(&nacl->device_list_lock); | |
f2083241 | 1554 | deve = nacl->device_list[lacl->mapped_lun]; |
12d23384 NB |
1555 | if (!deve->se_lun || !deve->se_lun_acl) { |
1556 | spin_unlock_irq(&nacl->device_list_lock); | |
1557 | return -ENODEV; | |
1558 | } | |
1559 | /* scsiAttIntrPortAuthIntrIdx */ | |
1560 | ret = snprintf(page, PAGE_SIZE, "%u\n", nacl->acl_index); | |
1561 | spin_unlock_irq(&nacl->device_list_lock); | |
1562 | return ret; | |
1563 | } | |
1564 | DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_auth_indx); | |
1565 | ||
1566 | static ssize_t target_stat_scsi_att_intr_port_show_attr_port_ident( | |
1567 | struct se_ml_stat_grps *lgrps, char *page) | |
1568 | { | |
1569 | struct se_lun_acl *lacl = container_of(lgrps, | |
1570 | struct se_lun_acl, ml_stat_grps); | |
1571 | struct se_node_acl *nacl = lacl->se_lun_nacl; | |
1572 | struct se_session *se_sess; | |
1573 | struct se_portal_group *tpg; | |
1574 | ssize_t ret; | |
1575 | unsigned char buf[64]; | |
1576 | ||
1577 | spin_lock_irq(&nacl->nacl_sess_lock); | |
1578 | se_sess = nacl->nacl_sess; | |
1579 | if (!se_sess) { | |
1580 | spin_unlock_irq(&nacl->nacl_sess_lock); | |
1581 | return -ENODEV; | |
1582 | } | |
1583 | ||
1584 | tpg = nacl->se_tpg; | |
1585 | /* scsiAttIntrPortName+scsiAttIntrPortIdentifier */ | |
1586 | memset(buf, 0, 64); | |
e3d6f909 | 1587 | if (tpg->se_tpg_tfo->sess_get_initiator_sid != NULL) |
8359cf43 | 1588 | tpg->se_tpg_tfo->sess_get_initiator_sid(se_sess, buf, 64); |
12d23384 NB |
1589 | |
1590 | ret = snprintf(page, PAGE_SIZE, "%s+i+%s\n", nacl->initiatorname, buf); | |
1591 | spin_unlock_irq(&nacl->nacl_sess_lock); | |
1592 | return ret; | |
1593 | } | |
1594 | DEV_STAT_SCSI_ATTR_INTR_PORT_ATTR_RO(port_ident); | |
1595 | ||
1596 | CONFIGFS_EATTR_OPS(target_stat_scsi_att_intr_port, se_ml_stat_grps, | |
1597 | scsi_att_intr_port_group); | |
1598 | ||
1599 | static struct configfs_attribute *target_stat_scsi_ath_intr_port_attrs[] = { | |
1600 | &target_stat_scsi_att_intr_port_inst.attr, | |
1601 | &target_stat_scsi_att_intr_port_dev.attr, | |
1602 | &target_stat_scsi_att_intr_port_port.attr, | |
1603 | &target_stat_scsi_att_intr_port_indx.attr, | |
1604 | &target_stat_scsi_att_intr_port_port_auth_indx.attr, | |
1605 | &target_stat_scsi_att_intr_port_port_ident.attr, | |
1606 | NULL, | |
1607 | }; | |
1608 | ||
1609 | static struct configfs_item_operations target_stat_scsi_att_intr_port_attrib_ops = { | |
1610 | .show_attribute = target_stat_scsi_att_intr_port_attr_show, | |
1611 | .store_attribute = target_stat_scsi_att_intr_port_attr_store, | |
1612 | }; | |
1613 | ||
1614 | static struct config_item_type target_stat_scsi_att_intr_port_cit = { | |
1615 | .ct_item_ops = &target_stat_scsi_att_intr_port_attrib_ops, | |
1616 | .ct_attrs = target_stat_scsi_ath_intr_port_attrs, | |
1617 | .ct_owner = THIS_MODULE, | |
1618 | }; | |
1619 | ||
1620 | /* | |
1621 | * Called from target_core_fabric_configfs.c:target_fabric_make_mappedlun() to setup | |
1622 | * the target MappedLUN statistics groups + configfs CITs located in target_core_stat.c | |
1623 | */ | |
1624 | void target_stat_setup_mappedlun_default_groups(struct se_lun_acl *lacl) | |
1625 | { | |
e3d6f909 | 1626 | struct config_group *ml_stat_grp = &lacl->ml_stat_grps.stat_group; |
12d23384 | 1627 | |
e3d6f909 | 1628 | config_group_init_type_name(&lacl->ml_stat_grps.scsi_auth_intr_group, |
12d23384 | 1629 | "scsi_auth_intr", &target_stat_scsi_auth_intr_cit); |
e3d6f909 | 1630 | config_group_init_type_name(&lacl->ml_stat_grps.scsi_att_intr_port_group, |
12d23384 NB |
1631 | "scsi_att_intr_port", &target_stat_scsi_att_intr_port_cit); |
1632 | ||
e3d6f909 AG |
1633 | ml_stat_grp->default_groups[0] = &lacl->ml_stat_grps.scsi_auth_intr_group; |
1634 | ml_stat_grp->default_groups[1] = &lacl->ml_stat_grps.scsi_att_intr_port_group; | |
12d23384 NB |
1635 | ml_stat_grp->default_groups[2] = NULL; |
1636 | } |