]> www.infradead.org Git - users/willy/linux.git/commitdiff
mmc: wbsd: handle highmem pages
authorChristoph Hellwig <hch@lst.de>
Fri, 18 May 2018 17:18:46 +0000 (19:18 +0200)
committerUlf Hansson <ulf.hansson@linaro.org>
Mon, 21 May 2018 13:49:21 +0000 (15:49 +0200)
Use sg_copy_{from,to}_buffer to bounce buffer and kmap_atomic to map the
scatterlist entry before using it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
drivers/mmc/host/wbsd.c

index f4233576153bf40f0543435d248ea2c6fbe537fe..1e54bbf13d75bb68bc8383655842353a74e8803b 100644 (file)
@@ -268,43 +268,29 @@ static inline int wbsd_next_sg(struct wbsd_host *host)
        return host->num_sg;
 }
 
-static inline char *wbsd_sg_to_buffer(struct wbsd_host *host)
+static inline char *wbsd_map_sg(struct wbsd_host *host)
 {
-       return sg_virt(host->cur_sg);
+       return kmap_atomic(sg_page(host->cur_sg)) + host->cur_sg->offset;
 }
 
 static inline void wbsd_sg_to_dma(struct wbsd_host *host, struct mmc_data *data)
 {
-       unsigned int len, i;
-       struct scatterlist *sg;
-       char *dmabuf = host->dma_buffer;
-       char *sgbuf;
-
-       sg = data->sg;
-       len = data->sg_len;
-
-       for (i = 0; i < len; i++) {
-               sgbuf = sg_virt(&sg[i]);
-               memcpy(dmabuf, sgbuf, sg[i].length);
-               dmabuf += sg[i].length;
-       }
+       size_t len = 0;
+       int i;
+
+       for (i = 0; i < data->sg_len; i++)
+               len += data->sg[i].length;
+       sg_copy_to_buffer(data->sg, data->sg_len, host->dma_buffer, len);
 }
 
 static inline void wbsd_dma_to_sg(struct wbsd_host *host, struct mmc_data *data)
 {
-       unsigned int len, i;
-       struct scatterlist *sg;
-       char *dmabuf = host->dma_buffer;
-       char *sgbuf;
-
-       sg = data->sg;
-       len = data->sg_len;
-
-       for (i = 0; i < len; i++) {
-               sgbuf = sg_virt(&sg[i]);
-               memcpy(sgbuf, dmabuf, sg[i].length);
-               dmabuf += sg[i].length;
-       }
+       size_t len = 0;
+       int i;
+
+       for (i = 0; i < data->sg_len; i++)
+               len += data->sg[i].length;
+       sg_copy_from_buffer(data->sg, data->sg_len, host->dma_buffer, len);
 }
 
 /*
@@ -418,7 +404,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
 {
        struct mmc_data *data = host->mrq->cmd->data;
        char *buffer;
-       int i, fsr, fifo;
+       int i, idx, fsr, fifo;
 
        /*
         * Handle excessive data.
@@ -426,7 +412,8 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
        if (host->num_sg == 0)
                return;
 
-       buffer = wbsd_sg_to_buffer(host) + host->offset;
+       buffer = wbsd_map_sg(host) + host->offset;
+       idx = 0;
 
        /*
         * Drain the fifo. This has a tendency to loop longer
@@ -445,8 +432,7 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
                        fifo = 1;
 
                for (i = 0; i < fifo; i++) {
-                       *buffer = inb(host->base + WBSD_DFR);
-                       buffer++;
+                       buffer[idx++] = inb(host->base + WBSD_DFR);
                        host->offset++;
                        host->remain--;
 
@@ -456,16 +442,19 @@ static void wbsd_empty_fifo(struct wbsd_host *host)
                         * End of scatter list entry?
                         */
                        if (host->remain == 0) {
+                               kunmap_atomic(buffer);
                                /*
                                 * Get next entry. Check if last.
                                 */
                                if (!wbsd_next_sg(host))
                                        return;
 
-                               buffer = wbsd_sg_to_buffer(host);
+                               buffer = wbsd_map_sg(host);
+                               idx = 0;
                        }
                }
        }
+       kunmap_atomic(buffer);
 
        /*
         * This is a very dirty hack to solve a
@@ -480,7 +469,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
 {
        struct mmc_data *data = host->mrq->cmd->data;
        char *buffer;
-       int i, fsr, fifo;
+       int i, idx, fsr, fifo;
 
        /*
         * Check that we aren't being called after the
@@ -489,7 +478,8 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
        if (host->num_sg == 0)
                return;
 
-       buffer = wbsd_sg_to_buffer(host) + host->offset;
+       buffer = wbsd_map_sg(host) + host->offset;
+       idx = 0;
 
        /*
         * Fill the fifo. This has a tendency to loop longer
@@ -508,8 +498,7 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
                        fifo = 15;
 
                for (i = 16; i > fifo; i--) {
-                       outb(*buffer, host->base + WBSD_DFR);
-                       buffer++;
+                       outb(buffer[idx], host->base + WBSD_DFR);
                        host->offset++;
                        host->remain--;
 
@@ -519,16 +508,19 @@ static void wbsd_fill_fifo(struct wbsd_host *host)
                         * End of scatter list entry?
                         */
                        if (host->remain == 0) {
+                               kunmap_atomic(buffer);
                                /*
                                 * Get next entry. Check if last.
                                 */
                                if (!wbsd_next_sg(host))
                                        return;
 
-                               buffer = wbsd_sg_to_buffer(host);
+                               buffer = wbsd_map_sg(host);
+                               idx = 0;
                        }
                }
        }
+       kunmap_atomic(buffer);
 
        /*
         * The controller stops sending interrupts for