Commit eaf76e0d027a917a013ad8a88a94132d0feab622
1 parent
544df55d6c
Exists in
master
and in
39 other branches
firewire: sbp2: provide fallback if mgt_ORB_timeout is missing
The Unit_Characteristics entry of an SBP-2 unit directory is not mandatory as far as I can tell. If it is missing, we would probably fail to log in into the target because firewire-sbp2 would not wait for status after it sent the login request. The fix moves the cleanup of tgt->mgt_orb_timeout into a place where it is executed exactly once before login, rather than 0..n times depending on the target's config ROM. With targets with one or more Unit_Characteristics entries, the result is the same as before. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Showing 1 changed file with 19 additions and 20 deletions Side-by-side Diff
drivers/firewire/sbp2.c
... | ... | @@ -188,14 +188,7 @@ |
188 | 188 | /* Impossible login_id, to detect logout attempt before successful login */ |
189 | 189 | #define INVALID_LOGIN_ID 0x10000 |
190 | 190 | |
191 | -/* | |
192 | - * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be | |
193 | - * provided in the config rom. Most devices do provide a value, which | |
194 | - * we'll use for login management orbs, but with some sane limits. | |
195 | - */ | |
196 | -#define SBP2_MIN_LOGIN_ORB_TIMEOUT 5000U /* Timeout in ms */ | |
197 | -#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */ | |
198 | -#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ | |
191 | +#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */ | |
199 | 192 | #define SBP2_ORB_NULL 0x80000000 |
200 | 193 | #define SBP2_RETRY_LIMIT 0xf /* 15 retries */ |
201 | 194 | #define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */ |
... | ... | @@ -1034,7 +1027,6 @@ |
1034 | 1027 | { |
1035 | 1028 | struct fw_csr_iterator ci; |
1036 | 1029 | int key, value; |
1037 | - unsigned int timeout; | |
1038 | 1030 | |
1039 | 1031 | fw_csr_iterator_init(&ci, directory); |
1040 | 1032 | while (fw_csr_iterator_next(&ci, &key, &value)) { |
... | ... | @@ -1059,17 +1051,7 @@ |
1059 | 1051 | |
1060 | 1052 | case SBP2_CSR_UNIT_CHARACTERISTICS: |
1061 | 1053 | /* the timeout value is stored in 500ms units */ |
1062 | - timeout = ((unsigned int) value >> 8 & 0xff) * 500; | |
1063 | - timeout = max(timeout, SBP2_MIN_LOGIN_ORB_TIMEOUT); | |
1064 | - tgt->mgt_orb_timeout = | |
1065 | - min(timeout, SBP2_MAX_LOGIN_ORB_TIMEOUT); | |
1066 | - | |
1067 | - if (timeout > tgt->mgt_orb_timeout) | |
1068 | - fw_notify("%s: config rom contains %ds " | |
1069 | - "management ORB timeout, limiting " | |
1070 | - "to %ds\n", tgt->bus_id, | |
1071 | - timeout / 1000, | |
1072 | - tgt->mgt_orb_timeout / 1000); | |
1054 | + tgt->mgt_orb_timeout = (value >> 8 & 0xff) * 500; | |
1073 | 1055 | break; |
1074 | 1056 | |
1075 | 1057 | case SBP2_CSR_LOGICAL_UNIT_NUMBER: |
... | ... | @@ -1087,6 +1069,22 @@ |
1087 | 1069 | return 0; |
1088 | 1070 | } |
1089 | 1071 | |
1072 | +/* | |
1073 | + * Per section 7.4.8 of the SBP-2 spec, a mgt_ORB_timeout value can be | |
1074 | + * provided in the config rom. Most devices do provide a value, which | |
1075 | + * we'll use for login management orbs, but with some sane limits. | |
1076 | + */ | |
1077 | +static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt) | |
1078 | +{ | |
1079 | + unsigned int timeout = tgt->mgt_orb_timeout; | |
1080 | + | |
1081 | + if (timeout > 40000) | |
1082 | + fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n", | |
1083 | + tgt->bus_id, timeout / 1000); | |
1084 | + | |
1085 | + tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000); | |
1086 | +} | |
1087 | + | |
1090 | 1088 | static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, |
1091 | 1089 | u32 firmware_revision) |
1092 | 1090 | { |
... | ... | @@ -1171,6 +1169,7 @@ |
1171 | 1169 | &firmware_revision) < 0) |
1172 | 1170 | goto fail_tgt_put; |
1173 | 1171 | |
1172 | + sbp2_clamp_management_orb_timeout(tgt); | |
1174 | 1173 | sbp2_init_workarounds(tgt, model, firmware_revision); |
1175 | 1174 | |
1176 | 1175 | /* |