Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=384170da9384b7bb3650c0c9b9d17ba0f7bde4ff
Commit:     384170da9384b7bb3650c0c9b9d17ba0f7bde4ff
Parent:     a4c379c1979fbc417099cd22ba16735bc3625bbf
Author:     Jarod Wilson <[EMAIL PROTECTED]>
AuthorDate: Fri Jan 25 23:31:12 2008 -0500
Committer:  Stefan Richter <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 22:22:29 2008 +0100

    firewire: fw-sbp2: Use sbp2 device-provided mgt orb timeout for logins
    
    To be more compliant with section 7.4.8 of the SBP-2 specification,
    use the mgt_ORB_timeout specified in the SBP-2 device's config rom
    for login ORB attempts (though with some sanity checks). A happy
    side-effect is that certain device and controller combinations that
    sometimes take more than 20 seconds to get synced up (like my laptop
    with just about any SBP-2 device) now function more reliably.
    
    Signed-off-by: Jarod Wilson <[EMAIL PROTECTED]>
    Signed-off-by: Stefan Richter <[EMAIL PROTECTED]> (silenced sparse)
---
 drivers/firewire/fw-sbp2.c |   29 ++++++++++++++++++++++++-----
 1 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 794bade..19ece9b 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -149,15 +149,17 @@ struct sbp2_target {
 
        unsigned workarounds;
        struct list_head lu_list;
+
+       unsigned int mgt_orb_timeout;
 };
 
 /*
  * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
- * provided in the config rom.  A high timeout value really only matters
- * on initial login, where we'll just use 20s rather than hassling with
- * reading the config rom, since it really wouldn't buy us much.
+ * provided in the config rom. Most devices do provide a value, which
+ * we'll use for login management orbs, but with some sane limits.
  */
-#define SBP2_LOGIN_ORB_TIMEOUT         20000   /* Timeout in ms */
+#define SBP2_MIN_LOGIN_ORB_TIMEOUT     5000U   /* Timeout in ms */
+#define SBP2_MAX_LOGIN_ORB_TIMEOUT     40000U  /* Timeout in ms */
 #define SBP2_ORB_TIMEOUT               2000    /* Timeout in ms */
 #define SBP2_ORB_NULL                  0x80000000
 #define SBP2_MAX_SG_ELEMENT_LENGTH     0xf000
@@ -166,6 +168,7 @@ struct sbp2_target {
 #define SBP2_DIRECTION_FROM_MEDIA      0x1
 
 /* Unit directory keys */
+#define SBP2_CSR_UNIT_CHARACTERISTICS  0x3a
 #define SBP2_CSR_FIRMWARE_REVISION     0x3c
 #define SBP2_CSR_LOGICAL_UNIT_NUMBER   0x14
 #define SBP2_CSR_LOGICAL_UNIT_DIRECTORY        0xd4
@@ -527,7 +530,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int 
node_id,
                orb->request.misc |=
                        MANAGEMENT_ORB_RECONNECT(2) |
                        MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login);
-               timeout = SBP2_LOGIN_ORB_TIMEOUT;
+               timeout = lu->tgt->mgt_orb_timeout;
        } else {
                timeout = SBP2_ORB_TIMEOUT;
        }
@@ -777,6 +780,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 
*directory,
 {
        struct fw_csr_iterator ci;
        int key, value;
+       unsigned int timeout;
 
        fw_csr_iterator_init(&ci, directory);
        while (fw_csr_iterator_next(&ci, &key, &value)) {
@@ -799,6 +803,21 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 
*directory,
                        *firmware_revision = value;
                        break;
 
+               case SBP2_CSR_UNIT_CHARACTERISTICS:
+                       /* the timeout value is stored in 500ms units */
+                       timeout = ((unsigned int) value >> 8 & 0xff) * 500;
+                       timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT);
+                       tgt->mgt_orb_timeout =
+                                 min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT);
+
+                       if (timeout > tgt->mgt_orb_timeout)
+                               fw_notify("%s: config rom contains %ds "
+                                         "management ORB timeout, limiting "
+                                         "to %ds\n", tgt->unit->device.bus_id,
+                                         timeout / 1000,
+                                         tgt->mgt_orb_timeout / 1000);
+                       break;
+
                case SBP2_CSR_LOGICAL_UNIT_NUMBER:
                        if (sbp2_add_logical_unit(tgt, value) < 0)
                                return -ENOMEM;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to