diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_attr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 118 |
1 files changed, 61 insertions, 57 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 8dd88fc1244a..7a4409ab30ea 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -20,18 +20,12 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, | |||
20 | { | 20 | { |
21 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 21 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
22 | struct device, kobj))); | 22 | struct device, kobj))); |
23 | char *rbuf = (char *)ha->fw_dump; | ||
24 | 23 | ||
25 | if (ha->fw_dump_reading == 0) | 24 | if (ha->fw_dump_reading == 0) |
26 | return 0; | 25 | 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 | 26 | ||
32 | memcpy(buf, &rbuf[off], count); | 27 | return memory_read_from_buffer(buf, count, &off, ha->fw_dump, |
33 | 28 | ha->fw_dump_len); | |
34 | return (count); | ||
35 | } | 29 | } |
36 | 30 | ||
37 | static ssize_t | 31 | static ssize_t |
@@ -94,20 +88,13 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, | |||
94 | { | 88 | { |
95 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 89 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
96 | struct device, kobj))); | 90 | struct device, kobj))); |
97 | int size = ha->nvram_size; | ||
98 | char *nvram_cache = ha->nvram; | ||
99 | 91 | ||
100 | if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) | 92 | if (!capable(CAP_SYS_ADMIN)) |
101 | return 0; | 93 | return 0; |
102 | if (off + count > size) { | ||
103 | size -= off; | ||
104 | count = size; | ||
105 | } | ||
106 | 94 | ||
107 | /* Read NVRAM data from cache. */ | 95 | /* Read NVRAM data from cache. */ |
108 | memcpy(buf, &nvram_cache[off], count); | 96 | return memory_read_from_buffer(buf, count, &off, ha->nvram, |
109 | 97 | ha->nvram_size); | |
110 | return count; | ||
111 | } | 98 | } |
112 | 99 | ||
113 | static ssize_t | 100 | static ssize_t |
@@ -175,14 +162,9 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, | |||
175 | 162 | ||
176 | if (ha->optrom_state != QLA_SREADING) | 163 | if (ha->optrom_state != QLA_SREADING) |
177 | return 0; | 164 | return 0; |
178 | if (off > ha->optrom_region_size) | ||
179 | return 0; | ||
180 | if (off + count > ha->optrom_region_size) | ||
181 | count = ha->optrom_region_size - off; | ||
182 | |||
183 | memcpy(buf, &ha->optrom_buffer[off], count); | ||
184 | 165 | ||
185 | return count; | 166 | return memory_read_from_buffer(buf, count, &off, ha->optrom_buffer, |
167 | ha->optrom_region_size); | ||
186 | } | 168 | } |
187 | 169 | ||
188 | static ssize_t | 170 | static ssize_t |
@@ -374,20 +356,12 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
374 | { | 356 | { |
375 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, | 357 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
376 | struct device, kobj))); | 358 | struct device, kobj))); |
377 | int size = ha->vpd_size; | ||
378 | char *vpd_cache = ha->vpd; | ||
379 | 359 | ||
380 | if (!capable(CAP_SYS_ADMIN) || off > size || count == 0) | 360 | if (!capable(CAP_SYS_ADMIN)) |
381 | return 0; | 361 | return 0; |
382 | if (off + count > size) { | ||
383 | size -= off; | ||
384 | count = size; | ||
385 | } | ||
386 | 362 | ||
387 | /* Read NVRAM data from cache. */ | 363 | /* Read NVRAM data from cache. */ |
388 | memcpy(buf, &vpd_cache[off], count); | 364 | return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size); |
389 | |||
390 | return count; | ||
391 | } | 365 | } |
392 | 366 | ||
393 | static ssize_t | 367 | static ssize_t |
@@ -557,8 +531,10 @@ qla2x00_serial_num_show(struct device *dev, struct device_attribute *attr, | |||
557 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | 531 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); |
558 | uint32_t sn; | 532 | uint32_t sn; |
559 | 533 | ||
560 | if (IS_FWI2_CAPABLE(ha)) | 534 | if (IS_FWI2_CAPABLE(ha)) { |
561 | return snprintf(buf, PAGE_SIZE, "\n"); | 535 | qla2xxx_get_vpd_field(ha, "SN", buf, PAGE_SIZE); |
536 | return snprintf(buf, PAGE_SIZE, "%s\n", buf); | ||
537 | } | ||
562 | 538 | ||
563 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; | 539 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; |
564 | return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, | 540 | return snprintf(buf, PAGE_SIZE, "%c%05d\n", 'A' + sn / 100000, |
@@ -809,6 +785,16 @@ qla2x00_optrom_fw_version_show(struct device *dev, | |||
809 | ha->fw_revision[3]); | 785 | ha->fw_revision[3]); |
810 | } | 786 | } |
811 | 787 | ||
788 | static ssize_t | ||
789 | qla2x00_total_isp_aborts_show(struct device *dev, | ||
790 | struct device_attribute *attr, char *buf) | ||
791 | { | ||
792 | scsi_qla_host_t *ha = shost_priv(class_to_shost(dev)); | ||
793 | |||
794 | return snprintf(buf, PAGE_SIZE, "%d\n", | ||
795 | ha->qla_stats.total_isp_aborts); | ||
796 | } | ||
797 | |||
812 | static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); | 798 | static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); |
813 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); | 799 | static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); |
814 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); | 800 | static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); |
@@ -831,6 +817,8 @@ static DEVICE_ATTR(optrom_fcode_version, S_IRUGO, | |||
831 | qla2x00_optrom_fcode_version_show, NULL); | 817 | qla2x00_optrom_fcode_version_show, NULL); |
832 | static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show, | 818 | static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show, |
833 | NULL); | 819 | NULL); |
820 | static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show, | ||
821 | NULL); | ||
834 | 822 | ||
835 | struct device_attribute *qla2x00_host_attrs[] = { | 823 | struct device_attribute *qla2x00_host_attrs[] = { |
836 | &dev_attr_driver_version, | 824 | &dev_attr_driver_version, |
@@ -849,6 +837,7 @@ struct device_attribute *qla2x00_host_attrs[] = { | |||
849 | &dev_attr_optrom_efi_version, | 837 | &dev_attr_optrom_efi_version, |
850 | &dev_attr_optrom_fcode_version, | 838 | &dev_attr_optrom_fcode_version, |
851 | &dev_attr_optrom_fw_version, | 839 | &dev_attr_optrom_fw_version, |
840 | &dev_attr_total_isp_aborts, | ||
852 | NULL, | 841 | NULL, |
853 | }; | 842 | }; |
854 | 843 | ||
@@ -972,26 +961,39 @@ qla2x00_get_starget_port_id(struct scsi_target *starget) | |||
972 | } | 961 | } |
973 | 962 | ||
974 | static void | 963 | static void |
975 | qla2x00_get_rport_loss_tmo(struct fc_rport *rport) | 964 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
976 | { | 965 | { |
977 | struct Scsi_Host *host = rport_to_shost(rport); | 966 | if (timeout) |
978 | scsi_qla_host_t *ha = shost_priv(host); | 967 | rport->dev_loss_tmo = timeout; |
979 | 968 | else | |
980 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 969 | rport->dev_loss_tmo = 1; |
981 | } | 970 | } |
982 | 971 | ||
983 | static void | 972 | static void |
984 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | 973 | qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) |
985 | { | 974 | { |
986 | struct Scsi_Host *host = rport_to_shost(rport); | 975 | struct Scsi_Host *host = rport_to_shost(rport); |
987 | scsi_qla_host_t *ha = shost_priv(host); | 976 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; |
977 | |||
978 | qla2x00_abort_fcport_cmds(fcport); | ||
979 | |||
980 | /* | ||
981 | * Transport has effectively 'deleted' the rport, clear | ||
982 | * all local references. | ||
983 | */ | ||
984 | spin_lock_irq(host->host_lock); | ||
985 | fcport->rport = NULL; | ||
986 | *((fc_port_t **)rport->dd_data) = NULL; | ||
987 | spin_unlock_irq(host->host_lock); | ||
988 | } | ||
988 | 989 | ||
989 | if (timeout) | 990 | static void |
990 | ha->port_down_retry_count = timeout; | 991 | qla2x00_terminate_rport_io(struct fc_rport *rport) |
991 | else | 992 | { |
992 | ha->port_down_retry_count = 1; | 993 | fc_port_t *fcport = *(fc_port_t **)rport->dd_data; |
993 | 994 | ||
994 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 995 | qla2x00_abort_fcport_cmds(fcport); |
996 | scsi_target_unblock(&rport->dev); | ||
995 | } | 997 | } |
996 | 998 | ||
997 | static int | 999 | static int |
@@ -1045,6 +1047,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | |||
1045 | pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt; | 1047 | pfc_host_stat->invalid_tx_word_count = stats->inval_xmit_word_cnt; |
1046 | pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt; | 1048 | pfc_host_stat->invalid_crc_count = stats->inval_crc_cnt; |
1047 | if (IS_FWI2_CAPABLE(ha)) { | 1049 | if (IS_FWI2_CAPABLE(ha)) { |
1050 | pfc_host_stat->lip_count = stats->lip_cnt; | ||
1048 | pfc_host_stat->tx_frames = stats->tx_frames; | 1051 | pfc_host_stat->tx_frames = stats->tx_frames; |
1049 | pfc_host_stat->rx_frames = stats->rx_frames; | 1052 | pfc_host_stat->rx_frames = stats->rx_frames; |
1050 | pfc_host_stat->dumped_frames = stats->dumped_frames; | 1053 | pfc_host_stat->dumped_frames = stats->dumped_frames; |
@@ -1173,17 +1176,16 @@ vport_create_failed_2: | |||
1173 | static int | 1176 | static int |
1174 | qla24xx_vport_delete(struct fc_vport *fc_vport) | 1177 | qla24xx_vport_delete(struct fc_vport *fc_vport) |
1175 | { | 1178 | { |
1176 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); | ||
1177 | scsi_qla_host_t *vha = fc_vport->dd_data; | 1179 | scsi_qla_host_t *vha = fc_vport->dd_data; |
1180 | scsi_qla_host_t *pha = to_qla_parent(vha); | ||
1181 | |||
1182 | while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) || | ||
1183 | test_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags)) | ||
1184 | msleep(1000); | ||
1178 | 1185 | ||
1179 | qla24xx_disable_vp(vha); | 1186 | qla24xx_disable_vp(vha); |
1180 | qla24xx_deallocate_vp_id(vha); | 1187 | qla24xx_deallocate_vp_id(vha); |
1181 | 1188 | ||
1182 | mutex_lock(&ha->vport_lock); | ||
1183 | ha->cur_vport_count--; | ||
1184 | clear_bit(vha->vp_idx, ha->vp_idx_map); | ||
1185 | mutex_unlock(&ha->vport_lock); | ||
1186 | |||
1187 | kfree(vha->node_name); | 1189 | kfree(vha->node_name); |
1188 | kfree(vha->port_name); | 1190 | kfree(vha->port_name); |
1189 | 1191 | ||
@@ -1248,11 +1250,12 @@ struct fc_function_template qla2xxx_transport_functions = { | |||
1248 | .get_starget_port_id = qla2x00_get_starget_port_id, | 1250 | .get_starget_port_id = qla2x00_get_starget_port_id, |
1249 | .show_starget_port_id = 1, | 1251 | .show_starget_port_id = 1, |
1250 | 1252 | ||
1251 | .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, | ||
1252 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, | 1253 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, |
1253 | .show_rport_dev_loss_tmo = 1, | 1254 | .show_rport_dev_loss_tmo = 1, |
1254 | 1255 | ||
1255 | .issue_fc_host_lip = qla2x00_issue_lip, | 1256 | .issue_fc_host_lip = qla2x00_issue_lip, |
1257 | .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, | ||
1258 | .terminate_rport_io = qla2x00_terminate_rport_io, | ||
1256 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | 1259 | .get_fc_host_stats = qla2x00_get_fc_host_stats, |
1257 | 1260 | ||
1258 | .vport_create = qla24xx_vport_create, | 1261 | .vport_create = qla24xx_vport_create, |
@@ -1291,11 +1294,12 @@ struct fc_function_template qla2xxx_transport_vport_functions = { | |||
1291 | .get_starget_port_id = qla2x00_get_starget_port_id, | 1294 | .get_starget_port_id = qla2x00_get_starget_port_id, |
1292 | .show_starget_port_id = 1, | 1295 | .show_starget_port_id = 1, |
1293 | 1296 | ||
1294 | .get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo, | ||
1295 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, | 1297 | .set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo, |
1296 | .show_rport_dev_loss_tmo = 1, | 1298 | .show_rport_dev_loss_tmo = 1, |
1297 | 1299 | ||
1298 | .issue_fc_host_lip = qla2x00_issue_lip, | 1300 | .issue_fc_host_lip = qla2x00_issue_lip, |
1301 | .dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk, | ||
1302 | .terminate_rport_io = qla2x00_terminate_rport_io, | ||
1299 | .get_fc_host_stats = qla2x00_get_fc_host_stats, | 1303 | .get_fc_host_stats = qla2x00_get_fc_host_stats, |
1300 | }; | 1304 | }; |
1301 | 1305 | ||