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.c118
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
37static ssize_t 31static 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
113static ssize_t 100static 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
188static ssize_t 170static 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
393static ssize_t 367static 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
788static ssize_t
789qla2x00_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
812static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL); 798static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
813static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL); 799static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
814static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL); 800static 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);
832static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show, 818static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
833 NULL); 819 NULL);
820static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
821 NULL);
834 822
835struct device_attribute *qla2x00_host_attrs[] = { 823struct 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
974static void 963static void
975qla2x00_get_rport_loss_tmo(struct fc_rport *rport) 964qla2x00_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
983static void 972static void
984qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) 973qla2x00_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) 990static void
990 ha->port_down_retry_count = timeout; 991qla2x00_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
997static int 999static 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:
1173static int 1176static int
1174qla24xx_vport_delete(struct fc_vport *fc_vport) 1177qla24xx_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