forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/scsi/qla2xxx/qla_attr.c
....@@ -1,8 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * QLogic Fibre Channel HBA Driver
34 * Copyright (c) 2003-2014 QLogic Corporation
4
- *
5
- * See LICENSE.qla2xxx for copyright and licensing details.
65 */
76 #include "qla_def.h"
87 #include "qla_target.h"
....@@ -26,27 +25,35 @@
2625 struct qla_hw_data *ha = vha->hw;
2726 int rval = 0;
2827
29
- if (!(ha->fw_dump_reading || ha->mctp_dump_reading))
28
+ if (!(ha->fw_dump_reading || ha->mctp_dump_reading ||
29
+ ha->mpi_fw_dump_reading))
3030 return 0;
3131
32
+ mutex_lock(&ha->optrom_mutex);
3233 if (IS_P3P_TYPE(ha)) {
3334 if (off < ha->md_template_size) {
3435 rval = memory_read_from_buffer(buf, count,
3536 &off, ha->md_tmplt_hdr, ha->md_template_size);
36
- return rval;
37
+ } else {
38
+ off -= ha->md_template_size;
39
+ rval = memory_read_from_buffer(buf, count,
40
+ &off, ha->md_dump, ha->md_dump_size);
3741 }
38
- off -= ha->md_template_size;
39
- rval = memory_read_from_buffer(buf, count,
40
- &off, ha->md_dump, ha->md_dump_size);
41
- return rval;
42
- } else if (ha->mctp_dumped && ha->mctp_dump_reading)
43
- return memory_read_from_buffer(buf, count, &off, ha->mctp_dump,
42
+ } else if (ha->mctp_dumped && ha->mctp_dump_reading) {
43
+ rval = memory_read_from_buffer(buf, count, &off, ha->mctp_dump,
4444 MCTP_DUMP_SIZE);
45
- else if (ha->fw_dump_reading)
46
- return memory_read_from_buffer(buf, count, &off, ha->fw_dump,
45
+ } else if (ha->mpi_fw_dumped && ha->mpi_fw_dump_reading) {
46
+ rval = memory_read_from_buffer(buf, count, &off,
47
+ ha->mpi_fw_dump,
48
+ ha->mpi_fw_dump_len);
49
+ } else if (ha->fw_dump_reading) {
50
+ rval = memory_read_from_buffer(buf, count, &off, ha->fw_dump,
4751 ha->fw_dump_len);
48
- else
49
- return 0;
52
+ } else {
53
+ rval = 0;
54
+ }
55
+ mutex_unlock(&ha->optrom_mutex);
56
+ return rval;
5057 }
5158
5259 static ssize_t
....@@ -76,7 +83,7 @@
7683 qla82xx_md_prep(vha);
7784 }
7885 ha->fw_dump_reading = 0;
79
- ha->fw_dumped = 0;
86
+ ha->fw_dumped = false;
8087 break;
8188 case 1:
8289 if (ha->fw_dumped && !ha->fw_dump_reading) {
....@@ -99,8 +106,9 @@
99106 qla8044_idc_lock(ha);
100107 qla82xx_set_reset_owner(vha);
101108 qla8044_idc_unlock(ha);
102
- } else
109
+ } else {
103110 qla2x00_system_error(vha);
111
+ }
104112 break;
105113 case 4:
106114 if (IS_P3P_TYPE(ha)) {
....@@ -132,6 +140,30 @@
132140 vha->host_no);
133141 }
134142 break;
143
+ case 8:
144
+ if (!ha->mpi_fw_dump_reading)
145
+ break;
146
+ ql_log(ql_log_info, vha, 0x70e7,
147
+ "MPI firmware dump cleared on (%ld).\n", vha->host_no);
148
+ ha->mpi_fw_dump_reading = 0;
149
+ ha->mpi_fw_dumped = 0;
150
+ break;
151
+ case 9:
152
+ if (ha->mpi_fw_dumped && !ha->mpi_fw_dump_reading) {
153
+ ha->mpi_fw_dump_reading = 1;
154
+ ql_log(ql_log_info, vha, 0x70e8,
155
+ "Raw MPI firmware dump ready for read on (%ld).\n",
156
+ vha->host_no);
157
+ }
158
+ break;
159
+ case 10:
160
+ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
161
+ ql_log(ql_log_info, vha, 0x70e9,
162
+ "Issuing MPI firmware dump on host#%ld.\n",
163
+ vha->host_no);
164
+ ha->isp_ops->mpi_fw_dump(vha, 0);
165
+ }
166
+ break;
135167 }
136168 return count;
137169 }
....@@ -154,13 +186,34 @@
154186 struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
155187 struct device, kobj)));
156188 struct qla_hw_data *ha = vha->hw;
189
+ uint32_t faddr;
190
+ struct active_regions active_regions = { };
157191
158192 if (!capable(CAP_SYS_ADMIN))
159193 return 0;
160194
161
- if (IS_NOCACHE_VPD_TYPE(ha))
162
- ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
163
- ha->nvram_size);
195
+ mutex_lock(&ha->optrom_mutex);
196
+ if (qla2x00_chip_is_down(vha)) {
197
+ mutex_unlock(&ha->optrom_mutex);
198
+ return -EAGAIN;
199
+ }
200
+
201
+ if (!IS_NOCACHE_VPD_TYPE(ha)) {
202
+ mutex_unlock(&ha->optrom_mutex);
203
+ goto skip;
204
+ }
205
+
206
+ faddr = ha->flt_region_nvram;
207
+ if (IS_QLA28XX(ha)) {
208
+ qla28xx_get_aux_images(vha, &active_regions);
209
+ if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
210
+ faddr = ha->flt_region_nvram_sec;
211
+ }
212
+ ha->isp_ops->read_optrom(vha, ha->nvram, faddr << 2, ha->nvram_size);
213
+
214
+ mutex_unlock(&ha->optrom_mutex);
215
+
216
+skip:
164217 return memory_read_from_buffer(buf, count, &off, ha->nvram,
165218 ha->nvram_size);
166219 }
....@@ -181,10 +234,9 @@
181234
182235 /* Checksum NVRAM. */
183236 if (IS_FWI2_CAPABLE(ha)) {
184
- uint32_t *iter;
237
+ __le32 *iter = (__force __le32 *)buf;
185238 uint32_t chksum;
186239
187
- iter = (uint32_t *)buf;
188240 chksum = 0;
189241 for (cnt = 0; cnt < ((count >> 2) - 1); cnt++, iter++)
190242 chksum += le32_to_cpu(*iter);
....@@ -208,10 +260,17 @@
208260 return -EAGAIN;
209261 }
210262
263
+ mutex_lock(&ha->optrom_mutex);
264
+ if (qla2x00_chip_is_down(vha)) {
265
+ mutex_unlock(&ha->optrom_mutex);
266
+ return -EAGAIN;
267
+ }
268
+
211269 /* Write NVRAM. */
212
- ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
213
- ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
270
+ ha->isp_ops->write_nvram(vha, buf, ha->nvram_base, count);
271
+ ha->isp_ops->read_nvram(vha, ha->nvram, ha->nvram_base,
214272 count);
273
+ mutex_unlock(&ha->optrom_mutex);
215274
216275 ql_dbg(ql_dbg_user, vha, 0x7060,
217276 "Setting ISP_ABORT_NEEDED\n");
....@@ -322,6 +381,10 @@
322381 size = ha->optrom_size - start;
323382
324383 mutex_lock(&ha->optrom_mutex);
384
+ if (qla2x00_chip_is_down(vha)) {
385
+ mutex_unlock(&ha->optrom_mutex);
386
+ return -EAGAIN;
387
+ }
325388 switch (val) {
326389 case 0:
327390 if (ha->optrom_state != QLA_SREADING &&
....@@ -348,7 +411,7 @@
348411 ha->optrom_region_size = size;
349412
350413 ha->optrom_state = QLA_SREADING;
351
- ha->optrom_buffer = vmalloc(ha->optrom_region_size);
414
+ ha->optrom_buffer = vzalloc(ha->optrom_region_size);
352415 if (ha->optrom_buffer == NULL) {
353416 ql_log(ql_log_warn, vha, 0x7062,
354417 "Unable to allocate memory for optrom retrieval "
....@@ -370,7 +433,6 @@
370433 "Reading flash region -- 0x%x/0x%x.\n",
371434 ha->optrom_region_start, ha->optrom_region_size);
372435
373
- memset(ha->optrom_buffer, 0, ha->optrom_region_size);
374436 ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
375437 ha->optrom_region_start, ha->optrom_region_size);
376438 break;
....@@ -399,16 +461,15 @@
399461 * 0x000000 -> 0x07ffff -- Boot code.
400462 * 0x080000 -> 0x0fffff -- Firmware.
401463 * 0x120000 -> 0x12ffff -- VPD and HBA parameters.
464
+ *
465
+ * > ISP25xx type boards:
466
+ *
467
+ * None -- should go through BSG.
402468 */
403469 valid = 0;
404470 if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
405471 valid = 1;
406
- else if (start == (ha->flt_region_boot * 4) ||
407
- start == (ha->flt_region_fw * 4))
408
- valid = 1;
409
- else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)
410
- || IS_CNA_CAPABLE(ha) || IS_QLA2031(ha)
411
- || IS_QLA27XX(ha))
472
+ else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
412473 valid = 1;
413474 if (!valid) {
414475 ql_log(ql_log_warn, vha, 0x7065,
....@@ -421,7 +482,7 @@
421482 ha->optrom_region_size = size;
422483
423484 ha->optrom_state = QLA_SWRITING;
424
- ha->optrom_buffer = vmalloc(ha->optrom_region_size);
485
+ ha->optrom_buffer = vzalloc(ha->optrom_region_size);
425486 if (ha->optrom_buffer == NULL) {
426487 ql_log(ql_log_warn, vha, 0x7066,
427488 "Unable to allocate memory for optrom update "
....@@ -436,7 +497,6 @@
436497 "Staging flash region write -- 0x%x/0x%x.\n",
437498 ha->optrom_region_start, ha->optrom_region_size);
438499
439
- memset(ha->optrom_buffer, 0, ha->optrom_region_size);
440500 break;
441501 case 3:
442502 if (ha->optrom_state != QLA_SWRITING) {
....@@ -455,8 +515,10 @@
455515 "Writing flash region -- 0x%x/0x%x.\n",
456516 ha->optrom_region_start, ha->optrom_region_size);
457517
458
- ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
518
+ rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
459519 ha->optrom_region_start, ha->optrom_region_size);
520
+ if (rval)
521
+ rval = -EIO;
460522 break;
461523 default:
462524 rval = -EINVAL;
....@@ -485,6 +547,7 @@
485547 struct device, kobj)));
486548 struct qla_hw_data *ha = vha->hw;
487549 uint32_t faddr;
550
+ struct active_regions active_regions = { };
488551
489552 if (unlikely(pci_channel_offline(ha->pdev)))
490553 return -EAGAIN;
....@@ -492,16 +555,33 @@
492555 if (!capable(CAP_SYS_ADMIN))
493556 return -EINVAL;
494557
495
- if (IS_NOCACHE_VPD_TYPE(ha)) {
496
- faddr = ha->flt_region_vpd << 2;
558
+ if (!IS_NOCACHE_VPD_TYPE(ha))
559
+ goto skip;
497560
498
- if (IS_QLA27XX(ha) &&
499
- qla27xx_find_valid_image(vha) == QLA27XX_SECONDARY_IMAGE)
561
+ faddr = ha->flt_region_vpd << 2;
562
+
563
+ if (IS_QLA28XX(ha)) {
564
+ qla28xx_get_aux_images(vha, &active_regions);
565
+ if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE)
500566 faddr = ha->flt_region_vpd_sec << 2;
501567
502
- ha->isp_ops->read_optrom(vha, ha->vpd, faddr,
503
- ha->vpd_size);
568
+ ql_dbg(ql_dbg_init, vha, 0x7070,
569
+ "Loading %s nvram image.\n",
570
+ active_regions.aux.vpd_nvram == QLA27XX_PRIMARY_IMAGE ?
571
+ "primary" : "secondary");
504572 }
573
+
574
+ mutex_lock(&ha->optrom_mutex);
575
+ if (qla2x00_chip_is_down(vha)) {
576
+ mutex_unlock(&ha->optrom_mutex);
577
+ return -EAGAIN;
578
+ }
579
+
580
+ ha->isp_ops->read_optrom(vha, ha->vpd, faddr, ha->vpd_size);
581
+ mutex_unlock(&ha->optrom_mutex);
582
+
583
+ ha->isp_ops->read_optrom(vha, ha->vpd, faddr, ha->vpd_size);
584
+skip:
505585 return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
506586 }
507587
....@@ -531,22 +611,33 @@
531611 return -EAGAIN;
532612 }
533613
614
+ mutex_lock(&ha->optrom_mutex);
615
+ if (qla2x00_chip_is_down(vha)) {
616
+ mutex_unlock(&ha->optrom_mutex);
617
+ return -EAGAIN;
618
+ }
619
+
534620 /* Write NVRAM. */
535
- ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
536
- ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
621
+ ha->isp_ops->write_nvram(vha, buf, ha->vpd_base, count);
622
+ ha->isp_ops->read_nvram(vha, ha->vpd, ha->vpd_base, count);
537623
538624 /* Update flash version information for 4Gb & above. */
539
- if (!IS_FWI2_CAPABLE(ha))
625
+ if (!IS_FWI2_CAPABLE(ha)) {
626
+ mutex_unlock(&ha->optrom_mutex);
540627 return -EINVAL;
628
+ }
541629
542630 tmp_data = vmalloc(256);
543631 if (!tmp_data) {
632
+ mutex_unlock(&ha->optrom_mutex);
544633 ql_log(ql_log_warn, vha, 0x706b,
545634 "Unable to allocate memory for VPD information update.\n");
546635 return -ENOMEM;
547636 }
548637 ha->isp_ops->get_flash_version(vha, tmp_data);
549638 vfree(tmp_data);
639
+
640
+ mutex_unlock(&ha->optrom_mutex);
550641
551642 return count;
552643 }
....@@ -573,10 +664,15 @@
573664 if (!capable(CAP_SYS_ADMIN) || off != 0 || count < SFP_DEV_SIZE)
574665 return 0;
575666
576
- if (qla2x00_chip_is_down(vha))
667
+ mutex_lock(&vha->hw->optrom_mutex);
668
+ if (qla2x00_chip_is_down(vha)) {
669
+ mutex_unlock(&vha->hw->optrom_mutex);
577670 return 0;
671
+ }
578672
579673 rval = qla2x00_read_sfp_dev(vha, buf, count);
674
+ mutex_unlock(&vha->hw->optrom_mutex);
675
+
580676 if (rval)
581677 return -EIO;
582678
....@@ -604,6 +700,7 @@
604700 int type;
605701 uint32_t idc_control;
606702 uint8_t *tmp_data = NULL;
703
+
607704 if (off != 0)
608705 return -EINVAL;
609706
....@@ -635,13 +732,14 @@
635732 scsi_unblock_requests(vha->host);
636733 break;
637734 case 0x2025d:
638
- if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
735
+ if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
736
+ !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
639737 return -EPERM;
640738
641739 ql_log(ql_log_info, vha, 0x706f,
642740 "Issuing MPI reset.\n");
643741
644
- if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
742
+ if (IS_QLA83XX(ha)) {
645743 uint32_t idc_control;
646744
647745 qla83xx_idc_lock(vha, 0);
....@@ -666,6 +764,7 @@
666764 scsi_unblock_requests(vha->host);
667765 break;
668766 }
767
+ break;
669768 case 0x2025e:
670769 if (!IS_P3P_TYPE(ha) || vha != base_vha) {
671770 ql_log(ql_log_info, vha, 0x7071,
....@@ -786,9 +885,11 @@
786885
787886 if (unlikely(pci_channel_offline(ha->pdev)))
788887 return 0;
789
-
790
- if (qla2x00_chip_is_down(vha))
888
+ mutex_lock(&vha->hw->optrom_mutex);
889
+ if (qla2x00_chip_is_down(vha)) {
890
+ mutex_unlock(&vha->hw->optrom_mutex);
791891 return 0;
892
+ }
792893
793894 if (ha->xgmac_data)
794895 goto do_read;
....@@ -796,6 +897,7 @@
796897 ha->xgmac_data = dma_alloc_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE,
797898 &ha->xgmac_data_dma, GFP_KERNEL);
798899 if (!ha->xgmac_data) {
900
+ mutex_unlock(&vha->hw->optrom_mutex);
799901 ql_log(ql_log_warn, vha, 0x7076,
800902 "Unable to allocate memory for XGMAC read-data.\n");
801903 return 0;
....@@ -807,13 +909,15 @@
807909
808910 rval = qla2x00_get_xgmac_stats(vha, ha->xgmac_data_dma,
809911 XGMAC_DATA_SIZE, &actual_size);
912
+
913
+ mutex_unlock(&vha->hw->optrom_mutex);
810914 if (rval != QLA_SUCCESS) {
811915 ql_log(ql_log_warn, vha, 0x7077,
812916 "Unable to read XGMAC data (%x).\n", rval);
813917 count = 0;
814918 }
815919
816
- count = actual_size > count ? count: actual_size;
920
+ count = actual_size > count ? count : actual_size;
817921 memcpy(buf, ha->xgmac_data, count);
818922
819923 return count;
....@@ -843,13 +947,16 @@
843947
844948 if (ha->dcbx_tlv)
845949 goto do_read;
846
-
847
- if (qla2x00_chip_is_down(vha))
950
+ mutex_lock(&vha->hw->optrom_mutex);
951
+ if (qla2x00_chip_is_down(vha)) {
952
+ mutex_unlock(&vha->hw->optrom_mutex);
848953 return 0;
954
+ }
849955
850956 ha->dcbx_tlv = dma_alloc_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
851957 &ha->dcbx_tlv_dma, GFP_KERNEL);
852958 if (!ha->dcbx_tlv) {
959
+ mutex_unlock(&vha->hw->optrom_mutex);
853960 ql_log(ql_log_warn, vha, 0x7078,
854961 "Unable to allocate memory for DCBX TLV read-data.\n");
855962 return -ENOMEM;
....@@ -860,6 +967,9 @@
860967
861968 rval = qla2x00_get_dcbx_params(vha, ha->dcbx_tlv_dma,
862969 DCBX_TLV_DATA_SIZE);
970
+
971
+ mutex_unlock(&vha->hw->optrom_mutex);
972
+
863973 if (rval != QLA_SUCCESS) {
864974 ql_log(ql_log_warn, vha, 0x7079,
865975 "Unable to read DCBX TLV (%x).\n", rval);
....@@ -883,7 +993,7 @@
883993 static struct sysfs_entry {
884994 char *name;
885995 struct bin_attribute *attr;
886
- int is4GBp_only;
996
+ int type;
887997 } bin_file_entries[] = {
888998 { "fw_dump", &sysfs_fw_dump_attr, },
889999 { "nvram", &sysfs_nvram_attr, },
....@@ -906,11 +1016,11 @@
9061016 int ret;
9071017
9081018 for (iter = bin_file_entries; iter->name; iter++) {
909
- if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw))
1019
+ if (iter->type && !IS_FWI2_CAPABLE(vha->hw))
9101020 continue;
911
- if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
1021
+ if (iter->type == 2 && !IS_QLA25XX(vha->hw))
9121022 continue;
913
- if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw)))
1023
+ if (iter->type == 3 && !(IS_CNA_CAPABLE(vha->hw)))
9141024 continue;
9151025
9161026 ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
....@@ -934,13 +1044,11 @@
9341044 struct qla_hw_data *ha = vha->hw;
9351045
9361046 for (iter = bin_file_entries; iter->name; iter++) {
937
- if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
1047
+ if (iter->type && !IS_FWI2_CAPABLE(ha))
9381048 continue;
939
- if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
1049
+ if (iter->type == 2 && !IS_QLA25XX(ha))
9401050 continue;
941
- if (iter->is4GBp_only == 3 && !(IS_CNA_CAPABLE(vha->hw)))
942
- continue;
943
- if (iter->is4GBp_only == 0x27 && !IS_QLA27XX(vha->hw))
1051
+ if (iter->type == 3 && !(IS_CNA_CAPABLE(ha)))
9441052 continue;
9451053
9461054 sysfs_remove_bin_file(&host->shost_gendev.kobj,
....@@ -954,7 +1062,7 @@
9541062 /* Scsi_Host attributes. */
9551063
9561064 static ssize_t
957
-qla2x00_drvr_version_show(struct device *dev,
1065
+qla2x00_driver_version_show(struct device *dev,
9581066 struct device_attribute *attr, char *buf)
9591067 {
9601068 return scnprintf(buf, PAGE_SIZE, "%s\n", qla2x00_version_str);
....@@ -998,6 +1106,7 @@
9981106 char *buf)
9991107 {
10001108 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1109
+
10011110 return scnprintf(buf, PAGE_SIZE, "ISP%04X\n", vha->hw->pdev->device);
10021111 }
10031112
....@@ -1031,6 +1140,7 @@
10311140 char *buf)
10321141 {
10331142 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1143
+
10341144 return scnprintf(buf, PAGE_SIZE, "%s\n", vha->hw->model_desc);
10351145 }
10361146
....@@ -1042,7 +1152,8 @@
10421152 char pci_info[30];
10431153
10441154 return scnprintf(buf, PAGE_SIZE, "%s\n",
1045
- vha->hw->isp_ops->pci_info_str(vha, pci_info));
1155
+ vha->hw->isp_ops->pci_info_str(vha, pci_info,
1156
+ sizeof(pci_info)));
10461157 }
10471158
10481159 static ssize_t
....@@ -1160,6 +1271,34 @@
11601271 }
11611272
11621273 static ssize_t
1274
+qla_zio_threshold_show(struct device *dev, struct device_attribute *attr,
1275
+ char *buf)
1276
+{
1277
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1278
+
1279
+ return scnprintf(buf, PAGE_SIZE, "%d exchanges\n",
1280
+ vha->hw->last_zio_threshold);
1281
+}
1282
+
1283
+static ssize_t
1284
+qla_zio_threshold_store(struct device *dev, struct device_attribute *attr,
1285
+ const char *buf, size_t count)
1286
+{
1287
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1288
+ int val = 0;
1289
+
1290
+ if (vha->hw->zio_mode != QLA_ZIO_MODE_6)
1291
+ return -EINVAL;
1292
+ if (sscanf(buf, "%d", &val) != 1)
1293
+ return -EINVAL;
1294
+ if (val < 0 || val > 256)
1295
+ return -ERANGE;
1296
+
1297
+ atomic_set(&vha->hw->zio_threshold, val);
1298
+ return strlen(buf);
1299
+}
1300
+
1301
+static ssize_t
11631302 qla2x00_beacon_show(struct device *dev, struct device_attribute *attr,
11641303 char *buf)
11651304 {
....@@ -1185,14 +1324,16 @@
11851324 if (IS_QLA2100(ha) || IS_QLA2200(ha))
11861325 return -EPERM;
11871326
1327
+ if (sscanf(buf, "%d", &val) != 1)
1328
+ return -EINVAL;
1329
+
1330
+ mutex_lock(&vha->hw->optrom_mutex);
11881331 if (qla2x00_chip_is_down(vha)) {
1332
+ mutex_unlock(&vha->hw->optrom_mutex);
11891333 ql_log(ql_log_warn, vha, 0x707a,
11901334 "Abort ISP active -- ignoring beacon request.\n");
11911335 return -EBUSY;
11921336 }
1193
-
1194
- if (sscanf(buf, "%d", &val) != 1)
1195
- return -EINVAL;
11961337
11971338 if (val)
11981339 rval = ha->isp_ops->beacon_on(vha);
....@@ -1201,6 +1342,81 @@
12011342
12021343 if (rval != QLA_SUCCESS)
12031344 count = 0;
1345
+
1346
+ mutex_unlock(&vha->hw->optrom_mutex);
1347
+
1348
+ return count;
1349
+}
1350
+
1351
+static ssize_t
1352
+qla2x00_beacon_config_show(struct device *dev, struct device_attribute *attr,
1353
+ char *buf)
1354
+{
1355
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1356
+ struct qla_hw_data *ha = vha->hw;
1357
+ uint16_t led[3] = { 0 };
1358
+
1359
+ if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
1360
+ return -EPERM;
1361
+
1362
+ if (ql26xx_led_config(vha, 0, led))
1363
+ return scnprintf(buf, PAGE_SIZE, "\n");
1364
+
1365
+ return scnprintf(buf, PAGE_SIZE, "%#04hx %#04hx %#04hx\n",
1366
+ led[0], led[1], led[2]);
1367
+}
1368
+
1369
+static ssize_t
1370
+qla2x00_beacon_config_store(struct device *dev, struct device_attribute *attr,
1371
+ const char *buf, size_t count)
1372
+{
1373
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1374
+ struct qla_hw_data *ha = vha->hw;
1375
+ uint16_t options = BIT_0;
1376
+ uint16_t led[3] = { 0 };
1377
+ uint16_t word[4];
1378
+ int n;
1379
+
1380
+ if (!IS_QLA2031(ha) && !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
1381
+ return -EPERM;
1382
+
1383
+ n = sscanf(buf, "%hx %hx %hx %hx", word+0, word+1, word+2, word+3);
1384
+ if (n == 4) {
1385
+ if (word[0] == 3) {
1386
+ options |= BIT_3|BIT_2|BIT_1;
1387
+ led[0] = word[1];
1388
+ led[1] = word[2];
1389
+ led[2] = word[3];
1390
+ goto write;
1391
+ }
1392
+ return -EINVAL;
1393
+ }
1394
+
1395
+ if (n == 2) {
1396
+ /* check led index */
1397
+ if (word[0] == 0) {
1398
+ options |= BIT_2;
1399
+ led[0] = word[1];
1400
+ goto write;
1401
+ }
1402
+ if (word[0] == 1) {
1403
+ options |= BIT_3;
1404
+ led[1] = word[1];
1405
+ goto write;
1406
+ }
1407
+ if (word[0] == 2) {
1408
+ options |= BIT_1;
1409
+ led[2] = word[1];
1410
+ goto write;
1411
+ }
1412
+ return -EINVAL;
1413
+ }
1414
+
1415
+ return -EINVAL;
1416
+
1417
+write:
1418
+ if (ql26xx_led_config(vha, options, led))
1419
+ return -EFAULT;
12041420
12051421 return count;
12061422 }
....@@ -1211,6 +1427,7 @@
12111427 {
12121428 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12131429 struct qla_hw_data *ha = vha->hw;
1430
+
12141431 return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1],
12151432 ha->bios_revision[0]);
12161433 }
....@@ -1221,6 +1438,7 @@
12211438 {
12221439 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12231440 struct qla_hw_data *ha = vha->hw;
1441
+
12241442 return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1],
12251443 ha->efi_revision[0]);
12261444 }
....@@ -1231,6 +1449,7 @@
12311449 {
12321450 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12331451 struct qla_hw_data *ha = vha->hw;
1452
+
12341453 return scnprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1],
12351454 ha->fcode_revision[0]);
12361455 }
....@@ -1241,6 +1460,7 @@
12411460 {
12421461 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12431462 struct qla_hw_data *ha = vha->hw;
1463
+
12441464 return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n",
12451465 ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2],
12461466 ha->fw_revision[3]);
....@@ -1253,7 +1473,8 @@
12531473 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12541474 struct qla_hw_data *ha = vha->hw;
12551475
1256
- if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA27XX(ha))
1476
+ if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
1477
+ !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
12571478 return scnprintf(buf, PAGE_SIZE, "\n");
12581479
12591480 return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%d)\n",
....@@ -1266,6 +1487,7 @@
12661487 struct device_attribute *attr, char *buf)
12671488 {
12681489 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1490
+
12691491 return scnprintf(buf, PAGE_SIZE, "%d\n",
12701492 vha->qla_stats.total_isp_aborts);
12711493 }
....@@ -1275,21 +1497,37 @@
12751497 struct device_attribute *attr, char *buf)
12761498 {
12771499 int rval = QLA_SUCCESS;
1278
- uint16_t status[2] = {0, 0};
1500
+ uint16_t status[2] = { 0 };
12791501 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
12801502 struct qla_hw_data *ha = vha->hw;
12811503
12821504 if (!IS_QLA84XX(ha))
12831505 return scnprintf(buf, PAGE_SIZE, "\n");
12841506
1285
- if (ha->cs84xx->op_fw_version == 0)
1507
+ if (!ha->cs84xx->op_fw_version) {
12861508 rval = qla84xx_verify_chip(vha, status);
12871509
1288
- if ((rval == QLA_SUCCESS) && (status[0] == 0))
1289
- return scnprintf(buf, PAGE_SIZE, "%u\n",
1290
- (uint32_t)ha->cs84xx->op_fw_version);
1510
+ if (!rval && !status[0])
1511
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
1512
+ (uint32_t)ha->cs84xx->op_fw_version);
1513
+ }
12911514
12921515 return scnprintf(buf, PAGE_SIZE, "\n");
1516
+}
1517
+
1518
+static ssize_t
1519
+qla2x00_serdes_version_show(struct device *dev, struct device_attribute *attr,
1520
+ char *buf)
1521
+{
1522
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1523
+ struct qla_hw_data *ha = vha->hw;
1524
+
1525
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
1526
+ return scnprintf(buf, PAGE_SIZE, "\n");
1527
+
1528
+ return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
1529
+ ha->serdes_version[0], ha->serdes_version[1],
1530
+ ha->serdes_version[2]);
12931531 }
12941532
12951533 static ssize_t
....@@ -1300,7 +1538,7 @@
13001538 struct qla_hw_data *ha = vha->hw;
13011539
13021540 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha) &&
1303
- !IS_QLA27XX(ha))
1541
+ !IS_QLA27XX(ha) && !IS_QLA28XX(ha))
13041542 return scnprintf(buf, PAGE_SIZE, "\n");
13051543
13061544 return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
....@@ -1371,18 +1609,24 @@
13711609 {
13721610 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
13731611 uint16_t temp = 0;
1612
+ int rc;
13741613
1614
+ mutex_lock(&vha->hw->optrom_mutex);
13751615 if (qla2x00_chip_is_down(vha)) {
1616
+ mutex_unlock(&vha->hw->optrom_mutex);
13761617 ql_log(ql_log_warn, vha, 0x70dc, "ISP reset active.\n");
13771618 goto done;
13781619 }
13791620
13801621 if (vha->hw->flags.eeh_busy) {
1622
+ mutex_unlock(&vha->hw->optrom_mutex);
13811623 ql_log(ql_log_warn, vha, 0x70dd, "PCI EEH busy.\n");
13821624 goto done;
13831625 }
13841626
1385
- if (qla2x00_get_thermal_temp(vha, &temp) == QLA_SUCCESS)
1627
+ rc = qla2x00_get_thermal_temp(vha, &temp);
1628
+ mutex_unlock(&vha->hw->optrom_mutex);
1629
+ if (rc == QLA_SUCCESS)
13861630 return scnprintf(buf, PAGE_SIZE, "%d\n", temp);
13871631
13881632 done:
....@@ -1403,13 +1647,24 @@
14031647 return scnprintf(buf, PAGE_SIZE, "0x%x\n", pstate);
14041648 }
14051649
1406
- if (qla2x00_chip_is_down(vha))
1650
+ mutex_lock(&vha->hw->optrom_mutex);
1651
+ if (qla2x00_chip_is_down(vha)) {
1652
+ mutex_unlock(&vha->hw->optrom_mutex);
14071653 ql_log(ql_log_warn, vha, 0x707c,
14081654 "ISP reset active.\n");
1409
- else if (!vha->hw->flags.eeh_busy)
1410
- rval = qla2x00_get_firmware_state(vha, state);
1411
- if (rval != QLA_SUCCESS)
1655
+ goto out;
1656
+ } else if (vha->hw->flags.eeh_busy) {
1657
+ mutex_unlock(&vha->hw->optrom_mutex);
1658
+ goto out;
1659
+ }
1660
+
1661
+ rval = qla2x00_get_firmware_state(vha, state);
1662
+ mutex_unlock(&vha->hw->optrom_mutex);
1663
+out:
1664
+ if (rval != QLA_SUCCESS) {
14121665 memset(state, -1, sizeof(state));
1666
+ rval = qla2x00_get_firmware_state(vha, state);
1667
+ }
14131668
14141669 return scnprintf(buf, PAGE_SIZE, "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
14151670 state[0], state[1], state[2], state[3], state[4], state[5]);
....@@ -1496,7 +1751,7 @@
14961751 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
14971752 struct qla_hw_data *ha = vha->hw;
14981753
1499
- if (!IS_QLA27XX(ha))
1754
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
15001755 return scnprintf(buf, PAGE_SIZE, "\n");
15011756
15021757 return scnprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
....@@ -1504,38 +1759,630 @@
15041759 }
15051760
15061761 static ssize_t
1507
-qla2x00_min_link_speed_show(struct device *dev, struct device_attribute *attr,
1508
- char *buf)
1762
+qla2x00_min_supported_speed_show(struct device *dev,
1763
+ struct device_attribute *attr, char *buf)
15091764 {
15101765 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
15111766 struct qla_hw_data *ha = vha->hw;
15121767
1513
- if (!IS_QLA27XX(ha))
1768
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
15141769 return scnprintf(buf, PAGE_SIZE, "\n");
15151770
15161771 return scnprintf(buf, PAGE_SIZE, "%s\n",
1517
- ha->min_link_speed == 5 ? "32Gps" :
1518
- ha->min_link_speed == 4 ? "16Gps" :
1519
- ha->min_link_speed == 3 ? "8Gps" :
1520
- ha->min_link_speed == 2 ? "4Gps" :
1521
- ha->min_link_speed != 0 ? "unknown" : "");
1772
+ ha->min_supported_speed == 6 ? "64Gps" :
1773
+ ha->min_supported_speed == 5 ? "32Gps" :
1774
+ ha->min_supported_speed == 4 ? "16Gps" :
1775
+ ha->min_supported_speed == 3 ? "8Gps" :
1776
+ ha->min_supported_speed == 2 ? "4Gps" :
1777
+ ha->min_supported_speed != 0 ? "unknown" : "");
15221778 }
15231779
15241780 static ssize_t
1525
-qla2x00_max_speed_sup_show(struct device *dev, struct device_attribute *attr,
1526
- char *buf)
1781
+qla2x00_max_supported_speed_show(struct device *dev,
1782
+ struct device_attribute *attr, char *buf)
15271783 {
15281784 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
15291785 struct qla_hw_data *ha = vha->hw;
15301786
1531
- if (!IS_QLA27XX(ha))
1787
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
15321788 return scnprintf(buf, PAGE_SIZE, "\n");
15331789
15341790 return scnprintf(buf, PAGE_SIZE, "%s\n",
1535
- ha->max_speed_sup ? "32Gps" : "16Gps");
1791
+ ha->max_supported_speed == 2 ? "64Gps" :
1792
+ ha->max_supported_speed == 1 ? "32Gps" :
1793
+ ha->max_supported_speed == 0 ? "16Gps" : "unknown");
15361794 }
15371795
1538
-static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
1796
+static ssize_t
1797
+qla2x00_port_speed_store(struct device *dev, struct device_attribute *attr,
1798
+ const char *buf, size_t count)
1799
+{
1800
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev));
1801
+ ulong type, speed;
1802
+ int oldspeed, rval;
1803
+ int mode = QLA_SET_DATA_RATE_LR;
1804
+ struct qla_hw_data *ha = vha->hw;
1805
+
1806
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) {
1807
+ ql_log(ql_log_warn, vha, 0x70d8,
1808
+ "Speed setting not supported \n");
1809
+ return -EINVAL;
1810
+ }
1811
+
1812
+ rval = kstrtol(buf, 10, &type);
1813
+ if (rval)
1814
+ return rval;
1815
+ speed = type;
1816
+ if (type == 40 || type == 80 || type == 160 ||
1817
+ type == 320) {
1818
+ ql_dbg(ql_dbg_user, vha, 0x70d9,
1819
+ "Setting will be affected after a loss of sync\n");
1820
+ type = type/10;
1821
+ mode = QLA_SET_DATA_RATE_NOLR;
1822
+ }
1823
+
1824
+ oldspeed = ha->set_data_rate;
1825
+
1826
+ switch (type) {
1827
+ case 0:
1828
+ ha->set_data_rate = PORT_SPEED_AUTO;
1829
+ break;
1830
+ case 4:
1831
+ ha->set_data_rate = PORT_SPEED_4GB;
1832
+ break;
1833
+ case 8:
1834
+ ha->set_data_rate = PORT_SPEED_8GB;
1835
+ break;
1836
+ case 16:
1837
+ ha->set_data_rate = PORT_SPEED_16GB;
1838
+ break;
1839
+ case 32:
1840
+ ha->set_data_rate = PORT_SPEED_32GB;
1841
+ break;
1842
+ default:
1843
+ ql_log(ql_log_warn, vha, 0x1199,
1844
+ "Unrecognized speed setting:%lx. Setting Autoneg\n",
1845
+ speed);
1846
+ ha->set_data_rate = PORT_SPEED_AUTO;
1847
+ }
1848
+
1849
+ if (qla2x00_chip_is_down(vha) || (oldspeed == ha->set_data_rate))
1850
+ return -EINVAL;
1851
+
1852
+ ql_log(ql_log_info, vha, 0x70da,
1853
+ "Setting speed to %lx Gbps \n", type);
1854
+
1855
+ rval = qla2x00_set_data_rate(vha, mode);
1856
+ if (rval != QLA_SUCCESS)
1857
+ return -EIO;
1858
+
1859
+ return strlen(buf);
1860
+}
1861
+
1862
+static const struct {
1863
+ u16 rate;
1864
+ char *str;
1865
+} port_speed_str[] = {
1866
+ { PORT_SPEED_4GB, "4" },
1867
+ { PORT_SPEED_8GB, "8" },
1868
+ { PORT_SPEED_16GB, "16" },
1869
+ { PORT_SPEED_32GB, "32" },
1870
+ { PORT_SPEED_64GB, "64" },
1871
+ { PORT_SPEED_10GB, "10" },
1872
+};
1873
+
1874
+static ssize_t
1875
+qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr,
1876
+ char *buf)
1877
+{
1878
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev));
1879
+ struct qla_hw_data *ha = vha->hw;
1880
+ ssize_t rval;
1881
+ u16 i;
1882
+ char *speed = "Unknown";
1883
+
1884
+ rval = qla2x00_get_data_rate(vha);
1885
+ if (rval != QLA_SUCCESS) {
1886
+ ql_log(ql_log_warn, vha, 0x70db,
1887
+ "Unable to get port speed rval:%zd\n", rval);
1888
+ return -EINVAL;
1889
+ }
1890
+
1891
+ for (i = 0; i < ARRAY_SIZE(port_speed_str); i++) {
1892
+ if (port_speed_str[i].rate != ha->link_data_rate)
1893
+ continue;
1894
+ speed = port_speed_str[i].str;
1895
+ break;
1896
+ }
1897
+
1898
+ return scnprintf(buf, PAGE_SIZE, "%s\n", speed);
1899
+}
1900
+
1901
+/* ----- */
1902
+
1903
+static ssize_t
1904
+qlini_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
1905
+{
1906
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1907
+ int len = 0;
1908
+
1909
+ len += scnprintf(buf + len, PAGE_SIZE-len,
1910
+ "Supported options: enabled | disabled | dual | exclusive\n");
1911
+
1912
+ /* --- */
1913
+ len += scnprintf(buf + len, PAGE_SIZE-len, "Current selection: ");
1914
+
1915
+ switch (vha->qlini_mode) {
1916
+ case QLA2XXX_INI_MODE_EXCLUSIVE:
1917
+ len += scnprintf(buf + len, PAGE_SIZE-len,
1918
+ QLA2XXX_INI_MODE_STR_EXCLUSIVE);
1919
+ break;
1920
+ case QLA2XXX_INI_MODE_DISABLED:
1921
+ len += scnprintf(buf + len, PAGE_SIZE-len,
1922
+ QLA2XXX_INI_MODE_STR_DISABLED);
1923
+ break;
1924
+ case QLA2XXX_INI_MODE_ENABLED:
1925
+ len += scnprintf(buf + len, PAGE_SIZE-len,
1926
+ QLA2XXX_INI_MODE_STR_ENABLED);
1927
+ break;
1928
+ case QLA2XXX_INI_MODE_DUAL:
1929
+ len += scnprintf(buf + len, PAGE_SIZE-len,
1930
+ QLA2XXX_INI_MODE_STR_DUAL);
1931
+ break;
1932
+ }
1933
+ len += scnprintf(buf + len, PAGE_SIZE-len, "\n");
1934
+
1935
+ return len;
1936
+}
1937
+
1938
+static char *mode_to_str[] = {
1939
+ "exclusive",
1940
+ "disabled",
1941
+ "enabled",
1942
+ "dual",
1943
+};
1944
+
1945
+#define NEED_EXCH_OFFLOAD(_exchg) ((_exchg) > FW_DEF_EXCHANGES_CNT)
1946
+static void qla_set_ini_mode(scsi_qla_host_t *vha, int op)
1947
+{
1948
+ enum {
1949
+ NO_ACTION,
1950
+ MODE_CHANGE_ACCEPT,
1951
+ MODE_CHANGE_NO_ACTION,
1952
+ TARGET_STILL_ACTIVE,
1953
+ };
1954
+ int action = NO_ACTION;
1955
+ int set_mode = 0;
1956
+ u8 eo_toggle = 0; /* exchange offload flipped */
1957
+
1958
+ switch (vha->qlini_mode) {
1959
+ case QLA2XXX_INI_MODE_DISABLED:
1960
+ switch (op) {
1961
+ case QLA2XXX_INI_MODE_DISABLED:
1962
+ if (qla_tgt_mode_enabled(vha)) {
1963
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
1964
+ vha->hw->flags.exchoffld_enabled)
1965
+ eo_toggle = 1;
1966
+ if (((vha->ql2xexchoffld !=
1967
+ vha->u_ql2xexchoffld) &&
1968
+ NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
1969
+ eo_toggle) {
1970
+ /*
1971
+ * The number of exchange to be offload
1972
+ * was tweaked or offload option was
1973
+ * flipped
1974
+ */
1975
+ action = MODE_CHANGE_ACCEPT;
1976
+ } else {
1977
+ action = MODE_CHANGE_NO_ACTION;
1978
+ }
1979
+ } else {
1980
+ action = MODE_CHANGE_NO_ACTION;
1981
+ }
1982
+ break;
1983
+ case QLA2XXX_INI_MODE_EXCLUSIVE:
1984
+ if (qla_tgt_mode_enabled(vha)) {
1985
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
1986
+ vha->hw->flags.exchoffld_enabled)
1987
+ eo_toggle = 1;
1988
+ if (((vha->ql2xexchoffld !=
1989
+ vha->u_ql2xexchoffld) &&
1990
+ NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
1991
+ eo_toggle) {
1992
+ /*
1993
+ * The number of exchange to be offload
1994
+ * was tweaked or offload option was
1995
+ * flipped
1996
+ */
1997
+ action = MODE_CHANGE_ACCEPT;
1998
+ } else {
1999
+ action = MODE_CHANGE_NO_ACTION;
2000
+ }
2001
+ } else {
2002
+ action = MODE_CHANGE_ACCEPT;
2003
+ }
2004
+ break;
2005
+ case QLA2XXX_INI_MODE_DUAL:
2006
+ action = MODE_CHANGE_ACCEPT;
2007
+ /* active_mode is target only, reset it to dual */
2008
+ if (qla_tgt_mode_enabled(vha)) {
2009
+ set_mode = 1;
2010
+ action = MODE_CHANGE_ACCEPT;
2011
+ } else {
2012
+ action = MODE_CHANGE_NO_ACTION;
2013
+ }
2014
+ break;
2015
+
2016
+ case QLA2XXX_INI_MODE_ENABLED:
2017
+ if (qla_tgt_mode_enabled(vha))
2018
+ action = TARGET_STILL_ACTIVE;
2019
+ else {
2020
+ action = MODE_CHANGE_ACCEPT;
2021
+ set_mode = 1;
2022
+ }
2023
+ break;
2024
+ }
2025
+ break;
2026
+
2027
+ case QLA2XXX_INI_MODE_EXCLUSIVE:
2028
+ switch (op) {
2029
+ case QLA2XXX_INI_MODE_EXCLUSIVE:
2030
+ if (qla_tgt_mode_enabled(vha)) {
2031
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
2032
+ vha->hw->flags.exchoffld_enabled)
2033
+ eo_toggle = 1;
2034
+ if (((vha->ql2xexchoffld !=
2035
+ vha->u_ql2xexchoffld) &&
2036
+ NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
2037
+ eo_toggle)
2038
+ /*
2039
+ * The number of exchange to be offload
2040
+ * was tweaked or offload option was
2041
+ * flipped
2042
+ */
2043
+ action = MODE_CHANGE_ACCEPT;
2044
+ else
2045
+ action = NO_ACTION;
2046
+ } else
2047
+ action = NO_ACTION;
2048
+
2049
+ break;
2050
+
2051
+ case QLA2XXX_INI_MODE_DISABLED:
2052
+ if (qla_tgt_mode_enabled(vha)) {
2053
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld) !=
2054
+ vha->hw->flags.exchoffld_enabled)
2055
+ eo_toggle = 1;
2056
+ if (((vha->ql2xexchoffld !=
2057
+ vha->u_ql2xexchoffld) &&
2058
+ NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld)) ||
2059
+ eo_toggle)
2060
+ action = MODE_CHANGE_ACCEPT;
2061
+ else
2062
+ action = MODE_CHANGE_NO_ACTION;
2063
+ } else
2064
+ action = MODE_CHANGE_NO_ACTION;
2065
+ break;
2066
+
2067
+ case QLA2XXX_INI_MODE_DUAL: /* exclusive -> dual */
2068
+ if (qla_tgt_mode_enabled(vha)) {
2069
+ action = MODE_CHANGE_ACCEPT;
2070
+ set_mode = 1;
2071
+ } else
2072
+ action = MODE_CHANGE_ACCEPT;
2073
+ break;
2074
+
2075
+ case QLA2XXX_INI_MODE_ENABLED:
2076
+ if (qla_tgt_mode_enabled(vha))
2077
+ action = TARGET_STILL_ACTIVE;
2078
+ else {
2079
+ if (vha->hw->flags.fw_started)
2080
+ action = MODE_CHANGE_NO_ACTION;
2081
+ else
2082
+ action = MODE_CHANGE_ACCEPT;
2083
+ }
2084
+ break;
2085
+ }
2086
+ break;
2087
+
2088
+ case QLA2XXX_INI_MODE_ENABLED:
2089
+ switch (op) {
2090
+ case QLA2XXX_INI_MODE_ENABLED:
2091
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg) !=
2092
+ vha->hw->flags.exchoffld_enabled)
2093
+ eo_toggle = 1;
2094
+ if (((vha->ql2xiniexchg != vha->u_ql2xiniexchg) &&
2095
+ NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg)) ||
2096
+ eo_toggle)
2097
+ action = MODE_CHANGE_ACCEPT;
2098
+ else
2099
+ action = NO_ACTION;
2100
+ break;
2101
+ case QLA2XXX_INI_MODE_DUAL:
2102
+ case QLA2XXX_INI_MODE_DISABLED:
2103
+ action = MODE_CHANGE_ACCEPT;
2104
+ break;
2105
+ default:
2106
+ action = MODE_CHANGE_NO_ACTION;
2107
+ break;
2108
+ }
2109
+ break;
2110
+
2111
+ case QLA2XXX_INI_MODE_DUAL:
2112
+ switch (op) {
2113
+ case QLA2XXX_INI_MODE_DUAL:
2114
+ if (qla_tgt_mode_enabled(vha) ||
2115
+ qla_dual_mode_enabled(vha)) {
2116
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld +
2117
+ vha->u_ql2xiniexchg) !=
2118
+ vha->hw->flags.exchoffld_enabled)
2119
+ eo_toggle = 1;
2120
+
2121
+ if ((((vha->ql2xexchoffld +
2122
+ vha->ql2xiniexchg) !=
2123
+ (vha->u_ql2xiniexchg +
2124
+ vha->u_ql2xexchoffld)) &&
2125
+ NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg +
2126
+ vha->u_ql2xexchoffld)) || eo_toggle)
2127
+ action = MODE_CHANGE_ACCEPT;
2128
+ else
2129
+ action = NO_ACTION;
2130
+ } else {
2131
+ if (NEED_EXCH_OFFLOAD(vha->u_ql2xexchoffld +
2132
+ vha->u_ql2xiniexchg) !=
2133
+ vha->hw->flags.exchoffld_enabled)
2134
+ eo_toggle = 1;
2135
+
2136
+ if ((((vha->ql2xexchoffld + vha->ql2xiniexchg)
2137
+ != (vha->u_ql2xiniexchg +
2138
+ vha->u_ql2xexchoffld)) &&
2139
+ NEED_EXCH_OFFLOAD(vha->u_ql2xiniexchg +
2140
+ vha->u_ql2xexchoffld)) || eo_toggle)
2141
+ action = MODE_CHANGE_NO_ACTION;
2142
+ else
2143
+ action = NO_ACTION;
2144
+ }
2145
+ break;
2146
+
2147
+ case QLA2XXX_INI_MODE_DISABLED:
2148
+ if (qla_tgt_mode_enabled(vha) ||
2149
+ qla_dual_mode_enabled(vha)) {
2150
+ /* turning off initiator mode */
2151
+ set_mode = 1;
2152
+ action = MODE_CHANGE_ACCEPT;
2153
+ } else {
2154
+ action = MODE_CHANGE_NO_ACTION;
2155
+ }
2156
+ break;
2157
+
2158
+ case QLA2XXX_INI_MODE_EXCLUSIVE:
2159
+ if (qla_tgt_mode_enabled(vha) ||
2160
+ qla_dual_mode_enabled(vha)) {
2161
+ set_mode = 1;
2162
+ action = MODE_CHANGE_ACCEPT;
2163
+ } else {
2164
+ action = MODE_CHANGE_ACCEPT;
2165
+ }
2166
+ break;
2167
+
2168
+ case QLA2XXX_INI_MODE_ENABLED:
2169
+ if (qla_tgt_mode_enabled(vha) ||
2170
+ qla_dual_mode_enabled(vha)) {
2171
+ action = TARGET_STILL_ACTIVE;
2172
+ } else {
2173
+ action = MODE_CHANGE_ACCEPT;
2174
+ }
2175
+ }
2176
+ break;
2177
+ }
2178
+
2179
+ switch (action) {
2180
+ case MODE_CHANGE_ACCEPT:
2181
+ ql_log(ql_log_warn, vha, 0xffff,
2182
+ "Mode change accepted. From %s to %s, Tgt exchg %d|%d. ini exchg %d|%d\n",
2183
+ mode_to_str[vha->qlini_mode], mode_to_str[op],
2184
+ vha->ql2xexchoffld, vha->u_ql2xexchoffld,
2185
+ vha->ql2xiniexchg, vha->u_ql2xiniexchg);
2186
+
2187
+ vha->qlini_mode = op;
2188
+ vha->ql2xexchoffld = vha->u_ql2xexchoffld;
2189
+ vha->ql2xiniexchg = vha->u_ql2xiniexchg;
2190
+ if (set_mode)
2191
+ qlt_set_mode(vha);
2192
+ vha->flags.online = 1;
2193
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
2194
+ break;
2195
+
2196
+ case MODE_CHANGE_NO_ACTION:
2197
+ ql_log(ql_log_warn, vha, 0xffff,
2198
+ "Mode is set. No action taken. From %s to %s, Tgt exchg %d|%d. ini exchg %d|%d\n",
2199
+ mode_to_str[vha->qlini_mode], mode_to_str[op],
2200
+ vha->ql2xexchoffld, vha->u_ql2xexchoffld,
2201
+ vha->ql2xiniexchg, vha->u_ql2xiniexchg);
2202
+ vha->qlini_mode = op;
2203
+ vha->ql2xexchoffld = vha->u_ql2xexchoffld;
2204
+ vha->ql2xiniexchg = vha->u_ql2xiniexchg;
2205
+ break;
2206
+
2207
+ case TARGET_STILL_ACTIVE:
2208
+ ql_log(ql_log_warn, vha, 0xffff,
2209
+ "Target Mode is active. Unable to change Mode.\n");
2210
+ break;
2211
+
2212
+ case NO_ACTION:
2213
+ default:
2214
+ ql_log(ql_log_warn, vha, 0xffff,
2215
+ "Mode unchange. No action taken. %d|%d pct %d|%d.\n",
2216
+ vha->qlini_mode, op,
2217
+ vha->ql2xexchoffld, vha->u_ql2xexchoffld);
2218
+ break;
2219
+ }
2220
+}
2221
+
2222
+static ssize_t
2223
+qlini_mode_store(struct device *dev, struct device_attribute *attr,
2224
+ const char *buf, size_t count)
2225
+{
2226
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2227
+ int ini;
2228
+
2229
+ if (!buf)
2230
+ return -EINVAL;
2231
+
2232
+ if (strncasecmp(QLA2XXX_INI_MODE_STR_EXCLUSIVE, buf,
2233
+ strlen(QLA2XXX_INI_MODE_STR_EXCLUSIVE)) == 0)
2234
+ ini = QLA2XXX_INI_MODE_EXCLUSIVE;
2235
+ else if (strncasecmp(QLA2XXX_INI_MODE_STR_DISABLED, buf,
2236
+ strlen(QLA2XXX_INI_MODE_STR_DISABLED)) == 0)
2237
+ ini = QLA2XXX_INI_MODE_DISABLED;
2238
+ else if (strncasecmp(QLA2XXX_INI_MODE_STR_ENABLED, buf,
2239
+ strlen(QLA2XXX_INI_MODE_STR_ENABLED)) == 0)
2240
+ ini = QLA2XXX_INI_MODE_ENABLED;
2241
+ else if (strncasecmp(QLA2XXX_INI_MODE_STR_DUAL, buf,
2242
+ strlen(QLA2XXX_INI_MODE_STR_DUAL)) == 0)
2243
+ ini = QLA2XXX_INI_MODE_DUAL;
2244
+ else
2245
+ return -EINVAL;
2246
+
2247
+ qla_set_ini_mode(vha, ini);
2248
+ return strlen(buf);
2249
+}
2250
+
2251
+static ssize_t
2252
+ql2xexchoffld_show(struct device *dev, struct device_attribute *attr,
2253
+ char *buf)
2254
+{
2255
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2256
+ int len = 0;
2257
+
2258
+ len += scnprintf(buf + len, PAGE_SIZE-len,
2259
+ "target exchange: new %d : current: %d\n\n",
2260
+ vha->u_ql2xexchoffld, vha->ql2xexchoffld);
2261
+
2262
+ len += scnprintf(buf + len, PAGE_SIZE-len,
2263
+ "Please (re)set operating mode via \"/sys/class/scsi_host/host%ld/qlini_mode\" to load new setting.\n",
2264
+ vha->host_no);
2265
+
2266
+ return len;
2267
+}
2268
+
2269
+static ssize_t
2270
+ql2xexchoffld_store(struct device *dev, struct device_attribute *attr,
2271
+ const char *buf, size_t count)
2272
+{
2273
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2274
+ int val = 0;
2275
+
2276
+ if (sscanf(buf, "%d", &val) != 1)
2277
+ return -EINVAL;
2278
+
2279
+ if (val > FW_MAX_EXCHANGES_CNT)
2280
+ val = FW_MAX_EXCHANGES_CNT;
2281
+ else if (val < 0)
2282
+ val = 0;
2283
+
2284
+ vha->u_ql2xexchoffld = val;
2285
+ return strlen(buf);
2286
+}
2287
+
2288
+static ssize_t
2289
+ql2xiniexchg_show(struct device *dev, struct device_attribute *attr,
2290
+ char *buf)
2291
+{
2292
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2293
+ int len = 0;
2294
+
2295
+ len += scnprintf(buf + len, PAGE_SIZE-len,
2296
+ "target exchange: new %d : current: %d\n\n",
2297
+ vha->u_ql2xiniexchg, vha->ql2xiniexchg);
2298
+
2299
+ len += scnprintf(buf + len, PAGE_SIZE-len,
2300
+ "Please (re)set operating mode via \"/sys/class/scsi_host/host%ld/qlini_mode\" to load new setting.\n",
2301
+ vha->host_no);
2302
+
2303
+ return len;
2304
+}
2305
+
2306
+static ssize_t
2307
+ql2xiniexchg_store(struct device *dev, struct device_attribute *attr,
2308
+ const char *buf, size_t count)
2309
+{
2310
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2311
+ int val = 0;
2312
+
2313
+ if (sscanf(buf, "%d", &val) != 1)
2314
+ return -EINVAL;
2315
+
2316
+ if (val > FW_MAX_EXCHANGES_CNT)
2317
+ val = FW_MAX_EXCHANGES_CNT;
2318
+ else if (val < 0)
2319
+ val = 0;
2320
+
2321
+ vha->u_ql2xiniexchg = val;
2322
+ return strlen(buf);
2323
+}
2324
+
2325
+static ssize_t
2326
+qla2x00_dif_bundle_statistics_show(struct device *dev,
2327
+ struct device_attribute *attr, char *buf)
2328
+{
2329
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2330
+ struct qla_hw_data *ha = vha->hw;
2331
+
2332
+ return scnprintf(buf, PAGE_SIZE,
2333
+ "cross=%llu read=%llu write=%llu kalloc=%llu dma_alloc=%llu unusable=%u\n",
2334
+ ha->dif_bundle_crossed_pages, ha->dif_bundle_reads,
2335
+ ha->dif_bundle_writes, ha->dif_bundle_kallocs,
2336
+ ha->dif_bundle_dma_allocs, ha->pool.unusable.count);
2337
+}
2338
+
2339
+static ssize_t
2340
+qla2x00_fw_attr_show(struct device *dev,
2341
+ struct device_attribute *attr, char *buf)
2342
+{
2343
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2344
+ struct qla_hw_data *ha = vha->hw;
2345
+
2346
+ if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2347
+ return scnprintf(buf, PAGE_SIZE, "\n");
2348
+
2349
+ return scnprintf(buf, PAGE_SIZE, "%llx\n",
2350
+ (uint64_t)ha->fw_attributes_ext[1] << 48 |
2351
+ (uint64_t)ha->fw_attributes_ext[0] << 32 |
2352
+ (uint64_t)ha->fw_attributes_h << 16 |
2353
+ (uint64_t)ha->fw_attributes);
2354
+}
2355
+
2356
+static ssize_t
2357
+qla2x00_port_no_show(struct device *dev, struct device_attribute *attr,
2358
+ char *buf)
2359
+{
2360
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2361
+
2362
+ return scnprintf(buf, PAGE_SIZE, "%u\n", vha->hw->port_no);
2363
+}
2364
+
2365
+static ssize_t
2366
+qla2x00_dport_diagnostics_show(struct device *dev,
2367
+ struct device_attribute *attr, char *buf)
2368
+{
2369
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
2370
+
2371
+ if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
2372
+ !IS_QLA28XX(vha->hw))
2373
+ return scnprintf(buf, PAGE_SIZE, "\n");
2374
+
2375
+ if (!*vha->dport_data)
2376
+ return scnprintf(buf, PAGE_SIZE, "\n");
2377
+
2378
+ return scnprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n",
2379
+ vha->dport_data[0], vha->dport_data[1],
2380
+ vha->dport_data[2], vha->dport_data[3]);
2381
+}
2382
+static DEVICE_ATTR(dport_diagnostics, 0444,
2383
+ qla2x00_dport_diagnostics_show, NULL);
2384
+
2385
+static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_driver_version_show, NULL);
15392386 static DEVICE_ATTR(fw_version, S_IRUGO, qla2x00_fw_version_show, NULL);
15402387 static DEVICE_ATTR(serial_num, S_IRUGO, qla2x00_serial_num_show, NULL);
15412388 static DEVICE_ATTR(isp_name, S_IRUGO, qla2x00_isp_name_show, NULL);
....@@ -1549,6 +2396,8 @@
15492396 qla2x00_zio_timer_store);
15502397 static DEVICE_ATTR(beacon, S_IRUGO | S_IWUSR, qla2x00_beacon_show,
15512398 qla2x00_beacon_store);
2399
+static DEVICE_ATTR(beacon_config, 0644, qla2x00_beacon_config_show,
2400
+ qla2x00_beacon_config_store);
15522401 static DEVICE_ATTR(optrom_bios_version, S_IRUGO,
15532402 qla2x00_optrom_bios_version_show, NULL);
15542403 static DEVICE_ATTR(optrom_efi_version, S_IRUGO,
....@@ -1563,6 +2412,7 @@
15632412 NULL);
15642413 static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
15652414 NULL);
2415
+static DEVICE_ATTR(serdes_version, 0444, qla2x00_serdes_version_show, NULL);
15662416 static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
15672417 static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
15682418 static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
....@@ -1580,8 +2430,23 @@
15802430 qla2x00_allow_cna_fw_dump_show,
15812431 qla2x00_allow_cna_fw_dump_store);
15822432 static DEVICE_ATTR(pep_version, S_IRUGO, qla2x00_pep_version_show, NULL);
1583
-static DEVICE_ATTR(min_link_speed, S_IRUGO, qla2x00_min_link_speed_show, NULL);
1584
-static DEVICE_ATTR(max_speed_sup, S_IRUGO, qla2x00_max_speed_sup_show, NULL);
2433
+static DEVICE_ATTR(min_supported_speed, 0444,
2434
+ qla2x00_min_supported_speed_show, NULL);
2435
+static DEVICE_ATTR(max_supported_speed, 0444,
2436
+ qla2x00_max_supported_speed_show, NULL);
2437
+static DEVICE_ATTR(zio_threshold, 0644,
2438
+ qla_zio_threshold_show,
2439
+ qla_zio_threshold_store);
2440
+static DEVICE_ATTR_RW(qlini_mode);
2441
+static DEVICE_ATTR_RW(ql2xexchoffld);
2442
+static DEVICE_ATTR_RW(ql2xiniexchg);
2443
+static DEVICE_ATTR(dif_bundle_statistics, 0444,
2444
+ qla2x00_dif_bundle_statistics_show, NULL);
2445
+static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show,
2446
+ qla2x00_port_speed_store);
2447
+static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL);
2448
+static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL);
2449
+
15852450
15862451 struct device_attribute *qla2x00_host_attrs[] = {
15872452 &dev_attr_driver_version,
....@@ -1596,12 +2461,14 @@
15962461 &dev_attr_zio,
15972462 &dev_attr_zio_timer,
15982463 &dev_attr_beacon,
2464
+ &dev_attr_beacon_config,
15992465 &dev_attr_optrom_bios_version,
16002466 &dev_attr_optrom_efi_version,
16012467 &dev_attr_optrom_fcode_version,
16022468 &dev_attr_optrom_fw_version,
16032469 &dev_attr_84xx_fw_version,
16042470 &dev_attr_total_isp_aborts,
2471
+ &dev_attr_serdes_version,
16052472 &dev_attr_mpi_version,
16062473 &dev_attr_phy_version,
16072474 &dev_attr_flash_block_size,
....@@ -1616,10 +2483,34 @@
16162483 &dev_attr_fw_dump_size,
16172484 &dev_attr_allow_cna_fw_dump,
16182485 &dev_attr_pep_version,
1619
- &dev_attr_min_link_speed,
1620
- &dev_attr_max_speed_sup,
2486
+ &dev_attr_min_supported_speed,
2487
+ &dev_attr_max_supported_speed,
2488
+ &dev_attr_zio_threshold,
2489
+ &dev_attr_dif_bundle_statistics,
2490
+ &dev_attr_port_speed,
2491
+ &dev_attr_port_no,
2492
+ &dev_attr_fw_attr,
2493
+ &dev_attr_dport_diagnostics,
2494
+ NULL, /* reserve for qlini_mode */
2495
+ NULL, /* reserve for ql2xiniexchg */
2496
+ NULL, /* reserve for ql2xexchoffld */
16212497 NULL,
16222498 };
2499
+
2500
+void qla_insert_tgt_attrs(void)
2501
+{
2502
+ struct device_attribute **attr;
2503
+
2504
+ /* advance to empty slot */
2505
+ for (attr = &qla2x00_host_attrs[0]; *attr; ++attr)
2506
+ continue;
2507
+
2508
+ *attr = &dev_attr_qlini_mode;
2509
+ attr++;
2510
+ *attr = &dev_attr_ql2xiniexchg;
2511
+ attr++;
2512
+ *attr = &dev_attr_ql2xexchoffld;
2513
+}
16232514
16242515 /* Host attributes. */
16252516
....@@ -1635,16 +2526,15 @@
16352526 static void
16362527 qla2x00_get_host_speed(struct Scsi_Host *shost)
16372528 {
1638
- struct qla_hw_data *ha = ((struct scsi_qla_host *)
1639
- (shost_priv(shost)))->hw;
1640
- u32 speed = FC_PORTSPEED_UNKNOWN;
2529
+ scsi_qla_host_t *vha = shost_priv(shost);
2530
+ u32 speed;
16412531
1642
- if (IS_QLAFX00(ha)) {
2532
+ if (IS_QLAFX00(vha->hw)) {
16432533 qlafx00_get_host_speed(shost);
16442534 return;
16452535 }
16462536
1647
- switch (ha->link_data_rate) {
2537
+ switch (vha->hw->link_data_rate) {
16482538 case PORT_SPEED_1GB:
16492539 speed = FC_PORTSPEED_1GBIT;
16502540 break;
....@@ -1666,7 +2556,14 @@
16662556 case PORT_SPEED_32GB:
16672557 speed = FC_PORTSPEED_32GBIT;
16682558 break;
2559
+ case PORT_SPEED_64GB:
2560
+ speed = FC_PORTSPEED_64GBIT;
2561
+ break;
2562
+ default:
2563
+ speed = FC_PORTSPEED_UNKNOWN;
2564
+ break;
16692565 }
2566
+
16702567 fc_host_speed(shost) = speed;
16712568 }
16722569
....@@ -1674,7 +2571,7 @@
16742571 qla2x00_get_host_port_type(struct Scsi_Host *shost)
16752572 {
16762573 scsi_qla_host_t *vha = shost_priv(shost);
1677
- uint32_t port_type = FC_PORTTYPE_UNKNOWN;
2574
+ uint32_t port_type;
16782575
16792576 if (vha->vp_idx) {
16802577 fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
....@@ -1693,7 +2590,11 @@
16932590 case ISP_CFG_F:
16942591 port_type = FC_PORTTYPE_NPORT;
16952592 break;
2593
+ default:
2594
+ port_type = FC_PORTTYPE_UNKNOWN;
2595
+ break;
16962596 }
2597
+
16972598 fc_host_port_type(shost) = port_type;
16982599 }
16992600
....@@ -1755,13 +2656,10 @@
17552656 fc_starget_port_id(starget) = port_id;
17562657 }
17572658
1758
-static void
2659
+static inline void
17592660 qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
17602661 {
1761
- if (timeout)
1762
- rport->dev_loss_tmo = timeout;
1763
- else
1764
- rport->dev_loss_tmo = 1;
2662
+ rport->dev_loss_tmo = timeout ? timeout : 1;
17652663 }
17662664
17672665 static void
....@@ -1800,6 +2698,7 @@
18002698 qla2x00_terminate_rport_io(struct fc_rport *rport)
18012699 {
18022700 fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
2701
+ scsi_qla_host_t *vha;
18032702
18042703 if (!fcport)
18052704 return;
....@@ -1809,9 +2708,12 @@
18092708
18102709 if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags))
18112710 return;
2711
+ vha = fcport->vha;
18122712
18132713 if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
18142714 qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
2715
+ qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24,
2716
+ 0, WAIT_TARGET);
18152717 return;
18162718 }
18172719 /*
....@@ -1825,6 +2727,15 @@
18252727 fcport->d_id.b.area, fcport->d_id.b.al_pa);
18262728 else
18272729 qla2x00_port_logout(fcport->vha, fcport);
2730
+ }
2731
+
2732
+ /* check for any straggling io left behind */
2733
+ if (qla2x00_eh_wait_for_pending_commands(fcport->vha, fcport->d_id.b24, 0, WAIT_TARGET)) {
2734
+ ql_log(ql_log_warn, vha, 0x300b,
2735
+ "IO not return. Resetting. \n");
2736
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
2737
+ qla2xxx_wake_dpc(vha);
2738
+ qla2x00_wait_for_chip_reset(vha);
18282739 }
18292740 }
18302741
....@@ -1850,6 +2761,9 @@
18502761 struct link_statistics *stats;
18512762 dma_addr_t stats_dma;
18522763 struct fc_host_statistics *p = &vha->fc_host_stat;
2764
+ struct qla_qpair *qpair;
2765
+ int i;
2766
+ u64 ib = 0, ob = 0, ir = 0, or = 0;
18532767
18542768 memset(p, -1, sizeof(*p));
18552769
....@@ -1865,8 +2779,8 @@
18652779 if (qla2x00_chip_is_down(vha))
18662780 goto done;
18672781
1868
- stats = dma_zalloc_coherent(&ha->pdev->dev, sizeof(*stats),
1869
- &stats_dma, GFP_KERNEL);
2782
+ stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma,
2783
+ GFP_KERNEL);
18702784 if (!stats) {
18712785 ql_log(ql_log_warn, vha, 0x707d,
18722786 "Failed to allocate memory for stats.\n");
....@@ -1886,30 +2800,58 @@
18862800 if (rval != QLA_SUCCESS)
18872801 goto done_free;
18882802
1889
- p->link_failure_count = stats->link_fail_cnt;
1890
- p->loss_of_sync_count = stats->loss_sync_cnt;
1891
- p->loss_of_signal_count = stats->loss_sig_cnt;
1892
- p->prim_seq_protocol_err_count = stats->prim_seq_err_cnt;
1893
- p->invalid_tx_word_count = stats->inval_xmit_word_cnt;
1894
- p->invalid_crc_count = stats->inval_crc_cnt;
1895
- if (IS_FWI2_CAPABLE(ha)) {
1896
- p->lip_count = stats->lip_cnt;
1897
- p->tx_frames = stats->tx_frames;
1898
- p->rx_frames = stats->rx_frames;
1899
- p->dumped_frames = stats->discarded_frames;
1900
- p->nos_count = stats->nos_rcvd;
1901
- p->error_frames =
1902
- stats->dropped_frames + stats->discarded_frames;
1903
- p->rx_words = vha->qla_stats.input_bytes;
1904
- p->tx_words = vha->qla_stats.output_bytes;
2803
+ /* --- */
2804
+ for (i = 0; i < vha->hw->max_qpairs; i++) {
2805
+ qpair = vha->hw->queue_pair_map[i];
2806
+ if (!qpair)
2807
+ continue;
2808
+ ir += qpair->counters.input_requests;
2809
+ or += qpair->counters.output_requests;
2810
+ ib += qpair->counters.input_bytes;
2811
+ ob += qpair->counters.output_bytes;
19052812 }
2813
+ ir += ha->base_qpair->counters.input_requests;
2814
+ or += ha->base_qpair->counters.output_requests;
2815
+ ib += ha->base_qpair->counters.input_bytes;
2816
+ ob += ha->base_qpair->counters.output_bytes;
2817
+
2818
+ ir += vha->qla_stats.input_requests;
2819
+ or += vha->qla_stats.output_requests;
2820
+ ib += vha->qla_stats.input_bytes;
2821
+ ob += vha->qla_stats.output_bytes;
2822
+ /* --- */
2823
+
2824
+ p->link_failure_count = le32_to_cpu(stats->link_fail_cnt);
2825
+ p->loss_of_sync_count = le32_to_cpu(stats->loss_sync_cnt);
2826
+ p->loss_of_signal_count = le32_to_cpu(stats->loss_sig_cnt);
2827
+ p->prim_seq_protocol_err_count = le32_to_cpu(stats->prim_seq_err_cnt);
2828
+ p->invalid_tx_word_count = le32_to_cpu(stats->inval_xmit_word_cnt);
2829
+ p->invalid_crc_count = le32_to_cpu(stats->inval_crc_cnt);
2830
+ if (IS_FWI2_CAPABLE(ha)) {
2831
+ p->lip_count = le32_to_cpu(stats->lip_cnt);
2832
+ p->tx_frames = le32_to_cpu(stats->tx_frames);
2833
+ p->rx_frames = le32_to_cpu(stats->rx_frames);
2834
+ p->dumped_frames = le32_to_cpu(stats->discarded_frames);
2835
+ p->nos_count = le32_to_cpu(stats->nos_rcvd);
2836
+ p->error_frames =
2837
+ le32_to_cpu(stats->dropped_frames) +
2838
+ le32_to_cpu(stats->discarded_frames);
2839
+ if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
2840
+ p->rx_words = le64_to_cpu(stats->fpm_recv_word_cnt);
2841
+ p->tx_words = le64_to_cpu(stats->fpm_xmit_word_cnt);
2842
+ } else {
2843
+ p->rx_words = ib >> 2;
2844
+ p->tx_words = ob >> 2;
2845
+ }
2846
+ }
2847
+
19062848 p->fcp_control_requests = vha->qla_stats.control_requests;
1907
- p->fcp_input_requests = vha->qla_stats.input_requests;
1908
- p->fcp_output_requests = vha->qla_stats.output_requests;
1909
- p->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20;
1910
- p->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20;
2849
+ p->fcp_input_requests = ir;
2850
+ p->fcp_output_requests = or;
2851
+ p->fcp_input_megabytes = ib >> 20;
2852
+ p->fcp_output_megabytes = ob >> 20;
19112853 p->seconds_since_last_reset =
1912
- get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
2854
+ get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset;
19132855 do_div(p->seconds_since_last_reset, HZ);
19142856
19152857 done_free:
....@@ -1927,9 +2869,18 @@
19272869 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
19282870 struct link_statistics *stats;
19292871 dma_addr_t stats_dma;
2872
+ int i;
2873
+ struct qla_qpair *qpair;
19302874
19312875 memset(&vha->qla_stats, 0, sizeof(vha->qla_stats));
19322876 memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat));
2877
+ for (i = 0; i < vha->hw->max_qpairs; i++) {
2878
+ qpair = vha->hw->queue_pair_map[i];
2879
+ if (!qpair)
2880
+ continue;
2881
+ memset(&qpair->counters, 0, sizeof(qpair->counters));
2882
+ }
2883
+ memset(&ha->base_qpair->counters, 0, sizeof(qpair->counters));
19332884
19342885 vha->qla_stats.jiffies_at_last_reset = get_jiffies_64();
19352886
....@@ -1977,8 +2928,9 @@
19772928 qla2x00_get_host_fabric_name(struct Scsi_Host *shost)
19782929 {
19792930 scsi_qla_host_t *vha = shost_priv(shost);
1980
- uint8_t node_name[WWN_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, \
1981
- 0xFF, 0xFF, 0xFF, 0xFF};
2931
+ static const uint8_t node_name[WWN_SIZE] = {
2932
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
2933
+ };
19822934 u64 fabric_name = wwn_to_u64(node_name);
19832935
19842936 if (vha->device_flags & SWITCH_FOUND)
....@@ -2056,8 +3008,8 @@
20563008
20573009 /* initialized vport states */
20583010 atomic_set(&vha->loop_state, LOOP_DOWN);
2059
- vha->vp_err_state= VP_ERR_PORTDWN;
2060
- vha->vp_prev_err_state= VP_ERR_UNKWN;
3011
+ vha->vp_err_state = VP_ERR_PORTDWN;
3012
+ vha->vp_prev_err_state = VP_ERR_UNKWN;
20613013 /* Check if physical ha port is Up */
20623014 if (atomic_read(&base_vha->loop_state) == LOOP_DOWN ||
20633015 atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
....@@ -2072,11 +3024,10 @@
20723024 if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
20733025 if (ha->fw_attributes & BIT_4) {
20743026 int prot = 0, guard;
3027
+
20753028 vha->flags.difdix_supported = 1;
20763029 ql_dbg(ql_dbg_user, vha, 0x7082,
20773030 "Registered for DIF/DIX type 1 and 3 protection.\n");
2078
- if (ql2xenabledif == 1)
2079
- prot = SHOST_DIX_TYPE0_PROTECTION;
20803031 scsi_host_set_prot(vha->host,
20813032 prot | SHOST_DIF_TYPE1_PROTECTION
20823033 | SHOST_DIF_TYPE2_PROTECTION
....@@ -2163,6 +3114,8 @@
21633114 scsi_qla_host_t *vha = fc_vport->dd_data;
21643115 struct qla_hw_data *ha = vha->hw;
21653116 uint16_t id = vha->vp_idx;
3117
+
3118
+ set_bit(VPORT_DELETE, &vha->dpc_flags);
21663119
21673120 while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
21683121 test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
....@@ -2320,11 +3273,34 @@
23203273 .bsg_timeout = qla24xx_bsg_timeout,
23213274 };
23223275
3276
+static uint
3277
+qla2x00_get_host_supported_speeds(scsi_qla_host_t *vha, uint speeds)
3278
+{
3279
+ uint supported_speeds = FC_PORTSPEED_UNKNOWN;
3280
+
3281
+ if (speeds & FDMI_PORT_SPEED_64GB)
3282
+ supported_speeds |= FC_PORTSPEED_64GBIT;
3283
+ if (speeds & FDMI_PORT_SPEED_32GB)
3284
+ supported_speeds |= FC_PORTSPEED_32GBIT;
3285
+ if (speeds & FDMI_PORT_SPEED_16GB)
3286
+ supported_speeds |= FC_PORTSPEED_16GBIT;
3287
+ if (speeds & FDMI_PORT_SPEED_8GB)
3288
+ supported_speeds |= FC_PORTSPEED_8GBIT;
3289
+ if (speeds & FDMI_PORT_SPEED_4GB)
3290
+ supported_speeds |= FC_PORTSPEED_4GBIT;
3291
+ if (speeds & FDMI_PORT_SPEED_2GB)
3292
+ supported_speeds |= FC_PORTSPEED_2GBIT;
3293
+ if (speeds & FDMI_PORT_SPEED_1GB)
3294
+ supported_speeds |= FC_PORTSPEED_1GBIT;
3295
+
3296
+ return supported_speeds;
3297
+}
3298
+
23233299 void
23243300 qla2x00_init_host_attr(scsi_qla_host_t *vha)
23253301 {
23263302 struct qla_hw_data *ha = vha->hw;
2327
- u32 speed = FC_PORTSPEED_UNKNOWN;
3303
+ u32 speeds = 0, fdmi_speed = 0;
23283304
23293305 fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count;
23303306 fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name);
....@@ -2334,26 +3310,8 @@
23343310 fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports;
23353311 fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count;
23363312
2337
- if (IS_CNA_CAPABLE(ha))
2338
- speed = FC_PORTSPEED_10GBIT;
2339
- else if (IS_QLA2031(ha))
2340
- speed = FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT |
2341
- FC_PORTSPEED_4GBIT;
2342
- else if (IS_QLA25XX(ha))
2343
- speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
2344
- FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
2345
- else if (IS_QLA24XX_TYPE(ha))
2346
- speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
2347
- FC_PORTSPEED_1GBIT;
2348
- else if (IS_QLA23XX(ha))
2349
- speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
2350
- else if (IS_QLAFX00(ha))
2351
- speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
2352
- FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
2353
- else if (IS_QLA27XX(ha))
2354
- speed = FC_PORTSPEED_32GBIT | FC_PORTSPEED_16GBIT |
2355
- FC_PORTSPEED_8GBIT;
2356
- else
2357
- speed = FC_PORTSPEED_1GBIT;
2358
- fc_host_supported_speeds(vha->host) = speed;
3313
+ fdmi_speed = qla25xx_fdmi_port_speed_capability(ha);
3314
+ speeds = qla2x00_get_host_supported_speeds(vha, fdmi_speed);
3315
+
3316
+ fc_host_supported_speeds(vha->host) = speeds;
23593317 }