ieee1394: sbp2: let nodemgr retry node updates during bus reset series
authorStefan Richter <stefanr@s5r6.in-berlin.de>
Sat, 16 Aug 2008 11:39:26 +0000 (13:39 +0200)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Tue, 19 Aug 2008 16:47:56 +0000 (18:47 +0200)
sbp2 was too quick to report .update() to the ieee1394 core as failed.
(Logged as "Failed to reconnect to sbp2 device!".)  The core would then
unbind sbp2 from the device.

This is not justified if the .update() failed because another bus reset
happened.  We check this and tell the ieee1394 that .update() succeeded,
and the core will call sbp2's .update() for the new bus reset as well.

This improves reconnection/re-login especially on buses with several
disks as they may issue bus resets in close succession when they come
online.

Tested by Damien Benoist.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
drivers/ieee1394/sbp2.c

index 9cbf315..1d6ad34 100644 (file)
@@ -731,15 +731,26 @@ static int sbp2_update(struct unit_directory *ud)
 {
        struct sbp2_lu *lu = ud->device.driver_data;
 
-       if (sbp2_reconnect_device(lu)) {
-               /* Reconnect has failed. Perhaps we didn't reconnect fast
-                * enough. Try a regular login, but first log out just in
-                * case of any weirdness. */
+       if (sbp2_reconnect_device(lu) != 0) {
+               /*
+                * Reconnect failed.  If another bus reset happened,
+                * let nodemgr proceed and call sbp2_update again later
+                * (or sbp2_remove if this node went away).
+                */
+               if (!hpsb_node_entry_valid(lu->ne))
+                       return 0;
+               /*
+                * Or the target rejected the reconnect because we weren't
+                * fast enough.  Try a regular login, but first log out
+                * just in case of any weirdness.
+                */
                sbp2_logout_device(lu);
 
-               if (sbp2_login_device(lu)) {
-                       /* Login failed too, just fail, and the backend
-                        * will call our sbp2_remove for us */
+               if (sbp2_login_device(lu) != 0) {
+                       if (!hpsb_node_entry_valid(lu->ne))
+                               return 0;
+
+                       /* Maybe another initiator won the login. */
                        SBP2_ERR("Failed to reconnect to sbp2 device!");
                        return -EBUSY;
                }