aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h4
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c83
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c16
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c55
5 files changed, 95 insertions, 69 deletions
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 79d8a914f9d0..bad066e5772a 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -1680,7 +1680,8 @@ typedef struct fc_port {
1680 uint8_t mp_byte; /* multi-path byte (not used) */ 1680 uint8_t mp_byte; /* multi-path byte (not used) */
1681 uint8_t cur_path; /* current path id */ 1681 uint8_t cur_path; /* current path id */
1682 1682
1683 struct fc_rport *rport; 1683 spinlock_t rport_lock;
1684 struct fc_rport *rport, *drport;
1684 u32 supported_classes; 1685 u32 supported_classes;
1685 struct work_struct rport_add_work; 1686 struct work_struct rport_add_work;
1686 struct work_struct rport_del_work; 1687 struct work_struct rport_del_work;
@@ -2270,6 +2271,7 @@ typedef struct scsi_qla_host {
2270#define LOOP_RESET_NEEDED 24 2271#define LOOP_RESET_NEEDED 24
2271#define BEACON_BLINK_NEEDED 25 2272#define BEACON_BLINK_NEEDED 25
2272#define REGISTER_FDMI_NEEDED 26 2273#define REGISTER_FDMI_NEEDED 26
2274#define FCPORT_UPDATE_NEEDED 27
2273 2275
2274 uint32_t device_flags; 2276 uint32_t device_flags;
2275#define DFLG_LOCAL_DEVICES BIT_0 2277#define DFLG_LOCAL_DEVICES BIT_0
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 32be4c14cccb..35266bd5d538 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -47,9 +47,11 @@ extern int qla2x00_local_device_login(scsi_qla_host_t *, uint16_t);
47extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); 47extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
48 48
49extern void qla2x00_rescan_fcports(scsi_qla_host_t *); 49extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
50extern void qla2x00_update_fcports(scsi_qla_host_t *);
50 51
51extern int qla2x00_abort_isp(scsi_qla_host_t *); 52extern int qla2x00_abort_isp(scsi_qla_host_t *);
52 53
54extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
53extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); 55extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);
54 56
55/* 57/*
@@ -70,8 +72,8 @@ extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
70 72
71extern void qla2x00_cmd_timeout(srb_t *); 73extern void qla2x00_cmd_timeout(srb_t *);
72 74
73extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); 75extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
74extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); 76extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
75 77
76extern void qla2x00_blink_led(scsi_qla_host_t *); 78extern void qla2x00_blink_led(scsi_qla_host_t *);
77 79
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index a91fea69ad63..e67bb0997818 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -32,7 +32,6 @@ static int qla2x00_fw_ready(scsi_qla_host_t *);
32static int qla2x00_configure_hba(scsi_qla_host_t *); 32static int qla2x00_configure_hba(scsi_qla_host_t *);
33static int qla2x00_configure_loop(scsi_qla_host_t *); 33static int qla2x00_configure_loop(scsi_qla_host_t *);
34static int qla2x00_configure_local_loop(scsi_qla_host_t *); 34static int qla2x00_configure_local_loop(scsi_qla_host_t *);
35static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
36static int qla2x00_configure_fabric(scsi_qla_host_t *); 35static int qla2x00_configure_fabric(scsi_qla_host_t *);
37static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); 36static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *);
38static int qla2x00_device_resync(scsi_qla_host_t *); 37static int qla2x00_device_resync(scsi_qla_host_t *);
@@ -1688,10 +1687,16 @@ static void
1688qla2x00_rport_del(void *data) 1687qla2x00_rport_del(void *data)
1689{ 1688{
1690 fc_port_t *fcport = data; 1689 fc_port_t *fcport = data;
1690 struct fc_rport *rport;
1691 unsigned long flags;
1692
1693 spin_lock_irqsave(&fcport->rport_lock, flags);
1694 rport = fcport->drport;
1695 fcport->drport = NULL;
1696 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1697 if (rport)
1698 fc_remote_port_delete(rport);
1691 1699
1692 if (fcport->rport)
1693 fc_remote_port_delete(fcport->rport);
1694 fcport->rport = NULL;
1695} 1700}
1696 1701
1697/** 1702/**
@@ -1719,6 +1724,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags)
1719 atomic_set(&fcport->state, FCS_UNCONFIGURED); 1724 atomic_set(&fcport->state, FCS_UNCONFIGURED);
1720 fcport->flags = FCF_RLC_SUPPORT; 1725 fcport->flags = FCF_RLC_SUPPORT;
1721 fcport->supported_classes = FC_COS_UNSPECIFIED; 1726 fcport->supported_classes = FC_COS_UNSPECIFIED;
1727 spin_lock_init(&fcport->rport_lock);
1722 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); 1728 INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport);
1723 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); 1729 INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport);
1724 1730
@@ -2008,7 +2014,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
2008{ 2014{
2009 fc_port_t *fcport; 2015 fc_port_t *fcport;
2010 2016
2011 qla2x00_mark_all_devices_lost(ha); 2017 qla2x00_mark_all_devices_lost(ha, 0);
2012 list_for_each_entry(fcport, &ha->fcports, list) { 2018 list_for_each_entry(fcport, &ha->fcports, list) {
2013 if (fcport->port_type != FCT_TARGET) 2019 if (fcport->port_type != FCT_TARGET)
2014 continue; 2020 continue;
@@ -2032,13 +2038,9 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
2032 * Context: 2038 * Context:
2033 * Kernel context. 2039 * Kernel context.
2034 */ 2040 */
2035static void 2041void
2036qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) 2042qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
2037{ 2043{
2038 uint16_t index;
2039 unsigned long flags;
2040 srb_t *sp;
2041
2042 fcport->ha = ha; 2044 fcport->ha = ha;
2043 fcport->login_retry = 0; 2045 fcport->login_retry = 0;
2044 fcport->port_login_retry_count = ha->port_down_retry_count * 2046 fcport->port_login_retry_count = ha->port_down_retry_count *
@@ -2047,28 +2049,6 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
2047 PORT_RETRY_TIME); 2049 PORT_RETRY_TIME);
2048 fcport->flags &= ~FCF_LOGIN_NEEDED; 2050 fcport->flags &= ~FCF_LOGIN_NEEDED;
2049 2051
2050 /*
2051 * Check for outstanding cmd on tape Bypass LUN discovery if active
2052 * command on tape.
2053 */
2054 if (fcport->flags & FCF_TAPE_PRESENT) {
2055 spin_lock_irqsave(&ha->hardware_lock, flags);
2056 for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
2057 fc_port_t *sfcp;
2058
2059 if ((sp = ha->outstanding_cmds[index]) != 0) {
2060 sfcp = sp->fcport;
2061 if (sfcp == fcport) {
2062 atomic_set(&fcport->state, FCS_ONLINE);
2063 spin_unlock_irqrestore(
2064 &ha->hardware_lock, flags);
2065 return;
2066 }
2067 }
2068 }
2069 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2070 }
2071
2072 if (fcport->port_type == FCT_INITIATOR || 2052 if (fcport->port_type == FCT_INITIATOR ||
2073 fcport->port_type == FCT_BROADCAST) 2053 fcport->port_type == FCT_BROADCAST)
2074 fcport->device_type = TYPE_PROCESSOR; 2054 fcport->device_type = TYPE_PROCESSOR;
@@ -2084,24 +2064,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
2084{ 2064{
2085 struct fc_rport_identifiers rport_ids; 2065 struct fc_rport_identifiers rport_ids;
2086 struct fc_rport *rport; 2066 struct fc_rport *rport;
2067 unsigned long flags;
2087 2068
2088 if (fcport->rport) { 2069 if (fcport->drport)
2089 fc_remote_port_delete(fcport->rport); 2070 qla2x00_rport_del(fcport);
2090 fcport->rport = NULL; 2071 if (fcport->rport)
2091 } 2072 return;
2092 2073
2093 rport_ids.node_name = wwn_to_u64(fcport->node_name); 2074 rport_ids.node_name = wwn_to_u64(fcport->node_name);
2094 rport_ids.port_name = wwn_to_u64(fcport->port_name); 2075 rport_ids.port_name = wwn_to_u64(fcport->port_name);
2095 rport_ids.port_id = fcport->d_id.b.domain << 16 | 2076 rport_ids.port_id = fcport->d_id.b.domain << 16 |
2096 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; 2077 fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
2097 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2078 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
2098 fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); 2079 rport = fc_remote_port_add(ha->host, 0, &rport_ids);
2099 if (!rport) { 2080 if (!rport) {
2100 qla_printk(KERN_WARNING, ha, 2081 qla_printk(KERN_WARNING, ha,
2101 "Unable to allocate fc remote port!\n"); 2082 "Unable to allocate fc remote port!\n");
2102 return; 2083 return;
2103 } 2084 }
2085 spin_lock_irqsave(&fcport->rport_lock, flags);
2086 fcport->rport = rport;
2104 *((fc_port_t **)rport->dd_data) = fcport; 2087 *((fc_port_t **)rport->dd_data) = fcport;
2088 spin_unlock_irqrestore(&fcport->rport_lock, flags);
2089
2105 rport->supported_classes = fcport->supported_classes; 2090 rport->supported_classes = fcport->supported_classes;
2106 2091
2107 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; 2092 rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
@@ -2217,12 +2202,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
2217 2202
2218 if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { 2203 if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) {
2219 qla2x00_mark_device_lost(ha, fcport, 2204 qla2x00_mark_device_lost(ha, fcport,
2220 ql2xplogiabsentdevice); 2205 ql2xplogiabsentdevice, 0);
2221 if (fcport->loop_id != FC_NO_LOOP_ID && 2206 if (fcport->loop_id != FC_NO_LOOP_ID &&
2222 (fcport->flags & FCF_TAPE_PRESENT) == 0 && 2207 (fcport->flags & FCF_TAPE_PRESENT) == 0 &&
2223 fcport->port_type != FCT_INITIATOR && 2208 fcport->port_type != FCT_INITIATOR &&
2224 fcport->port_type != FCT_BROADCAST) { 2209 fcport->port_type != FCT_BROADCAST) {
2225
2226 ha->isp_ops.fabric_logout(ha, 2210 ha->isp_ops.fabric_logout(ha,
2227 fcport->loop_id, 2211 fcport->loop_id,
2228 fcport->d_id.b.domain, 2212 fcport->d_id.b.domain,
@@ -2694,7 +2678,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha)
2694 if (atomic_read(&fcport->state) == FCS_ONLINE) { 2678 if (atomic_read(&fcport->state) == FCS_ONLINE) {
2695 if (format != 3 || 2679 if (format != 3 ||
2696 fcport->port_type != FCT_INITIATOR) { 2680 fcport->port_type != FCT_INITIATOR) {
2697 qla2x00_mark_device_lost(ha, fcport, 0); 2681 qla2x00_mark_device_lost(ha, fcport,
2682 0, 0);
2698 } 2683 }
2699 } 2684 }
2700 fcport->flags &= ~FCF_FARP_DONE; 2685 fcport->flags &= ~FCF_FARP_DONE;
@@ -2741,8 +2726,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport,
2741 ha->isp_ops.fabric_logout(ha, fcport->loop_id, 2726 ha->isp_ops.fabric_logout(ha, fcport->loop_id,
2742 fcport->d_id.b.domain, fcport->d_id.b.area, 2727 fcport->d_id.b.domain, fcport->d_id.b.area,
2743 fcport->d_id.b.al_pa); 2728 fcport->d_id.b.al_pa);
2744 qla2x00_mark_device_lost(ha, fcport, 1); 2729 qla2x00_mark_device_lost(ha, fcport, 1, 0);
2745
2746 } else { 2730 } else {
2747 qla2x00_update_fcport(ha, fcport); 2731 qla2x00_update_fcport(ha, fcport);
2748 } 2732 }
@@ -2855,7 +2839,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport,
2855 ha->isp_ops.fabric_logout(ha, fcport->loop_id, 2839 ha->isp_ops.fabric_logout(ha, fcport->loop_id,
2856 fcport->d_id.b.domain, fcport->d_id.b.area, 2840 fcport->d_id.b.domain, fcport->d_id.b.area,
2857 fcport->d_id.b.al_pa); 2841 fcport->d_id.b.al_pa);
2858 qla2x00_mark_device_lost(ha, fcport, 1); 2842 qla2x00_mark_device_lost(ha, fcport, 1, 0);
2859 2843
2860 rval = 1; 2844 rval = 1;
2861 break; 2845 break;
@@ -2990,6 +2974,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha)
2990 qla2x00_probe_for_all_luns(ha); 2974 qla2x00_probe_for_all_luns(ha);
2991} 2975}
2992 2976
2977void
2978qla2x00_update_fcports(scsi_qla_host_t *ha)
2979{
2980 fc_port_t *fcport;
2981
2982 /* Go with deferred removal of rport references. */
2983 list_for_each_entry(fcport, &ha->fcports, list)
2984 if (fcport->drport)
2985 qla2x00_rport_del(fcport);
2986}
2987
2993/* 2988/*
2994* qla2x00_abort_isp 2989* qla2x00_abort_isp
2995* Resets ISP and aborts all outstanding commands. 2990* Resets ISP and aborts all outstanding commands.
@@ -3019,7 +3014,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha)
3019 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); 3014 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
3020 if (atomic_read(&ha->loop_state) != LOOP_DOWN) { 3015 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
3021 atomic_set(&ha->loop_state, LOOP_DOWN); 3016 atomic_set(&ha->loop_state, LOOP_DOWN);
3022 qla2x00_mark_all_devices_lost(ha); 3017 qla2x00_mark_all_devices_lost(ha, 0);
3023 } else { 3018 } else {
3024 if (!atomic_read(&ha->loop_down_timer)) 3019 if (!atomic_read(&ha->loop_down_timer))
3025 atomic_set(&ha->loop_down_timer, 3020 atomic_set(&ha->loop_down_timer,
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f63af081d4ff..71a46fcee8cc 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -389,7 +389,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
389 if (atomic_read(&ha->loop_state) != LOOP_DOWN) { 389 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
390 atomic_set(&ha->loop_state, LOOP_DOWN); 390 atomic_set(&ha->loop_state, LOOP_DOWN);
391 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); 391 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
392 qla2x00_mark_all_devices_lost(ha); 392 qla2x00_mark_all_devices_lost(ha, 1);
393 } 393 }
394 394
395 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); 395 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
@@ -432,7 +432,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
432 atomic_set(&ha->loop_state, LOOP_DOWN); 432 atomic_set(&ha->loop_state, LOOP_DOWN);
433 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); 433 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
434 ha->device_flags |= DFLG_NO_CABLE; 434 ha->device_flags |= DFLG_NO_CABLE;
435 qla2x00_mark_all_devices_lost(ha); 435 qla2x00_mark_all_devices_lost(ha, 1);
436 } 436 }
437 437
438 ha->flags.management_server_logged_in = 0; 438 ha->flags.management_server_logged_in = 0;
@@ -453,7 +453,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
453 if (atomic_read(&ha->loop_state) != LOOP_DOWN) { 453 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
454 atomic_set(&ha->loop_state, LOOP_DOWN); 454 atomic_set(&ha->loop_state, LOOP_DOWN);
455 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); 455 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
456 qla2x00_mark_all_devices_lost(ha); 456 qla2x00_mark_all_devices_lost(ha, 1);
457 } 457 }
458 458
459 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); 459 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
@@ -482,7 +482,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
482 if (!atomic_read(&ha->loop_down_timer)) 482 if (!atomic_read(&ha->loop_down_timer))
483 atomic_set(&ha->loop_down_timer, 483 atomic_set(&ha->loop_down_timer,
484 LOOP_DOWN_TIME); 484 LOOP_DOWN_TIME);
485 qla2x00_mark_all_devices_lost(ha); 485 qla2x00_mark_all_devices_lost(ha, 1);
486 } 486 }
487 487
488 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) { 488 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
@@ -506,7 +506,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
506 if (!atomic_read(&ha->loop_down_timer)) 506 if (!atomic_read(&ha->loop_down_timer))
507 atomic_set(&ha->loop_down_timer, 507 atomic_set(&ha->loop_down_timer,
508 LOOP_DOWN_TIME); 508 LOOP_DOWN_TIME);
509 qla2x00_mark_all_devices_lost(ha); 509 qla2x00_mark_all_devices_lost(ha, 1);
510 } 510 }
511 511
512 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); 512 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
@@ -580,7 +580,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
580 */ 580 */
581 atomic_set(&ha->loop_state, LOOP_UP); 581 atomic_set(&ha->loop_state, LOOP_UP);
582 582
583 qla2x00_mark_all_devices_lost(ha); 583 qla2x00_mark_all_devices_lost(ha, 1);
584 584
585 ha->flags.rscn_queue_overflow = 1; 585 ha->flags.rscn_queue_overflow = 1;
586 586
@@ -1091,7 +1091,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
1091 1091
1092 cp->result = DID_BUS_BUSY << 16; 1092 cp->result = DID_BUS_BUSY << 16;
1093 if (atomic_read(&fcport->state) == FCS_ONLINE) { 1093 if (atomic_read(&fcport->state) == FCS_ONLINE) {
1094 qla2x00_mark_device_lost(ha, fcport, 1); 1094 qla2x00_mark_device_lost(ha, fcport, 1, 1);
1095 } 1095 }
1096 break; 1096 break;
1097 1097
@@ -1135,7 +1135,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
1135 1135
1136 /* Check to see if logout occurred. */ 1136 /* Check to see if logout occurred. */
1137 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT)) 1137 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
1138 qla2x00_mark_device_lost(ha, fcport, 1); 1138 qla2x00_mark_device_lost(ha, fcport, 1, 1);
1139 break; 1139 break;
1140 1140
1141 case CS_QUEUE_FULL: 1141 case CS_QUEUE_FULL:
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4916847d84ec..5866a7c706a8 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -756,7 +756,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
756 if (ret == SUCCESS) { 756 if (ret == SUCCESS) {
757 if (fcport->flags & FC_FABRIC_DEVICE) { 757 if (fcport->flags & FC_FABRIC_DEVICE) {
758 ha->isp_ops.fabric_logout(ha, fcport->loop_id); 758 ha->isp_ops.fabric_logout(ha, fcport->loop_id);
759 qla2x00_mark_device_lost(ha, fcport); 759 qla2x00_mark_device_lost(ha, fcport, 0, 0);
760 } 760 }
761 } 761 }
762#endif 762#endif
@@ -1642,6 +1642,31 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1642 pci_disable_device(ha->pdev); 1642 pci_disable_device(ha->pdev);
1643} 1643}
1644 1644
1645static inline void
1646qla2x00_schedule_rport_del(struct scsi_qla_host *ha, fc_port_t *fcport,
1647 int defer)
1648{
1649 unsigned long flags;
1650 struct fc_rport *rport;
1651
1652 if (!fcport->rport)
1653 return;
1654
1655 rport = fcport->rport;
1656 if (defer) {
1657 spin_lock_irqsave(&fcport->rport_lock, flags);
1658 fcport->drport = rport;
1659 fcport->rport = NULL;
1660 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1661 set_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags);
1662 } else {
1663 spin_lock_irqsave(&fcport->rport_lock, flags);
1664 fcport->rport = NULL;
1665 spin_unlock_irqrestore(&fcport->rport_lock, flags);
1666 fc_remote_port_delete(rport);
1667 }
1668}
1669
1645/* 1670/*
1646 * qla2x00_mark_device_lost Updates fcport state when device goes offline. 1671 * qla2x00_mark_device_lost Updates fcport state when device goes offline.
1647 * 1672 *
@@ -1652,10 +1677,10 @@ qla2x00_free_device(scsi_qla_host_t *ha)
1652 * Context: 1677 * Context:
1653 */ 1678 */
1654void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, 1679void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1655 int do_login) 1680 int do_login, int defer)
1656{ 1681{
1657 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1682 if (atomic_read(&fcport->state) == FCS_ONLINE)
1658 schedule_work(&fcport->rport_del_work); 1683 qla2x00_schedule_rport_del(ha, fcport, defer);
1659 1684
1660 /* 1685 /*
1661 * We may need to retry the login, so don't change the state of the 1686 * We may need to retry the login, so don't change the state of the
@@ -1702,7 +1727,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,
1702 * Context: 1727 * Context:
1703 */ 1728 */
1704void 1729void
1705qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) 1730qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha, int defer)
1706{ 1731{
1707 fc_port_t *fcport; 1732 fc_port_t *fcport;
1708 1733
@@ -1716,10 +1741,13 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha)
1716 */ 1741 */
1717 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) 1742 if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
1718 continue; 1743 continue;
1719 if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport) 1744 if (atomic_read(&fcport->state) == FCS_ONLINE)
1720 schedule_work(&fcport->rport_del_work); 1745 qla2x00_schedule_rport_del(ha, fcport, defer);
1721 atomic_set(&fcport->state, FCS_DEVICE_LOST); 1746 atomic_set(&fcport->state, FCS_DEVICE_LOST);
1722 } 1747 }
1748
1749 if (defer && ha->dpc_wait && !ha->dpc_active)
1750 up(ha->dpc_wait);
1723} 1751}
1724 1752
1725/* 1753/*
@@ -2161,6 +2189,9 @@ qla2x00_do_dpc(void *data)
2161 ha->host_no)); 2189 ha->host_no));
2162 } 2190 }
2163 2191
2192 if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
2193 qla2x00_update_fcports(ha);
2194
2164 if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) { 2195 if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
2165 DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n", 2196 DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
2166 ha->host_no)); 2197 ha->host_no));
@@ -2219,13 +2250,8 @@ qla2x00_do_dpc(void *data)
2219 DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n", 2250 DEBUG(printk("scsi(%ld): port login OK: logged in ID 0x%x\n",
2220 ha->host_no, fcport->loop_id)); 2251 ha->host_no, fcport->loop_id));
2221 2252
2222 fcport->port_login_retry_count = 2253 qla2x00_update_fcport(ha,
2223 ha->port_down_retry_count * PORT_RETRY_TIME; 2254 fcport);
2224 atomic_set(&fcport->state, FCS_ONLINE);
2225 atomic_set(&fcport->port_down_timer,
2226 ha->port_down_retry_count * PORT_RETRY_TIME);
2227
2228 fcport->login_retry = 0;
2229 } else if (status == 1) { 2255 } else if (status == 1) {
2230 set_bit(RELOGIN_NEEDED, &ha->dpc_flags); 2256 set_bit(RELOGIN_NEEDED, &ha->dpc_flags);
2231 /* retry the login again */ 2257 /* retry the login again */
@@ -2469,6 +2495,7 @@ qla2x00_timer(scsi_qla_host_t *ha)
2469 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || 2495 if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
2470 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || 2496 test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
2471 test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || 2497 test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
2498 test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
2472 start_dpc || 2499 start_dpc ||
2473 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || 2500 test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
2474 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || 2501 test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||