aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_init.c
diff options
context:
space:
mode:
authorAndrew Vasquez <andrew.vasquez@qlogic.com>2006-11-22 11:22:19 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-11-22 17:43:16 -0500
commitd19044c32baadeb80e135027124a9e845c6f057c (patch)
treee525d1b048d3ab68b02b1f90eeb6ce3b9925588d /drivers/scsi/qla2xxx/qla_init.c
parent1aa8fab2acf1cb8b341131b726773fcff0abc707 (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.c94
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
59qla2x00_initialize_adapter(scsi_qla_host_t *ha) 59qla2x00_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) {
123check_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
2215void 2139void