diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-22 19:54:54 (GMT) |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-22 19:54:54 (GMT) |
commit | cfc94b2c9ac603b20db54225408df6ed80188dcd (patch) | |
tree | 6e5b21adac556242b89931c4d0929b66efb8c0b9 /drivers/firewire/ohci.c | |
parent | 4c6a3999651741419cd3cc4303cf0c2be07d89bc (diff) | |
parent | e1393667be574807a13bfaf1bb471f5fd1a5287b (diff) | |
download | linux-cfc94b2c9ac603b20db54225408df6ed80188dcd.tar.xz |
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/ohci.c')
-rw-r--r-- | drivers/firewire/ohci.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 0cf4d7f..94b16e0 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1158,7 +1158,7 @@ static void handle_local_lock(struct fw_ohci *ohci, struct fw_packet *packet, u32 csr) { struct fw_packet response; - int tcode, length, ext_tcode, sel; + int tcode, length, ext_tcode, sel, try; __be32 *payload, lock_old; u32 lock_arg, lock_data; @@ -1185,21 +1185,26 @@ static void handle_local_lock(struct fw_ohci *ohci, reg_write(ohci, OHCI1394_CSRCompareData, lock_arg); reg_write(ohci, OHCI1394_CSRControl, sel); - if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) - lock_old = cpu_to_be32(reg_read(ohci, OHCI1394_CSRData)); - else - fw_notify("swap not done yet\n"); + for (try = 0; try < 20; try++) + if (reg_read(ohci, OHCI1394_CSRControl) & 0x80000000) { + lock_old = cpu_to_be32(reg_read(ohci, + OHCI1394_CSRData)); + fw_fill_response(&response, packet->header, + RCODE_COMPLETE, + &lock_old, sizeof(lock_old)); + goto out; + } + + fw_error("swap not done (CSR lock timeout)\n"); + fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); - fw_fill_response(&response, packet->header, - RCODE_COMPLETE, &lock_old, sizeof(lock_old)); out: fw_core_handle_response(&ohci->card, &response); } static void handle_local_request(struct context *ctx, struct fw_packet *packet) { - u64 offset; - u32 csr; + u64 offset, csr; if (ctx == &ctx->ohci->at_request_ctx) { packet->ack = ACK_PENDING; |