qla_attr.c revision 7914d004bcff3e59ca7c0d628f9862fe6655429c
1/* 2 * QLogic Fibre Channel HBA Driver 3 * Copyright (c) 2003-2005 QLogic Corporation 4 * 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 */ 7#include "qla_def.h" 8 9#include <linux/vmalloc.h> 10 11/* SYSFS attributes --------------------------------------------------------- */ 12 13static ssize_t 14qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off, 15 size_t count) 16{ 17 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 18 struct device, kobj))); 19 char *rbuf = (char *)ha->fw_dump; 20 21 if (ha->fw_dump_reading == 0) 22 return 0; 23 if (off > ha->fw_dump_len) 24 return 0; 25 if (off + count > ha->fw_dump_len) 26 count = ha->fw_dump_len - off; 27 28 memcpy(buf, &rbuf[off], count); 29 30 return (count); 31} 32 33static ssize_t 34qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off, 35 size_t count) 36{ 37 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 38 struct device, kobj))); 39 int reading; 40 41 if (off != 0) 42 return (0); 43 44 reading = simple_strtol(buf, NULL, 10); 45 switch (reading) { 46 case 0: 47 if (!ha->fw_dump_reading) 48 break; 49 50 qla_printk(KERN_INFO, ha, 51 "Firmware dump cleared on (%ld).\n", ha->host_no); 52 53 ha->fw_dump_reading = 0; 54 ha->fw_dumped = 0; 55 break; 56 case 1: 57 if (ha->fw_dumped && !ha->fw_dump_reading) { 58 ha->fw_dump_reading = 1; 59 60 qla_printk(KERN_INFO, ha, 61 "Raw firmware dump ready for read on (%ld).\n", 62 ha->host_no); 63 } 64 break; 65 case 2: 66 qla2x00_alloc_fw_dump(ha); 67 break; 68 } 69 return (count); 70} 71 72static struct bin_attribute sysfs_fw_dump_attr = { 73 .attr = { 74 .name = "fw_dump", 75 .mode = S_IRUSR | S_IWUSR, 76 .owner = THIS_MODULE, 77 }, 78 .size = 0, 79 .read = qla2x00_sysfs_read_fw_dump, 80 .write = qla2x00_sysfs_write_fw_dump, 81}; 82 83static ssize_t 84qla2x00_sysfs_read_nvram(struct kobject *kobj, char *buf, loff_t off, 85 size_t count) 86{ 87 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 88 struct device, kobj))); 89 unsigned long flags; 90 91 if (!capable(CAP_SYS_ADMIN) || off != 0) 92 return 0; 93 94 /* Read NVRAM. */ 95 spin_lock_irqsave(&ha->hardware_lock, flags); 96 ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->nvram_base, 97 ha->nvram_size); 98 spin_unlock_irqrestore(&ha->hardware_lock, flags); 99 100 return ha->nvram_size; 101} 102 103static ssize_t 104qla2x00_sysfs_write_nvram(struct kobject *kobj, char *buf, loff_t off, 105 size_t count) 106{ 107 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 108 struct device, kobj))); 109 unsigned long flags; 110 uint16_t cnt; 111 112 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) 113 return 0; 114 115 /* Checksum NVRAM. */ 116 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 117 uint32_t *iter; 118 uint32_t chksum; 119 120 iter = (uint32_t *)buf; 121 chksum = 0; 122 for (cnt = 0; cnt < ((count >> 2) - 1); cnt++) 123 chksum += le32_to_cpu(*iter++); 124 chksum = ~chksum + 1; 125 *iter = cpu_to_le32(chksum); 126 } else { 127 uint8_t *iter; 128 uint8_t chksum; 129 130 iter = (uint8_t *)buf; 131 chksum = 0; 132 for (cnt = 0; cnt < count - 1; cnt++) 133 chksum += *iter++; 134 chksum = ~chksum + 1; 135 *iter = chksum; 136 } 137 138 /* Write NVRAM. */ 139 spin_lock_irqsave(&ha->hardware_lock, flags); 140 ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); 141 spin_unlock_irqrestore(&ha->hardware_lock, flags); 142 143 return (count); 144} 145 146static struct bin_attribute sysfs_nvram_attr = { 147 .attr = { 148 .name = "nvram", 149 .mode = S_IRUSR | S_IWUSR, 150 .owner = THIS_MODULE, 151 }, 152 .size = 512, 153 .read = qla2x00_sysfs_read_nvram, 154 .write = qla2x00_sysfs_write_nvram, 155}; 156 157static ssize_t 158qla2x00_sysfs_read_optrom(struct kobject *kobj, char *buf, loff_t off, 159 size_t count) 160{ 161 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 162 struct device, kobj))); 163 164 if (ha->optrom_state != QLA_SREADING) 165 return 0; 166 if (off > ha->optrom_size) 167 return 0; 168 if (off + count > ha->optrom_size) 169 count = ha->optrom_size - off; 170 171 memcpy(buf, &ha->optrom_buffer[off], count); 172 173 return count; 174} 175 176static ssize_t 177qla2x00_sysfs_write_optrom(struct kobject *kobj, char *buf, loff_t off, 178 size_t count) 179{ 180 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 181 struct device, kobj))); 182 183 if (ha->optrom_state != QLA_SWRITING) 184 return -EINVAL; 185 if (off > ha->optrom_size) 186 return -ERANGE; 187 if (off + count > ha->optrom_size) 188 count = ha->optrom_size - off; 189 190 memcpy(&ha->optrom_buffer[off], buf, count); 191 192 return count; 193} 194 195static struct bin_attribute sysfs_optrom_attr = { 196 .attr = { 197 .name = "optrom", 198 .mode = S_IRUSR | S_IWUSR, 199 .owner = THIS_MODULE, 200 }, 201 .size = OPTROM_SIZE_24XX, 202 .read = qla2x00_sysfs_read_optrom, 203 .write = qla2x00_sysfs_write_optrom, 204}; 205 206static ssize_t 207qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, char *buf, loff_t off, 208 size_t count) 209{ 210 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 211 struct device, kobj))); 212 int val; 213 214 if (off) 215 return 0; 216 217 if (sscanf(buf, "%d", &val) != 1) 218 return -EINVAL; 219 220 switch (val) { 221 case 0: 222 if (ha->optrom_state != QLA_SREADING && 223 ha->optrom_state != QLA_SWRITING) 224 break; 225 226 ha->optrom_state = QLA_SWAITING; 227 vfree(ha->optrom_buffer); 228 ha->optrom_buffer = NULL; 229 break; 230 case 1: 231 if (ha->optrom_state != QLA_SWAITING) 232 break; 233 234 ha->optrom_state = QLA_SREADING; 235 ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); 236 if (ha->optrom_buffer == NULL) { 237 qla_printk(KERN_WARNING, ha, 238 "Unable to allocate memory for optrom retrieval " 239 "(%x).\n", ha->optrom_size); 240 241 ha->optrom_state = QLA_SWAITING; 242 return count; 243 } 244 245 memset(ha->optrom_buffer, 0, ha->optrom_size); 246 ha->isp_ops.read_optrom(ha, ha->optrom_buffer, 0, 247 ha->optrom_size); 248 break; 249 case 2: 250 if (ha->optrom_state != QLA_SWAITING) 251 break; 252 253 ha->optrom_state = QLA_SWRITING; 254 ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); 255 if (ha->optrom_buffer == NULL) { 256 qla_printk(KERN_WARNING, ha, 257 "Unable to allocate memory for optrom update " 258 "(%x).\n", ha->optrom_size); 259 260 ha->optrom_state = QLA_SWAITING; 261 return count; 262 } 263 memset(ha->optrom_buffer, 0, ha->optrom_size); 264 break; 265 case 3: 266 if (ha->optrom_state != QLA_SWRITING) 267 break; 268 269 ha->isp_ops.write_optrom(ha, ha->optrom_buffer, 0, 270 ha->optrom_size); 271 break; 272 } 273 return count; 274} 275 276static struct bin_attribute sysfs_optrom_ctl_attr = { 277 .attr = { 278 .name = "optrom_ctl", 279 .mode = S_IWUSR, 280 .owner = THIS_MODULE, 281 }, 282 .size = 0, 283 .write = qla2x00_sysfs_write_optrom_ctl, 284}; 285 286static ssize_t 287qla2x00_sysfs_read_vpd(struct kobject *kobj, char *buf, loff_t off, 288 size_t count) 289{ 290 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 291 struct device, kobj))); 292 unsigned long flags; 293 294 if (!capable(CAP_SYS_ADMIN) || off != 0) 295 return 0; 296 297 /* Read NVRAM. */ 298 spin_lock_irqsave(&ha->hardware_lock, flags); 299 ha->isp_ops.read_nvram(ha, (uint8_t *)buf, ha->vpd_base, ha->vpd_size); 300 spin_unlock_irqrestore(&ha->hardware_lock, flags); 301 302 return ha->vpd_size; 303} 304 305static ssize_t 306qla2x00_sysfs_write_vpd(struct kobject *kobj, char *buf, loff_t off, 307 size_t count) 308{ 309 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 310 struct device, kobj))); 311 unsigned long flags; 312 313 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) 314 return 0; 315 316 /* Write NVRAM. */ 317 spin_lock_irqsave(&ha->hardware_lock, flags); 318 ha->isp_ops.write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); 319 spin_unlock_irqrestore(&ha->hardware_lock, flags); 320 321 return count; 322} 323 324static struct bin_attribute sysfs_vpd_attr = { 325 .attr = { 326 .name = "vpd", 327 .mode = S_IRUSR | S_IWUSR, 328 .owner = THIS_MODULE, 329 }, 330 .size = 0, 331 .read = qla2x00_sysfs_read_vpd, 332 .write = qla2x00_sysfs_write_vpd, 333}; 334 335static ssize_t 336qla2x00_sysfs_read_sfp(struct kobject *kobj, char *buf, loff_t off, 337 size_t count) 338{ 339 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 340 struct device, kobj))); 341 uint16_t iter, addr, offset; 342 int rval; 343 344 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2) 345 return 0; 346 347 addr = 0xa0; 348 for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE; 349 iter++, offset += SFP_BLOCK_SIZE) { 350 if (iter == 4) { 351 /* Skip to next device address. */ 352 addr = 0xa2; 353 offset = 0; 354 } 355 356 rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset, 357 SFP_BLOCK_SIZE); 358 if (rval != QLA_SUCCESS) { 359 qla_printk(KERN_WARNING, ha, 360 "Unable to read SFP data (%x/%x/%x).\n", rval, 361 addr, offset); 362 count = 0; 363 break; 364 } 365 memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE); 366 buf += SFP_BLOCK_SIZE; 367 } 368 369 return count; 370} 371 372static struct bin_attribute sysfs_sfp_attr = { 373 .attr = { 374 .name = "sfp", 375 .mode = S_IRUSR | S_IWUSR, 376 .owner = THIS_MODULE, 377 }, 378 .size = SFP_DEV_SIZE * 2, 379 .read = qla2x00_sysfs_read_sfp, 380}; 381 382void 383qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) 384{ 385 struct Scsi_Host *host = ha->host; 386 387 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); 388 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); 389 sysfs_create_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); 390 sysfs_create_bin_file(&host->shost_gendev.kobj, 391 &sysfs_optrom_ctl_attr); 392 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 393 sysfs_create_bin_file(&host->shost_gendev.kobj, 394 &sysfs_vpd_attr); 395 sysfs_create_bin_file(&host->shost_gendev.kobj, 396 &sysfs_sfp_attr); 397 } 398} 399 400void 401qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) 402{ 403 struct Scsi_Host *host = ha->host; 404 405 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_fw_dump_attr); 406 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_nvram_attr); 407 sysfs_remove_bin_file(&host->shost_gendev.kobj, &sysfs_optrom_attr); 408 sysfs_remove_bin_file(&host->shost_gendev.kobj, 409 &sysfs_optrom_ctl_attr); 410 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 411 sysfs_remove_bin_file(&host->shost_gendev.kobj, 412 &sysfs_vpd_attr); 413 sysfs_remove_bin_file(&host->shost_gendev.kobj, 414 &sysfs_sfp_attr); 415 } 416 417 if (ha->beacon_blink_led == 1) 418 ha->isp_ops.beacon_off(ha); 419} 420 421/* Scsi_Host attributes. */ 422 423static ssize_t 424qla2x00_drvr_version_show(struct class_device *cdev, char *buf) 425{ 426 return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str); 427} 428 429static ssize_t 430qla2x00_fw_version_show(struct class_device *cdev, char *buf) 431{ 432 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 433 char fw_str[30]; 434 435 return snprintf(buf, PAGE_SIZE, "%s\n", 436 ha->isp_ops.fw_version_str(ha, fw_str)); 437} 438 439static ssize_t 440qla2x00_serial_num_show(struct class_device *cdev, char *buf) 441{ 442 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 443 uint32_t sn; 444 445 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; 446 return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, 447 sn % 100000); 448} 449 450static ssize_t 451qla2x00_isp_name_show(struct class_device *cdev, char *buf) 452{ 453 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 454 return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); 455} 456 457static ssize_t 458qla2x00_isp_id_show(struct class_device *cdev, char *buf) 459{ 460 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 461 return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", 462 ha->product_id[0], ha->product_id[1], ha->product_id[2], 463 ha->product_id[3]); 464} 465 466static ssize_t 467qla2x00_model_name_show(struct class_device *cdev, char *buf) 468{ 469 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 470 return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number); 471} 472 473static ssize_t 474qla2x00_model_desc_show(struct class_device *cdev, char *buf) 475{ 476 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 477 return snprintf(buf, PAGE_SIZE, "%s\n", 478 ha->model_desc ? ha->model_desc: ""); 479} 480 481static ssize_t 482qla2x00_pci_info_show(struct class_device *cdev, char *buf) 483{ 484 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 485 char pci_info[30]; 486 487 return snprintf(buf, PAGE_SIZE, "%s\n", 488 ha->isp_ops.pci_info_str(ha, pci_info)); 489} 490 491static ssize_t 492qla2x00_state_show(struct class_device *cdev, char *buf) 493{ 494 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 495 int len = 0; 496 497 if (atomic_read(&ha->loop_state) == LOOP_DOWN || 498 atomic_read(&ha->loop_state) == LOOP_DEAD) 499 len = snprintf(buf, PAGE_SIZE, "Link Down\n"); 500 else if (atomic_read(&ha->loop_state) != LOOP_READY || 501 test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || 502 test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) 503 len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n"); 504 else { 505 len = snprintf(buf, PAGE_SIZE, "Link Up - "); 506 507 switch (ha->current_topology) { 508 case ISP_CFG_NL: 509 len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n"); 510 break; 511 case ISP_CFG_FL: 512 len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n"); 513 break; 514 case ISP_CFG_N: 515 len += snprintf(buf + len, PAGE_SIZE-len, 516 "N_Port to N_Port\n"); 517 break; 518 case ISP_CFG_F: 519 len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n"); 520 break; 521 default: 522 len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n"); 523 break; 524 } 525 } 526 return len; 527} 528 529static ssize_t 530qla2x00_zio_show(struct class_device *cdev, char *buf) 531{ 532 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 533 int len = 0; 534 535 switch (ha->zio_mode) { 536 case QLA_ZIO_MODE_6: 537 len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); 538 break; 539 case QLA_ZIO_DISABLED: 540 len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); 541 break; 542 } 543 return len; 544} 545 546static ssize_t 547qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) 548{ 549 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 550 int val = 0; 551 uint16_t zio_mode; 552 553 if (!IS_ZIO_SUPPORTED(ha)) 554 return -ENOTSUPP; 555 556 if (sscanf(buf, "%d", &val) != 1) 557 return -EINVAL; 558 559 if (val) 560 zio_mode = QLA_ZIO_MODE_6; 561 else 562 zio_mode = QLA_ZIO_DISABLED; 563 564 /* Update per-hba values and queue a reset. */ 565 if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { 566 ha->zio_mode = zio_mode; 567 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 568 } 569 return strlen(buf); 570} 571 572static ssize_t 573qla2x00_zio_timer_show(struct class_device *cdev, char *buf) 574{ 575 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 576 577 return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); 578} 579 580static ssize_t 581qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, 582 size_t count) 583{ 584 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 585 int val = 0; 586 uint16_t zio_timer; 587 588 if (sscanf(buf, "%d", &val) != 1) 589 return -EINVAL; 590 if (val > 25500 || val < 100) 591 return -ERANGE; 592 593 zio_timer = (uint16_t)(val / 100); 594 ha->zio_timer = zio_timer; 595 596 return strlen(buf); 597} 598 599static ssize_t 600qla2x00_beacon_show(struct class_device *cdev, char *buf) 601{ 602 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 603 int len = 0; 604 605 if (ha->beacon_blink_led) 606 len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n"); 607 else 608 len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); 609 return len; 610} 611 612static ssize_t 613qla2x00_beacon_store(struct class_device *cdev, const char *buf, 614 size_t count) 615{ 616 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 617 int val = 0; 618 int rval; 619 620 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 621 return -EPERM; 622 623 if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) { 624 qla_printk(KERN_WARNING, ha, 625 "Abort ISP active -- ignoring beacon request.\n"); 626 return -EBUSY; 627 } 628 629 if (sscanf(buf, "%d", &val) != 1) 630 return -EINVAL; 631 632 if (val) 633 rval = ha->isp_ops.beacon_on(ha); 634 else 635 rval = ha->isp_ops.beacon_off(ha); 636 637 if (rval != QLA_SUCCESS) 638 count = 0; 639 640 return count; 641} 642 643static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, 644 NULL); 645static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); 646static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); 647static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL); 648static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL); 649static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL); 650static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL); 651static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL); 652static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL); 653static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show, 654 qla2x00_zio_store); 655static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, 656 qla2x00_zio_timer_store); 657static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, 658 qla2x00_beacon_store); 659 660struct class_device_attribute *qla2x00_host_attrs[] = { 661 &class_device_attr_driver_version, 662 &class_device_attr_fw_version, 663 &class_device_attr_serial_num, 664 &class_device_attr_isp_name, 665 &class_device_attr_isp_id, 666 &class_device_attr_model_name, 667 &class_device_attr_model_desc, 668 &class_device_attr_pci_info, 669 &class_device_attr_state, 670 &class_device_attr_zio, 671 &class_device_attr_zio_timer, 672 &class_device_attr_beacon, 673 NULL, 674}; 675 676/* Host attributes. */ 677 678static void 679qla2x00_get_host_port_id(struct Scsi_Host *shost) 680{ 681 scsi_qla_host_t *ha = to_qla_host(shost); 682 683 fc_host_port_id(shost) = ha->d_id.b.domain << 16 | 684 ha->d_id.b.area << 8 | ha->d_id.b.al_pa; 685} 686 687static void 688qla2x00_get_host_speed(struct Scsi_Host *shost) 689{ 690 scsi_qla_host_t *ha = to_qla_host(shost); 691 uint32_t speed = 0; 692 693 switch (ha->link_data_rate) { 694 case LDR_1GB: 695 speed = 1; 696 break; 697 case LDR_2GB: 698 speed = 2; 699 break; 700 case LDR_4GB: 701 speed = 4; 702 break; 703 } 704 fc_host_speed(shost) = speed; 705} 706 707static void 708qla2x00_get_host_port_type(struct Scsi_Host *shost) 709{ 710 scsi_qla_host_t *ha = to_qla_host(shost); 711 uint32_t port_type = FC_PORTTYPE_UNKNOWN; 712 713 switch (ha->current_topology) { 714 case ISP_CFG_NL: 715 port_type = FC_PORTTYPE_LPORT; 716 break; 717 case ISP_CFG_FL: 718 port_type = FC_PORTTYPE_NLPORT; 719 break; 720 case ISP_CFG_N: 721 port_type = FC_PORTTYPE_PTP; 722 break; 723 case ISP_CFG_F: 724 port_type = FC_PORTTYPE_NPORT; 725 break; 726 } 727 fc_host_port_type(shost) = port_type; 728} 729 730static void 731qla2x00_get_starget_node_name(struct scsi_target *starget) 732{ 733 struct Scsi_Host *host = dev_to_shost(starget->dev.parent); 734 scsi_qla_host_t *ha = to_qla_host(host); 735 fc_port_t *fcport; 736 u64 node_name = 0; 737 738 list_for_each_entry(fcport, &ha->fcports, list) { 739 if (starget->id == fcport->os_target_id) { 740 node_name = wwn_to_u64(fcport->node_name); 741 break; 742 } 743 } 744 745 fc_starget_node_name(starget) = node_name; 746} 747 748static void 749qla2x00_get_starget_port_name(struct scsi_target *starget) 750{ 751 struct Scsi_Host *host = dev_to_shost(starget->dev.parent); 752 scsi_qla_host_t *ha = to_qla_host(host); 753 fc_port_t *fcport; 754 u64 port_name = 0; 755 756 list_for_each_entry(fcport, &ha->fcports, list) { 757 if (starget->id == fcport->os_target_id) { 758 port_name = wwn_to_u64(fcport->port_name); 759 break; 760 } 761 } 762 763 fc_starget_port_name(starget) = port_name; 764} 765 766static void 767qla2x00_get_starget_port_id(struct scsi_target *starget) 768{ 769 struct Scsi_Host *host = dev_to_shost(starget->dev.parent); 770 scsi_qla_host_t *ha = to_qla_host(host); 771 fc_port_t *fcport; 772 uint32_t port_id = ~0U; 773 774 list_for_each_entry(fcport, &ha->fcports, list) { 775 if (starget->id == fcport->os_target_id) { 776 port_id = fcport->d_id.b.domain << 16 | 777 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; 778 break; 779 } 780 } 781 782 fc_starget_port_id(starget) = port_id; 783} 784 785static void 786qla2x00_get_rport_loss_tmo(struct fc_rport *rport) 787{ 788 struct Scsi_Host *host = rport_to_shost(rport); 789 scsi_qla_host_t *ha = to_qla_host(host); 790 791 rport->dev_loss_tmo = ha->port_down_retry_count + 5; 792} 793 794static void 795qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 796{ 797 struct Scsi_Host *host = rport_to_shost(rport); 798 scsi_qla_host_t *ha = to_qla_host(host); 799 800 if (timeout) 801 ha->port_down_retry_count = timeout; 802 else 803 ha->port_down_retry_count = 1; 804 805 rport->dev_loss_tmo = ha->port_down_retry_count + 5; 806} 807 808static int 809qla2x00_issue_lip(struct Scsi_Host *shost) 810{ 811 scsi_qla_host_t *ha = to_qla_host(shost); 812 813 set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags); 814 return 0; 815} 816 817static struct fc_host_statistics * 818qla2x00_get_fc_host_stats(struct Scsi_Host *shost) 819{ 820 scsi_qla_host_t *ha = to_qla_host(shost); 821 int rval; 822 uint16_t mb_stat[1]; 823 link_stat_t stat_buf; 824 struct fc_host_statistics *pfc_host_stat; 825 826 pfc_host_stat = &ha->fc_host_stat; 827 memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); 828 829 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) { 830 rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, 831 sizeof(stat_buf) / 4, mb_stat); 832 } else { 833 rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, 834 mb_stat); 835 } 836 if (rval != 0) { 837 qla_printk(KERN_WARNING, ha, 838 "Unable to retrieve host statistics (%d).\n", mb_stat[0]); 839 return pfc_host_stat; 840 } 841 842 pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; 843 pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; 844 pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt; 845 pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; 846 pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; 847 pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; 848 849 return pfc_host_stat; 850} 851 852struct fc_function_template qla2xxx_transport_functions = { 853 854 .show_host_node_name = 1, 855 .show_host_port_name = 1, 856 .show_host_supported_classes = 1, 857 858 .get_host_port_id = qla2x00_get_host_port_id, 859 .show_host_port_id = 1, 860 .get_host_speed = qla2x00_get_host_speed, 861 .show_host_speed = 1, 862 .get_host_port_type = qla2x00_get_host_port_type, 863 .show_host_port_type = 1, 864 865 .dd_fcrport_size = sizeof(struct fc_port *), 866 .show_rport_supported_classes = 1, 867 868 .get_starget_node_name = qla2x00_get_starget_node_name, 869 .show_starget_node_name = 1, 870 .get_starget_port_name = qla2x00_get_starget_port_name, 871 .show_starget_port_name = 1, 872 .get_starget_port_id = qla2x00_get_starget_port_id, 873 .show_starget_port_id = 1, 874 875 .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, 876 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, 877 .show_rport_dev_loss_tmo = 1, 878 879 .issue_fc_host_lip = qla2x00_issue_lip, 880 .get_fc_host_stats = qla2x00_get_fc_host_stats, 881}; 882 883void 884qla2x00_init_host_attr(scsi_qla_host_t *ha) 885{ 886 fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); 887 fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); 888 fc_host_supported_classes(ha->host) = FC_COS_CLASS3; 889} 890