aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2007-04-12 03:05:25 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-05-01 07:04:15 -0400
commit13cdf48ef15befbd36f8295091b9e0f9bd322963 (patch)
treed1092ee1a8aaad0ee6feaf6e98f441315bc1f18e
parent5897d657b58efb244b1f82a912ee93e5141ed14c (diff)
tifm_sd: implement software scatter-gather
It was found that delays associated with issue and completion of the commands severely limit performance of the new, fast SD cards. To alleviate this issue scatter-gather emulation in software is implemented for both dma and pio transfer modes. Non-block aligned and high memory sg entries are accounted for. Signed-off-by: Alex Dubov <oakad@yahoo.com> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/tifm_sd.c443
-rw-r--r--include/linux/tifm.h1
2 files changed, 297 insertions, 147 deletions
diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c
index d20ccfcd911e..8e69514e415d 100644
--- a/drivers/mmc/tifm_sd.c
+++ b/drivers/mmc/tifm_sd.c
@@ -14,6 +14,7 @@
14#include <linux/mmc/protocol.h> 14#include <linux/mmc/protocol.h>
15#include <linux/mmc/host.h> 15#include <linux/mmc/host.h>
16#include <linux/highmem.h> 16#include <linux/highmem.h>
17#include <linux/scatterlist.h>
17#include <asm/io.h> 18#include <asm/io.h>
18 19
19#define DRIVER_NAME "tifm_sd" 20#define DRIVER_NAME "tifm_sd"
@@ -69,6 +70,8 @@ module_param(fixed_timeout, bool, 0644);
69#define TIFM_MMCSD_CMD_AC 0x2000 70#define TIFM_MMCSD_CMD_AC 0x2000
70#define TIFM_MMCSD_CMD_ADTC 0x3000 71#define TIFM_MMCSD_CMD_ADTC 0x3000
71 72
73#define TIFM_MMCSD_MAX_BLOCK_SIZE 0x0800UL
74
72enum { 75enum {
73 CMD_READY = 0x0001, 76 CMD_READY = 0x0001,
74 FIFO_READY = 0x0002, 77 FIFO_READY = 0x0002,
@@ -95,63 +98,227 @@ struct tifm_sd {
95 struct timer_list timer; 98 struct timer_list timer;
96 struct mmc_request *req; 99 struct mmc_request *req;
97 100
98 size_t written_blocks; 101 int sg_len;
99 size_t buffer_size; 102 int sg_pos;
100 size_t buffer_pos; 103 unsigned int block_pos;
101 104 struct scatterlist bounce_buf;
105 unsigned char bounce_buf_data[TIFM_MMCSD_MAX_BLOCK_SIZE];
102}; 106};
103 107
104static char* tifm_sd_data_buffer(struct mmc_data *data) 108/* for some reason, host won't respond correctly to readw/writew */
109static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg,
110 unsigned int off, unsigned int cnt)
105{ 111{
106 return page_address(data->sg->page) + data->sg->offset; 112 struct tifm_dev *sock = host->dev;
113 unsigned char *buf;
114 unsigned int pos = 0, val;
115
116 buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off;
117 if (host->cmd_flags & DATA_CARRY) {
118 buf[pos++] = host->bounce_buf_data[0];
119 host->cmd_flags &= ~DATA_CARRY;
120 }
121
122 while (pos < cnt) {
123 val = readl(sock->addr + SOCK_MMCSD_DATA);
124 buf[pos++] = val & 0xff;
125 if (pos == cnt) {
126 host->bounce_buf_data[0] = (val >> 8) & 0xff;
127 host->cmd_flags |= DATA_CARRY;
128 break;
129 }
130 buf[pos++] = (val >> 8) & 0xff;
131 }
132 kunmap_atomic(buf - off, KM_BIO_DST_IRQ);
107} 133}
108 134
109static int tifm_sd_transfer_data(struct tifm_dev *sock, struct tifm_sd *host, 135static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
110 unsigned int host_status) 136 unsigned int off, unsigned int cnt)
111{ 137{
112 struct mmc_command *cmd = host->req->cmd; 138 struct tifm_dev *sock = host->dev;
113 unsigned int t_val = 0, cnt = 0; 139 unsigned char *buf;
114 char *buffer; 140 unsigned int pos = 0, val;
115 141
116 if (host_status & TIFM_MMCSD_BRS) { 142 buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off;
117 /* in non-dma rx mode BRS fires when fifo is still not empty */ 143 if (host->cmd_flags & DATA_CARRY) {
118 if (host->no_dma && (cmd->data->flags & MMC_DATA_READ)) { 144 val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00);
119 buffer = tifm_sd_data_buffer(host->req->data); 145 writel(val, sock->addr + SOCK_MMCSD_DATA);
120 while (host->buffer_size > host->buffer_pos) { 146 host->cmd_flags &= ~DATA_CARRY;
121 t_val = readl(sock->addr + SOCK_MMCSD_DATA); 147 }
122 buffer[host->buffer_pos++] = t_val & 0xff; 148
123 buffer[host->buffer_pos++] = 149 while (pos < cnt) {
124 (t_val >> 8) & 0xff; 150 val = buf[pos++];
125 } 151 if (pos == cnt) {
152 host->bounce_buf_data[0] = val & 0xff;
153 host->cmd_flags |= DATA_CARRY;
154 break;
126 } 155 }
127 return 1; 156 val |= (buf[pos++] << 8) & 0xff00;
128 } else if (host->no_dma) { 157 writel(val, sock->addr + SOCK_MMCSD_DATA);
129 buffer = tifm_sd_data_buffer(host->req->data); 158 }
130 if ((cmd->data->flags & MMC_DATA_READ) && 159 kunmap_atomic(buf - off, KM_BIO_SRC_IRQ);
131 (host_status & TIFM_MMCSD_AF)) { 160}
132 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { 161
133 t_val = readl(sock->addr + SOCK_MMCSD_DATA); 162static void tifm_sd_transfer_data(struct tifm_sd *host)
134 if (host->buffer_size > host->buffer_pos) { 163{
135 buffer[host->buffer_pos++] = 164 struct mmc_data *r_data = host->req->cmd->data;
136 t_val & 0xff; 165 struct scatterlist *sg = r_data->sg;
137 buffer[host->buffer_pos++] = 166 unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2;
138 (t_val >> 8) & 0xff; 167 unsigned int p_off, p_cnt;
139 } 168 struct page *pg;
140 } 169
141 } else if ((cmd->data->flags & MMC_DATA_WRITE) 170 if (host->sg_pos == host->sg_len)
142 && (host_status & TIFM_MMCSD_AE)) { 171 return;
143 for (cnt = 0; cnt < TIFM_MMCSD_FIFO_SIZE; cnt++) { 172 while (t_size) {
144 if (host->buffer_size > host->buffer_pos) { 173 cnt = sg[host->sg_pos].length - host->block_pos;
145 t_val = buffer[host->buffer_pos++] 174 if (!cnt) {
146 & 0x00ff; 175 host->block_pos = 0;
147 t_val |= ((buffer[host->buffer_pos++]) 176 host->sg_pos++;
148 << 8) & 0xff00; 177 if (host->sg_pos == host->sg_len) {
149 writel(t_val, 178 if ((r_data->flags & MMC_DATA_WRITE)
150 sock->addr + SOCK_MMCSD_DATA); 179 && DATA_CARRY)
151 } 180 writel(host->bounce_buf_data[0],
181 host->dev->addr
182 + SOCK_MMCSD_DATA);
183
184 return;
152 } 185 }
186 cnt = sg[host->sg_pos].length;
153 } 187 }
188 off = sg[host->sg_pos].offset + host->block_pos;
189
190 pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
191 p_off = offset_in_page(off);
192 p_cnt = PAGE_SIZE - p_off;
193 p_cnt = min(p_cnt, cnt);
194 p_cnt = min(p_cnt, t_size);
195
196 if (r_data->flags & MMC_DATA_READ)
197 tifm_sd_read_fifo(host, pg, p_off, p_cnt);
198 else if (r_data->flags & MMC_DATA_WRITE)
199 tifm_sd_write_fifo(host, pg, p_off, p_cnt);
200
201 t_size -= p_cnt;
202 host->block_pos += p_cnt;
203 }
204}
205
206static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off,
207 struct page *src, unsigned int src_off,
208 unsigned int count)
209{
210 unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off;
211 unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off;
212
213 memcpy(dst_buf, src_buf, count);
214
215 kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ);
216 kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ);
217}
218
219static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
220{
221 struct scatterlist *sg = r_data->sg;
222 unsigned int t_size = r_data->blksz;
223 unsigned int off, cnt;
224 unsigned int p_off, p_cnt;
225 struct page *pg;
226
227 dev_dbg(&host->dev->dev, "bouncing block\n");
228 while (t_size) {
229 cnt = sg[host->sg_pos].length - host->block_pos;
230 if (!cnt) {
231 host->block_pos = 0;
232 host->sg_pos++;
233 if (host->sg_pos == host->sg_len)
234 return;
235 cnt = sg[host->sg_pos].length;
236 }
237 off = sg[host->sg_pos].offset + host->block_pos;
238
239 pg = nth_page(sg[host->sg_pos].page, off >> PAGE_SHIFT);
240 p_off = offset_in_page(off);
241 p_cnt = PAGE_SIZE - p_off;
242 p_cnt = min(p_cnt, cnt);
243 p_cnt = min(p_cnt, t_size);
244
245 if (r_data->flags & MMC_DATA_WRITE)
246 tifm_sd_copy_page(host->bounce_buf.page,
247 r_data->blksz - t_size,
248 pg, p_off, p_cnt);
249 else if (r_data->flags & MMC_DATA_READ)
250 tifm_sd_copy_page(pg, p_off, host->bounce_buf.page,
251 r_data->blksz - t_size, p_cnt);
252
253 t_size -= p_cnt;
254 host->block_pos += p_cnt;
255 }
256}
257
258int tifm_sd_set_dma_data(struct tifm_sd *host, struct mmc_data *r_data)
259{
260 struct tifm_dev *sock = host->dev;
261 unsigned int t_size = TIFM_DMA_TSIZE * r_data->blksz;
262 unsigned int dma_len, dma_blk_cnt, dma_off;
263 struct scatterlist *sg = NULL;
264 unsigned long flags;
265
266 if (host->sg_pos == host->sg_len)
267 return 1;
268
269 if (host->cmd_flags & DATA_CARRY) {
270 host->cmd_flags &= ~DATA_CARRY;
271 local_irq_save(flags);
272 tifm_sd_bounce_block(host, r_data);
273 local_irq_restore(flags);
274 if (host->sg_pos == host->sg_len)
275 return 1;
276 }
277
278 dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos;
279 if (!dma_len) {
280 host->block_pos = 0;
281 host->sg_pos++;
282 if (host->sg_pos == host->sg_len)
283 return 1;
284 dma_len = sg_dma_len(&r_data->sg[host->sg_pos]);
285 }
286
287 if (dma_len < t_size) {
288 dma_blk_cnt = dma_len / r_data->blksz;
289 dma_off = host->block_pos;
290 host->block_pos += dma_blk_cnt * r_data->blksz;
291 } else {
292 dma_blk_cnt = TIFM_DMA_TSIZE;
293 dma_off = host->block_pos;
294 host->block_pos += t_size;
154 } 295 }
296
297 if (dma_blk_cnt)
298 sg = &r_data->sg[host->sg_pos];
299 else if (dma_len) {
300 if (r_data->flags & MMC_DATA_WRITE) {
301 local_irq_save(flags);
302 tifm_sd_bounce_block(host, r_data);
303 local_irq_restore(flags);
304 } else
305 host->cmd_flags |= DATA_CARRY;
306
307 sg = &host->bounce_buf;
308 dma_off = 0;
309 dma_blk_cnt = 1;
310 } else
311 return 1;
312
313 dev_dbg(&sock->dev, "setting dma for %d blocks\n", dma_blk_cnt);
314 writel(sg_dma_address(sg) + dma_off, sock->addr + SOCK_DMA_ADDRESS);
315 if (r_data->flags & MMC_DATA_WRITE)
316 writel((dma_blk_cnt << 8) | TIFM_DMA_TX | TIFM_DMA_EN,
317 sock->addr + SOCK_DMA_CONTROL);
318 else
319 writel((dma_blk_cnt << 8) | TIFM_DMA_EN,
320 sock->addr + SOCK_DMA_CONTROL);
321
155 return 0; 322 return 0;
156} 323}
157 324
@@ -317,8 +484,10 @@ static void tifm_sd_data_event(struct tifm_dev *sock)
317 r_data = host->req->cmd->data; 484 r_data = host->req->cmd->data;
318 485
319 if (r_data && (fifo_status & TIFM_FIFO_READY)) { 486 if (r_data && (fifo_status & TIFM_FIFO_READY)) {
320 host->cmd_flags |= FIFO_READY; 487 if (tifm_sd_set_dma_data(host, r_data)) {
321 tifm_sd_check_status(host); 488 host->cmd_flags |= FIFO_READY;
489 tifm_sd_check_status(host);
490 }
322 } 491 }
323 } 492 }
324 493
@@ -398,7 +567,7 @@ static void tifm_sd_card_event(struct tifm_dev *sock)
398 if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF 567 if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF
399 | TIFM_MMCSD_BRS)) { 568 | TIFM_MMCSD_BRS)) {
400 local_irq_save(flags); 569 local_irq_save(flags);
401 tifm_sd_transfer_data(sock, host, host_status); 570 tifm_sd_transfer_data(host);
402 local_irq_restore(flags); 571 local_irq_restore(flags);
403 host_status &= ~TIFM_MMCSD_AE; 572 host_status &= ~TIFM_MMCSD_AE;
404 } 573 }
@@ -416,38 +585,6 @@ done:
416 spin_unlock(&sock->lock); 585 spin_unlock(&sock->lock);
417} 586}
418 587
419static void tifm_sd_prepare_data(struct tifm_sd *host, struct mmc_command *cmd)
420{
421 struct tifm_dev *sock = host->dev;
422 unsigned int dest_cnt;
423
424 /* DMA style IO */
425 dev_dbg(&sock->dev, "setting dma for %d blocks\n",
426 cmd->data->blocks);
427 writel(TIFM_FIFO_INT_SETALL,
428 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
429 writel(ilog2(cmd->data->blksz) - 2,
430 sock->addr + SOCK_FIFO_PAGE_SIZE);
431 writel(TIFM_FIFO_ENABLE, sock->addr + SOCK_FIFO_CONTROL);
432 writel(TIFM_FIFO_INTMASK, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
433
434 dest_cnt = (cmd->data->blocks) << 8;
435
436 writel(sg_dma_address(cmd->data->sg), sock->addr + SOCK_DMA_ADDRESS);
437
438 writel(cmd->data->blocks - 1, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
439 writel(cmd->data->blksz - 1, sock->addr + SOCK_MMCSD_BLOCK_LEN);
440
441 if (cmd->data->flags & MMC_DATA_WRITE) {
442 writel(TIFM_MMCSD_TXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
443 writel(dest_cnt | TIFM_DMA_TX | TIFM_DMA_EN,
444 sock->addr + SOCK_DMA_CONTROL);
445 } else {
446 writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
447 writel(dest_cnt | TIFM_DMA_EN, sock->addr + SOCK_DMA_CONTROL);
448 }
449}
450
451static void tifm_sd_set_data_timeout(struct tifm_sd *host, 588static void tifm_sd_set_data_timeout(struct tifm_sd *host,
452 struct mmc_data *data) 589 struct mmc_data *data)
453{ 590{
@@ -481,7 +618,6 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
481 struct tifm_sd *host = mmc_priv(mmc); 618 struct tifm_sd *host = mmc_priv(mmc);
482 struct tifm_dev *sock = host->dev; 619 struct tifm_dev *sock = host->dev;
483 unsigned long flags; 620 unsigned long flags;
484 int sg_count = 0;
485 struct mmc_data *r_data = mrq->cmd->data; 621 struct mmc_data *r_data = mrq->cmd->data;
486 622
487 spin_lock_irqsave(&sock->lock, flags); 623 spin_lock_irqsave(&sock->lock, flags);
@@ -496,13 +632,19 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
496 goto err_out; 632 goto err_out;
497 } 633 }
498 634
635 host->cmd_flags = 0;
636 host->block_pos = 0;
637 host->sg_pos = 0;
638
499 if (r_data) { 639 if (r_data) {
500 tifm_sd_set_data_timeout(host, r_data); 640 tifm_sd_set_data_timeout(host, r_data);
501 641
502 if (host->no_dma) { 642 if ((r_data->flags & MMC_DATA_WRITE) && !mrq->stop)
503 host->buffer_size = mrq->cmd->data->blocks 643 writel(TIFM_MMCSD_EOFB
504 * mrq->cmd->data->blksz; 644 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
645 sock->addr + SOCK_MMCSD_INT_ENABLE);
505 646
647 if (host->no_dma) {
506 writel(TIFM_MMCSD_BUFINT 648 writel(TIFM_MMCSD_BUFINT
507 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE), 649 | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
508 sock->addr + SOCK_MMCSD_INT_ENABLE); 650 sock->addr + SOCK_MMCSD_INT_ENABLE);
@@ -510,34 +652,64 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
510 | (TIFM_MMCSD_FIFO_SIZE - 1), 652 | (TIFM_MMCSD_FIFO_SIZE - 1),
511 sock->addr + SOCK_MMCSD_BUFFER_CONFIG); 653 sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
512 654
513 host->written_blocks = 0; 655 host->sg_len = r_data->sg_len;
514 host->cmd_flags &= ~CARD_BUSY;
515 host->buffer_pos = 0;
516 writel(r_data->blocks - 1,
517 sock->addr + SOCK_MMCSD_NUM_BLOCKS);
518 writel(r_data->blksz - 1,
519 sock->addr + SOCK_MMCSD_BLOCK_LEN);
520 } else { 656 } else {
521 sg_count = tifm_map_sg(sock, r_data->sg, r_data->sg_len, 657 sg_init_one(&host->bounce_buf, host->bounce_buf_data,
522 mrq->cmd->flags & MMC_DATA_WRITE 658 r_data->blksz);
523 ? PCI_DMA_TODEVICE 659
524 : PCI_DMA_FROMDEVICE); 660 if(1 != tifm_map_sg(sock, &host->bounce_buf, 1,
525 if (sg_count != 1) { 661 r_data->flags & MMC_DATA_WRITE
526 printk(KERN_ERR DRIVER_NAME 662 ? PCI_DMA_TODEVICE
527 ": scatterlist map failed\n"); 663 : PCI_DMA_FROMDEVICE)) {
664 printk(KERN_ERR "%s : scatterlist map failed\n",
665 sock->dev.bus_id);
666 spin_unlock_irqrestore(&sock->lock, flags);
667 goto err_out;
668 }
669 host->sg_len = tifm_map_sg(sock, r_data->sg,
670 r_data->sg_len,
671 r_data->flags
672 & MMC_DATA_WRITE
673 ? PCI_DMA_TODEVICE
674 : PCI_DMA_FROMDEVICE);
675 if (host->sg_len < 1) {
676 printk(KERN_ERR "%s : scatterlist map failed\n",
677 sock->dev.bus_id);
678 tifm_unmap_sg(sock, &host->bounce_buf, 1,
679 r_data->flags & MMC_DATA_WRITE
680 ? PCI_DMA_TODEVICE
681 : PCI_DMA_FROMDEVICE);
528 spin_unlock_irqrestore(&sock->lock, flags); 682 spin_unlock_irqrestore(&sock->lock, flags);
529 goto err_out; 683 goto err_out;
530 } 684 }
531 685
532 host->written_blocks = 0; 686 writel(TIFM_FIFO_INT_SETALL,
533 host->cmd_flags &= ~CARD_BUSY; 687 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
534 tifm_sd_prepare_data(host, mrq->cmd); 688 writel(ilog2(r_data->blksz) - 2,
689 sock->addr + SOCK_FIFO_PAGE_SIZE);
690 writel(TIFM_FIFO_ENABLE,
691 sock->addr + SOCK_FIFO_CONTROL);
692 writel(TIFM_FIFO_INTMASK,
693 sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
694
695 if (r_data->flags & MMC_DATA_WRITE)
696 writel(TIFM_MMCSD_TXDE,
697 sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
698 else
699 writel(TIFM_MMCSD_RXDE,
700 sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
701
702 tifm_sd_set_dma_data(host, r_data);
535 } 703 }
704
705 writel(r_data->blocks - 1,
706 sock->addr + SOCK_MMCSD_NUM_BLOCKS);
707 writel(r_data->blksz - 1,
708 sock->addr + SOCK_MMCSD_BLOCK_LEN);
536 } 709 }
537 710
538 host->req = mrq; 711 host->req = mrq;
539 mod_timer(&host->timer, jiffies + host->timeout_jiffies); 712 mod_timer(&host->timer, jiffies + host->timeout_jiffies);
540 host->cmd_flags = 0;
541 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL), 713 writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
542 sock->addr + SOCK_CONTROL); 714 sock->addr + SOCK_CONTROL);
543 tifm_sd_exec(host, mrq->cmd); 715 tifm_sd_exec(host, mrq->cmd);
@@ -545,11 +717,6 @@ static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
545 return; 717 return;
546 718
547err_out: 719err_out:
548 if (sg_count > 0)
549 tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
550 (r_data->flags & MMC_DATA_WRITE)
551 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
552
553 mrq->cmd->error = MMC_ERR_TIMEOUT; 720 mrq->cmd->error = MMC_ERR_TIMEOUT;
554 mmc_request_done(mmc, mrq); 721 mmc_request_done(mmc, mrq);
555} 722}
@@ -578,40 +745,23 @@ static void tifm_sd_end_cmd(unsigned long data)
578 r_data = mrq->cmd->data; 745 r_data = mrq->cmd->data;
579 if (r_data) { 746 if (r_data) {
580 if (host->no_dma) { 747 if (host->no_dma) {
581 writel((~TIFM_MMCSD_BUFINT) & 748 writel((~TIFM_MMCSD_BUFINT)
582 readl(sock->addr + SOCK_MMCSD_INT_ENABLE), 749 & readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
583 sock->addr + SOCK_MMCSD_INT_ENABLE); 750 sock->addr + SOCK_MMCSD_INT_ENABLE);
584
585 if (r_data->flags & MMC_DATA_WRITE) {
586 r_data->bytes_xfered = host->written_blocks
587 * r_data->blksz;
588 } else {
589 r_data->bytes_xfered = r_data->blocks -
590 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS)
591 - 1;
592 r_data->bytes_xfered *= r_data->blksz;
593 r_data->bytes_xfered += r_data->blksz
594 - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN)
595 + 1;
596 }
597 host->buffer_pos = 0;
598 host->buffer_size = 0;
599 } else { 751 } else {
600 if (r_data->flags & MMC_DATA_WRITE) { 752 tifm_unmap_sg(sock, &host->bounce_buf, 1,
601 r_data->bytes_xfered = host->written_blocks 753 (r_data->flags & MMC_DATA_WRITE)
602 * r_data->blksz; 754 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
603 } else {
604 r_data->bytes_xfered = r_data->blocks -
605 readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
606 r_data->bytes_xfered *= r_data->blksz;
607 r_data->bytes_xfered += r_data->blksz -
608 readl(sock->addr + SOCK_MMCSD_BLOCK_LEN)
609 + 1;
610 }
611 tifm_unmap_sg(sock, r_data->sg, r_data->sg_len, 755 tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
612 (r_data->flags & MMC_DATA_WRITE) 756 (r_data->flags & MMC_DATA_WRITE)
613 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); 757 ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
614 } 758 }
759
760 r_data->bytes_xfered = r_data->blocks
761 - readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
762 r_data->bytes_xfered *= r_data->blksz;
763 r_data->bytes_xfered += r_data->blksz
764 - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
615 } 765 }
616 766
617 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL), 767 writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
@@ -810,15 +960,14 @@ static int tifm_sd_probe(struct tifm_dev *sock)
810 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE; 960 mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
811 mmc->f_min = 20000000 / 60; 961 mmc->f_min = 20000000 / 60;
812 mmc->f_max = 24000000; 962 mmc->f_max = 24000000;
813 mmc->max_hw_segs = 1; 963
814 mmc->max_phys_segs = 1; 964 mmc->max_blk_count = 2048;
815 // limited by DMA counter - it's safer to stick with 965 mmc->max_hw_segs = mmc->max_blk_count;
816 // block counter has 11 bits though 966 mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE);
817 mmc->max_blk_count = 256; 967 mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
818 // 2k maximum hw block length 968 mmc->max_req_size = mmc->max_seg_size;
819 mmc->max_blk_size = 2048; 969 mmc->max_phys_segs = mmc->max_hw_segs;
820 mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; 970
821 mmc->max_seg_size = mmc->max_req_size;
822 sock->card_event = tifm_sd_card_event; 971 sock->card_event = tifm_sd_card_event;
823 sock->data_event = tifm_sd_data_event; 972 sock->data_event = tifm_sd_data_event;
824 rc = tifm_sd_initialize_host(host); 973 rc = tifm_sd_initialize_host(host);
diff --git a/include/linux/tifm.h b/include/linux/tifm.h
index c8449fcea0c7..7ccad0795466 100644
--- a/include/linux/tifm.h
+++ b/include/linux/tifm.h
@@ -74,6 +74,7 @@ enum {
74#define TIFM_DMA_RESET 0x00000002 /* Meaning of this constant is unverified */ 74#define TIFM_DMA_RESET 0x00000002 /* Meaning of this constant is unverified */
75#define TIFM_DMA_TX 0x00008000 /* Meaning of this constant is unverified */ 75#define TIFM_DMA_TX 0x00008000 /* Meaning of this constant is unverified */
76#define TIFM_DMA_EN 0x00000001 /* Meaning of this constant is unverified */ 76#define TIFM_DMA_EN 0x00000001 /* Meaning of this constant is unverified */
77#define TIFM_DMA_TSIZE 0x0000007f
77 78
78#define TIFM_TYPE_XD 1 79#define TIFM_TYPE_XD 1
79#define TIFM_TYPE_MS 2 80#define TIFM_TYPE_MS 2