diff options
| -rw-r--r-- | 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 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; |
