diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2006-11-22 11:22:19 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 17:43:16 -0500 |
commit | d19044c32baadeb80e135027124a9e845c6f057c (patch) | |
tree | e525d1b048d3ab68b02b1f90eeb6ce3b9925588d /drivers/scsi/qla2xxx/qla_init.c | |
parent | 1aa8fab2acf1cb8b341131b726773fcff0abc707 (diff) |
[SCSI] qla2xxx: defer topology discovery to DPC thread during initialization.
Modify intialization semantics:
- perform basic hardware configuration only (as usual)
- allocate resources
- load and execute firmware
- defer link (transport) negotiations to the DPC thread
- again the code in qla2x00_initialize_adapter() to stall probe()
completion was needed for legacy-style scanning.
- DPC thread stalls until probe() complete.
- before probe() completes, set DPC flags to perform loop-resync logic
(similar to what's done during cable-insertion/removal).
Benefits: user does not have to wait 20+ seconds in case the FC cable
is unplugged during driver load, code consolidation (removal of
redundant link negotiation logic during initialize_adaoter()), and
finilly, the driver no longer needs to defer the fc_remote_port_add()
calls to hold off lun-scanning prior to returning from the probe()
function.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 94 |
1 files changed, 9 insertions, 85 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 08cb5e3fb553..a823f0bc519d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -59,9 +59,6 @@ int | |||
59 | qla2x00_initialize_adapter(scsi_qla_host_t *ha) | 59 | qla2x00_initialize_adapter(scsi_qla_host_t *ha) |
60 | { | 60 | { |
61 | int rval; | 61 | int rval; |
62 | uint8_t restart_risc = 0; | ||
63 | uint8_t retry; | ||
64 | uint32_t wait_time; | ||
65 | 62 | ||
66 | /* Clear adapter flags. */ | 63 | /* Clear adapter flags. */ |
67 | ha->flags.online = 0; | 64 | ha->flags.online = 0; |
@@ -104,87 +101,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha) | |||
104 | 101 | ||
105 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); | 102 | qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n"); |
106 | 103 | ||
107 | retry = 10; | 104 | if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { |
108 | /* | 105 | rval = ha->isp_ops.chip_diag(ha); |
109 | * Try to configure the loop. | 106 | if (rval) |
110 | */ | 107 | return (rval); |
111 | do { | 108 | rval = qla2x00_setup_chip(ha); |
112 | restart_risc = 0; | 109 | if (rval) |
113 | 110 | return (rval); | |
114 | /* If firmware needs to be loaded */ | ||
115 | if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) { | ||
116 | if ((rval = ha->isp_ops.chip_diag(ha)) == QLA_SUCCESS) { | ||
117 | rval = qla2x00_setup_chip(ha); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | if (rval == QLA_SUCCESS && | ||
122 | (rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) { | ||
123 | check_fw_ready_again: | ||
124 | /* | ||
125 | * Wait for a successful LIP up to a maximum | ||
126 | * of (in seconds): RISC login timeout value, | ||
127 | * RISC retry count value, and port down retry | ||
128 | * value OR a minimum of 4 seconds OR If no | ||
129 | * cable, only 5 seconds. | ||
130 | */ | ||
131 | rval = qla2x00_fw_ready(ha); | ||
132 | if (rval == QLA_SUCCESS) { | ||
133 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | ||
134 | |||
135 | /* Issue a marker after FW becomes ready. */ | ||
136 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | ||
137 | |||
138 | /* | ||
139 | * Wait at most MAX_TARGET RSCNs for a stable | ||
140 | * link. | ||
141 | */ | ||
142 | wait_time = 256; | ||
143 | do { | ||
144 | clear_bit(LOOP_RESYNC_NEEDED, | ||
145 | &ha->dpc_flags); | ||
146 | rval = qla2x00_configure_loop(ha); | ||
147 | |||
148 | if (test_and_clear_bit(ISP_ABORT_NEEDED, | ||
149 | &ha->dpc_flags)) { | ||
150 | restart_risc = 1; | ||
151 | break; | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * If loop state change while we were | ||
156 | * discoverying devices then wait for | ||
157 | * LIP to complete | ||
158 | */ | ||
159 | |||
160 | if (atomic_read(&ha->loop_state) != | ||
161 | LOOP_READY && retry--) { | ||
162 | goto check_fw_ready_again; | ||
163 | } | ||
164 | wait_time--; | ||
165 | } while (!atomic_read(&ha->loop_down_timer) && | ||
166 | retry && | ||
167 | wait_time && | ||
168 | (test_bit(LOOP_RESYNC_NEEDED, | ||
169 | &ha->dpc_flags))); | ||
170 | |||
171 | if (wait_time == 0) | ||
172 | rval = QLA_FUNCTION_FAILED; | ||
173 | } else if (ha->device_flags & DFLG_NO_CABLE) | ||
174 | /* If no cable, then all is good. */ | ||
175 | rval = QLA_SUCCESS; | ||
176 | } | ||
177 | } while (restart_risc && retry--); | ||
178 | |||
179 | if (rval == QLA_SUCCESS) { | ||
180 | clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | ||
181 | qla2x00_marker(ha, 0, 0, MK_SYNC_ALL); | ||
182 | ha->marker_needed = 0; | ||
183 | |||
184 | ha->flags.online = 1; | ||
185 | } else { | ||
186 | DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__)); | ||
187 | } | 111 | } |
112 | rval = qla2x00_init_rings(ha); | ||
188 | 113 | ||
189 | return (rval); | 114 | return (rval); |
190 | } | 115 | } |
@@ -2208,8 +2133,7 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2208 | 2133 | ||
2209 | atomic_set(&fcport->state, FCS_ONLINE); | 2134 | atomic_set(&fcport->state, FCS_ONLINE); |
2210 | 2135 | ||
2211 | if (ha->flags.init_done) | 2136 | qla2x00_reg_remote_port(ha, fcport); |
2212 | qla2x00_reg_remote_port(ha, fcport); | ||
2213 | } | 2137 | } |
2214 | 2138 | ||
2215 | void | 2139 | void |