diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 6 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 83 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 55 |
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); | |||
47 | extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); | 47 | extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t); |
48 | 48 | ||
49 | extern void qla2x00_rescan_fcports(scsi_qla_host_t *); | 49 | extern void qla2x00_rescan_fcports(scsi_qla_host_t *); |
50 | extern void qla2x00_update_fcports(scsi_qla_host_t *); | ||
50 | 51 | ||
51 | extern int qla2x00_abort_isp(scsi_qla_host_t *); | 52 | extern int qla2x00_abort_isp(scsi_qla_host_t *); |
52 | 53 | ||
54 | extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | ||
53 | extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *); | 55 | extern 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 | ||
71 | extern void qla2x00_cmd_timeout(srb_t *); | 73 | extern void qla2x00_cmd_timeout(srb_t *); |
72 | 74 | ||
73 | extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); | 75 | extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); |
74 | extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); | 76 | extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); |
75 | 77 | ||
76 | extern void qla2x00_blink_led(scsi_qla_host_t *); | 78 | extern 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 *); | |||
32 | static int qla2x00_configure_hba(scsi_qla_host_t *); | 32 | static int qla2x00_configure_hba(scsi_qla_host_t *); |
33 | static int qla2x00_configure_loop(scsi_qla_host_t *); | 33 | static int qla2x00_configure_loop(scsi_qla_host_t *); |
34 | static int qla2x00_configure_local_loop(scsi_qla_host_t *); | 34 | static int qla2x00_configure_local_loop(scsi_qla_host_t *); |
35 | static void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *); | ||
36 | static int qla2x00_configure_fabric(scsi_qla_host_t *); | 35 | static int qla2x00_configure_fabric(scsi_qla_host_t *); |
37 | static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); | 36 | static int qla2x00_find_all_fabric_devs(scsi_qla_host_t *, struct list_head *); |
38 | static int qla2x00_device_resync(scsi_qla_host_t *); | 37 | static int qla2x00_device_resync(scsi_qla_host_t *); |
@@ -1688,10 +1687,16 @@ static void | |||
1688 | qla2x00_rport_del(void *data) | 1687 | qla2x00_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 | */ |
2035 | static void | 2041 | void |
2036 | qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | 2042 | qla2x00_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 | ||
2977 | void | ||
2978 | qla2x00_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 | ||
1645 | static inline void | ||
1646 | qla2x00_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 | */ |
1654 | void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport, | 1679 | void 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 | */ |
1704 | void | 1729 | void |
1705 | qla2x00_mark_all_devices_lost(scsi_qla_host_t *ha) | 1730 | qla2x00_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) || |