]> pilppa.com Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: Fix MMC DMA frame count overflow
authorTony Lindgren <tony@atomide.com>
Tue, 16 Aug 2005 12:00:57 +0000 (05:00 -0700)
committerTony Lindgren <tony@atomide.com>
Tue, 16 Aug 2005 12:00:57 +0000 (05:00 -0700)
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 &

drivers/mmc/omap.c

index 3c79d949f6534623aa7aeaeabbea80ccc6d23482..68c8a8a6a8ce50ba13c4cfbac6dd74a96bcfddae 100644 (file)
@@ -637,7 +637,8 @@ mmc_omap_prepare_dma(struct mmc_omap_host *host, struct mmc_data *data)
 {
        int dma_ch = host->dma_ch;
        unsigned long data_addr;
-       u16 buf, frame, count;
+       u16 buf, frame;
+       u32 count;
        struct scatterlist *sg = &data->sg[host->sg_idx];
 
        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)
                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_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S16,
                        frame, count, OMAP_DMA_SYNC_FRAME);
@@ -1152,7 +1157,7 @@ static int __init mmc_omap_probe(struct device *dev)
         */
        mmc->max_phys_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;
 
        if (host->power_pin >= 0) {