aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-04-22 15:54:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-04-22 15:54:54 -0400
commitcfc94b2c9ac603b20db54225408df6ed80188dcd (patch)
tree6e5b21adac556242b89931c4d0929b66efb8c0b9 /drivers/firewire
parent4c6a3999651741419cd3cc4303cf0c2be07d89bc (diff)
parente1393667be574807a13bfaf1bb471f5fd1a5287b (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: firewire: ohci: wait for local CSR lock access to finish firewire: ohci: prevent aliasing of locally handled register addresses firewire: core: fw_iso_resource_manage: return -EBUSY when out of resources firewire: core: fix retries calculation in iso manage_channel() firewire: cdev: fix cut+paste mistake in disclaimer
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-iso.c14
-rw-r--r--drivers/firewire/ohci.c23
2 files changed, 24 insertions, 13 deletions
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 3784a47865b..8f5aebfb29d 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -190,7 +190,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
190 for (try = 0; try < 5; try++) { 190 for (try = 0; try < 5; try++) {
191 new = allocate ? old - bandwidth : old + bandwidth; 191 new = allocate ? old - bandwidth : old + bandwidth;
192 if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL) 192 if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL)
193 break; 193 return -EBUSY;
194 194
195 data[0] = cpu_to_be32(old); 195 data[0] = cpu_to_be32(old);
196 data[1] = cpu_to_be32(new); 196 data[1] = cpu_to_be32(new);
@@ -218,7 +218,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
218 u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) 218 u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
219{ 219{
220 __be32 c, all, old; 220 __be32 c, all, old;
221 int i, retry = 5; 221 int i, ret = -EIO, retry = 5;
222 222
223 old = all = allocate ? cpu_to_be32(~0) : 0; 223 old = all = allocate ? cpu_to_be32(~0) : 0;
224 224
@@ -226,6 +226,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
226 if (!(channels_mask & 1 << i)) 226 if (!(channels_mask & 1 << i))
227 continue; 227 continue;
228 228
229 ret = -EBUSY;
230
229 c = cpu_to_be32(1 << (31 - i)); 231 c = cpu_to_be32(1 << (31 - i));
230 if ((old & c) != (all & c)) 232 if ((old & c) != (all & c))
231 continue; 233 continue;
@@ -251,12 +253,16 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
251 253
252 /* 1394-1995 IRM, fall through to retry. */ 254 /* 1394-1995 IRM, fall through to retry. */
253 default: 255 default:
254 if (retry--) 256 if (retry) {
257 retry--;
255 i--; 258 i--;
259 } else {
260 ret = -EIO;
261 }
256 } 262 }
257 } 263 }
258 264
259 return -EIO; 265 return ret;
260} 266}
261 267
262static void deallocate_channel(struct fw_card *card, int irm_id, 268static void deallocate_channel(struct fw_card *card, int irm_id,
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 0cf4d7f562c..94b16e0340a 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1158,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci,
1158 struct fw_packet *packet, u32 csr) 1158 struct fw_packet *packet, u32 csr)
1159{ 1159{
1160 struct fw_packet response; 1160 struct fw_packet response;
1161 int tcode, length, ext_tcode, sel; 1161 int tcode, length, ext_tcode, sel, try;
1162 __be32 *payload, lock_old; 1162 __be32 *payload, lock_old;
1163 u32 lock_arg, lock_data; 1163 u32 lock_arg, lock_data;
1164 1164
@@ -1185,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci,
1185 reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); 1185 reg_write(ohci, OHCI1394_CSRCompareData, lock_arg);
1186 reg_write(ohci, OHCI1394_CSRControl, sel); 1186 reg_write(ohci, OHCI1394_CSRControl, sel);
1187 1187
1188 if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) 1188 for (try = 0; try < 20; try++)
1189 lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData)); 1189 if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) {
1190 else 1190 lock_old = cpu_to_be32(reg_read(ohci,
1191 fw_notify("swap not done yet\n"); 1191 OHCI1394_CSRData));
1192 fw_fill_response(&response, packet->header,
1193 RCODE_COMPLETE,
1194 &lock_old, sizeof(lock_old));
1195 goto out;
1196 }
1197
1198 fw_error("swap not done (CSR lock timeout)\n");
1199 fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0);
1192 1200
1193 fw_fill_response(&response, packet->header,
1194 RCODE_COMPLETE, &lock_old, sizeof(lock_old));
1195 out: 1201 out:
1196 fw_core_handle_response(&ohci->card, &response); 1202 fw_core_handle_response(&ohci->card, &response);
1197} 1203}
1198 1204
1199static void handle_local_request(struct context *ctx, struct fw_packet *packet) 1205static void handle_local_request(struct context *ctx, struct fw_packet *packet)
1200{ 1206{
1201 u64 offset; 1207 u64 offset, csr;
1202 u32 csr;
1203 1208
1204 if (ctx == &ctx->ohci->at_request_ctx) { 1209 if (ctx == &ctx->ohci->at_request_ctx) {
1205 packet->ack = ACK_PENDING; 1210 packet->ack = ACK_PENDING;