diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 15:55:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-22 15:55:29 -0400 |
commit | 424a6f6ef990b7e9f56f6627bfc6c46b493faeb4 (patch) | |
tree | 0028356ed8003495fbbe1f716f359e3c8ebc35b6 /drivers/scsi/qla2xxx/qla_attr.c | |
parent | 1ab142d499294b844ecc81e8004db4ce029b0b61 (diff) | |
parent | cd8df932d894f3128c884e3ae1b2b484540513db (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
SCSI updates from James Bottomley:
"The update includes the usual assortment of driver updates (lpfc,
qla2xxx, qla4xxx, bfa, bnx2fc, bnx2i, isci, fcoe, hpsa) plus a huge
amount of infrastructure work in the SAS library and transport class
as well as an iSCSI update. There's also a new SCSI based virtio
driver."
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (177 commits)
[SCSI] qla4xxx: Update driver version to 5.02.00-k15
[SCSI] qla4xxx: trivial cleanup
[SCSI] qla4xxx: Fix sparse warning
[SCSI] qla4xxx: Add support for multiple session per host.
[SCSI] qla4xxx: Export CHAP index as sysfs attribute
[SCSI] scsi_transport: Export CHAP index as sysfs attribute
[SCSI] qla4xxx: Add support to display CHAP list and delete CHAP entry
[SCSI] iscsi_transport: Add support to display CHAP list and delete CHAP entry
[SCSI] pm8001: fix endian issue with code optimization.
[SCSI] pm8001: Fix possible racing condition.
[SCSI] pm8001: Fix bogus interrupt state flag issue.
[SCSI] ipr: update PCI ID definitions for new adapters
[SCSI] qla2xxx: handle default case in qla2x00_request_firmware()
[SCSI] isci: improvements in driver unloading routine
[SCSI] isci: improve phy event warnings
[SCSI] isci: debug, provide state-enum-to-string conversions
[SCSI] scsi_transport_sas: 'enable' phys on reset
[SCSI] libsas: don't recover end devices attached to disabled phys
[SCSI] libsas: fixup target_port_protocols for expanders that don't report sata
[SCSI] libsas: set attached device type and target protocols for local phys
...
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 177 |
1 files changed, 23 insertions, 154 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 9f41b3b4358f..5926f5a87ea8 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -356,7 +356,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, | |||
356 | else if (start == (ha->flt_region_boot * 4) || | 356 | else if (start == (ha->flt_region_boot * 4) || |
357 | start == (ha->flt_region_fw * 4)) | 357 | start == (ha->flt_region_fw * 4)) |
358 | valid = 1; | 358 | valid = 1; |
359 | else if (IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha)) | 359 | else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) |
360 | || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)) | ||
360 | valid = 1; | 361 | valid = 1; |
361 | if (!valid) { | 362 | if (!valid) { |
362 | ql_log(ql_log_warn, vha, 0x7065, | 363 | ql_log(ql_log_warn, vha, 0x7065, |
@@ -627,144 +628,6 @@ static struct bin_attribute sysfs_reset_attr = { | |||
627 | }; | 628 | }; |
628 | 629 | ||
629 | static ssize_t | 630 | static ssize_t |
630 | qla2x00_sysfs_write_edc(struct file *filp, struct kobject *kobj, | ||
631 | struct bin_attribute *bin_attr, | ||
632 | char *buf, loff_t off, size_t count) | ||
633 | { | ||
634 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | ||
635 | struct device, kobj))); | ||
636 | struct qla_hw_data *ha = vha->hw; | ||
637 | uint16_t dev, adr, opt, len; | ||
638 | int rval; | ||
639 | |||
640 | ha->edc_data_len = 0; | ||
641 | |||
642 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8) | ||
643 | return -EINVAL; | ||
644 | |||
645 | if (!ha->edc_data) { | ||
646 | ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | ||
647 | &ha->edc_data_dma); | ||
648 | if (!ha->edc_data) { | ||
649 | ql_log(ql_log_warn, vha, 0x7073, | ||
650 | "Unable to allocate memory for EDC write.\n"); | ||
651 | return -ENOMEM; | ||
652 | } | ||
653 | } | ||
654 | |||
655 | dev = le16_to_cpup((void *)&buf[0]); | ||
656 | adr = le16_to_cpup((void *)&buf[2]); | ||
657 | opt = le16_to_cpup((void *)&buf[4]); | ||
658 | len = le16_to_cpup((void *)&buf[6]); | ||
659 | |||
660 | if (!(opt & BIT_0)) | ||
661 | if (len == 0 || len > DMA_POOL_SIZE || len > count - 8) | ||
662 | return -EINVAL; | ||
663 | |||
664 | memcpy(ha->edc_data, &buf[8], len); | ||
665 | |||
666 | rval = qla2x00_write_sfp(vha, ha->edc_data_dma, ha->edc_data, | ||
667 | dev, adr, len, opt); | ||
668 | if (rval != QLA_SUCCESS) { | ||
669 | ql_log(ql_log_warn, vha, 0x7074, | ||
670 | "Unable to write EDC (%x) %02x:%04x:%02x:%02x:%02hhx\n", | ||
671 | rval, dev, adr, opt, len, buf[8]); | ||
672 | return -EIO; | ||
673 | } | ||
674 | |||
675 | return count; | ||
676 | } | ||
677 | |||
678 | static struct bin_attribute sysfs_edc_attr = { | ||
679 | .attr = { | ||
680 | .name = "edc", | ||
681 | .mode = S_IWUSR, | ||
682 | }, | ||
683 | .size = 0, | ||
684 | .write = qla2x00_sysfs_write_edc, | ||
685 | }; | ||
686 | |||
687 | static ssize_t | ||
688 | qla2x00_sysfs_write_edc_status(struct file *filp, struct kobject *kobj, | ||
689 | struct bin_attribute *bin_attr, | ||
690 | char *buf, loff_t off, size_t count) | ||
691 | { | ||
692 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | ||
693 | struct device, kobj))); | ||
694 | struct qla_hw_data *ha = vha->hw; | ||
695 | uint16_t dev, adr, opt, len; | ||
696 | int rval; | ||
697 | |||
698 | ha->edc_data_len = 0; | ||
699 | |||
700 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8) | ||
701 | return -EINVAL; | ||
702 | |||
703 | if (!ha->edc_data) { | ||
704 | ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, | ||
705 | &ha->edc_data_dma); | ||
706 | if (!ha->edc_data) { | ||
707 | ql_log(ql_log_warn, vha, 0x708c, | ||
708 | "Unable to allocate memory for EDC status.\n"); | ||
709 | return -ENOMEM; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | dev = le16_to_cpup((void *)&buf[0]); | ||
714 | adr = le16_to_cpup((void *)&buf[2]); | ||
715 | opt = le16_to_cpup((void *)&buf[4]); | ||
716 | len = le16_to_cpup((void *)&buf[6]); | ||
717 | |||
718 | if (!(opt & BIT_0)) | ||
719 | if (len == 0 || len > DMA_POOL_SIZE) | ||
720 | return -EINVAL; | ||
721 | |||
722 | memset(ha->edc_data, 0, len); | ||
723 | rval = qla2x00_read_sfp(vha, ha->edc_data_dma, ha->edc_data, | ||
724 | dev, adr, len, opt); | ||
725 | if (rval != QLA_SUCCESS) { | ||
726 | ql_log(ql_log_info, vha, 0x7075, | ||
727 | "Unable to write EDC status (%x) %02x:%04x:%02x:%02x.\n", | ||
728 | rval, dev, adr, opt, len); | ||
729 | return -EIO; | ||
730 | } | ||
731 | |||
732 | ha->edc_data_len = len; | ||
733 | |||
734 | return count; | ||
735 | } | ||
736 | |||
737 | static ssize_t | ||
738 | qla2x00_sysfs_read_edc_status(struct file *filp, struct kobject *kobj, | ||
739 | struct bin_attribute *bin_attr, | ||
740 | char *buf, loff_t off, size_t count) | ||
741 | { | ||
742 | struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj, | ||
743 | struct device, kobj))); | ||
744 | struct qla_hw_data *ha = vha->hw; | ||
745 | |||
746 | if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0) | ||
747 | return 0; | ||
748 | |||
749 | if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count) | ||
750 | return -EINVAL; | ||
751 | |||
752 | memcpy(buf, ha->edc_data, ha->edc_data_len); | ||
753 | |||
754 | return ha->edc_data_len; | ||
755 | } | ||
756 | |||
757 | static struct bin_attribute sysfs_edc_status_attr = { | ||
758 | .attr = { | ||
759 | .name = "edc_status", | ||
760 | .mode = S_IRUSR | S_IWUSR, | ||
761 | }, | ||
762 | .size = 0, | ||
763 | .write = qla2x00_sysfs_write_edc_status, | ||
764 | .read = qla2x00_sysfs_read_edc_status, | ||
765 | }; | ||
766 | |||
767 | static ssize_t | ||
768 | qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj, | 631 | qla2x00_sysfs_read_xgmac_stats(struct file *filp, struct kobject *kobj, |
769 | struct bin_attribute *bin_attr, | 632 | struct bin_attribute *bin_attr, |
770 | char *buf, loff_t off, size_t count) | 633 | char *buf, loff_t off, size_t count) |
@@ -879,8 +742,6 @@ static struct sysfs_entry { | |||
879 | { "vpd", &sysfs_vpd_attr, 1 }, | 742 | { "vpd", &sysfs_vpd_attr, 1 }, |
880 | { "sfp", &sysfs_sfp_attr, 1 }, | 743 | { "sfp", &sysfs_sfp_attr, 1 }, |
881 | { "reset", &sysfs_reset_attr, }, | 744 | { "reset", &sysfs_reset_attr, }, |
882 | { "edc", &sysfs_edc_attr, 2 }, | ||
883 | { "edc_status", &sysfs_edc_status_attr, 2 }, | ||
884 | { "xgmac_stats", &sysfs_xgmac_stats_attr, 3 }, | 745 | { "xgmac_stats", &sysfs_xgmac_stats_attr, 3 }, |
885 | { "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 }, | 746 | { "dcbx_tlv", &sysfs_dcbx_tlv_attr, 3 }, |
886 | { NULL }, | 747 | { NULL }, |
@@ -898,7 +759,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) | |||
898 | continue; | 759 | continue; |
899 | if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) | 760 | if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw)) |
900 | continue; | 761 | continue; |
901 | if (iter->is4GBp_only == 3 && !(IS_QLA8XXX_TYPE(vha->hw))) | 762 | if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
902 | continue; | 763 | continue; |
903 | 764 | ||
904 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, | 765 | ret = sysfs_create_bin_file(&host->shost_gendev.kobj, |
@@ -926,7 +787,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) | |||
926 | continue; | 787 | continue; |
927 | if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) | 788 | if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha)) |
928 | continue; | 789 | continue; |
929 | if (iter->is4GBp_only == 3 && !!(IS_QLA8XXX_TYPE(vha->hw))) | 790 | if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw))) |
930 | continue; | 791 | continue; |
931 | 792 | ||
932 | sysfs_remove_bin_file(&host->shost_gendev.kobj, | 793 | sysfs_remove_bin_file(&host->shost_gendev.kobj, |
@@ -1231,7 +1092,7 @@ qla2x00_optrom_gold_fw_version_show(struct device *dev, | |||
1231 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1092 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1232 | struct qla_hw_data *ha = vha->hw; | 1093 | struct qla_hw_data *ha = vha->hw; |
1233 | 1094 | ||
1234 | if (!IS_QLA81XX(ha)) | 1095 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) |
1235 | return snprintf(buf, PAGE_SIZE, "\n"); | 1096 | return snprintf(buf, PAGE_SIZE, "\n"); |
1236 | 1097 | ||
1237 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", | 1098 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n", |
@@ -1278,7 +1139,7 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr, | |||
1278 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1139 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1279 | struct qla_hw_data *ha = vha->hw; | 1140 | struct qla_hw_data *ha = vha->hw; |
1280 | 1141 | ||
1281 | if (!IS_QLA81XX(ha)) | 1142 | if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) |
1282 | return snprintf(buf, PAGE_SIZE, "\n"); | 1143 | return snprintf(buf, PAGE_SIZE, "\n"); |
1283 | 1144 | ||
1284 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", | 1145 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", |
@@ -1293,7 +1154,7 @@ qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr, | |||
1293 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1154 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1294 | struct qla_hw_data *ha = vha->hw; | 1155 | struct qla_hw_data *ha = vha->hw; |
1295 | 1156 | ||
1296 | if (!IS_QLA81XX(ha)) | 1157 | if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) |
1297 | return snprintf(buf, PAGE_SIZE, "\n"); | 1158 | return snprintf(buf, PAGE_SIZE, "\n"); |
1298 | 1159 | ||
1299 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", | 1160 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", |
@@ -1316,7 +1177,7 @@ qla2x00_vlan_id_show(struct device *dev, struct device_attribute *attr, | |||
1316 | { | 1177 | { |
1317 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1178 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1318 | 1179 | ||
1319 | if (!IS_QLA8XXX_TYPE(vha->hw)) | 1180 | if (!IS_CNA_CAPABLE(vha->hw)) |
1320 | return snprintf(buf, PAGE_SIZE, "\n"); | 1181 | return snprintf(buf, PAGE_SIZE, "\n"); |
1321 | 1182 | ||
1322 | return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id); | 1183 | return snprintf(buf, PAGE_SIZE, "%d\n", vha->fcoe_vlan_id); |
@@ -1328,7 +1189,7 @@ qla2x00_vn_port_mac_address_show(struct device *dev, | |||
1328 | { | 1189 | { |
1329 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); | 1190 | scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); |
1330 | 1191 | ||
1331 | if (!IS_QLA8XXX_TYPE(vha->hw)) | 1192 | if (!IS_CNA_CAPABLE(vha->hw)) |
1332 | return snprintf(buf, PAGE_SIZE, "\n"); | 1193 | return snprintf(buf, PAGE_SIZE, "\n"); |
1333 | 1194 | ||
1334 | return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", | 1195 | return snprintf(buf, PAGE_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x\n", |
@@ -1364,7 +1225,7 @@ qla2x00_thermal_temp_show(struct device *dev, | |||
1364 | else if (!vha->hw->flags.eeh_busy) | 1225 | else if (!vha->hw->flags.eeh_busy) |
1365 | rval = qla2x00_get_thermal_temp(vha, &temp, &frac); | 1226 | rval = qla2x00_get_thermal_temp(vha, &temp, &frac); |
1366 | if (rval != QLA_SUCCESS) | 1227 | if (rval != QLA_SUCCESS) |
1367 | temp = frac = 0; | 1228 | return snprintf(buf, PAGE_SIZE, "\n"); |
1368 | 1229 | ||
1369 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", temp, frac); | 1230 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", temp, frac); |
1370 | } | 1231 | } |
@@ -1493,6 +1354,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
1493 | case PORT_SPEED_10GB: | 1354 | case PORT_SPEED_10GB: |
1494 | speed = FC_PORTSPEED_10GBIT; | 1355 | speed = FC_PORTSPEED_10GBIT; |
1495 | break; | 1356 | break; |
1357 | case PORT_SPEED_16GB: | ||
1358 | speed = FC_PORTSPEED_16GBIT; | ||
1359 | break; | ||
1496 | } | 1360 | } |
1497 | fc_host_speed(shost) = speed; | 1361 | fc_host_speed(shost) = speed; |
1498 | } | 1362 | } |
@@ -1643,10 +1507,14 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) | |||
1643 | * final cleanup of firmware resources (PCBs and XCBs). | 1507 | * final cleanup of firmware resources (PCBs and XCBs). |
1644 | */ | 1508 | */ |
1645 | if (fcport->loop_id != FC_NO_LOOP_ID && | 1509 | if (fcport->loop_id != FC_NO_LOOP_ID && |
1646 | !test_bit(UNLOADING, &fcport->vha->dpc_flags)) | 1510 | !test_bit(UNLOADING, &fcport->vha->dpc_flags)) { |
1647 | fcport->vha->hw->isp_ops->fabric_logout(fcport->vha, | 1511 | if (IS_FWI2_CAPABLE(fcport->vha->hw)) |
1648 | fcport->loop_id, fcport->d_id.b.domain, | 1512 | fcport->vha->hw->isp_ops->fabric_logout(fcport->vha, |
1649 | fcport->d_id.b.area, fcport->d_id.b.al_pa); | 1513 | fcport->loop_id, fcport->d_id.b.domain, |
1514 | fcport->d_id.b.area, fcport->d_id.b.al_pa); | ||
1515 | else | ||
1516 | qla2x00_port_logout(fcport->vha, fcport); | ||
1517 | } | ||
1650 | } | 1518 | } |
1651 | 1519 | ||
1652 | static int | 1520 | static int |
@@ -1889,6 +1757,7 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1889 | break; | 1757 | break; |
1890 | } | 1758 | } |
1891 | } | 1759 | } |
1760 | |||
1892 | if (qos) { | 1761 | if (qos) { |
1893 | ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0, | 1762 | ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0, |
1894 | qos); | 1763 | qos); |
@@ -2086,7 +1955,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) | |||
2086 | fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; | 1955 | fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; |
2087 | fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; | 1956 | fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; |
2088 | 1957 | ||
2089 | if (IS_QLA8XXX_TYPE(ha)) | 1958 | if (IS_CNA_CAPABLE(ha)) |
2090 | speed = FC_PORTSPEED_10GBIT; | 1959 | speed = FC_PORTSPEED_10GBIT; |
2091 | else if (IS_QLA25XX(ha)) | 1960 | else if (IS_QLA25XX(ha)) |
2092 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | | 1961 | speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | |