V4L/DVB (5252): Qt1010: use ARRAY_SIZE macro when appropriate
[safe/jmp/linux-2.6] / drivers / mmc / wbsd.c
index 39b3d97..05ccfc4 100644 (file)
@@ -1,11 +1,12 @@
 /*
  *  linux/drivers/mmc/wbsd.c - Winbond W83L51xD SD/MMC driver
  *
- *  Copyright (C) 2004-2005 Pierre Ossman, All Rights Reserved.
+ *  Copyright (C) 2004-2006 Pierre Ossman, All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
  *
  *
  * Warning!
@@ -21,7 +22,6 @@
  * - On APIC systems the FIFO empty interrupt is sometimes lost.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -42,7 +42,6 @@
 #include "wbsd.h"
 
 #define DRIVER_NAME "wbsd"
-#define DRIVER_VERSION "1.5"
 
 #define DBG(x...) \
        pr_debug(DRIVER_NAME ": " x)
@@ -272,16 +271,9 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
        return host->num_sg;
 }
 
-static inline char *wbsd_kmap_sg(struct wbsd_host *host)
+static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
 {
-       host->mapped_sg = kmap_atomic(host->cur_sg->page, KM_BIO_SRC_IRQ) +
-               host->cur_sg->offset;
-       return host->mapped_sg;
-}
-
-static inline void wbsd_kunmap_sg(struct wbsd_host *host)
-{
-       kunmap_atomic(host->mapped_sg, KM_BIO_SRC_IRQ);
+       return page_address(host->cur_sg->page) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
@@ -302,12 +294,11 @@ static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
         * we do not transfer too much.
         */
        for (i = 0; i < len; i++) {
-               sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
+               sgbuf = page_address(sg[i].page) + sg[i].offset;
                if (size < sg[i].length)
                        memcpy(dmabuf, sgbuf, size);
                else
                        memcpy(dmabuf, sgbuf, sg[i].length);
-               kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
                dmabuf += sg[i].length;
 
                if (size < sg[i].length)
@@ -347,12 +338,11 @@ static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
         * we do not transfer too much.
         */
        for (i = 0; i < len; i++) {
-               sgbuf = kmap_atomic(sg[i].page, KM_BIO_SRC_IRQ) + sg[i].offset;
+               sgbuf = page_address(sg[i].page) + sg[i].offset;
                if (size < sg[i].length)
                        memcpy(sgbuf, dmabuf, size);
                else
                        memcpy(sgbuf, dmabuf, sg[i].length);
-               kunmap_atomic(sgbuf, KM_BIO_SRC_IRQ);
                dmabuf += sg[i].length;
 
                if (size < sg[i].length)
@@ -497,7 +487,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
        if (data->bytes_xfered == host->size)
                return;
 
-       buffer = wbsd_kmap_sg(host) + host->offset;
+       buffer = wbsd_sg_to_buffer(host) + host->offset;
 
        /*
         * Drain the fifo. This has a tendency to loop longer
@@ -526,17 +516,13 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
                        /*
                         * Transfer done?
                         */
-                       if (data->bytes_xfered == host->size) {
-                               wbsd_kunmap_sg(host);
+                       if (data->bytes_xfered == host->size)
                                return;
-                       }
 
                        /*
                         * End of scatter list entry?
                         */
                        if (host->remain == 0) {
-                               wbsd_kunmap_sg(host);
-
                                /*
                                 * Get next entry. Check if last.
                                 */
@@ -554,13 +540,11 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
                                        return;
                                }
 
-                               buffer = wbsd_kmap_sg(host);
+                               buffer = wbsd_sg_to_buffer(host);
                        }
                }
        }
 
-       wbsd_kunmap_sg(host);
-
        /*
         * This is a very dirty hack to solve a
         * hardware problem. The chip doesn't trigger
@@ -583,7 +567,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
        if (data->bytes_xfered == host->size)
                return;
 
-       buffer = wbsd_kmap_sg(host) + host->offset;
+       buffer = wbsd_sg_to_buffer(host) + host->offset;
 
        /*
         * Fill the fifo. This has a tendency to loop longer
@@ -612,17 +596,13 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
                        /*
                         * Transfer done?
                         */
-                       if (data->bytes_xfered == host->size) {
-                               wbsd_kunmap_sg(host);
+                       if (data->bytes_xfered == host->size)
                                return;
-                       }
 
                        /*
                         * End of scatter list entry?
                         */
                        if (host->remain == 0) {
-                               wbsd_kunmap_sg(host);
-
                                /*
                                 * Get next entry. Check if last.
                                 */
@@ -640,13 +620,11 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
                                        return;
                                }
 
-                               buffer = wbsd_kmap_sg(host);
+                               buffer = wbsd_sg_to_buffer(host);
                        }
                }
        }
 
-       wbsd_kunmap_sg(host);
-
        /*
         * The controller stops sending interrupts for
         * 'FIFO empty' under certain conditions. So we
@@ -662,14 +640,14 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
        unsigned long dmaflags;
 
        DBGF("blksz %04x blks %04x flags %08x\n",
-               1 << data->blksz_bits, data->blocks, data->flags);
+               data->blksz, data->blocks, data->flags);
        DBGF("tsac %d ms nsac %d clk\n",
                data->timeout_ns / 1000000, data->timeout_clks);
 
        /*
         * Calculate size.
         */
-       host->size = data->blocks << data->blksz_bits;
+       host->size = data->blocks * data->blksz;
 
        /*
         * Check timeout values for overflow.
@@ -696,12 +674,12 @@ static void wbsd_prepare_data(struct wbsd_host *host, struct mmc_data *data)
         * Two bytes are needed for each data line.
         */
        if (host->bus_width == MMC_BUS_WIDTH_1) {
-               blksize = (1 << data->blksz_bits) + 2;
+               blksize = data->blksz + 2;
 
                wbsd_write_index(host, WBSD_IDX_PBSMSB, (blksize >> 4) & 0xF0);
                wbsd_write_index(host, WBSD_IDX_PBSLSB, blksize & 0xFF);
        } else if (host->bus_width == MMC_BUS_WIDTH_4) {
-               blksize = (1 << data->blksz_bits) + 2 * 4;
+               blksize = data->blksz + 2 * 4;
 
                wbsd_write_index(host, WBSD_IDX_PBSMSB,
                        ((blksize >> 4) & 0xF0) | WBSD_DATA_WIDTH);
@@ -910,6 +888,45 @@ static void wbsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
         */
        if (cmd->data && (cmd->error == MMC_ERR_NONE)) {
                /*
+                * The hardware is so delightfully stupid that it has a list
+                * of "data" commands. If a command isn't on this list, it'll
+                * just go back to the idle state and won't send any data
+                * interrupts.
+                */
+               switch (cmd->opcode) {
+               case 11:
+               case 17:
+               case 18:
+               case 20:
+               case 24:
+               case 25:
+               case 26:
+               case 27:
+               case 30:
+               case 42:
+               case 56:
+                       break;
+
+               /* ACMDs. We don't keep track of state, so we just treat them
+                * like any other command. */
+               case 51:
+                       break;
+
+               default:
+#ifdef CONFIG_MMC_DEBUG
+                       printk(KERN_WARNING "%s: Data command %d is not "
+                               "supported by this controller.\n",
+                               mmc_hostname(host->mmc), cmd->opcode);
+#endif
+                       cmd->data->error = MMC_ERR_INVALID;
+
+                       if (cmd->data->stop)
+                               wbsd_send_command(host, cmd->data->stop);
+
+                       goto done;
+               };
+
+               /*
                 * Dirty fix for hardware bug.
                 */
                if (host->dma == -1)
@@ -1021,7 +1038,7 @@ static int wbsd_get_ro(struct mmc_host *mmc)
        return csr & WBSD_WRPT;
 }
 
-static struct mmc_host_ops wbsd_ops = {
+static const struct mmc_host_ops wbsd_ops = {
        .request        = wbsd_request,
        .set_ios        = wbsd_set_ios,
        .get_ro         = wbsd_get_ro,
@@ -1256,7 +1273,7 @@ end:
  * Interrupt handling
  */
 
-static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t wbsd_irq(int irq, void *dev_id)
 {
        struct wbsd_host *host = dev_id;
        int isr;
@@ -1324,7 +1341,7 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
        mmc->f_min = 375000;
        mmc->f_max = 24000000;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-       mmc->caps = MMC_CAP_4_BIT_DATA;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE | MMC_CAP_BYTEBLOCK;
 
        spin_lock_init(&host->lock);
 
@@ -1343,16 +1360,27 @@ static int __devinit wbsd_alloc_mmc(struct device *dev)
        mmc->max_phys_segs = 128;
 
        /*
-        * Maximum number of sectors in one transfer. Also limited by 64kB
-        * buffer.
+        * Maximum request size. Also limited by 64KiB buffer.
         */
-       mmc->max_sectors = 128;
+       mmc->max_req_size = 65536;
 
        /*
         * Maximum segment size. Could be one segment with the maximum number
-        * of segments.
+        * of bytes.
+        */
+       mmc->max_seg_size = mmc->max_req_size;
+
+       /*
+        * Maximum block size. We have 12 bits (= 4095) but have to subtract
+        * space for CRC. So the maximum is 4095 - 4*2 = 4087.
+        */
+       mmc->max_blk_size = 4087;
+
+       /*
+        * Maximum block count. There is no real limit so the maximum
+        * request size will be the only restriction.
         */
-       mmc->max_seg_size = mmc->max_sectors * 512;
+       mmc->max_blk_count = mmc->max_req_size;
 
        dev_set_drvdata(dev, mmc);
 
@@ -1440,13 +1468,13 @@ static int __devinit wbsd_scan(struct wbsd_host *host)
 
 static int __devinit wbsd_request_region(struct wbsd_host *host, int base)
 {
-       if (io & 0x7)
+       if (base & 0x7)
                return -EINVAL;
 
        if (!request_region(base, 8, DRIVER_NAME))
                return -EIO;
 
-       host->base = io;
+       host->base = base;
 
        return 0;
 }
@@ -1488,7 +1516,7 @@ static void __devinit wbsd_request_dma(struct wbsd_host *host, int dma)
        /*
         * Translate the address to a physical address.
         */
-       host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer,
+       host->dma_addr = dma_map_single(mmc_dev(host->mmc), host->dma_buffer,
                WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
 
        /*
@@ -1512,7 +1540,7 @@ kfree:
         */
        BUG_ON(1);
 
-       dma_unmap_single(host->mmc->dev, host->dma_addr,
+       dma_unmap_single(mmc_dev(host->mmc), host->dma_addr,
                WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
        host->dma_addr = (dma_addr_t)NULL;
 
@@ -1530,7 +1558,7 @@ err:
 static void __devexit wbsd_release_dma(struct wbsd_host *host)
 {
        if (host->dma_addr) {
-               dma_unmap_single(host->mmc->dev, host->dma_addr,
+               dma_unmap_single(mmc_dev(host->mmc), host->dma_addr,
                        WBSD_DMA_SIZE, DMA_BIDIRECTIONAL);
        }
        kfree(host->dma_buffer);
@@ -1554,7 +1582,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq)
         * Allocate interrupt.
         */
 
-       ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host);
+       ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host);
        if (ret)
                return ret;
 
@@ -1774,7 +1802,7 @@ static int __devinit wbsd_init(struct device *dev, int base, int irq, int dma,
        /*
         * Request resources.
         */
-       ret = wbsd_request_resources(host, io, irq, dma);
+       ret = wbsd_request_resources(host, base, irq, dma);
        if (ret) {
                wbsd_release_resources(host);
                wbsd_free_mmc(dev);
@@ -1862,6 +1890,7 @@ static void __devexit wbsd_shutdown(struct device *dev, int pnp)
 
 static int __devinit wbsd_probe(struct platform_device *dev)
 {
+       /* Use the module parameters for resources */
        return wbsd_init(&dev->dev, io, irq, dma, 0);
 }
 
@@ -2070,8 +2099,7 @@ static int __init wbsd_drv_init(void)
        int result;
 
        printk(KERN_INFO DRIVER_NAME
-               ": Winbond W83L51xD SD/MMC card interface driver, "
-               DRIVER_VERSION "\n");
+               ": Winbond W83L51xD SD/MMC card interface driver\n");
        printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n");
 
 #ifdef CONFIG_PNP
@@ -2135,7 +2163,6 @@ module_param(dma, int, 0444);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Pierre Ossman <drzeus@drzeus.cx>");
 MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver");
-MODULE_VERSION(DRIVER_VERSION);
 
 #ifdef CONFIG_PNP
 MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)");