aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-sbp2.c
diff options
context:
space:
mode:
authorJarod Wilson <jwilson@redhat.com>2008-01-25 23:31:12 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-01-30 16:22:29 -0500
commit384170da9384b7bb3650c0c9b9d17ba0f7bde4ff (patch)
tree93d92b0d68a37a8b7785b0da5f7f477df851f2ef /drivers/firewire/fw-sbp2.c
parenta4c379c1979fbc417099cd22ba16735bc3625bbf (diff)
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 <jwilson@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (silenced sparse)
Diffstat (limited to 'drivers/firewire/fw-sbp2.c')
-rw-r--r--drivers/firewire/fw-sbp2.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 794badeee0e2..19ece9b6d742 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -149,15 +149,17 @@ struct sbp2_target {
149 149
150 unsigned workarounds; 150 unsigned workarounds;
151 struct list_head lu_list; 151 struct list_head lu_list;
152
153 unsigned int mgt_orb_timeout;
152}; 154};
153 155
154/* 156/*
155 * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be 157 * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be
156 * provided in the config rom. A high timeout value really only matters 158 * provided in the config rom. Most devices do provide a value, which
157 * on initial login, where we'll just use 20s rather than hassling with 159 * we'll use for login management orbs, but with some sane limits.
158 * reading the config rom, since it really wouldn't buy us much.
159 */ 160 */
160#define SBP2_LOGIN_ORB_TIMEOUT 20000 /* Timeout in ms */ 161#define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */
162#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
161#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */ 163#define SBP2_ORB_TIMEOUT 2000 /* Timeout in ms */
162#define SBP2_ORB_NULL 0x80000000 164#define SBP2_ORB_NULL 0x80000000
163#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 165#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
@@ -166,6 +168,7 @@ struct sbp2_target {
166#define SBP2_DIRECTION_FROM_MEDIA 0x1 168#define SBP2_DIRECTION_FROM_MEDIA 0x1
167 169
168/* Unit directory keys */ 170/* Unit directory keys */
171#define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a
169#define SBP2_CSR_FIRMWARE_REVISION 0x3c 172#define SBP2_CSR_FIRMWARE_REVISION 0x3c
170#define SBP2_CSR_LOGICAL_UNIT_NUMBER 0x14 173#define SBP2_CSR_LOGICAL_UNIT_NUMBER 0x14
171#define SBP2_CSR_LOGICAL_UNIT_DIRECTORY 0xd4 174#define SBP2_CSR_LOGICAL_UNIT_DIRECTORY 0xd4
@@ -527,7 +530,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
527 orb->request.misc |= 530 orb->request.misc |=
528 MANAGEMENT_ORB_RECONNECT(2) | 531 MANAGEMENT_ORB_RECONNECT(2) |
529 MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login); 532 MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login);
530 timeout = SBP2_LOGIN_ORB_TIMEOUT; 533 timeout = lu->tgt->mgt_orb_timeout;
531 } else { 534 } else {
532 timeout = SBP2_ORB_TIMEOUT; 535 timeout = SBP2_ORB_TIMEOUT;
533 } 536 }
@@ -777,6 +780,7 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
777{ 780{
778 struct fw_csr_iterator ci; 781 struct fw_csr_iterator ci;
779 int key, value; 782 int key, value;
783 unsigned int timeout;
780 784
781 fw_csr_iterator_init(&ci, directory); 785 fw_csr_iterator_init(&ci, directory);
782 while (fw_csr_iterator_next(&ci, &key, &value)) { 786 while (fw_csr_iterator_next(&ci, &key, &value)) {
@@ -799,6 +803,21 @@ static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
799 *firmware_revision = value; 803 *firmware_revision = value;
800 break; 804 break;
801 805
806 case SBP2_CSR_UNIT_CHARACTERISTICS:
807 /* the timeout value is stored in 500ms units */
808 timeout = ((unsigned int) value >> 8 & 0xff) * 500;
809 timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT);
810 tgt->mgt_orb_timeout =
811 min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT);
812
813 if (timeout > tgt->mgt_orb_timeout)
814 fw_notify("%s: config rom contains %ds "
815 "management ORB timeout, limiting "
816 "to %ds\n", tgt->unit->device.bus_id,
817 timeout / 1000,
818 tgt->mgt_orb_timeout / 1000);
819 break;
820
802 case SBP2_CSR_LOGICAL_UNIT_NUMBER: 821 case SBP2_CSR_LOGICAL_UNIT_NUMBER:
803 if (sbp2_add_logical_unit(tgt, value) < 0) 822 if (sbp2_add_logical_unit(tgt, value) < 0)
804 return -ENOMEM; 823 return -ENOMEM;