diff options
author | Andrew Vasquez <andrew.vasquez@qlogic.com> | 2008-08-13 21:36:56 -0700 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-08-16 10:21:09 -0500 |
commit | 6390d1f33faecf48e31f27dd7dbe928540f8acfc (patch) | |
tree | f6ff0fa0888f89117618e832bdcd257da0f5803d /drivers/scsi | |
parent | fe42625cdf0d4e06f01e365897a64b68d7f7de7d (diff) |
[SCSI] qla2xxx: Correct synchronization of software/firmware fcport states.
Greg Wettstein (greg@enjellic.com) noted:
http://article.gmane.org/gmane.linux.scsi/43409
on a reboot of a previously recognized SCST target, the initiator
driver would be unable to re-recognize the device as a target.
It turns out that prior to the SCST software reloading and
returning it's "target-capable" abilities in the PRLI payload,
the HBA would be re-initialized as an initiator-only type port.
Since initiators typically classify themselves as an FCP-2
capable device, both software and firmware do not perform an
explicit logout during port-loss. Unfortunately, as can be seen
by the failure case, when the port (now target-capable) returns,
firmware performs an ADISC without a follow-on PRLI, leaving
stale 'initiator-only' data in the firmware's port database.
Correct the discrepancy by performing the explicit logout during
the transport's request to terminate-rport-io, thus synchronizing
port states and ensuring a follow-on PRLI is performed.
Reported-by: Greg Wettstein <greg@enjellic.com>
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
Cc: Stable Tree <stable@kernel.org>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index a319a20ed440..45e7dcb4b34d 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -993,6 +993,17 @@ qla2x00_terminate_rport_io(struct fc_rport *rport) { fc_port_t *fcport = *(fc_port_t **)rport->dd_data; + /* + * At this point all fcport's software-states are cleared. Perform any + * final cleanup of firmware resources (PCBs and XCBs). + */ + if (fcport->loop_id != FC_NO_LOOP_ID) { + fcport->ha->isp_ops->fabric_logout(fcport->ha, fcport->loop_id, + fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa); + fcport->loop_id = FC_NO_LOOP_ID; + } + qla2x00_abort_fcport_cmds(fcport); scsi_target_unblock(&rport->dev); } |