diff options
author | Russell King - ARM Linux <linux@arm.linux.org.uk> | 2011-01-03 17:30:44 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2011-01-04 22:16:10 -0500 |
commit | 4440aacf3a171a0ab498feda58d100a320c5d9ff (patch) | |
tree | 582fa3a2b9a99d2f36394e29d02ac001d72d2ff6 /drivers/dma/amba-pl08x.c | |
parent | e8b5e11df3d02e7bbd85c025cc705a8e67746f73 (diff) |
ARM: PL08x: fix array overflow in dma_set_runtime_config()
If maxburst was passed in as zero, we would overflow the burst_sizes[]
array. Fix this by checking for this condition, and defaulting to
single transfer 'bursts'.
Improve the readability of the loop using a for() loop rather than
a while() loop with the iterator initialized far from the loop.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/dma/amba-pl08x.c')
-rw-r--r-- | drivers/dma/amba-pl08x.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 3da49ed5f800..0809810f9e7a 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c | |||
@@ -1207,7 +1207,7 @@ static void dma_set_runtime_config(struct dma_chan *chan, | |||
1207 | u32 cctl = 0; | 1207 | u32 cctl = 0; |
1208 | /* Mask out all except src and dst channel */ | 1208 | /* Mask out all except src and dst channel */ |
1209 | u32 ccfg = cd->ccfg & 0x000003DEU; | 1209 | u32 ccfg = cd->ccfg & 0x000003DEU; |
1210 | int i = 0; | 1210 | int i; |
1211 | 1211 | ||
1212 | /* Transfer direction */ | 1212 | /* Transfer direction */ |
1213 | plchan->runtime_direction = config->direction; | 1213 | plchan->runtime_direction = config->direction; |
@@ -1250,18 +1250,17 @@ static void dma_set_runtime_config(struct dma_chan *chan, | |||
1250 | 1250 | ||
1251 | /* | 1251 | /* |
1252 | * Now decide on a maxburst: | 1252 | * Now decide on a maxburst: |
1253 | * If this channel will only request single transfers, set | 1253 | * If this channel will only request single transfers, set this |
1254 | * this down to ONE element. | 1254 | * down to ONE element. Also select one element if no maxburst |
1255 | * is specified. | ||
1255 | */ | 1256 | */ |
1256 | if (plchan->cd->single) { | 1257 | if (plchan->cd->single || maxburst == 0) { |
1257 | cctl |= (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) | | 1258 | cctl |= (PL080_BSIZE_1 << PL080_CONTROL_SB_SIZE_SHIFT) | |
1258 | (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT); | 1259 | (PL080_BSIZE_1 << PL080_CONTROL_DB_SIZE_SHIFT); |
1259 | } else { | 1260 | } else { |
1260 | while (i < ARRAY_SIZE(burst_sizes)) { | 1261 | for (i = 0; i < ARRAY_SIZE(burst_sizes); i++) |
1261 | if (burst_sizes[i].burstwords <= maxburst) | 1262 | if (burst_sizes[i].burstwords <= maxburst) |
1262 | break; | 1263 | break; |
1263 | i++; | ||
1264 | } | ||
1265 | cctl |= burst_sizes[i].reg; | 1264 | cctl |= burst_sizes[i].reg; |
1266 | } | 1265 | } |
1267 | 1266 | ||