aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c295
1 files changed, 285 insertions, 10 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index ee9d4015243..b09993a0657 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -96,7 +96,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
96 if (!capable(CAP_SYS_ADMIN)) 96 if (!capable(CAP_SYS_ADMIN))
97 return 0; 97 return 0;
98 98
99 /* Read NVRAM data from cache. */ 99 if (IS_NOCACHE_VPD_TYPE(ha))
100 ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_nvram << 2,
101 ha->nvram_size);
100 return memory_read_from_buffer(buf, count, &off, ha->nvram, 102 return memory_read_from_buffer(buf, count, &off, ha->nvram,
101 ha->nvram_size); 103 ha->nvram_size);
102} 104}
@@ -111,7 +113,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
111 struct qla_hw_data *ha = vha->hw; 113 struct qla_hw_data *ha = vha->hw;
112 uint16_t cnt; 114 uint16_t cnt;
113 115
114 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size) 116 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size ||
117 !ha->isp_ops->write_nvram)
115 return 0; 118 return 0;
116 119
117 /* Checksum NVRAM. */ 120 /* Checksum NVRAM. */
@@ -137,12 +140,21 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
137 *iter = chksum; 140 *iter = chksum;
138 } 141 }
139 142
143 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
144 qla_printk(KERN_WARNING, ha,
145 "HBA not online, failing NVRAM update.\n");
146 return -EAGAIN;
147 }
148
140 /* Write NVRAM. */ 149 /* Write NVRAM. */
141 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count); 150 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
142 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base, 151 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
143 count); 152 count);
144 153
154 /* NVRAM settings take effect immediately. */
145 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 155 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
156 qla2xxx_wake_dpc(vha);
157 qla2x00_wait_for_chip_reset(vha);
146 158
147 return (count); 159 return (count);
148} 160}
@@ -330,6 +342,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
330 if (ha->optrom_state != QLA_SWRITING) 342 if (ha->optrom_state != QLA_SWRITING)
331 break; 343 break;
332 344
345 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
346 qla_printk(KERN_WARNING, ha,
347 "HBA not online, failing flash update.\n");
348 return -EAGAIN;
349 }
350
333 DEBUG2(qla_printk(KERN_INFO, ha, 351 DEBUG2(qla_printk(KERN_INFO, ha,
334 "Writing flash region -- 0x%x/0x%x.\n", 352 "Writing flash region -- 0x%x/0x%x.\n",
335 ha->optrom_region_start, ha->optrom_region_size)); 353 ha->optrom_region_start, ha->optrom_region_size));
@@ -364,7 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
364 if (!capable(CAP_SYS_ADMIN)) 382 if (!capable(CAP_SYS_ADMIN))
365 return 0; 383 return 0;
366 384
367 /* Read NVRAM data from cache. */ 385 if (IS_NOCACHE_VPD_TYPE(ha))
386 ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
387 ha->vpd_size);
368 return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); 388 return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
369} 389}
370 390
@@ -376,14 +396,35 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
376 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, 396 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
377 struct device, kobj))); 397 struct device, kobj)));
378 struct qla_hw_data *ha = vha->hw; 398 struct qla_hw_data *ha = vha->hw;
399 uint8_t *tmp_data;
379 400
380 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size) 401 if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
402 !ha->isp_ops->write_nvram)
381 return 0; 403 return 0;
382 404
405 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
406 qla_printk(KERN_WARNING, ha,
407 "HBA not online, failing VPD update.\n");
408 return -EAGAIN;
409 }
410
383 /* Write NVRAM. */ 411 /* Write NVRAM. */
384 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count); 412 ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
385 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count); 413 ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
386 414
415 /* Update flash version information for 4Gb & above. */
416 if (!IS_FWI2_CAPABLE(ha))
417 goto done;
418
419 tmp_data = vmalloc(256);
420 if (!tmp_data) {
421 qla_printk(KERN_WARNING, ha,
422 "Unable to allocate memory for VPD information update.\n");
423 goto done;
424 }
425 ha->isp_ops->get_flash_version(vha, tmp_data);
426 vfree(tmp_data);
427done:
387 return count; 428 return count;
388} 429}
389 430
@@ -458,6 +499,199 @@ static struct bin_attribute sysfs_sfp_attr = {
458 .read = qla2x00_sysfs_read_sfp, 499 .read = qla2x00_sysfs_read_sfp,
459}; 500};
460 501
502static ssize_t
503qla2x00_sysfs_write_reset(struct kobject *kobj,
504 struct bin_attribute *bin_attr,
505 char *buf, loff_t off, size_t count)
506{
507 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
508 struct device, kobj)));
509 struct qla_hw_data *ha = vha->hw;
510 int type;
511
512 if (off != 0)
513 return 0;
514
515 type = simple_strtol(buf, NULL, 10);
516 switch (type) {
517 case 0x2025c:
518 qla_printk(KERN_INFO, ha,
519 "Issuing ISP reset on (%ld).\n", vha->host_no);
520
521 scsi_block_requests(vha->host);
522 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
523 qla2xxx_wake_dpc(vha);
524 qla2x00_wait_for_chip_reset(vha);
525 scsi_unblock_requests(vha->host);
526 break;
527 case 0x2025d:
528 if (!IS_QLA81XX(ha))
529 break;
530
531 qla_printk(KERN_INFO, ha,
532 "Issuing MPI reset on (%ld).\n", vha->host_no);
533
534 /* Make sure FC side is not in reset */
535 qla2x00_wait_for_hba_online(vha);
536
537 /* Issue MPI reset */
538 scsi_block_requests(vha->host);
539 if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
540 qla_printk(KERN_WARNING, ha,
541 "MPI reset failed on (%ld).\n", vha->host_no);
542 scsi_unblock_requests(vha->host);
543 break;
544 }
545 return count;
546}
547
548static struct bin_attribute sysfs_reset_attr = {
549 .attr = {
550 .name = "reset",
551 .mode = S_IWUSR,
552 },
553 .size = 0,
554 .write = qla2x00_sysfs_write_reset,
555};
556
557static ssize_t
558qla2x00_sysfs_write_edc(struct kobject *kobj,
559 struct bin_attribute *bin_attr,
560 char *buf, loff_t off, size_t count)
561{
562 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
563 struct device, kobj)));
564 struct qla_hw_data *ha = vha->hw;
565 uint16_t dev, adr, opt, len;
566 int rval;
567
568 ha->edc_data_len = 0;
569
570 if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
571 return 0;
572
573 if (!ha->edc_data) {
574 ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
575 &ha->edc_data_dma);
576 if (!ha->edc_data) {
577 DEBUG2(qla_printk(KERN_INFO, ha,
578 "Unable to allocate memory for EDC write.\n"));
579 return 0;
580 }
581 }
582
583 dev = le16_to_cpup((void *)&buf[0]);
584 adr = le16_to_cpup((void *)&buf[2]);
585 opt = le16_to_cpup((void *)&buf[4]);
586 len = le16_to_cpup((void *)&buf[6]);
587
588 if (!(opt & BIT_0))
589 if (len == 0 || len > DMA_POOL_SIZE || len > count - 8)
590 return -EINVAL;
591
592 memcpy(ha->edc_data, &buf[8], len);
593
594 rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma,
595 ha->edc_data, len, opt);
596 if (rval != QLA_SUCCESS) {
597 DEBUG2(qla_printk(KERN_INFO, ha,
598 "Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n",
599 rval, dev, adr, opt, len, *buf));
600 return 0;
601 }
602
603 return count;
604}
605
606static struct bin_attribute sysfs_edc_attr = {
607 .attr = {
608 .name = "edc",
609 .mode = S_IWUSR,
610 },
611 .size = 0,
612 .write = qla2x00_sysfs_write_edc,
613};
614
615static ssize_t
616qla2x00_sysfs_write_edc_status(struct kobject *kobj,
617 struct bin_attribute *bin_attr,
618 char *buf, loff_t off, size_t count)
619{
620 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
621 struct device, kobj)));
622 struct qla_hw_data *ha = vha->hw;
623 uint16_t dev, adr, opt, len;
624 int rval;
625
626 ha->edc_data_len = 0;
627
628 if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
629 return 0;
630
631 if (!ha->edc_data) {
632 ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
633 &ha->edc_data_dma);
634 if (!ha->edc_data) {
635 DEBUG2(qla_printk(KERN_INFO, ha,
636 "Unable to allocate memory for EDC status.\n"));
637 return 0;
638 }
639 }
640
641 dev = le16_to_cpup((void *)&buf[0]);
642 adr = le16_to_cpup((void *)&buf[2]);
643 opt = le16_to_cpup((void *)&buf[4]);
644 len = le16_to_cpup((void *)&buf[6]);
645
646 if (!(opt & BIT_0))
647 if (len == 0 || len > DMA_POOL_SIZE)
648 return -EINVAL;
649
650 memset(ha->edc_data, 0, len);
651 rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma,
652 ha->edc_data, len, opt);
653 if (rval != QLA_SUCCESS) {
654 DEBUG2(qla_printk(KERN_INFO, ha,
655 "Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n",
656 rval, dev, adr, opt, len));
657 return 0;
658 }
659
660 ha->edc_data_len = len;
661
662 return count;
663}
664
665static ssize_t
666qla2x00_sysfs_read_edc_status(struct kobject *kobj,
667 struct bin_attribute *bin_attr,
668 char *buf, loff_t off, size_t count)
669{
670 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
671 struct device, kobj)));
672 struct qla_hw_data *ha = vha->hw;
673
674 if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0)
675 return 0;
676
677 if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count)
678 return -EINVAL;
679
680 memcpy(buf, ha->edc_data, ha->edc_data_len);
681
682 return ha->edc_data_len;
683}
684
685static struct bin_attribute sysfs_edc_status_attr = {
686 .attr = {
687 .name = "edc_status",
688 .mode = S_IRUSR | S_IWUSR,
689 },
690 .size = 0,
691 .write = qla2x00_sysfs_write_edc_status,
692 .read = qla2x00_sysfs_read_edc_status,
693};
694
461static struct sysfs_entry { 695static struct sysfs_entry {
462 char *name; 696 char *name;
463 struct bin_attribute *attr; 697 struct bin_attribute *attr;
@@ -469,6 +703,9 @@ static struct sysfs_entry {
469 { "optrom_ctl", &sysfs_optrom_ctl_attr, }, 703 { "optrom_ctl", &sysfs_optrom_ctl_attr, },
470 { "vpd", &sysfs_vpd_attr, 1 }, 704 { "vpd", &sysfs_vpd_attr, 1 },
471 { "sfp", &sysfs_sfp_attr, 1 }, 705 { "sfp", &sysfs_sfp_attr, 1 },
706 { "reset", &sysfs_reset_attr, },
707 { "edc", &sysfs_edc_attr, 2 },
708 { "edc_status", &sysfs_edc_status_attr, 2 },
472 { NULL }, 709 { NULL },
473}; 710};
474 711
@@ -482,6 +719,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
482 for (iter = bin_file_entries; iter->name; iter++) { 719 for (iter = bin_file_entries; iter->name; iter++) {
483 if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw)) 720 if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw))
484 continue; 721 continue;
722 if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
723 continue;
485 724
486 ret = sysfs_create_bin_file(&host->shost_gendev.kobj, 725 ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
487 iter->attr); 726 iter->attr);
@@ -502,6 +741,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
502 for (iter = bin_file_entries; iter->name; iter++) { 741 for (iter = bin_file_entries; iter->name; iter++) {
503 if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha)) 742 if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
504 continue; 743 continue;
744 if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
745 continue;
505 746
506 sysfs_remove_bin_file(&host->shost_gendev.kobj, 747 sysfs_remove_bin_file(&host->shost_gendev.kobj,
507 iter->attr); 748 iter->attr);
@@ -818,9 +1059,33 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
818 if (!IS_QLA81XX(ha)) 1059 if (!IS_QLA81XX(ha))
819 return snprintf(buf, PAGE_SIZE, "\n"); 1060 return snprintf(buf, PAGE_SIZE, "\n");
820 1061
821 return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x (%x)\n", 1062 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
822 ha->mpi_version[0], ha->mpi_version[1], ha->mpi_version[2], 1063 ha->mpi_version[0], ha->mpi_version[1], ha->mpi_version[2],
823 ha->mpi_version[3], ha->mpi_capabilities); 1064 ha->mpi_capabilities);
1065}
1066
1067static ssize_t
1068qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr,
1069 char *buf)
1070{
1071 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1072 struct qla_hw_data *ha = vha->hw;
1073
1074 if (!IS_QLA81XX(ha))
1075 return snprintf(buf, PAGE_SIZE, "\n");
1076
1077 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
1078 ha->phy_version[0], ha->phy_version[1], ha->phy_version[2]);
1079}
1080
1081static ssize_t
1082qla2x00_flash_block_size_show(struct device *dev,
1083 struct device_attribute *attr, char *buf)
1084{
1085 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1086 struct qla_hw_data *ha = vha->hw;
1087
1088 return snprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
824} 1089}
825 1090
826static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); 1091static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
@@ -848,6 +1113,9 @@ static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
848static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, 1113static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
849 NULL); 1114 NULL);
850static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL); 1115static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
1116static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
1117static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
1118 NULL);
851 1119
852struct device_attribute *qla2x00_host_attrs[] = { 1120struct device_attribute *qla2x00_host_attrs[] = {
853 &dev_attr_driver_version, 1121 &dev_attr_driver_version,
@@ -868,6 +1136,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
868 &dev_attr_optrom_fw_version, 1136 &dev_attr_optrom_fw_version,
869 &dev_attr_total_isp_aborts, 1137 &dev_attr_total_isp_aborts,
870 &dev_attr_mpi_version, 1138 &dev_attr_mpi_version,
1139 &dev_attr_phy_version,
1140 &dev_attr_flash_block_size,
871 NULL, 1141 NULL,
872}; 1142};
873 1143
@@ -1012,7 +1282,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
1012 if (!fcport) 1282 if (!fcport)
1013 return; 1283 return;
1014 1284
1015 qla2x00_abort_fcport_cmds(fcport); 1285 if (unlikely(pci_channel_offline(fcport->vha->hw->pdev)))
1286 qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
1287 else
1288 qla2x00_abort_fcport_cmds(fcport);
1016 1289
1017 /* 1290 /*
1018 * Transport has effectively 'deleted' the rport, clear 1291 * Transport has effectively 'deleted' the rport, clear
@@ -1032,16 +1305,18 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
1032 if (!fcport) 1305 if (!fcport)
1033 return; 1306 return;
1034 1307
1308 if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
1309 qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
1310 return;
1311 }
1035 /* 1312 /*
1036 * At this point all fcport's software-states are cleared. Perform any 1313 * At this point all fcport's software-states are cleared. Perform any
1037 * final cleanup of firmware resources (PCBs and XCBs). 1314 * final cleanup of firmware resources (PCBs and XCBs).
1038 */ 1315 */
1039 if (fcport->loop_id != FC_NO_LOOP_ID) { 1316 if (fcport->loop_id != FC_NO_LOOP_ID)
1040 fcport->vha->hw->isp_ops->fabric_logout(fcport->vha, 1317 fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
1041 fcport->loop_id, fcport->d_id.b.domain, 1318 fcport->loop_id, fcport->d_id.b.domain,
1042 fcport->d_id.b.area, fcport->d_id.b.al_pa); 1319 fcport->d_id.b.area, fcport->d_id.b.al_pa);
1043 fcport->loop_id = FC_NO_LOOP_ID;
1044 }
1045 1320
1046 qla2x00_abort_fcport_cmds(fcport); 1321 qla2x00_abort_fcport_cmds(fcport);
1047} 1322}