Commit d2fe8330 authored by Tony Lindgren's avatar Tony Lindgren

ARM: OMAP: Fix MMC DMA frame count overflow

In some cases u16 count = sg_dma_len(sg) would overflow resulting in 0
length DMA transfers which would hang the system.

Without this fix, the following command would hang:

# dd if=/dev/mmcblk0 of=/dev/null bs=1M count=1 &
parent 85049d4c
...@@ -637,7 +637,8 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) ...@@ -637,7 +637,8 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
{ {
int dma_ch = host->dma_ch; int dma_ch = host->dma_ch;
unsigned long data_addr; unsigned long data_addr;
u16 buf, frame, count; u16 buf, frame;
u32 count;
struct scatterlist *sg = &data->sg[host->sg_idx]; struct scatterlist *sg = &data->sg[host->sg_idx];
data_addr = virt_to_phys((void __force *) host->base) data_addr = virt_to_phys((void __force *) host->base)
...@@ -684,6 +685,10 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data) ...@@ -684,6 +685,10 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4); omap_set_dma_src_burst_mode(dma_ch, OMAP_DMA_DATA_BURST_4);
} }
/* Max limit for DMA frame count is 0xffff */
if (unlikely(count > 0xffff))
BUG();
OMAP_MMC_WRITE(host->base, BUF, buf); OMAP_MMC_WRITE(host->base, BUF, buf);
omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16, omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
frame, count, OMAP_DMA_SYNC_FRAME); frame, count, OMAP_DMA_SYNC_FRAME);
...@@ -1152,7 +1157,7 @@ static int __init mmc_omap_probe(struct device *dev) ...@@ -1152,7 +1157,7 @@ static int __init mmc_omap_probe(struct device *dev)
*/ */
mmc->max_phys_segs = 32; mmc->max_phys_segs = 32;
mmc->max_hw_segs = 32; mmc->max_hw_segs = 32;
mmc->max_sectors = 128; /* NBLK is a 11-bit value */ mmc->max_sectors = 256; /* NBLK max 11-bits, OMAP also limited by DMA */
mmc->max_seg_size = mmc->max_sectors * 512; mmc->max_seg_size = mmc->max_sectors * 512;
if (host->power_pin >= 0) { if (host->power_pin >= 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment