diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-02-03 23:11:39 +0100 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2008-02-16 15:40:35 +0100 |
commit | ce896d95cc7886ae05859c5b409a7b2f3b606ec1 (patch) | |
tree | c380b8830e1fbeea6eb91f5dc892cccdad5f796b /drivers/firewire | |
parent | 0fa6dfdb0a2768541e998a5dab10b368de56c60a (diff) | |
download | linux-next-ce896d95cc7886ae05859c5b409a7b2f3b606ec1.tar.gz |
firewire: fw-sbp2: logout and login after failed reconnect
If fw-sbp2 was too late with requesting the reconnect, the target would
reject this. In this case, log out before attempting the reconnect.
Else several firmwares will deny the re-login because they somehow
didn't invalidate the old login.
Also, don't retry reconnects in this situation. The retries won't
succeed either.
These changes improve chances for successful re-login and shorten the
period during which the logical unit is inaccessible.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Signed-off-by: Jarod Wilson <jwilson@redhat.com>
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index 914170bb50a8..80ab65161750 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -710,6 +710,11 @@ static void sbp2_login(struct work_struct *work) node_id = device->node_id; local_node_id = device->card->node_id; + /* If this is a re-login attempt, log out, or we might be rejected. */ + if (lu->sdev) + sbp2_send_management_orb(lu, device->node_id, generation, + SBP2_LOGOUT_REQUEST, lu->login_id, NULL); + if (sbp2_send_management_orb(lu, node_id, generation, SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) { if (lu->retries++ < 5) @@ -997,9 +1002,17 @@ static void sbp2_reconnect(struct work_struct *work) if (sbp2_send_management_orb(lu, node_id, generation, SBP2_RECONNECT_REQUEST, lu->login_id, NULL) < 0) { - if (lu->retries++ >= 5) { + /* + * If reconnect was impossible even though we are in the + * current generation, fall back and try to log in again. + * + * We could check for "Function rejected" status, but + * looking at the bus generation as simpler and more general. + */ + smp_rmb(); /* get current card generation */ + if (generation == device->card->generation || + lu->retries++ >= 5) { fw_error("%s: failed to reconnect\n", tgt->bus_id); - /* Fall back and try to log in again. */ lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); } |