From 3a1f0a0e3d871e3d3e08a1429009992151becda8 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 12 Apr 2010 10:35:05 +0200 Subject: firewire: core: fix retries calculation in iso manage_channel() If there is a permanent error condition when communicating with the IRM, after the sixth error, the retry variable will be decremented to -1. If, in this case, the bits in channels_mask are not yet exhausted, the next channel is retried 2^32 times. To fix this, check that retry is never decremented beyond zero. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-iso.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/firewire/core-iso.c') diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 99c20f1b613a..34a513725c9e 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -250,8 +250,10 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, /* 1394-1995 IRM, fall through to retry. */ default: - if (retry--) + if (retry) { + retry--; i--; + } } } -- cgit v1.2.3 From d6372b6e7c6142e6cc2108b3b850584cd7ade106 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 12 Apr 2010 10:35:18 +0200 Subject: firewire: core: fw_iso_resource_manage: return -EBUSY when out of resources Returning -EIO for all errors would not allow clients to determine if the resource allocation process itself failed, or if the resources are not available. (The latter information is needed by CMP to synchronize restoring of overlayed connections after a bus reset.) Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-iso.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/firewire/core-iso.c') diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 34a513725c9e..9198e030e895 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -189,7 +189,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation, for (try = 0; try < 5; try++) { new = allocate ? old - bandwidth : old + bandwidth; if (new < 0 || new > BANDWIDTH_AVAILABLE_INITIAL) - break; + return -EBUSY; data[0] = cpu_to_be32(old); data[1] = cpu_to_be32(new); @@ -217,7 +217,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, u32 channels_mask, u64 offset, bool allocate, __be32 data[2]) { __be32 c, all, old; - int i, retry = 5; + int i, ret = -EIO, retry = 5; old = all = allocate ? cpu_to_be32(~0) : 0; @@ -225,6 +225,8 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, if (!(channels_mask & 1 << i)) continue; + ret = -EBUSY; + c = cpu_to_be32(1 << (31 - i)); if ((old & c) != (all & c)) continue; @@ -253,11 +255,13 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation, if (retry) { retry--; i--; + } else { + ret = -EIO; } } } - return -EIO; + return ret; } static void deallocate_channel(struct fw_card *card, int irm_id, -- cgit v1.2.3