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