aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c94
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c29
2 files changed, 16 insertions, 107 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
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3eb4cd2cbc78..1cc8febcbadb 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1377,10 +1377,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1377 struct Scsi_Host *host; 1377 struct Scsi_Host *host;
1378 scsi_qla_host_t *ha; 1378 scsi_qla_host_t *ha;
1379 unsigned long flags = 0; 1379 unsigned long flags = 0;
1380 unsigned long wait_switch = 0;
1381 char pci_info[20]; 1380 char pci_info[20];
1382 char fw_str[30]; 1381 char fw_str[30];
1383 fc_port_t *fcport;
1384 struct scsi_host_template *sht; 1382 struct scsi_host_template *sht;
1385 1383
1386 if (pci_enable_device(pdev)) 1384 if (pci_enable_device(pdev))
@@ -1631,24 +1629,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1631 1629
1632 ha->isp_ops.enable_intrs(ha); 1630 ha->isp_ops.enable_intrs(ha);
1633 1631
1634 /* v2.19.5b6 */
1635 /*
1636 * Wait around max loop_reset_delay secs for the devices to come
1637 * on-line. We don't want Linux scanning before we are ready.
1638 *
1639 */
1640 for (wait_switch = jiffies + (ha->loop_reset_delay * HZ);
1641 time_before(jiffies,wait_switch) &&
1642 !(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES))
1643 && (ha->device_flags & SWITCH_FOUND) ;) {
1644
1645 qla2x00_check_fabric_devices(ha);
1646
1647 msleep(10);
1648 }
1649
1650 pci_set_drvdata(pdev, ha); 1632 pci_set_drvdata(pdev, ha);
1633
1634 /* Start link scan. */
1635 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
1636 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
1637 set_bit(RSCN_UPDATE, &ha->dpc_flags);
1651 ha->flags.init_done = 1; 1638 ha->flags.init_done = 1;
1639 ha->flags.online = 1;
1640
1652 num_hosts++; 1641 num_hosts++;
1653 1642
1654 ret = scsi_add_host(host, &pdev->dev); 1643 ret = scsi_add_host(host, &pdev->dev);
@@ -1669,10 +1658,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1669 ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no, 1658 ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
1670 ha->isp_ops.fw_version_str(ha, fw_str)); 1659 ha->isp_ops.fw_version_str(ha, fw_str));
1671 1660
1672 /* Go with fc_rport registration. */
1673 list_for_each_entry(fcport, &ha->fcports, list)
1674 qla2x00_reg_remote_port(ha, fcport);
1675
1676 return 0; 1661 return 0;
1677 1662
1678probe_failed: 1663probe_failed: