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/kthread.h> 10 #include <linux/vmalloc.h> 11 12 int qla24xx_vport_disable(struct fc_vport *, bool); 13 14 /* SYSFS attributes --------------------------------------------------------- */ 15 16 static ssize_t 17 qla2x00_sysfs_read_fw_dump(struct kobject *kobj, 18 struct bin_attribute *bin_attr, 19 char *buf, loff_t off, size_t count) 20 { 21 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 22 struct device, kobj))); 23 char *rbuf = (char *)ha->fw_dump; 24 25 if (ha->fw_dump_reading == 0) 26 return 0; 27 if (off > ha->fw_dump_len) 28 return 0; 29 if (off + count > ha->fw_dump_len) 30 count = ha->fw_dump_len - off; 31 32 memcpy(buf, &rbuf[off], count); 33 34 return (count); 35 } 36 37 static ssize_t 38 qla2x00_sysfs_write_fw_dump(struct kobject *kobj, 39 struct bin_attribute *bin_attr, 40 char *buf, loff_t off, size_t count) 41 { 42 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 43 struct device, kobj))); 44 int reading; 45 46 if (off != 0) 47 return (0); 48 49 reading = simple_strtol(buf, NULL, 10); 50 switch (reading) { 51 case 0: 52 if (!ha->fw_dump_reading) 53 break; 54 55 qla_printk(KERN_INFO, ha, 56 "Firmware dump cleared on (%ld).\n", ha->host_no); 57 58 ha->fw_dump_reading = 0; 59 ha->fw_dumped = 0; 60 break; 61 case 1: 62 if (ha->fw_dumped && !ha->fw_dump_reading) { 63 ha->fw_dump_reading = 1; 64 65 qla_printk(KERN_INFO, ha, 66 "Raw firmware dump ready for read on (%ld).\n", 67 ha->host_no); 68 } 69 break; 70 case 2: 71 qla2x00_alloc_fw_dump(ha); 72 break; 73 } 74 return (count); 75 } 76 77 static struct bin_attribute sysfs_fw_dump_attr = { 78 .attr = { 79 .name = "fw_dump", 80 .mode = S_IRUSR | S_IWUSR, 81 }, 82 .size = 0, 83 .read = qla2x00_sysfs_read_fw_dump, 84 .write = qla2x00_sysfs_write_fw_dump, 85 }; 86 87 static ssize_t 88 qla2x00_sysfs_read_nvram(struct kobject *kobj, 89 struct bin_attribute *bin_attr, 90 char *buf, loff_t off, size_t count) 91 { 92 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 93 struct device, kobj))); 94 int size = ha->nvram_size; 95 char *nvram_cache = ha->nvram; 96 97 if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) 98 return 0; 99 if (off + count > size) { 100 size -= off; 101 count = size; 102 } 103 104 /* Read NVRAM data from cache. */ 105 memcpy(buf, &nvram_cache[off], count); 106 107 return count; 108 } 109 110 static ssize_t 111 qla2x00_sysfs_write_nvram(struct kobject *kobj, 112 struct bin_attribute *bin_attr, 113 char *buf, loff_t off, size_t count) 114 { 115 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 116 struct device, kobj))); 117 unsigned long flags; 118 uint16_t cnt; 119 120 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) 121 return 0; 122 123 /* Checksum NVRAM. */ 124 if (IS_FWI2_CAPABLE(ha)) { 125 uint32_t *iter; 126 uint32_t chksum; 127 128 iter = (uint32_t *)buf; 129 chksum = 0; 130 for (cnt = 0; cnt < ((count >> 2) - 1); cnt++) 131 chksum += le32_to_cpu(*iter++); 132 chksum = ~chksum + 1; 133 *iter = cpu_to_le32(chksum); 134 } else { 135 uint8_t *iter; 136 uint8_t chksum; 137 138 iter = (uint8_t *)buf; 139 chksum = 0; 140 for (cnt = 0; cnt < count - 1; cnt++) 141 chksum += *iter++; 142 chksum = ~chksum + 1; 143 *iter = chksum; 144 } 145 146 /* Write NVRAM. */ 147 spin_lock_irqsave(&ha->hardware_lock, flags); 148 ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); 149 ha->isp_ops->read_nvram(ha, (uint8_t *)&ha->nvram, ha->nvram_base, 150 count); 151 spin_unlock_irqrestore(&ha->hardware_lock, flags); 152 153 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 154 155 return (count); 156 } 157 158 static struct bin_attribute sysfs_nvram_attr = { 159 .attr = { 160 .name = "nvram", 161 .mode = S_IRUSR | S_IWUSR, 162 }, 163 .size = 512, 164 .read = qla2x00_sysfs_read_nvram, 165 .write = qla2x00_sysfs_write_nvram, 166 }; 167 168 static ssize_t 169 qla2x00_sysfs_read_optrom(struct kobject *kobj, 170 struct bin_attribute *bin_attr, 171 char *buf, loff_t off, size_t count) 172 { 173 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 174 struct device, kobj))); 175 176 if (ha->optrom_state != QLA_SREADING) 177 return 0; 178 if (off > ha->optrom_size) 179 return 0; 180 if (off + count > ha->optrom_size) 181 count = ha->optrom_size - off; 182 183 memcpy(buf, &ha->optrom_buffer[off], count); 184 185 return count; 186 } 187 188 static ssize_t 189 qla2x00_sysfs_write_optrom(struct kobject *kobj, 190 struct bin_attribute *bin_attr, 191 char *buf, loff_t off, size_t count) 192 { 193 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 194 struct device, kobj))); 195 196 if (ha->optrom_state != QLA_SWRITING) 197 return -EINVAL; 198 if (off > ha->optrom_size) 199 return -ERANGE; 200 if (off + count > ha->optrom_size) 201 count = ha->optrom_size - off; 202 203 memcpy(&ha->optrom_buffer[off], buf, count); 204 205 return count; 206 } 207 208 static struct bin_attribute sysfs_optrom_attr = { 209 .attr = { 210 .name = "optrom", 211 .mode = S_IRUSR | S_IWUSR, 212 }, 213 .size = 0, 214 .read = qla2x00_sysfs_read_optrom, 215 .write = qla2x00_sysfs_write_optrom, 216 }; 217 218 static ssize_t 219 qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, 220 struct bin_attribute *bin_attr, 221 char *buf, loff_t off, size_t count) 222 { 223 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 224 struct device, kobj))); 225 int val; 226 227 if (off) 228 return 0; 229 230 if (sscanf(buf, "%d", &val) != 1) 231 return -EINVAL; 232 233 switch (val) { 234 case 0: 235 if (ha->optrom_state != QLA_SREADING && 236 ha->optrom_state != QLA_SWRITING) 237 break; 238 239 ha->optrom_state = QLA_SWAITING; 240 vfree(ha->optrom_buffer); 241 ha->optrom_buffer = NULL; 242 break; 243 case 1: 244 if (ha->optrom_state != QLA_SWAITING) 245 break; 246 247 ha->optrom_state = QLA_SREADING; 248 ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); 249 if (ha->optrom_buffer == NULL) { 250 qla_printk(KERN_WARNING, ha, 251 "Unable to allocate memory for optrom retrieval " 252 "(%x).\n", ha->optrom_size); 253 254 ha->optrom_state = QLA_SWAITING; 255 return count; 256 } 257 258 memset(ha->optrom_buffer, 0, ha->optrom_size); 259 ha->isp_ops->read_optrom(ha, ha->optrom_buffer, 0, 260 ha->optrom_size); 261 break; 262 case 2: 263 if (ha->optrom_state != QLA_SWAITING) 264 break; 265 266 ha->optrom_state = QLA_SWRITING; 267 ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); 268 if (ha->optrom_buffer == NULL) { 269 qla_printk(KERN_WARNING, ha, 270 "Unable to allocate memory for optrom update " 271 "(%x).\n", ha->optrom_size); 272 273 ha->optrom_state = QLA_SWAITING; 274 return count; 275 } 276 memset(ha->optrom_buffer, 0, ha->optrom_size); 277 break; 278 case 3: 279 if (ha->optrom_state != QLA_SWRITING) 280 break; 281 282 ha->isp_ops->write_optrom(ha, ha->optrom_buffer, 0, 283 ha->optrom_size); 284 break; 285 } 286 return count; 287 } 288 289 static struct bin_attribute sysfs_optrom_ctl_attr = { 290 .attr = { 291 .name = "optrom_ctl", 292 .mode = S_IWUSR, 293 }, 294 .size = 0, 295 .write = qla2x00_sysfs_write_optrom_ctl, 296 }; 297 298 static ssize_t 299 qla2x00_sysfs_read_vpd(struct kobject *kobj, 300 struct bin_attribute *bin_attr, 301 char *buf, loff_t off, size_t count) 302 { 303 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 304 struct device, kobj))); 305 int size = ha->vpd_size; 306 char *vpd_cache = ha->vpd; 307 308 if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) 309 return 0; 310 if (off + count > size) { 311 size -= off; 312 count = size; 313 } 314 315 /* Read NVRAM data from cache. */ 316 memcpy(buf, &vpd_cache[off], count); 317 318 return count; 319 } 320 321 static ssize_t 322 qla2x00_sysfs_write_vpd(struct kobject *kobj, 323 struct bin_attribute *bin_attr, 324 char *buf, loff_t off, size_t count) 325 { 326 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 327 struct device, kobj))); 328 unsigned long flags; 329 330 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) 331 return 0; 332 333 /* Write NVRAM. */ 334 spin_lock_irqsave(&ha->hardware_lock, flags); 335 ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->vpd_base, count); 336 ha->isp_ops->read_nvram(ha, (uint8_t *)ha->vpd, ha->vpd_base, count); 337 spin_unlock_irqrestore(&ha->hardware_lock, flags); 338 339 return count; 340 } 341 342 static struct bin_attribute sysfs_vpd_attr = { 343 .attr = { 344 .name = "vpd", 345 .mode = S_IRUSR | S_IWUSR, 346 }, 347 .size = 0, 348 .read = qla2x00_sysfs_read_vpd, 349 .write = qla2x00_sysfs_write_vpd, 350 }; 351 352 static ssize_t 353 qla2x00_sysfs_read_sfp(struct kobject *kobj, 354 struct bin_attribute *bin_attr, 355 char *buf, loff_t off, size_t count) 356 { 357 struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 358 struct device, kobj))); 359 uint16_t iter, addr, offset; 360 int rval; 361 362 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != SFP_DEV_SIZE * 2) 363 return 0; 364 365 addr = 0xa0; 366 for (iter = 0, offset = 0; iter < (SFP_DEV_SIZE * 2) / SFP_BLOCK_SIZE; 367 iter++, offset += SFP_BLOCK_SIZE) { 368 if (iter == 4) { 369 /* Skip to next device address. */ 370 addr = 0xa2; 371 offset = 0; 372 } 373 374 rval = qla2x00_read_sfp(ha, ha->sfp_data_dma, addr, offset, 375 SFP_BLOCK_SIZE); 376 if (rval != QLA_SUCCESS) { 377 qla_printk(KERN_WARNING, ha, 378 "Unable to read SFP data (%x/%x/%x).\n", rval, 379 addr, offset); 380 count = 0; 381 break; 382 } 383 memcpy(buf, ha->sfp_data, SFP_BLOCK_SIZE); 384 buf += SFP_BLOCK_SIZE; 385 } 386 387 return count; 388 } 389 390 static struct bin_attribute sysfs_sfp_attr = { 391 .attr = { 392 .name = "sfp", 393 .mode = S_IRUSR | S_IWUSR, 394 }, 395 .size = SFP_DEV_SIZE * 2, 396 .read = qla2x00_sysfs_read_sfp, 397 }; 398 399 static struct sysfs_entry { 400 char *name; 401 struct bin_attribute *attr; 402 int is4GBp_only; 403 } bin_file_entries[] = { 404 { "fw_dump", &sysfs_fw_dump_attr, }, 405 { "nvram", &sysfs_nvram_attr, }, 406 { "optrom", &sysfs_optrom_attr, }, 407 { "optrom_ctl", &sysfs_optrom_ctl_attr, }, 408 { "vpd", &sysfs_vpd_attr, 1 }, 409 { "sfp", &sysfs_sfp_attr, 1 }, 410 { NULL }, 411 }; 412 413 void 414 qla2x00_alloc_sysfs_attr(scsi_qla_host_t *ha) 415 { 416 struct Scsi_Host *host = ha->host; 417 struct sysfs_entry *iter; 418 int ret; 419 420 for (iter = bin_file_entries; iter->name; iter++) { 421 if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) 422 continue; 423 424 ret = sysfs_create_bin_file(&host->shost_gendev.kobj, 425 iter->attr); 426 if (ret) 427 qla_printk(KERN_INFO, ha, 428 "Unable to create sysfs %s binary attribute " 429 "(%d).\n", iter->name, ret); 430 } 431 } 432 433 void 434 qla2x00_free_sysfs_attr(scsi_qla_host_t *ha) 435 { 436 struct Scsi_Host *host = ha->host; 437 struct sysfs_entry *iter; 438 439 for (iter = bin_file_entries; iter->name; iter++) { 440 if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) 441 continue; 442 443 sysfs_remove_bin_file(&host->shost_gendev.kobj, 444 iter->attr); 445 } 446 447 if (ha->beacon_blink_led == 1) 448 ha->isp_ops->beacon_off(ha); 449 } 450 451 /* Scsi_Host attributes. */ 452 453 static ssize_t 454 qla2x00_drvr_version_show(struct class_device *cdev, char *buf) 455 { 456 return snprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str); 457 } 458 459 static ssize_t 460 qla2x00_fw_version_show(struct class_device *cdev, char *buf) 461 { 462 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 463 char fw_str[30]; 464 465 return snprintf(buf, PAGE_SIZE, "%s\n", 466 ha->isp_ops->fw_version_str(ha, fw_str)); 467 } 468 469 static ssize_t 470 qla2x00_serial_num_show(struct class_device *cdev, char *buf) 471 { 472 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 473 uint32_t sn; 474 475 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; 476 return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, 477 sn % 100000); 478 } 479 480 static ssize_t 481 qla2x00_isp_name_show(struct class_device *cdev, char *buf) 482 { 483 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 484 return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); 485 } 486 487 static ssize_t 488 qla2x00_isp_id_show(struct class_device *cdev, char *buf) 489 { 490 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 491 return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", 492 ha->product_id[0], ha->product_id[1], ha->product_id[2], 493 ha->product_id[3]); 494 } 495 496 static ssize_t 497 qla2x00_model_name_show(struct class_device *cdev, char *buf) 498 { 499 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 500 return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number); 501 } 502 503 static ssize_t 504 qla2x00_model_desc_show(struct class_device *cdev, char *buf) 505 { 506 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 507 return snprintf(buf, PAGE_SIZE, "%s\n", 508 ha->model_desc ? ha->model_desc: ""); 509 } 510 511 static ssize_t 512 qla2x00_pci_info_show(struct class_device *cdev, char *buf) 513 { 514 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 515 char pci_info[30]; 516 517 return snprintf(buf, PAGE_SIZE, "%s\n", 518 ha->isp_ops->pci_info_str(ha, pci_info)); 519 } 520 521 static ssize_t 522 qla2x00_state_show(struct class_device *cdev, char *buf) 523 { 524 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 525 int len = 0; 526 527 if (atomic_read(&ha->loop_state) == LOOP_DOWN || 528 atomic_read(&ha->loop_state) == LOOP_DEAD) 529 len = snprintf(buf, PAGE_SIZE, "Link Down\n"); 530 else if (atomic_read(&ha->loop_state) != LOOP_READY || 531 test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || 532 test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) 533 len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n"); 534 else { 535 len = snprintf(buf, PAGE_SIZE, "Link Up - "); 536 537 switch (ha->current_topology) { 538 case ISP_CFG_NL: 539 len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n"); 540 break; 541 case ISP_CFG_FL: 542 len += snprintf(buf + len, PAGE_SIZE-len, "FL_Port\n"); 543 break; 544 case ISP_CFG_N: 545 len += snprintf(buf + len, PAGE_SIZE-len, 546 "N_Port to N_Port\n"); 547 break; 548 case ISP_CFG_F: 549 len += snprintf(buf + len, PAGE_SIZE-len, "F_Port\n"); 550 break; 551 default: 552 len += snprintf(buf + len, PAGE_SIZE-len, "Loop\n"); 553 break; 554 } 555 } 556 return len; 557 } 558 559 static ssize_t 560 qla2x00_zio_show(struct class_device *cdev, char *buf) 561 { 562 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 563 int len = 0; 564 565 switch (ha->zio_mode) { 566 case QLA_ZIO_MODE_6: 567 len += snprintf(buf + len, PAGE_SIZE-len, "Mode 6\n"); 568 break; 569 case QLA_ZIO_DISABLED: 570 len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); 571 break; 572 } 573 return len; 574 } 575 576 static ssize_t 577 qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) 578 { 579 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 580 int val = 0; 581 uint16_t zio_mode; 582 583 if (!IS_ZIO_SUPPORTED(ha)) 584 return -ENOTSUPP; 585 586 if (sscanf(buf, "%d", &val) != 1) 587 return -EINVAL; 588 589 if (val) 590 zio_mode = QLA_ZIO_MODE_6; 591 else 592 zio_mode = QLA_ZIO_DISABLED; 593 594 /* Update per-hba values and queue a reset. */ 595 if (zio_mode != QLA_ZIO_DISABLED || ha->zio_mode != QLA_ZIO_DISABLED) { 596 ha->zio_mode = zio_mode; 597 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 598 } 599 return strlen(buf); 600 } 601 602 static ssize_t 603 qla2x00_zio_timer_show(struct class_device *cdev, char *buf) 604 { 605 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 606 607 return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); 608 } 609 610 static ssize_t 611 qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, 612 size_t count) 613 { 614 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 615 int val = 0; 616 uint16_t zio_timer; 617 618 if (sscanf(buf, "%d", &val) != 1) 619 return -EINVAL; 620 if (val > 25500 || val < 100) 621 return -ERANGE; 622 623 zio_timer = (uint16_t)(val / 100); 624 ha->zio_timer = zio_timer; 625 626 return strlen(buf); 627 } 628 629 static ssize_t 630 qla2x00_beacon_show(struct class_device *cdev, char *buf) 631 { 632 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 633 int len = 0; 634 635 if (ha->beacon_blink_led) 636 len += snprintf(buf + len, PAGE_SIZE-len, "Enabled\n"); 637 else 638 len += snprintf(buf + len, PAGE_SIZE-len, "Disabled\n"); 639 return len; 640 } 641 642 static ssize_t 643 qla2x00_beacon_store(struct class_device *cdev, const char *buf, 644 size_t count) 645 { 646 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 647 int val = 0; 648 int rval; 649 650 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 651 return -EPERM; 652 653 if (test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags)) { 654 qla_printk(KERN_WARNING, ha, 655 "Abort ISP active -- ignoring beacon request.\n"); 656 return -EBUSY; 657 } 658 659 if (sscanf(buf, "%d", &val) != 1) 660 return -EINVAL; 661 662 if (val) 663 rval = ha->isp_ops->beacon_on(ha); 664 else 665 rval = ha->isp_ops->beacon_off(ha); 666 667 if (rval != QLA_SUCCESS) 668 count = 0; 669 670 return count; 671 } 672 673 static ssize_t 674 qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) 675 { 676 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 677 678 return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], 679 ha->bios_revision[0]); 680 } 681 682 static ssize_t 683 qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) 684 { 685 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 686 687 return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], 688 ha->efi_revision[0]); 689 } 690 691 static ssize_t 692 qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) 693 { 694 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 695 696 return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], 697 ha->fcode_revision[0]); 698 } 699 700 static ssize_t 701 qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf) 702 { 703 scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); 704 705 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", 706 ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], 707 ha->fw_revision[3]); 708 } 709 710 static CLASS_DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, 711 NULL); 712 static CLASS_DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); 713 static CLASS_DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); 714 static CLASS_DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL); 715 static CLASS_DEVICE_ATTR(isp_id, S_IRUGO, qla2x00_isp_id_show, NULL); 716 static CLASS_DEVICE_ATTR(model_name, S_IRUGO, qla2x00_model_name_show, NULL); 717 static CLASS_DEVICE_ATTR(model_desc, S_IRUGO, qla2x00_model_desc_show, NULL); 718 static CLASS_DEVICE_ATTR(pci_info, S_IRUGO, qla2x00_pci_info_show, NULL); 719 static CLASS_DEVICE_ATTR(state, S_IRUGO, qla2x00_state_show, NULL); 720 static CLASS_DEVICE_ATTR(zio, S_IRUGO | S_IWUSR, qla2x00_zio_show, 721 qla2x00_zio_store); 722 static CLASS_DEVICE_ATTR(zio_timer, S_IRUGO | S_IWUSR, qla2x00_zio_timer_show, 723 qla2x00_zio_timer_store); 724 static CLASS_DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show, 725 qla2x00_beacon_store); 726 static CLASS_DEVICE_ATTR(optrom_bios_version, S_IRUGO, 727 qla2x00_optrom_bios_version_show, NULL); 728 static CLASS_DEVICE_ATTR(optrom_efi_version, S_IRUGO, 729 qla2x00_optrom_efi_version_show, NULL); 730 static CLASS_DEVICE_ATTR(optrom_fcode_version, S_IRUGO, 731 qla2x00_optrom_fcode_version_show, NULL); 732 static CLASS_DEVICE_ATTR(optrom_fw_version, S_IRUGO, 733 qla2x00_optrom_fw_version_show, NULL); 734 735 struct class_device_attribute *qla2x00_host_attrs[] = { 736 &class_device_attr_driver_version, 737 &class_device_attr_fw_version, 738 &class_device_attr_serial_num, 739 &class_device_attr_isp_name, 740 &class_device_attr_isp_id, 741 &class_device_attr_model_name, 742 &class_device_attr_model_desc, 743 &class_device_attr_pci_info, 744 &class_device_attr_state, 745 &class_device_attr_zio, 746 &class_device_attr_zio_timer, 747 &class_device_attr_beacon, 748 &class_device_attr_optrom_bios_version, 749 &class_device_attr_optrom_efi_version, 750 &class_device_attr_optrom_fcode_version, 751 &class_device_attr_optrom_fw_version, 752 NULL, 753 }; 754 755 /* Host attributes. */ 756 757 static void 758 qla2x00_get_host_port_id(struct Scsi_Host *shost) 759 { 760 scsi_qla_host_t *ha = to_qla_host(shost); 761 762 fc_host_port_id(shost) = ha->d_id.b.domain << 16 | 763 ha->d_id.b.area << 8 | ha->d_id.b.al_pa; 764 } 765 766 static void 767 qla2x00_get_host_speed(struct Scsi_Host *shost) 768 { 769 scsi_qla_host_t *ha = to_qla_host(shost); 770 uint32_t speed = 0; 771 772 switch (ha->link_data_rate) { 773 case PORT_SPEED_1GB: 774 speed = 1; 775 break; 776 case PORT_SPEED_2GB: 777 speed = 2; 778 break; 779 case PORT_SPEED_4GB: 780 speed = 4; 781 break; 782 } 783 fc_host_speed(shost) = speed; 784 } 785 786 static void 787 qla2x00_get_host_port_type(struct Scsi_Host *shost) 788 { 789 scsi_qla_host_t *ha = to_qla_host(shost); 790 uint32_t port_type = FC_PORTTYPE_UNKNOWN; 791 792 switch (ha->current_topology) { 793 case ISP_CFG_NL: 794 port_type = FC_PORTTYPE_LPORT; 795 break; 796 case ISP_CFG_FL: 797 port_type = FC_PORTTYPE_NLPORT; 798 break; 799 case ISP_CFG_N: 800 port_type = FC_PORTTYPE_PTP; 801 break; 802 case ISP_CFG_F: 803 port_type = FC_PORTTYPE_NPORT; 804 break; 805 } 806 fc_host_port_type(shost) = port_type; 807 } 808 809 static void 810 qla2x00_get_starget_node_name(struct scsi_target *starget) 811 { 812 struct Scsi_Host *host = dev_to_shost(starget->dev.parent); 813 scsi_qla_host_t *ha = to_qla_host(host); 814 fc_port_t *fcport; 815 u64 node_name = 0; 816 817 list_for_each_entry(fcport, &ha->fcports, list) { 818 if (starget->id == fcport->os_target_id) { 819 node_name = wwn_to_u64(fcport->node_name); 820 break; 821 } 822 } 823 824 fc_starget_node_name(starget) = node_name; 825 } 826 827 static void 828 qla2x00_get_starget_port_name(struct scsi_target *starget) 829 { 830 struct Scsi_Host *host = dev_to_shost(starget->dev.parent); 831 scsi_qla_host_t *ha = to_qla_host(host); 832 fc_port_t *fcport; 833 u64 port_name = 0; 834 835 list_for_each_entry(fcport, &ha->fcports, list) { 836 if (starget->id == fcport->os_target_id) { 837 port_name = wwn_to_u64(fcport->port_name); 838 break; 839 } 840 } 841 842 fc_starget_port_name(starget) = port_name; 843 } 844 845 static void 846 qla2x00_get_starget_port_id(struct scsi_target *starget) 847 { 848 struct Scsi_Host *host = dev_to_shost(starget->dev.parent); 849 scsi_qla_host_t *ha = to_qla_host(host); 850 fc_port_t *fcport; 851 uint32_t port_id = ~0U; 852 853 list_for_each_entry(fcport, &ha->fcports, list) { 854 if (starget->id == fcport->os_target_id) { 855 port_id = fcport->d_id.b.domain << 16 | 856 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; 857 break; 858 } 859 } 860 861 fc_starget_port_id(starget) = port_id; 862 } 863 864 static void 865 qla2x00_get_rport_loss_tmo(struct fc_rport *rport) 866 { 867 struct Scsi_Host *host = rport_to_shost(rport); 868 scsi_qla_host_t *ha = to_qla_host(host); 869 870 rport->dev_loss_tmo = ha->port_down_retry_count + 5; 871 } 872 873 static void 874 qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 875 { 876 struct Scsi_Host *host = rport_to_shost(rport); 877 scsi_qla_host_t *ha = to_qla_host(host); 878 879 if (timeout) 880 ha->port_down_retry_count = timeout; 881 else 882 ha->port_down_retry_count = 1; 883 884 rport->dev_loss_tmo = ha->port_down_retry_count + 5; 885 } 886 887 static int 888 qla2x00_issue_lip(struct Scsi_Host *shost) 889 { 890 scsi_qla_host_t *ha = to_qla_host(shost); 891 892 set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags); 893 return 0; 894 } 895 896 static struct fc_host_statistics * 897 qla2x00_get_fc_host_stats(struct Scsi_Host *shost) 898 { 899 scsi_qla_host_t *ha = to_qla_host(shost); 900 int rval; 901 uint16_t mb_stat[1]; 902 link_stat_t stat_buf; 903 struct fc_host_statistics *pfc_host_stat; 904 905 rval = QLA_FUNCTION_FAILED; 906 pfc_host_stat = &ha->fc_host_stat; 907 memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); 908 909 if (IS_FWI2_CAPABLE(ha)) { 910 rval = qla24xx_get_isp_stats(ha, (uint32_t *)&stat_buf, 911 sizeof(stat_buf) / 4, mb_stat); 912 } else if (atomic_read(&ha->loop_state) == LOOP_READY && 913 !test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) && 914 !test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) && 915 !ha->dpc_active) { 916 /* Must be in a 'READY' state for statistics retrieval. */ 917 rval = qla2x00_get_link_status(ha, ha->loop_id, &stat_buf, 918 mb_stat); 919 } 920 921 if (rval != QLA_SUCCESS) 922 goto done; 923 924 pfc_host_stat->link_failure_count = stat_buf.link_fail_cnt; 925 pfc_host_stat->loss_of_sync_count = stat_buf.loss_sync_cnt; 926 pfc_host_stat->loss_of_signal_count = stat_buf.loss_sig_cnt; 927 pfc_host_stat->prim_seq_protocol_err_count = stat_buf.prim_seq_err_cnt; 928 pfc_host_stat->invalid_tx_word_count = stat_buf.inval_xmit_word_cnt; 929 pfc_host_stat->invalid_crc_count = stat_buf.inval_crc_cnt; 930 done: 931 return pfc_host_stat; 932 } 933 934 static void 935 qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) 936 { 937 scsi_qla_host_t *ha = to_qla_host(shost); 938 939 qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); 940 } 941 942 static void 943 qla2x00_set_host_system_hostname(struct Scsi_Host *shost) 944 { 945 scsi_qla_host_t *ha = to_qla_host(shost); 946 947 set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); 948 } 949 950 static void 951 qla2x00_get_host_fabric_name(struct Scsi_Host *shost) 952 { 953 scsi_qla_host_t *ha = to_qla_host(shost); 954 u64 node_name; 955 956 if (ha->device_flags & SWITCH_FOUND) 957 node_name = wwn_to_u64(ha->fabric_node_name); 958 else 959 node_name = wwn_to_u64(ha->node_name); 960 961 fc_host_fabric_name(shost) = node_name; 962 } 963 964 static void 965 qla2x00_get_host_port_state(struct Scsi_Host *shost) 966 { 967 scsi_qla_host_t *ha = to_qla_host(shost); 968 969 if (!ha->flags.online) 970 fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; 971 else if (atomic_read(&ha->loop_state) == LOOP_TIMEOUT) 972 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; 973 else 974 fc_host_port_state(shost) = FC_PORTSTATE_ONLINE; 975 } 976 977 static int 978 qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) 979 { 980 int ret = 0; 981 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; 982 scsi_qla_host_t *vha; 983 984 ret = qla24xx_vport_create_req_sanity_check(fc_vport); 985 if (ret) { 986 DEBUG15(printk("qla24xx_vport_create_req_sanity_check failed, " 987 "status %x\n", ret)); 988 return (ret); 989 } 990 991 vha = qla24xx_create_vhost(fc_vport); 992 if (vha == NULL) { 993 DEBUG15(printk ("qla24xx_create_vhost failed, vha = %p\n", 994 vha)); 995 return FC_VPORT_FAILED; 996 } 997 if (disable) { 998 atomic_set(&vha->vp_state, VP_OFFLINE); 999 fc_vport_set_state(fc_vport, FC_VPORT_DISABLED); 1000 } else 1001 atomic_set(&vha->vp_state, VP_FAILED); 1002 1003 /* ready to create vport */ 1004 qla_printk(KERN_INFO, vha, "VP entry id %d assigned.\n", vha->vp_idx); 1005 1006 /* initialized vport states */ 1007 atomic_set(&vha->loop_state, LOOP_DOWN); 1008 vha->vp_err_state= VP_ERR_PORTDWN; 1009 vha->vp_prev_err_state= VP_ERR_UNKWN; 1010 /* Check if physical ha port is Up */ 1011 if (atomic_read(&ha->loop_state) == LOOP_DOWN || 1012 atomic_read(&ha->loop_state) == LOOP_DEAD) { 1013 /* Don't retry or attempt login of this virtual port */ 1014 DEBUG15(printk ("scsi(%ld): pport loop_state is not UP.\n", 1015 vha->host_no)); 1016 atomic_set(&vha->loop_state, LOOP_DEAD); 1017 if (!disable) 1018 fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); 1019 } 1020 1021 if (scsi_add_host(vha->host, &fc_vport->dev)) { 1022 DEBUG15(printk("scsi(%ld): scsi_add_host failure for VP[%d].\n", 1023 vha->host_no, vha->vp_idx)); 1024 goto vport_create_failed_2; 1025 } 1026 1027 /* initialize attributes */ 1028 fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); 1029 fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); 1030 fc_host_supported_classes(vha->host) = 1031 fc_host_supported_classes(ha->host); 1032 fc_host_supported_speeds(vha->host) = 1033 fc_host_supported_speeds(ha->host); 1034 1035 qla24xx_vport_disable(fc_vport, disable); 1036 1037 return 0; 1038 vport_create_failed_2: 1039 qla24xx_disable_vp(vha); 1040 qla24xx_deallocate_vp_id(vha); 1041 kfree(vha->port_name); 1042 kfree(vha->node_name); 1043 scsi_host_put(vha->host); 1044 return FC_VPORT_FAILED; 1045 } 1046 1047 int 1048 qla24xx_vport_delete(struct fc_vport *fc_vport) 1049 { 1050 scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; 1051 scsi_qla_host_t *vha = fc_vport->dd_data; 1052 1053 qla24xx_disable_vp(vha); 1054 qla24xx_deallocate_vp_id(vha); 1055 1056 down(&ha->vport_sem); 1057 ha->cur_vport_count--; 1058 clear_bit(vha->vp_idx, (unsigned long *)ha->vp_idx_map); 1059 up(&ha->vport_sem); 1060 1061 kfree(vha->node_name); 1062 kfree(vha->port_name); 1063 1064 if (vha->timer_active) { 1065 qla2x00_vp_stop_timer(vha); 1066 DEBUG15(printk ("scsi(%ld): timer for the vport[%d] = %p " 1067 "has stopped\n", 1068 vha->host_no, vha->vp_idx, vha)); 1069 } 1070 1071 fc_remove_host(vha->host); 1072 1073 scsi_remove_host(vha->host); 1074 1075 scsi_host_put(vha->host); 1076 1077 return 0; 1078 } 1079 1080 int 1081 qla24xx_vport_disable(struct fc_vport *fc_vport, bool disable) 1082 { 1083 scsi_qla_host_t *vha = fc_vport->dd_data; 1084 1085 if (disable) 1086 qla24xx_disable_vp(vha); 1087 else 1088 qla24xx_enable_vp(vha); 1089 1090 return 0; 1091 } 1092 1093 struct fc_function_template qla2xxx_transport_functions = { 1094 1095 .show_host_node_name = 1, 1096 .show_host_port_name = 1, 1097 .show_host_supported_classes = 1, 1098 1099 .get_host_port_id = qla2x00_get_host_port_id, 1100 .show_host_port_id = 1, 1101 .get_host_speed = qla2x00_get_host_speed, 1102 .show_host_speed = 1, 1103 .get_host_port_type = qla2x00_get_host_port_type, 1104 .show_host_port_type = 1, 1105 .get_host_symbolic_name = qla2x00_get_host_symbolic_name, 1106 .show_host_symbolic_name = 1, 1107 .set_host_system_hostname = qla2x00_set_host_system_hostname, 1108 .show_host_system_hostname = 1, 1109 .get_host_fabric_name = qla2x00_get_host_fabric_name, 1110 .show_host_fabric_name = 1, 1111 .get_host_port_state = qla2x00_get_host_port_state, 1112 .show_host_port_state = 1, 1113 1114 .dd_fcrport_size = sizeof(struct fc_port *), 1115 .show_rport_supported_classes = 1, 1116 1117 .get_starget_node_name = qla2x00_get_starget_node_name, 1118 .show_starget_node_name = 1, 1119 .get_starget_port_name = qla2x00_get_starget_port_name, 1120 .show_starget_port_name = 1, 1121 .get_starget_port_id = qla2x00_get_starget_port_id, 1122 .show_starget_port_id = 1, 1123 1124 .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, 1125 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, 1126 .show_rport_dev_loss_tmo = 1, 1127 1128 .issue_fc_host_lip = qla2x00_issue_lip, 1129 .get_fc_host_stats = qla2x00_get_fc_host_stats, 1130 1131 .vport_create = qla24xx_vport_create, 1132 .vport_disable = qla24xx_vport_disable, 1133 .vport_delete = qla24xx_vport_delete, 1134 }; 1135 1136 struct fc_function_template qla2xxx_transport_vport_functions = { 1137 1138 .show_host_node_name = 1, 1139 .show_host_port_name = 1, 1140 .show_host_supported_classes = 1, 1141 1142 .get_host_port_id = qla2x00_get_host_port_id, 1143 .show_host_port_id = 1, 1144 .get_host_speed = qla2x00_get_host_speed, 1145 .show_host_speed = 1, 1146 .get_host_port_type = qla2x00_get_host_port_type, 1147 .show_host_port_type = 1, 1148 .get_host_symbolic_name = qla2x00_get_host_symbolic_name, 1149 .show_host_symbolic_name = 1, 1150 .set_host_system_hostname = qla2x00_set_host_system_hostname, 1151 .show_host_system_hostname = 1, 1152 .get_host_fabric_name = qla2x00_get_host_fabric_name, 1153 .show_host_fabric_name = 1, 1154 .get_host_port_state = qla2x00_get_host_port_state, 1155 .show_host_port_state = 1, 1156 1157 .dd_fcrport_size = sizeof(struct fc_port *), 1158 .show_rport_supported_classes = 1, 1159 1160 .get_starget_node_name = qla2x00_get_starget_node_name, 1161 .show_starget_node_name = 1, 1162 .get_starget_port_name = qla2x00_get_starget_port_name, 1163 .show_starget_port_name = 1, 1164 .get_starget_port_id = qla2x00_get_starget_port_id, 1165 .show_starget_port_id = 1, 1166 1167 .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, 1168 .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, 1169 .show_rport_dev_loss_tmo = 1, 1170 1171 .issue_fc_host_lip = qla2x00_issue_lip, 1172 .get_fc_host_stats = qla2x00_get_fc_host_stats, 1173 }; 1174 1175 void 1176 qla2x00_init_host_attr(scsi_qla_host_t *ha) 1177 { 1178 fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); 1179 fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); 1180 fc_host_supported_classes(ha->host) = FC_COS_CLASS3; 1181 fc_host_max_npiv_vports(ha->host) = MAX_NUM_VPORT_FABRIC; 1182 fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; 1183 } 1184