diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 118 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_dbg.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 12 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gs.c | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 133 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_iocb.c | 14 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mbx.c | 9 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_mid.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 94 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_sup.c | 48 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_version.h | 2 |
13 files changed, 278 insertions, 185 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 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index cbef785765cf..510ba64bc286 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -216,7 +216,7 @@ qla24xx_soft_reset(scsi_qla_host_t *ha) | |||
216 | 216 | ||
217 | static int | 217 | static int |
218 | qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, | 218 | qla2xxx_dump_ram(scsi_qla_host_t *ha, uint32_t addr, uint16_t *ram, |
219 | uint16_t ram_words, void **nxt) | 219 | uint32_t ram_words, void **nxt) |
220 | { | 220 | { |
221 | int rval; | 221 | int rval; |
222 | uint32_t cnt, stat, timer, words, idx; | 222 | uint32_t cnt, stat, timer, words, idx; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 8dd600013bd1..6da31ba94404 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -864,7 +864,8 @@ struct link_statistics { | |||
864 | uint32_t prim_seq_err_cnt; | 864 | uint32_t prim_seq_err_cnt; |
865 | uint32_t inval_xmit_word_cnt; | 865 | uint32_t inval_xmit_word_cnt; |
866 | uint32_t inval_crc_cnt; | 866 | uint32_t inval_crc_cnt; |
867 | uint32_t unused1[0x1b]; | 867 | uint32_t lip_cnt; |
868 | uint32_t unused1[0x1a]; | ||
868 | uint32_t tx_frames; | 869 | uint32_t tx_frames; |
869 | uint32_t rx_frames; | 870 | uint32_t rx_frames; |
870 | uint32_t dumped_frames; | 871 | uint32_t dumped_frames; |
@@ -1544,7 +1545,6 @@ typedef struct fc_port { | |||
1544 | int login_retry; | 1545 | int login_retry; |
1545 | atomic_t port_down_timer; | 1546 | atomic_t port_down_timer; |
1546 | 1547 | ||
1547 | spinlock_t rport_lock; | ||
1548 | struct fc_rport *rport, *drport; | 1548 | struct fc_rport *rport, *drport; |
1549 | u32 supported_classes; | 1549 | u32 supported_classes; |
1550 | 1550 | ||
@@ -2155,6 +2155,10 @@ struct qla_chip_state_84xx { | |||
2155 | uint32_t gold_fw_version; | 2155 | uint32_t gold_fw_version; |
2156 | }; | 2156 | }; |
2157 | 2157 | ||
2158 | struct qla_statistics { | ||
2159 | uint32_t total_isp_aborts; | ||
2160 | }; | ||
2161 | |||
2158 | /* | 2162 | /* |
2159 | * Linux Host Adapter structure | 2163 | * Linux Host Adapter structure |
2160 | */ | 2164 | */ |
@@ -2166,7 +2170,6 @@ typedef struct scsi_qla_host { | |||
2166 | struct pci_dev *pdev; | 2170 | struct pci_dev *pdev; |
2167 | 2171 | ||
2168 | unsigned long host_no; | 2172 | unsigned long host_no; |
2169 | unsigned long instance; | ||
2170 | 2173 | ||
2171 | volatile struct { | 2174 | volatile struct { |
2172 | uint32_t init_done :1; | 2175 | uint32_t init_done :1; |
@@ -2515,7 +2518,7 @@ typedef struct scsi_qla_host { | |||
2515 | 2518 | ||
2516 | uint8_t model_number[16+1]; | 2519 | uint8_t model_number[16+1]; |
2517 | #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" | 2520 | #define BINZERO "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" |
2518 | char *model_desc; | 2521 | char model_desc[80]; |
2519 | uint8_t adapter_id[16+1]; | 2522 | uint8_t adapter_id[16+1]; |
2520 | 2523 | ||
2521 | uint8_t *node_name; | 2524 | uint8_t *node_name; |
@@ -2596,6 +2599,7 @@ typedef struct scsi_qla_host { | |||
2596 | int cur_vport_count; | 2599 | int cur_vport_count; |
2597 | 2600 | ||
2598 | struct qla_chip_state_84xx *cs84xx; | 2601 | struct qla_chip_state_84xx *cs84xx; |
2602 | struct qla_statistics qla_stats; | ||
2599 | } scsi_qla_host_t; | 2603 | } scsi_qla_host_t; |
2600 | 2604 | ||
2601 | 2605 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 9b4bebee6879..0b156735e9a6 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -62,7 +62,7 @@ extern int ql2xfdmienable; | |||
62 | extern int ql2xallocfwdump; | 62 | extern int ql2xallocfwdump; |
63 | extern int ql2xextended_error_logging; | 63 | extern int ql2xextended_error_logging; |
64 | extern int ql2xqfullrampup; | 64 | extern int ql2xqfullrampup; |
65 | extern int num_hosts; | 65 | extern int ql2xiidmaenable; |
66 | 66 | ||
67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); | 67 | extern int qla2x00_loop_reset(scsi_qla_host_t *); |
68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); | 68 | extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); |
@@ -71,6 +71,8 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum | |||
71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, | 71 | extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t, |
72 | uint16_t, uint16_t); | 72 | uint16_t, uint16_t); |
73 | 73 | ||
74 | extern void qla2x00_abort_fcport_cmds(fc_port_t *); | ||
75 | |||
74 | /* | 76 | /* |
75 | * Global Functions in qla_mid.c source file. | 77 | * Global Functions in qla_mid.c source file. |
76 | */ | 78 | */ |
@@ -312,6 +314,7 @@ extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t, | |||
312 | uint16_t, uint16_t); | 314 | uint16_t, uint16_t); |
313 | 315 | ||
314 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); | 316 | extern void qla2xxx_get_flash_info(scsi_qla_host_t *); |
317 | extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); | ||
315 | 318 | ||
316 | /* | 319 | /* |
317 | * Global Function Prototypes in qla_dbg.c source file. | 320 | * Global Function Prototypes in qla_dbg.c source file. |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 4cb80b476c85..c2a4bfbcb05b 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1661,6 +1661,12 @@ qla2x00_fdmi_register(scsi_qla_host_t *ha) | |||
1661 | { | 1661 | { |
1662 | int rval; | 1662 | int rval; |
1663 | 1663 | ||
1664 | if (IS_QLA2100(ha) || IS_QLA2200(ha)) { | ||
1665 | DEBUG2(printk("scsi(%ld): FDMI unsupported on " | ||
1666 | "ISP2100/ISP2200.\n", ha->host_no)); | ||
1667 | return QLA_SUCCESS; | ||
1668 | } | ||
1669 | |||
1664 | rval = qla2x00_mgmt_svr_login(ha); | 1670 | rval = qla2x00_mgmt_svr_login(ha); |
1665 | if (rval) | 1671 | if (rval) |
1666 | return rval; | 1672 | return rval; |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index bbbc5a632a1d..601a6b29750c 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -334,6 +334,8 @@ static int | |||
334 | qla2x00_isp_firmware(scsi_qla_host_t *ha) | 334 | qla2x00_isp_firmware(scsi_qla_host_t *ha) |
335 | { | 335 | { |
336 | int rval; | 336 | int rval; |
337 | uint16_t loop_id, topo, sw_cap; | ||
338 | uint8_t domain, area, al_pa; | ||
337 | 339 | ||
338 | /* Assume loading risc code */ | 340 | /* Assume loading risc code */ |
339 | rval = QLA_FUNCTION_FAILED; | 341 | rval = QLA_FUNCTION_FAILED; |
@@ -345,6 +347,11 @@ qla2x00_isp_firmware(scsi_qla_host_t *ha) | |||
345 | 347 | ||
346 | /* Verify checksum of loaded RISC code. */ | 348 | /* Verify checksum of loaded RISC code. */ |
347 | rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address); | 349 | rval = qla2x00_verify_checksum(ha, ha->fw_srisc_address); |
350 | if (rval == QLA_SUCCESS) { | ||
351 | /* And, verify we are not in ROM code. */ | ||
352 | rval = qla2x00_get_adapter_id(ha, &loop_id, &al_pa, | ||
353 | &area, &domain, &topo, &sw_cap); | ||
354 | } | ||
348 | } | 355 | } |
349 | 356 | ||
350 | if (rval) { | 357 | if (rval) { |
@@ -722,7 +729,7 @@ qla24xx_chip_diag(scsi_qla_host_t *ha) | |||
722 | /* Perform RISC reset. */ | 729 | /* Perform RISC reset. */ |
723 | qla24xx_reset_risc(ha); | 730 | qla24xx_reset_risc(ha); |
724 | 731 | ||
725 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * 1024; | 732 | ha->fw_transfer_size = REQUEST_ENTRY_SIZE * ha->request_q_length; |
726 | 733 | ||
727 | rval = qla2x00_mbx_reg_test(ha); | 734 | rval = qla2x00_mbx_reg_test(ha); |
728 | if (rval) { | 735 | if (rval) { |
@@ -768,42 +775,16 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
768 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * | 775 | mem_size = (ha->fw_memory_size - 0x100000 + 1) * |
769 | sizeof(uint32_t); | 776 | sizeof(uint32_t); |
770 | 777 | ||
771 | /* Allocate memory for Extended Trace Buffer. */ | ||
772 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, | ||
773 | GFP_KERNEL); | ||
774 | if (!tc) { | ||
775 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
776 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
777 | goto cont_alloc; | ||
778 | } | ||
779 | |||
780 | memset(tc, 0, EFT_SIZE); | ||
781 | rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); | ||
782 | if (rval) { | ||
783 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
784 | "EFT (%d).\n", rval); | ||
785 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, | ||
786 | tc_dma); | ||
787 | goto cont_alloc; | ||
788 | } | ||
789 | |||
790 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
791 | EFT_SIZE / 1024); | ||
792 | |||
793 | eft_size = EFT_SIZE; | ||
794 | ha->eft_dma = tc_dma; | ||
795 | ha->eft = tc; | ||
796 | |||
797 | /* Allocate memory for Fibre Channel Event Buffer. */ | 778 | /* Allocate memory for Fibre Channel Event Buffer. */ |
798 | if (!IS_QLA25XX(ha)) | 779 | if (!IS_QLA25XX(ha)) |
799 | goto cont_alloc; | 780 | goto try_eft; |
800 | 781 | ||
801 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, | 782 | tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma, |
802 | GFP_KERNEL); | 783 | GFP_KERNEL); |
803 | if (!tc) { | 784 | if (!tc) { |
804 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | 785 | qla_printk(KERN_WARNING, ha, "Unable to allocate " |
805 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); | 786 | "(%d KB) for FCE.\n", FCE_SIZE / 1024); |
806 | goto cont_alloc; | 787 | goto try_eft; |
807 | } | 788 | } |
808 | 789 | ||
809 | memset(tc, 0, FCE_SIZE); | 790 | memset(tc, 0, FCE_SIZE); |
@@ -815,7 +796,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
815 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, | 796 | dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, |
816 | tc_dma); | 797 | tc_dma); |
817 | ha->flags.fce_enabled = 0; | 798 | ha->flags.fce_enabled = 0; |
818 | goto cont_alloc; | 799 | goto try_eft; |
819 | } | 800 | } |
820 | 801 | ||
821 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", | 802 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n", |
@@ -825,6 +806,32 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *ha) | |||
825 | ha->flags.fce_enabled = 1; | 806 | ha->flags.fce_enabled = 1; |
826 | ha->fce_dma = tc_dma; | 807 | ha->fce_dma = tc_dma; |
827 | ha->fce = tc; | 808 | ha->fce = tc; |
809 | try_eft: | ||
810 | /* Allocate memory for Extended Trace Buffer. */ | ||
811 | tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma, | ||
812 | GFP_KERNEL); | ||
813 | if (!tc) { | ||
814 | qla_printk(KERN_WARNING, ha, "Unable to allocate " | ||
815 | "(%d KB) for EFT.\n", EFT_SIZE / 1024); | ||
816 | goto cont_alloc; | ||
817 | } | ||
818 | |||
819 | memset(tc, 0, EFT_SIZE); | ||
820 | rval = qla2x00_enable_eft_trace(ha, tc_dma, EFT_NUM_BUFFERS); | ||
821 | if (rval) { | ||
822 | qla_printk(KERN_WARNING, ha, "Unable to initialize " | ||
823 | "EFT (%d).\n", rval); | ||
824 | dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, | ||
825 | tc_dma); | ||
826 | goto cont_alloc; | ||
827 | } | ||
828 | |||
829 | qla_printk(KERN_INFO, ha, "Allocated (%d KB) for EFT...\n", | ||
830 | EFT_SIZE / 1024); | ||
831 | |||
832 | eft_size = EFT_SIZE; | ||
833 | ha->eft_dma = tc_dma; | ||
834 | ha->eft = tc; | ||
828 | } | 835 | } |
829 | cont_alloc: | 836 | cont_alloc: |
830 | req_q_size = ha->request_q_length * sizeof(request_t); | 837 | req_q_size = ha->request_q_length * sizeof(request_t); |
@@ -1501,18 +1508,25 @@ qla2x00_set_model_info(scsi_qla_host_t *ha, uint8_t *model, size_t len, char *de | |||
1501 | index = (ha->pdev->subsystem_device & 0xff); | 1508 | index = (ha->pdev->subsystem_device & 0xff); |
1502 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | 1509 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && |
1503 | index < QLA_MODEL_NAMES) | 1510 | index < QLA_MODEL_NAMES) |
1504 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | 1511 | strncpy(ha->model_desc, |
1512 | qla2x00_model_name[index * 2 + 1], | ||
1513 | sizeof(ha->model_desc) - 1); | ||
1505 | } else { | 1514 | } else { |
1506 | index = (ha->pdev->subsystem_device & 0xff); | 1515 | index = (ha->pdev->subsystem_device & 0xff); |
1507 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && | 1516 | if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC && |
1508 | index < QLA_MODEL_NAMES) { | 1517 | index < QLA_MODEL_NAMES) { |
1509 | strcpy(ha->model_number, | 1518 | strcpy(ha->model_number, |
1510 | qla2x00_model_name[index * 2]); | 1519 | qla2x00_model_name[index * 2]); |
1511 | ha->model_desc = qla2x00_model_name[index * 2 + 1]; | 1520 | strncpy(ha->model_desc, |
1521 | qla2x00_model_name[index * 2 + 1], | ||
1522 | sizeof(ha->model_desc) - 1); | ||
1512 | } else { | 1523 | } else { |
1513 | strcpy(ha->model_number, def); | 1524 | strcpy(ha->model_number, def); |
1514 | } | 1525 | } |
1515 | } | 1526 | } |
1527 | if (IS_FWI2_CAPABLE(ha)) | ||
1528 | qla2xxx_get_vpd_field(ha, "\x82", ha->model_desc, | ||
1529 | sizeof(ha->model_desc)); | ||
1516 | } | 1530 | } |
1517 | 1531 | ||
1518 | /* On sparc systems, obtain port and node WWN from firmware | 1532 | /* On sparc systems, obtain port and node WWN from firmware |
@@ -1864,12 +1878,11 @@ qla2x00_rport_del(void *data) | |||
1864 | { | 1878 | { |
1865 | fc_port_t *fcport = data; | 1879 | fc_port_t *fcport = data; |
1866 | struct fc_rport *rport; | 1880 | struct fc_rport *rport; |
1867 | unsigned long flags; | ||
1868 | 1881 | ||
1869 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1882 | spin_lock_irq(fcport->ha->host->host_lock); |
1870 | rport = fcport->drport; | 1883 | rport = fcport->drport; |
1871 | fcport->drport = NULL; | 1884 | fcport->drport = NULL; |
1872 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1885 | spin_unlock_irq(fcport->ha->host->host_lock); |
1873 | if (rport) | 1886 | if (rport) |
1874 | fc_remote_port_delete(rport); | 1887 | fc_remote_port_delete(rport); |
1875 | } | 1888 | } |
@@ -1898,7 +1911,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1898 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | 1911 | atomic_set(&fcport->state, FCS_UNCONFIGURED); |
1899 | fcport->flags = FCF_RLC_SUPPORT; | 1912 | fcport->flags = FCF_RLC_SUPPORT; |
1900 | fcport->supported_classes = FC_COS_UNSPECIFIED; | 1913 | fcport->supported_classes = FC_COS_UNSPECIFIED; |
1901 | spin_lock_init(&fcport->rport_lock); | ||
1902 | 1914 | ||
1903 | return fcport; | 1915 | return fcport; |
1904 | } | 1916 | } |
@@ -2007,8 +2019,10 @@ qla2x00_configure_loop(scsi_qla_host_t *ha) | |||
2007 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { | 2019 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { |
2008 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) | 2020 | if (test_bit(LOCAL_LOOP_UPDATE, &save_flags)) |
2009 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 2021 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
2010 | if (test_bit(RSCN_UPDATE, &save_flags)) | 2022 | if (test_bit(RSCN_UPDATE, &save_flags)) { |
2023 | ha->flags.rscn_queue_overflow = 1; | ||
2011 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 2024 | set_bit(RSCN_UPDATE, &ha->dpc_flags); |
2025 | } | ||
2012 | } | 2026 | } |
2013 | 2027 | ||
2014 | return (rval); | 2028 | return (rval); |
@@ -2243,28 +2257,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2243 | { | 2257 | { |
2244 | struct fc_rport_identifiers rport_ids; | 2258 | struct fc_rport_identifiers rport_ids; |
2245 | struct fc_rport *rport; | 2259 | struct fc_rport *rport; |
2246 | unsigned long flags; | ||
2247 | 2260 | ||
2248 | if (fcport->drport) | 2261 | if (fcport->drport) |
2249 | qla2x00_rport_del(fcport); | 2262 | qla2x00_rport_del(fcport); |
2250 | if (fcport->rport) | ||
2251 | return; | ||
2252 | 2263 | ||
2253 | rport_ids.node_name = wwn_to_u64(fcport->node_name); | 2264 | rport_ids.node_name = wwn_to_u64(fcport->node_name); |
2254 | rport_ids.port_name = wwn_to_u64(fcport->port_name); | 2265 | rport_ids.port_name = wwn_to_u64(fcport->port_name); |
2255 | rport_ids.port_id = fcport->d_id.b.domain << 16 | | 2266 | rport_ids.port_id = fcport->d_id.b.domain << 16 | |
2256 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 2267 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
2257 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2268 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
2258 | rport = fc_remote_port_add(ha->host, 0, &rport_ids); | 2269 | fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); |
2259 | if (!rport) { | 2270 | if (!rport) { |
2260 | qla_printk(KERN_WARNING, ha, | 2271 | qla_printk(KERN_WARNING, ha, |
2261 | "Unable to allocate fc remote port!\n"); | 2272 | "Unable to allocate fc remote port!\n"); |
2262 | return; | 2273 | return; |
2263 | } | 2274 | } |
2264 | spin_lock_irqsave(&fcport->rport_lock, flags); | 2275 | spin_lock_irq(fcport->ha->host->host_lock); |
2265 | fcport->rport = rport; | ||
2266 | *((fc_port_t **)rport->dd_data) = fcport; | 2276 | *((fc_port_t **)rport->dd_data) = fcport; |
2267 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 2277 | spin_unlock_irq(fcport->ha->host->host_lock); |
2268 | 2278 | ||
2269 | rport->supported_classes = fcport->supported_classes; | 2279 | rport->supported_classes = fcport->supported_classes; |
2270 | 2280 | ||
@@ -2565,7 +2575,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2565 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { | 2575 | } else if (qla2x00_gnn_id(ha, swl) != QLA_SUCCESS) { |
2566 | kfree(swl); | 2576 | kfree(swl); |
2567 | swl = NULL; | 2577 | swl = NULL; |
2568 | } else if (qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { | 2578 | } else if (ql2xiidmaenable && |
2579 | qla2x00_gfpn_id(ha, swl) == QLA_SUCCESS) { | ||
2569 | qla2x00_gpsc(ha, swl); | 2580 | qla2x00_gpsc(ha, swl); |
2570 | } | 2581 | } |
2571 | } | 2582 | } |
@@ -3220,7 +3231,8 @@ qla2x00_update_fcports(scsi_qla_host_t *ha) | |||
3220 | 3231 | ||
3221 | /* Go with deferred removal of rport references. */ | 3232 | /* Go with deferred removal of rport references. */ |
3222 | list_for_each_entry(fcport, &ha->fcports, list) | 3233 | list_for_each_entry(fcport, &ha->fcports, list) |
3223 | if (fcport->drport) | 3234 | if (fcport->drport && |
3235 | atomic_read(&fcport->state) != FCS_UNCONFIGURED) | ||
3224 | qla2x00_rport_del(fcport); | 3236 | qla2x00_rport_del(fcport); |
3225 | } | 3237 | } |
3226 | 3238 | ||
@@ -3243,6 +3255,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3243 | if (ha->flags.online) { | 3255 | if (ha->flags.online) { |
3244 | ha->flags.online = 0; | 3256 | ha->flags.online = 0; |
3245 | clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 3257 | clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
3258 | ha->qla_stats.total_isp_aborts++; | ||
3246 | 3259 | ||
3247 | qla_printk(KERN_INFO, ha, | 3260 | qla_printk(KERN_INFO, ha, |
3248 | "Performing ISP error recovery - ha= %p.\n", ha); | 3261 | "Performing ISP error recovery - ha= %p.\n", ha); |
@@ -3283,17 +3296,6 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3283 | ha->isp_abort_cnt = 0; | 3296 | ha->isp_abort_cnt = 0; |
3284 | clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); | 3297 | clear_bit(ISP_ABORT_RETRY, &ha->dpc_flags); |
3285 | 3298 | ||
3286 | if (ha->eft) { | ||
3287 | memset(ha->eft, 0, EFT_SIZE); | ||
3288 | rval = qla2x00_enable_eft_trace(ha, | ||
3289 | ha->eft_dma, EFT_NUM_BUFFERS); | ||
3290 | if (rval) { | ||
3291 | qla_printk(KERN_WARNING, ha, | ||
3292 | "Unable to reinitialize EFT " | ||
3293 | "(%d).\n", rval); | ||
3294 | } | ||
3295 | } | ||
3296 | |||
3297 | if (ha->fce) { | 3299 | if (ha->fce) { |
3298 | ha->flags.fce_enabled = 1; | 3300 | ha->flags.fce_enabled = 1; |
3299 | memset(ha->fce, 0, | 3301 | memset(ha->fce, 0, |
@@ -3308,6 +3310,17 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3308 | ha->flags.fce_enabled = 0; | 3310 | ha->flags.fce_enabled = 0; |
3309 | } | 3311 | } |
3310 | } | 3312 | } |
3313 | |||
3314 | if (ha->eft) { | ||
3315 | memset(ha->eft, 0, EFT_SIZE); | ||
3316 | rval = qla2x00_enable_eft_trace(ha, | ||
3317 | ha->eft_dma, EFT_NUM_BUFFERS); | ||
3318 | if (rval) { | ||
3319 | qla_printk(KERN_WARNING, ha, | ||
3320 | "Unable to reinitialize EFT " | ||
3321 | "(%d).\n", rval); | ||
3322 | } | ||
3323 | } | ||
3311 | } else { /* failed the ISP abort */ | 3324 | } else { /* failed the ISP abort */ |
3312 | ha->flags.online = 1; | 3325 | ha->flags.online = 1; |
3313 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { | 3326 | if (test_bit(ISP_ABORT_RETRY, &ha->dpc_flags)) { |
@@ -4026,8 +4039,8 @@ qla2x00_try_to_stop_firmware(scsi_qla_host_t *ha) | |||
4026 | ret = qla2x00_stop_firmware(ha); | 4039 | ret = qla2x00_stop_firmware(ha); |
4027 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && | 4040 | for (retries = 5; ret != QLA_SUCCESS && ret != QLA_FUNCTION_TIMEOUT && |
4028 | retries ; retries--) { | 4041 | retries ; retries--) { |
4029 | qla2x00_reset_chip(ha); | 4042 | ha->isp_ops->reset_chip(ha); |
4030 | if (qla2x00_chip_diag(ha) != QLA_SUCCESS) | 4043 | if (ha->isp_ops->chip_diag(ha) != QLA_SUCCESS) |
4031 | continue; | 4044 | continue; |
4032 | if (qla2x00_setup_chip(ha) != QLA_SUCCESS) | 4045 | if (qla2x00_setup_chip(ha) != QLA_SUCCESS) |
4033 | continue; | 4046 | continue; |
@@ -4049,7 +4062,7 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha) | |||
4049 | rval = qla2x00_fw_ready(ha->parent); | 4062 | rval = qla2x00_fw_ready(ha->parent); |
4050 | if (rval == QLA_SUCCESS) { | 4063 | if (rval == QLA_SUCCESS) { |
4051 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 4064 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); |
4052 | qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL); | 4065 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); |
4053 | } | 4066 | } |
4054 | 4067 | ||
4055 | ha->flags.management_server_logged_in = 0; | 4068 | ha->flags.management_server_logged_in = 0; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5489d5024673..d57669aa4615 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -454,10 +454,11 @@ qla2x00_marker(scsi_qla_host_t *ha, uint16_t loop_id, uint16_t lun, | |||
454 | { | 454 | { |
455 | int ret; | 455 | int ret; |
456 | unsigned long flags = 0; | 456 | unsigned long flags = 0; |
457 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
457 | 458 | ||
458 | spin_lock_irqsave(&ha->hardware_lock, flags); | 459 | spin_lock_irqsave(&pha->hardware_lock, flags); |
459 | ret = __qla2x00_marker(ha, loop_id, lun, type); | 460 | ret = __qla2x00_marker(ha, loop_id, lun, type); |
460 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 461 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
461 | 462 | ||
462 | return (ret); | 463 | return (ret); |
463 | } | 464 | } |
@@ -672,7 +673,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
672 | { | 673 | { |
673 | int ret, nseg; | 674 | int ret, nseg; |
674 | unsigned long flags; | 675 | unsigned long flags; |
675 | scsi_qla_host_t *ha; | 676 | scsi_qla_host_t *ha, *pha; |
676 | struct scsi_cmnd *cmd; | 677 | struct scsi_cmnd *cmd; |
677 | uint32_t *clr_ptr; | 678 | uint32_t *clr_ptr; |
678 | uint32_t index; | 679 | uint32_t index; |
@@ -686,6 +687,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
686 | /* Setup device pointers. */ | 687 | /* Setup device pointers. */ |
687 | ret = 0; | 688 | ret = 0; |
688 | ha = sp->ha; | 689 | ha = sp->ha; |
690 | pha = to_qla_parent(ha); | ||
689 | reg = &ha->iobase->isp24; | 691 | reg = &ha->iobase->isp24; |
690 | cmd = sp->cmd; | 692 | cmd = sp->cmd; |
691 | /* So we know we haven't pci_map'ed anything yet */ | 693 | /* So we know we haven't pci_map'ed anything yet */ |
@@ -700,7 +702,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
700 | } | 702 | } |
701 | 703 | ||
702 | /* Acquire ring specific lock */ | 704 | /* Acquire ring specific lock */ |
703 | spin_lock_irqsave(&ha->hardware_lock, flags); | 705 | spin_lock_irqsave(&pha->hardware_lock, flags); |
704 | 706 | ||
705 | /* Check for room in outstanding command list. */ | 707 | /* Check for room in outstanding command list. */ |
706 | handle = ha->current_outstanding_cmd; | 708 | handle = ha->current_outstanding_cmd; |
@@ -795,14 +797,14 @@ qla24xx_start_scsi(srb_t *sp) | |||
795 | ha->response_ring_ptr->signature != RESPONSE_PROCESSED) | 797 | ha->response_ring_ptr->signature != RESPONSE_PROCESSED) |
796 | qla24xx_process_response_queue(ha); | 798 | qla24xx_process_response_queue(ha); |
797 | 799 | ||
798 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 800 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
799 | return QLA_SUCCESS; | 801 | return QLA_SUCCESS; |
800 | 802 | ||
801 | queuing_error: | 803 | queuing_error: |
802 | if (tot_dsds) | 804 | if (tot_dsds) |
803 | scsi_dma_unmap(cmd); | 805 | scsi_dma_unmap(cmd); |
804 | 806 | ||
805 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 807 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
806 | 808 | ||
807 | return QLA_FUNCTION_FAILED; | 809 | return QLA_FUNCTION_FAILED; |
808 | } | 810 | } |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index ec63b79f900a..874d802edb7d 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -542,10 +542,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
542 | break; | 542 | break; |
543 | 543 | ||
544 | case MBA_PORT_UPDATE: /* Port database update */ | 544 | case MBA_PORT_UPDATE: /* Port database update */ |
545 | /* Only handle SCNs for our Vport index. */ | ||
546 | if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) | ||
547 | break; | ||
548 | |||
549 | /* | 545 | /* |
550 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET | 546 | * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET |
551 | * event etc. earlier indicating loop is down) then process | 547 | * event etc. earlier indicating loop is down) then process |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 250d2f604397..bc90d6b8d0a0 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -918,6 +918,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, | |||
918 | rval = qla2x00_mailbox_command(ha, mcp); | 918 | rval = qla2x00_mailbox_command(ha, mcp); |
919 | if (mcp->mb[0] == MBS_COMMAND_ERROR) | 919 | if (mcp->mb[0] == MBS_COMMAND_ERROR) |
920 | rval = QLA_COMMAND_ERROR; | 920 | rval = QLA_COMMAND_ERROR; |
921 | else if (mcp->mb[0] == MBS_INVALID_COMMAND) | ||
922 | rval = QLA_INVALID_COMMAND; | ||
921 | 923 | ||
922 | /* Return data. */ | 924 | /* Return data. */ |
923 | *id = mcp->mb[1]; | 925 | *id = mcp->mb[1]; |
@@ -2161,17 +2163,18 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) | |||
2161 | struct abort_entry_24xx *abt; | 2163 | struct abort_entry_24xx *abt; |
2162 | dma_addr_t abt_dma; | 2164 | dma_addr_t abt_dma; |
2163 | uint32_t handle; | 2165 | uint32_t handle; |
2166 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
2164 | 2167 | ||
2165 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | 2168 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); |
2166 | 2169 | ||
2167 | fcport = sp->fcport; | 2170 | fcport = sp->fcport; |
2168 | 2171 | ||
2169 | spin_lock_irqsave(&ha->hardware_lock, flags); | 2172 | spin_lock_irqsave(&pha->hardware_lock, flags); |
2170 | for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { | 2173 | for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { |
2171 | if (ha->outstanding_cmds[handle] == sp) | 2174 | if (pha->outstanding_cmds[handle] == sp) |
2172 | break; | 2175 | break; |
2173 | } | 2176 | } |
2174 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 2177 | spin_unlock_irqrestore(&pha->hardware_lock, flags); |
2175 | if (handle == MAX_OUTSTANDING_COMMANDS) { | 2178 | if (handle == MAX_OUTSTANDING_COMMANDS) { |
2176 | /* Command not found. */ | 2179 | /* Command not found. */ |
2177 | return QLA_FUNCTION_FAILED; | 2180 | return QLA_FUNCTION_FAILED; |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 62a3ad6e8ecb..50baf6a1d67c 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -43,6 +43,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) | |||
43 | 43 | ||
44 | set_bit(vp_id, ha->vp_idx_map); | 44 | set_bit(vp_id, ha->vp_idx_map); |
45 | ha->num_vhosts++; | 45 | ha->num_vhosts++; |
46 | ha->cur_vport_count++; | ||
46 | vha->vp_idx = vp_id; | 47 | vha->vp_idx = vp_id; |
47 | list_add_tail(&vha->vp_list, &ha->vp_list); | 48 | list_add_tail(&vha->vp_list, &ha->vp_list); |
48 | mutex_unlock(&ha->vport_lock); | 49 | mutex_unlock(&ha->vport_lock); |
@@ -58,6 +59,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) | |||
58 | mutex_lock(&ha->vport_lock); | 59 | mutex_lock(&ha->vport_lock); |
59 | vp_id = vha->vp_idx; | 60 | vp_id = vha->vp_idx; |
60 | ha->num_vhosts--; | 61 | ha->num_vhosts--; |
62 | ha->cur_vport_count--; | ||
61 | clear_bit(vp_id, ha->vp_idx_map); | 63 | clear_bit(vp_id, ha->vp_idx_map); |
62 | list_del(&vha->vp_list); | 64 | list_del(&vha->vp_list); |
63 | mutex_unlock(&ha->vport_lock); | 65 | mutex_unlock(&ha->vport_lock); |
@@ -103,8 +105,8 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | |||
103 | "loop_id=0x%04x :%x\n", | 105 | "loop_id=0x%04x :%x\n", |
104 | vha->host_no, fcport->loop_id, fcport->vp_idx)); | 106 | vha->host_no, fcport->loop_id, fcport->vp_idx)); |
105 | 107 | ||
106 | atomic_set(&fcport->state, FCS_DEVICE_DEAD); | ||
107 | qla2x00_mark_device_lost(vha, fcport, 0, 0); | 108 | qla2x00_mark_device_lost(vha, fcport, 0, 0); |
109 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | ||
108 | } | 110 | } |
109 | } | 111 | } |
110 | 112 | ||
@@ -276,7 +278,8 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha) | |||
276 | clear_bit(RESET_ACTIVE, &vha->dpc_flags); | 278 | clear_bit(RESET_ACTIVE, &vha->dpc_flags); |
277 | } | 279 | } |
278 | 280 | ||
279 | if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { | 281 | if (atomic_read(&vha->vp_state) == VP_ACTIVE && |
282 | test_and_clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) { | ||
280 | if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) { | 283 | if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))) { |
281 | qla2x00_loop_resync(vha); | 284 | qla2x00_loop_resync(vha); |
282 | clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags); | 285 | clear_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags); |
@@ -390,7 +393,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
390 | vha->parent = ha; | 393 | vha->parent = ha; |
391 | vha->fc_vport = fc_vport; | 394 | vha->fc_vport = fc_vport; |
392 | vha->device_flags = 0; | 395 | vha->device_flags = 0; |
393 | vha->instance = num_hosts; | ||
394 | vha->vp_idx = qla24xx_allocate_vp_id(vha); | 396 | vha->vp_idx = qla24xx_allocate_vp_id(vha); |
395 | if (vha->vp_idx > ha->max_npiv_vports) { | 397 | if (vha->vp_idx > ha->max_npiv_vports) { |
396 | DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n", | 398 | DEBUG15(printk("scsi(%ld): Couldn't allocate vp_id.\n", |
@@ -428,7 +430,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
428 | host->max_cmd_len = MAX_CMDSZ; | 430 | host->max_cmd_len = MAX_CMDSZ; |
429 | host->max_channel = MAX_BUSES - 1; | 431 | host->max_channel = MAX_BUSES - 1; |
430 | host->max_lun = MAX_LUNS; | 432 | host->max_lun = MAX_LUNS; |
431 | host->unique_id = vha->instance; | 433 | host->unique_id = host->host_no; |
432 | host->max_id = MAX_TARGETS_2200; | 434 | host->max_id = MAX_TARGETS_2200; |
433 | host->transportt = qla2xxx_transport_vport_template; | 435 | host->transportt = qla2xxx_transport_vport_template; |
434 | 436 | ||
@@ -436,12 +438,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
436 | vha->host_no, vha)); | 438 | vha->host_no, vha)); |
437 | 439 | ||
438 | vha->flags.init_done = 1; | 440 | vha->flags.init_done = 1; |
439 | num_hosts++; | ||
440 | |||
441 | mutex_lock(&ha->vport_lock); | ||
442 | set_bit(vha->vp_idx, ha->vp_idx_map); | ||
443 | ha->cur_vport_count++; | ||
444 | mutex_unlock(&ha->vport_lock); | ||
445 | 441 | ||
446 | return vha; | 442 | return vha; |
447 | 443 | ||
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 48eaa3bb5433..7c8af7ed2a5d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -27,7 +27,6 @@ char qla2x00_version_str[40]; | |||
27 | */ | 27 | */ |
28 | static struct kmem_cache *srb_cachep; | 28 | static struct kmem_cache *srb_cachep; |
29 | 29 | ||
30 | int num_hosts; | ||
31 | int ql2xlogintimeout = 20; | 30 | int ql2xlogintimeout = 20; |
32 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); | 31 | module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR); |
33 | MODULE_PARM_DESC(ql2xlogintimeout, | 32 | MODULE_PARM_DESC(ql2xlogintimeout, |
@@ -87,6 +86,13 @@ MODULE_PARM_DESC(ql2xqfullrampup, | |||
87 | "depth for a device after a queue-full condition has been " | 86 | "depth for a device after a queue-full condition has been " |
88 | "detected. Default is 120 seconds."); | 87 | "detected. Default is 120 seconds."); |
89 | 88 | ||
89 | int ql2xiidmaenable=1; | ||
90 | module_param(ql2xiidmaenable, int, S_IRUGO|S_IRUSR); | ||
91 | MODULE_PARM_DESC(ql2xiidmaenable, | ||
92 | "Enables iIDMA settings " | ||
93 | "Default is 1 - perform iIDMA. 0 - no iIDMA."); | ||
94 | |||
95 | |||
90 | /* | 96 | /* |
91 | * SCSI host template entry points | 97 | * SCSI host template entry points |
92 | */ | 98 | */ |
@@ -388,7 +394,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
388 | } | 394 | } |
389 | 395 | ||
390 | /* Close window on fcport/rport state-transitioning. */ | 396 | /* Close window on fcport/rport state-transitioning. */ |
391 | if (!*(fc_port_t **)rport->dd_data) { | 397 | if (fcport->drport) { |
392 | cmd->result = DID_IMM_RETRY << 16; | 398 | cmd->result = DID_IMM_RETRY << 16; |
393 | goto qc_fail_command; | 399 | goto qc_fail_command; |
394 | } | 400 | } |
@@ -443,7 +449,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
443 | int rval; | 449 | int rval; |
444 | scsi_qla_host_t *pha = to_qla_parent(ha); | 450 | scsi_qla_host_t *pha = to_qla_parent(ha); |
445 | 451 | ||
446 | if (unlikely(pci_channel_offline(ha->pdev))) { | 452 | if (unlikely(pci_channel_offline(pha->pdev))) { |
447 | cmd->result = DID_REQUEUE << 16; | 453 | cmd->result = DID_REQUEUE << 16; |
448 | goto qc24_fail_command; | 454 | goto qc24_fail_command; |
449 | } | 455 | } |
@@ -455,7 +461,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | |||
455 | } | 461 | } |
456 | 462 | ||
457 | /* Close window on fcport/rport state-transitioning. */ | 463 | /* Close window on fcport/rport state-transitioning. */ |
458 | if (!*(fc_port_t **)rport->dd_data) { | 464 | if (fcport->drport) { |
459 | cmd->result = DID_IMM_RETRY << 16; | 465 | cmd->result = DID_IMM_RETRY << 16; |
460 | goto qc24_fail_command; | 466 | goto qc24_fail_command; |
461 | } | 467 | } |
@@ -617,6 +623,40 @@ qla2x00_wait_for_loop_ready(scsi_qla_host_t *ha) | |||
617 | return (return_status); | 623 | return (return_status); |
618 | } | 624 | } |
619 | 625 | ||
626 | void | ||
627 | qla2x00_abort_fcport_cmds(fc_port_t *fcport) | ||
628 | { | ||
629 | int cnt; | ||
630 | unsigned long flags; | ||
631 | srb_t *sp; | ||
632 | scsi_qla_host_t *ha = fcport->ha; | ||
633 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
634 | |||
635 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
636 | for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { | ||
637 | sp = pha->outstanding_cmds[cnt]; | ||
638 | if (!sp) | ||
639 | continue; | ||
640 | if (sp->fcport != fcport) | ||
641 | continue; | ||
642 | |||
643 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
644 | if (ha->isp_ops->abort_command(ha, sp)) { | ||
645 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
646 | "Abort failed -- %lx\n", sp->cmd->serial_number)); | ||
647 | } else { | ||
648 | if (qla2x00_eh_wait_on_command(ha, sp->cmd) != | ||
649 | QLA_SUCCESS) | ||
650 | DEBUG2(qla_printk(KERN_WARNING, ha, | ||
651 | "Abort failed while waiting -- %lx\n", | ||
652 | sp->cmd->serial_number)); | ||
653 | |||
654 | } | ||
655 | spin_lock_irqsave(&pha->hardware_lock, flags); | ||
656 | } | ||
657 | spin_unlock_irqrestore(&pha->hardware_lock, flags); | ||
658 | } | ||
659 | |||
620 | static void | 660 | static void |
621 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | 661 | qla2x00_block_error_handler(struct scsi_cmnd *cmnd) |
622 | { | 662 | { |
@@ -1073,7 +1113,7 @@ qla2xxx_slave_configure(struct scsi_device *sdev) | |||
1073 | else | 1113 | else |
1074 | scsi_deactivate_tcq(sdev, ha->max_q_depth); | 1114 | scsi_deactivate_tcq(sdev, ha->max_q_depth); |
1075 | 1115 | ||
1076 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 1116 | rport->dev_loss_tmo = ha->port_down_retry_count; |
1077 | 1117 | ||
1078 | return 0; | 1118 | return 0; |
1079 | } | 1119 | } |
@@ -1629,9 +1669,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1629 | } | 1669 | } |
1630 | host->can_queue = ha->request_q_length + 128; | 1670 | host->can_queue = ha->request_q_length + 128; |
1631 | 1671 | ||
1632 | /* load the F/W, read paramaters, and init the H/W */ | ||
1633 | ha->instance = num_hosts; | ||
1634 | |||
1635 | mutex_init(&ha->vport_lock); | 1672 | mutex_init(&ha->vport_lock); |
1636 | init_completion(&ha->mbx_cmd_comp); | 1673 | init_completion(&ha->mbx_cmd_comp); |
1637 | complete(&ha->mbx_cmd_comp); | 1674 | complete(&ha->mbx_cmd_comp); |
@@ -1679,7 +1716,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1679 | 1716 | ||
1680 | host->this_id = 255; | 1717 | host->this_id = 255; |
1681 | host->cmd_per_lun = 3; | 1718 | host->cmd_per_lun = 3; |
1682 | host->unique_id = ha->instance; | 1719 | host->unique_id = host->host_no; |
1683 | host->max_cmd_len = MAX_CMDSZ; | 1720 | host->max_cmd_len = MAX_CMDSZ; |
1684 | host->max_channel = MAX_BUSES - 1; | 1721 | host->max_channel = MAX_BUSES - 1; |
1685 | host->max_lun = MAX_LUNS; | 1722 | host->max_lun = MAX_LUNS; |
@@ -1700,8 +1737,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1700 | ha->flags.init_done = 1; | 1737 | ha->flags.init_done = 1; |
1701 | ha->flags.online = 1; | 1738 | ha->flags.online = 1; |
1702 | 1739 | ||
1703 | num_hosts++; | ||
1704 | |||
1705 | ret = scsi_add_host(host, &pdev->dev); | 1740 | ret = scsi_add_host(host, &pdev->dev); |
1706 | if (ret) | 1741 | if (ret) |
1707 | goto probe_failed; | 1742 | goto probe_failed; |
@@ -1813,27 +1848,21 @@ static inline void | |||
1813 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, | 1848 | qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport, |
1814 | int defer) | 1849 | int defer) |
1815 | { | 1850 | { |
1816 | unsigned long flags; | ||
1817 | struct fc_rport *rport; | 1851 | struct fc_rport *rport; |
1852 | scsi_qla_host_t *pha = to_qla_parent(ha); | ||
1818 | 1853 | ||
1819 | if (!fcport->rport) | 1854 | if (!fcport->rport) |
1820 | return; | 1855 | return; |
1821 | 1856 | ||
1822 | rport = fcport->rport; | 1857 | rport = fcport->rport; |
1823 | if (defer) { | 1858 | if (defer) { |
1824 | spin_lock_irqsave(&fcport->rport_lock, flags); | 1859 | spin_lock_irq(ha->host->host_lock); |
1825 | fcport->drport = rport; | 1860 | fcport->drport = rport; |
1826 | fcport->rport = NULL; | 1861 | spin_unlock_irq(ha->host->host_lock); |
1827 | *(fc_port_t **)rport->dd_data = NULL; | 1862 | set_bit(FCPORT_UPDATE_NEEDED, &pha->dpc_flags); |
1828 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | 1863 | qla2xxx_wake_dpc(pha); |
1829 | set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | 1864 | } else |
1830 | } else { | ||
1831 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
1832 | fcport->rport = NULL; | ||
1833 | *(fc_port_t **)rport->dd_data = NULL; | ||
1834 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1835 | fc_remote_port_delete(rport); | 1865 | fc_remote_port_delete(rport); |
1836 | } | ||
1837 | } | 1866 | } |
1838 | 1867 | ||
1839 | /* | 1868 | /* |
@@ -1903,7 +1932,7 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | |||
1903 | scsi_qla_host_t *pha = to_qla_parent(ha); | 1932 | scsi_qla_host_t *pha = to_qla_parent(ha); |
1904 | 1933 | ||
1905 | list_for_each_entry(fcport, &pha->fcports, list) { | 1934 | list_for_each_entry(fcport, &pha->fcports, list) { |
1906 | if (ha->vp_idx != 0 && ha->vp_idx != fcport->vp_idx) | 1935 | if (ha->vp_idx != fcport->vp_idx) |
1907 | continue; | 1936 | continue; |
1908 | /* | 1937 | /* |
1909 | * No point in marking the device as lost, if the device is | 1938 | * No point in marking the device as lost, if the device is |
@@ -1911,17 +1940,10 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer) | |||
1911 | */ | 1940 | */ |
1912 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) | 1941 | if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) |
1913 | continue; | 1942 | continue; |
1914 | if (atomic_read(&fcport->state) == FCS_ONLINE) { | 1943 | if (atomic_read(&fcport->state) == FCS_ONLINE) |
1915 | if (defer) | 1944 | qla2x00_schedule_rport_del(ha, fcport, defer); |
1916 | qla2x00_schedule_rport_del(ha, fcport, defer); | ||
1917 | else if (ha->vp_idx == fcport->vp_idx) | ||
1918 | qla2x00_schedule_rport_del(ha, fcport, defer); | ||
1919 | } | ||
1920 | atomic_set(&fcport->state, FCS_DEVICE_LOST); | 1945 | atomic_set(&fcport->state, FCS_DEVICE_LOST); |
1921 | } | 1946 | } |
1922 | |||
1923 | if (defer) | ||
1924 | qla2xxx_wake_dpc(ha); | ||
1925 | } | 1947 | } |
1926 | 1948 | ||
1927 | /* | 1949 | /* |
@@ -2156,7 +2178,7 @@ qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type, | |||
2156 | static int | 2178 | static int |
2157 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) | 2179 | qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) |
2158 | { | 2180 | { |
2159 | unsigned long flags; | 2181 | unsigned long uninitialized_var(flags); |
2160 | scsi_qla_host_t *pha = to_qla_parent(ha); | 2182 | scsi_qla_host_t *pha = to_qla_parent(ha); |
2161 | 2183 | ||
2162 | if (!locked) | 2184 | if (!locked) |
@@ -2313,8 +2335,10 @@ qla2x00_do_dpc(void *data) | |||
2313 | ha->host_no)); | 2335 | ha->host_no)); |
2314 | } | 2336 | } |
2315 | 2337 | ||
2316 | if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) | 2338 | if (test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags)) { |
2317 | qla2x00_update_fcports(ha); | 2339 | qla2x00_update_fcports(ha); |
2340 | clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags); | ||
2341 | } | ||
2318 | 2342 | ||
2319 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && | 2343 | if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) && |
2320 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { | 2344 | (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) { |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 1728ab3ccb20..1bca74474935 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -869,11 +869,9 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
869 | uint32_t i; | 869 | uint32_t i; |
870 | uint32_t *dwptr; | 870 | uint32_t *dwptr; |
871 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 871 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
872 | unsigned long flags; | ||
873 | 872 | ||
874 | ret = QLA_SUCCESS; | 873 | ret = QLA_SUCCESS; |
875 | 874 | ||
876 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
877 | /* Enable flash write. */ | 875 | /* Enable flash write. */ |
878 | WRT_REG_DWORD(®->ctrl_status, | 876 | WRT_REG_DWORD(®->ctrl_status, |
879 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); | 877 | RD_REG_DWORD(®->ctrl_status) | CSRX_FLASH_ENABLE); |
@@ -907,7 +905,6 @@ qla24xx_write_nvram_data(scsi_qla_host_t *ha, uint8_t *buf, uint32_t naddr, | |||
907 | WRT_REG_DWORD(®->ctrl_status, | 905 | WRT_REG_DWORD(®->ctrl_status, |
908 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 906 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
909 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 907 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
910 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
911 | 908 | ||
912 | return ret; | 909 | return ret; |
913 | } | 910 | } |
@@ -2306,6 +2303,51 @@ qla24xx_get_flash_version(scsi_qla_host_t *ha, void *mbuf) | |||
2306 | } | 2303 | } |
2307 | 2304 | ||
2308 | static int | 2305 | static int |
2306 | qla2xxx_is_vpd_valid(uint8_t *pos, uint8_t *end) | ||
2307 | { | ||
2308 | if (pos >= end || *pos != 0x82) | ||
2309 | return 0; | ||
2310 | |||
2311 | pos += 3 + pos[1]; | ||
2312 | if (pos >= end || *pos != 0x90) | ||
2313 | return 0; | ||
2314 | |||
2315 | pos += 3 + pos[1]; | ||
2316 | if (pos >= end || *pos != 0x78) | ||
2317 | return 0; | ||
2318 | |||
2319 | return 1; | ||
2320 | } | ||
2321 | |||
2322 | int | ||
2323 | qla2xxx_get_vpd_field(scsi_qla_host_t *ha, char *key, char *str, size_t size) | ||
2324 | { | ||
2325 | uint8_t *pos = ha->vpd; | ||
2326 | uint8_t *end = pos + ha->vpd_size; | ||
2327 | int len = 0; | ||
2328 | |||
2329 | if (!IS_FWI2_CAPABLE(ha) || !qla2xxx_is_vpd_valid(pos, end)) | ||
2330 | return 0; | ||
2331 | |||
2332 | while (pos < end && *pos != 0x78) { | ||
2333 | len = (*pos == 0x82) ? pos[1] : pos[2]; | ||
2334 | |||
2335 | if (!strncmp(pos, key, strlen(key))) | ||
2336 | break; | ||
2337 | |||
2338 | if (*pos != 0x90 && *pos != 0x91) | ||
2339 | pos += len; | ||
2340 | |||
2341 | pos += 3; | ||
2342 | } | ||
2343 | |||
2344 | if (pos < end - len && *pos != 0x78) | ||
2345 | return snprintf(str, size, "%.*s", len, pos + 3); | ||
2346 | |||
2347 | return 0; | ||
2348 | } | ||
2349 | |||
2350 | static int | ||
2309 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) | 2351 | qla2xxx_hw_event_store(scsi_qla_host_t *ha, uint32_t *fdata) |
2310 | { | 2352 | { |
2311 | uint32_t d[2], faddr; | 2353 | uint32_t d[2], faddr; |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index d058c8862b35..676c390db354 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.01-k4" | 10 | #define QLA2XXX_VERSION "8.02.01-k6" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |