diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_gbl.h | 5 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 54 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 16 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_os.c | 46 |
5 files changed, 91 insertions, 34 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..0c1ec14f3072 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -47,6 +47,7 @@ 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 | ||
@@ -70,8 +71,8 @@ extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); | |||
70 | 71 | ||
71 | extern void qla2x00_cmd_timeout(srb_t *); | 72 | extern void qla2x00_cmd_timeout(srb_t *); |
72 | 73 | ||
73 | extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); | 74 | 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 *); | 75 | extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); |
75 | 76 | ||
76 | extern void qla2x00_blink_led(scsi_qla_host_t *); | 77 | extern void qla2x00_blink_led(scsi_qla_host_t *); |
77 | 78 | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index a91fea69ad63..4c7caece4ca7 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1688,10 +1688,16 @@ static void | |||
1688 | qla2x00_rport_del(void *data) | 1688 | qla2x00_rport_del(void *data) |
1689 | { | 1689 | { |
1690 | fc_port_t *fcport = data; | 1690 | fc_port_t *fcport = data; |
1691 | struct fc_rport *rport; | ||
1692 | unsigned long flags; | ||
1693 | |||
1694 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
1695 | rport = fcport->drport; | ||
1696 | fcport->drport = NULL; | ||
1697 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
1698 | if (rport) | ||
1699 | fc_remote_port_delete(rport); | ||
1691 | 1700 | ||
1692 | if (fcport->rport) | ||
1693 | fc_remote_port_delete(fcport->rport); | ||
1694 | fcport->rport = NULL; | ||
1695 | } | 1701 | } |
1696 | 1702 | ||
1697 | /** | 1703 | /** |
@@ -1719,6 +1725,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1719 | atomic_set(&fcport->state, FCS_UNCONFIGURED); | 1725 | atomic_set(&fcport->state, FCS_UNCONFIGURED); |
1720 | fcport->flags = FCF_RLC_SUPPORT; | 1726 | fcport->flags = FCF_RLC_SUPPORT; |
1721 | fcport->supported_classes = FC_COS_UNSPECIFIED; | 1727 | fcport->supported_classes = FC_COS_UNSPECIFIED; |
1728 | spin_lock_init(&fcport->rport_lock); | ||
1722 | INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); | 1729 | INIT_WORK(&fcport->rport_add_work, qla2x00_rport_add, fcport); |
1723 | INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); | 1730 | INIT_WORK(&fcport->rport_del_work, qla2x00_rport_del, fcport); |
1724 | 1731 | ||
@@ -2008,7 +2015,7 @@ qla2x00_probe_for_all_luns(scsi_qla_host_t *ha) | |||
2008 | { | 2015 | { |
2009 | fc_port_t *fcport; | 2016 | fc_port_t *fcport; |
2010 | 2017 | ||
2011 | qla2x00_mark_all_devices_lost(ha); | 2018 | qla2x00_mark_all_devices_lost(ha, 0); |
2012 | list_for_each_entry(fcport, &ha->fcports, list) { | 2019 | list_for_each_entry(fcport, &ha->fcports, list) { |
2013 | if (fcport->port_type != FCT_TARGET) | 2020 | if (fcport->port_type != FCT_TARGET) |
2014 | continue; | 2021 | continue; |
@@ -2084,24 +2091,29 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2084 | { | 2091 | { |
2085 | struct fc_rport_identifiers rport_ids; | 2092 | struct fc_rport_identifiers rport_ids; |
2086 | struct fc_rport *rport; | 2093 | struct fc_rport *rport; |
2094 | unsigned long flags; | ||
2087 | 2095 | ||
2088 | if (fcport->rport) { | 2096 | if (fcport->drport) |
2089 | fc_remote_port_delete(fcport->rport); | 2097 | qla2x00_rport_del(fcport); |
2090 | fcport->rport = NULL; | 2098 | if (fcport->rport) |
2091 | } | 2099 | return; |
2092 | 2100 | ||
2093 | rport_ids.node_name = wwn_to_u64(fcport->node_name); | 2101 | rport_ids.node_name = wwn_to_u64(fcport->node_name); |
2094 | rport_ids.port_name = wwn_to_u64(fcport->port_name); | 2102 | rport_ids.port_name = wwn_to_u64(fcport->port_name); |
2095 | rport_ids.port_id = fcport->d_id.b.domain << 16 | | 2103 | rport_ids.port_id = fcport->d_id.b.domain << 16 | |
2096 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; | 2104 | fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa; |
2097 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2105 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
2098 | fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids); | 2106 | rport = fc_remote_port_add(ha->host, 0, &rport_ids); |
2099 | if (!rport) { | 2107 | if (!rport) { |
2100 | qla_printk(KERN_WARNING, ha, | 2108 | qla_printk(KERN_WARNING, ha, |
2101 | "Unable to allocate fc remote port!\n"); | 2109 | "Unable to allocate fc remote port!\n"); |
2102 | return; | 2110 | return; |
2103 | } | 2111 | } |
2112 | spin_lock_irqsave(&fcport->rport_lock, flags); | ||
2113 | fcport->rport = rport; | ||
2104 | *((fc_port_t **)rport->dd_data) = fcport; | 2114 | *((fc_port_t **)rport->dd_data) = fcport; |
2115 | spin_unlock_irqrestore(&fcport->rport_lock, flags); | ||
2116 | |||
2105 | rport->supported_classes = fcport->supported_classes; | 2117 | rport->supported_classes = fcport->supported_classes; |
2106 | 2118 | ||
2107 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; | 2119 | rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; |
@@ -2217,12 +2229,11 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha) | |||
2217 | 2229 | ||
2218 | if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { | 2230 | if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { |
2219 | qla2x00_mark_device_lost(ha, fcport, | 2231 | qla2x00_mark_device_lost(ha, fcport, |
2220 | ql2xplogiabsentdevice); | 2232 | ql2xplogiabsentdevice, 0); |
2221 | if (fcport->loop_id != FC_NO_LOOP_ID && | 2233 | if (fcport->loop_id != FC_NO_LOOP_ID && |
2222 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && | 2234 | (fcport->flags & FCF_TAPE_PRESENT) == 0 && |
2223 | fcport->port_type != FCT_INITIATOR && | 2235 | fcport->port_type != FCT_INITIATOR && |
2224 | fcport->port_type != FCT_BROADCAST) { | 2236 | fcport->port_type != FCT_BROADCAST) { |
2225 | |||
2226 | ha->isp_ops.fabric_logout(ha, | 2237 | ha->isp_ops.fabric_logout(ha, |
2227 | fcport->loop_id, | 2238 | fcport->loop_id, |
2228 | fcport->d_id.b.domain, | 2239 | fcport->d_id.b.domain, |
@@ -2694,7 +2705,8 @@ qla2x00_device_resync(scsi_qla_host_t *ha) | |||
2694 | if (atomic_read(&fcport->state) == FCS_ONLINE) { | 2705 | if (atomic_read(&fcport->state) == FCS_ONLINE) { |
2695 | if (format != 3 || | 2706 | if (format != 3 || |
2696 | fcport->port_type != FCT_INITIATOR) { | 2707 | fcport->port_type != FCT_INITIATOR) { |
2697 | qla2x00_mark_device_lost(ha, fcport, 0); | 2708 | qla2x00_mark_device_lost(ha, fcport, |
2709 | 0, 0); | ||
2698 | } | 2710 | } |
2699 | } | 2711 | } |
2700 | fcport->flags &= ~FCF_FARP_DONE; | 2712 | fcport->flags &= ~FCF_FARP_DONE; |
@@ -2741,8 +2753,7 @@ qla2x00_fabric_dev_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
2741 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 2753 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, |
2742 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2754 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2743 | fcport->d_id.b.al_pa); | 2755 | fcport->d_id.b.al_pa); |
2744 | qla2x00_mark_device_lost(ha, fcport, 1); | 2756 | qla2x00_mark_device_lost(ha, fcport, 1, 0); |
2745 | |||
2746 | } else { | 2757 | } else { |
2747 | qla2x00_update_fcport(ha, fcport); | 2758 | qla2x00_update_fcport(ha, fcport); |
2748 | } | 2759 | } |
@@ -2855,7 +2866,7 @@ qla2x00_fabric_login(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
2855 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, | 2866 | ha->isp_ops.fabric_logout(ha, fcport->loop_id, |
2856 | fcport->d_id.b.domain, fcport->d_id.b.area, | 2867 | fcport->d_id.b.domain, fcport->d_id.b.area, |
2857 | fcport->d_id.b.al_pa); | 2868 | fcport->d_id.b.al_pa); |
2858 | qla2x00_mark_device_lost(ha, fcport, 1); | 2869 | qla2x00_mark_device_lost(ha, fcport, 1, 0); |
2859 | 2870 | ||
2860 | rval = 1; | 2871 | rval = 1; |
2861 | break; | 2872 | break; |
@@ -2990,6 +3001,17 @@ qla2x00_rescan_fcports(scsi_qla_host_t *ha) | |||
2990 | qla2x00_probe_for_all_luns(ha); | 3001 | qla2x00_probe_for_all_luns(ha); |
2991 | } | 3002 | } |
2992 | 3003 | ||
3004 | void | ||
3005 | qla2x00_update_fcports(scsi_qla_host_t *ha) | ||
3006 | { | ||
3007 | fc_port_t *fcport; | ||
3008 | |||
3009 | /* Go with deferred removal of rport references. */ | ||
3010 | list_for_each_entry(fcport, &ha->fcports, list) | ||
3011 | if (fcport->drport) | ||
3012 | qla2x00_rport_del(fcport); | ||
3013 | } | ||
3014 | |||
2993 | /* | 3015 | /* |
2994 | * qla2x00_abort_isp | 3016 | * qla2x00_abort_isp |
2995 | * Resets ISP and aborts all outstanding commands. | 3017 | * Resets ISP and aborts all outstanding commands. |
@@ -3019,7 +3041,7 @@ qla2x00_abort_isp(scsi_qla_host_t *ha) | |||
3019 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 3041 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); |
3020 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 3042 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { |
3021 | atomic_set(&ha->loop_state, LOOP_DOWN); | 3043 | atomic_set(&ha->loop_state, LOOP_DOWN); |
3022 | qla2x00_mark_all_devices_lost(ha); | 3044 | qla2x00_mark_all_devices_lost(ha, 0); |
3023 | } else { | 3045 | } else { |
3024 | if (!atomic_read(&ha->loop_down_timer)) | 3046 | if (!atomic_read(&ha->loop_down_timer)) |
3025 | atomic_set(&ha->loop_down_timer, | 3047 | 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..089e0f500363 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)); |
@@ -2469,6 +2500,7 @@ qla2x00_timer(scsi_qla_host_t *ha) | |||
2469 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || | 2500 | if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || |
2470 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || | 2501 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || |
2471 | test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || | 2502 | test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) || |
2503 | test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) || | ||
2472 | start_dpc || | 2504 | start_dpc || |
2473 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || | 2505 | test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) || |
2474 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || | 2506 | test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) || |