mirror of
https://github.com/torvalds/linux.git
synced 2024-11-05 03:21:32 +00:00
[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>
This commit is contained in:
parent
1aa8fab2ac
commit
d19044c32b
@ -59,9 +59,6 @@ int
|
|||||||
qla2x00_initialize_adapter(scsi_qla_host_t *ha)
|
qla2x00_initialize_adapter(scsi_qla_host_t *ha)
|
||||||
{
|
{
|
||||||
int rval;
|
int rval;
|
||||||
uint8_t restart_risc = 0;
|
|
||||||
uint8_t retry;
|
|
||||||
uint32_t wait_time;
|
|
||||||
|
|
||||||
/* Clear adapter flags. */
|
/* Clear adapter flags. */
|
||||||
ha->flags.online = 0;
|
ha->flags.online = 0;
|
||||||
@ -104,87 +101,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
|
|||||||
|
|
||||||
qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
|
qla_printk(KERN_INFO, ha, "Verifying loaded RISC code...\n");
|
||||||
|
|
||||||
retry = 10;
|
if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
|
||||||
/*
|
rval = ha->isp_ops.chip_diag(ha);
|
||||||
* Try to configure the loop.
|
if (rval)
|
||||||
*/
|
return (rval);
|
||||||
do {
|
rval = qla2x00_setup_chip(ha);
|
||||||
restart_risc = 0;
|
if (rval)
|
||||||
|
return (rval);
|
||||||
/* If firmware needs to be loaded */
|
|
||||||
if (qla2x00_isp_firmware(ha) != QLA_SUCCESS) {
|
|
||||||
if ((rval = ha->isp_ops.chip_diag(ha)) == QLA_SUCCESS) {
|
|
||||||
rval = qla2x00_setup_chip(ha);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rval == QLA_SUCCESS &&
|
|
||||||
(rval = qla2x00_init_rings(ha)) == QLA_SUCCESS) {
|
|
||||||
check_fw_ready_again:
|
|
||||||
/*
|
|
||||||
* Wait for a successful LIP up to a maximum
|
|
||||||
* of (in seconds): RISC login timeout value,
|
|
||||||
* RISC retry count value, and port down retry
|
|
||||||
* value OR a minimum of 4 seconds OR If no
|
|
||||||
* cable, only 5 seconds.
|
|
||||||
*/
|
|
||||||
rval = qla2x00_fw_ready(ha);
|
|
||||||
if (rval == QLA_SUCCESS) {
|
|
||||||
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
|
|
||||||
|
|
||||||
/* Issue a marker after FW becomes ready. */
|
|
||||||
qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait at most MAX_TARGET RSCNs for a stable
|
|
||||||
* link.
|
|
||||||
*/
|
|
||||||
wait_time = 256;
|
|
||||||
do {
|
|
||||||
clear_bit(LOOP_RESYNC_NEEDED,
|
|
||||||
&ha->dpc_flags);
|
|
||||||
rval = qla2x00_configure_loop(ha);
|
|
||||||
|
|
||||||
if (test_and_clear_bit(ISP_ABORT_NEEDED,
|
|
||||||
&ha->dpc_flags)) {
|
|
||||||
restart_risc = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If loop state change while we were
|
|
||||||
* discoverying devices then wait for
|
|
||||||
* LIP to complete
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (atomic_read(&ha->loop_state) !=
|
|
||||||
LOOP_READY && retry--) {
|
|
||||||
goto check_fw_ready_again;
|
|
||||||
}
|
|
||||||
wait_time--;
|
|
||||||
} while (!atomic_read(&ha->loop_down_timer) &&
|
|
||||||
retry &&
|
|
||||||
wait_time &&
|
|
||||||
(test_bit(LOOP_RESYNC_NEEDED,
|
|
||||||
&ha->dpc_flags)));
|
|
||||||
|
|
||||||
if (wait_time == 0)
|
|
||||||
rval = QLA_FUNCTION_FAILED;
|
|
||||||
} else if (ha->device_flags & DFLG_NO_CABLE)
|
|
||||||
/* If no cable, then all is good. */
|
|
||||||
rval = QLA_SUCCESS;
|
|
||||||
}
|
|
||||||
} while (restart_risc && retry--);
|
|
||||||
|
|
||||||
if (rval == QLA_SUCCESS) {
|
|
||||||
clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
|
|
||||||
qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
|
|
||||||
ha->marker_needed = 0;
|
|
||||||
|
|
||||||
ha->flags.online = 1;
|
|
||||||
} else {
|
|
||||||
DEBUG2_3(printk("%s(): **** FAILED ****\n", __func__));
|
|
||||||
}
|
}
|
||||||
|
rval = qla2x00_init_rings(ha);
|
||||||
|
|
||||||
return (rval);
|
return (rval);
|
||||||
}
|
}
|
||||||
@ -2208,8 +2133,7 @@ qla2x00_update_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
|
|||||||
|
|
||||||
atomic_set(&fcport->state, FCS_ONLINE);
|
atomic_set(&fcport->state, FCS_ONLINE);
|
||||||
|
|
||||||
if (ha->flags.init_done)
|
qla2x00_reg_remote_port(ha, fcport);
|
||||||
qla2x00_reg_remote_port(ha, fcport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1377,10 +1377,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
struct Scsi_Host *host;
|
struct Scsi_Host *host;
|
||||||
scsi_qla_host_t *ha;
|
scsi_qla_host_t *ha;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
unsigned long wait_switch = 0;
|
|
||||||
char pci_info[20];
|
char pci_info[20];
|
||||||
char fw_str[30];
|
char fw_str[30];
|
||||||
fc_port_t *fcport;
|
|
||||||
struct scsi_host_template *sht;
|
struct scsi_host_template *sht;
|
||||||
|
|
||||||
if (pci_enable_device(pdev))
|
if (pci_enable_device(pdev))
|
||||||
@ -1631,24 +1629,15 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
|
|
||||||
ha->isp_ops.enable_intrs(ha);
|
ha->isp_ops.enable_intrs(ha);
|
||||||
|
|
||||||
/* v2.19.5b6 */
|
|
||||||
/*
|
|
||||||
* Wait around max loop_reset_delay secs for the devices to come
|
|
||||||
* on-line. We don't want Linux scanning before we are ready.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
for (wait_switch = jiffies + (ha->loop_reset_delay * HZ);
|
|
||||||
time_before(jiffies,wait_switch) &&
|
|
||||||
!(ha->device_flags & (DFLG_NO_CABLE | DFLG_FABRIC_DEVICES))
|
|
||||||
&& (ha->device_flags & SWITCH_FOUND) ;) {
|
|
||||||
|
|
||||||
qla2x00_check_fabric_devices(ha);
|
|
||||||
|
|
||||||
msleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_set_drvdata(pdev, ha);
|
pci_set_drvdata(pdev, ha);
|
||||||
|
|
||||||
|
/* Start link scan. */
|
||||||
|
set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
|
||||||
|
set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
|
||||||
|
set_bit(RSCN_UPDATE, &ha->dpc_flags);
|
||||||
ha->flags.init_done = 1;
|
ha->flags.init_done = 1;
|
||||||
|
ha->flags.online = 1;
|
||||||
|
|
||||||
num_hosts++;
|
num_hosts++;
|
||||||
|
|
||||||
ret = scsi_add_host(host, &pdev->dev);
|
ret = scsi_add_host(host, &pdev->dev);
|
||||||
@ -1669,10 +1658,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
|
ha->flags.enable_64bit_addressing ? '+': '-', ha->host_no,
|
||||||
ha->isp_ops.fw_version_str(ha, fw_str));
|
ha->isp_ops.fw_version_str(ha, fw_str));
|
||||||
|
|
||||||
/* Go with fc_rport registration. */
|
|
||||||
list_for_each_entry(fcport, &ha->fcports, list)
|
|
||||||
qla2x00_reg_remote_port(ha, fcport);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
probe_failed:
|
probe_failed:
|
||||||
|
Loading…
Reference in New Issue
Block a user