do {
unsigned long flags;
+ unsigned int bio_remain;
char *buffer;
/*
/*
* Map the BIO buffer.
*/
- buffer = bio_kmap_irq(req->bio, &flags);
+ buffer = bio_kmap_irq(req->cbio, &flags);
+ bio_remain = (req->current_nr_sectors << 9) - host->offset;
do {
int count = host->size - (readl(base + MMCIFIFOCNT) << 2);
+ if (count > bio_remain)
+ count = bio_remain;
+
if (count > 0) {
ret = 1;
readsl(base + MMCIFIFO, buffer + host->offset, count >> 2);
host->offset += count;
host->size -= count;
+ bio_remain -= count;
+ if (bio_remain == 0)
+ goto next_bio;
}
status = readl(base + MMCISTATUS);
- } while (status & MCI_RXDATAAVLBL && host->size);
+ } while (status & MCI_RXDATAAVLBL);
bio_kunmap_irq(buffer, &flags);
break;
+
+ next_bio:
+ bio_kunmap_irq(buffer, &flags);
+
+ /*
+ * Ok, we've completed that BIO, move on to next
+ * BIO in the chain. Note: this doesn't actually
+ * complete the BIO!
+ */
+ if (!process_that_request_first(req, req->current_nr_sectors))
+ break;
+
+ host->offset = 0;
+ status = readl(base + MMCISTATUS);
} while (1);
return ret;
do {
unsigned long flags;
+ unsigned int bio_remain;
char *buffer;
/*
/*
* Map the BIO buffer.
*/
- buffer = bio_kmap_irq(req->bio, &flags);
+ buffer = bio_kmap_irq(req->cbio, &flags);
+ bio_remain = (req->current_nr_sectors << 9) - host->offset;
do {
unsigned int count, maxcnt;
maxcnt = status & MCI_TXFIFOEMPTY ?
MCI_FIFOSIZE : MCI_FIFOHALFSIZE;
- count = min(host->size, maxcnt);
+ count = min(bio_remain, maxcnt);
writesl(base + MMCIFIFO, buffer + host->offset, count >> 2);
host->offset += count;
host->size -= count;
+ bio_remain -= count;
ret = 1;
+ if (bio_remain == 0)
+ goto next_bio;
+
status = readl(base + MMCISTATUS);
- } while (status & MCI_TXFIFOHALFEMPTY && host->size);
+ } while (status & MCI_TXFIFOHALFEMPTY);
bio_kunmap_irq(buffer, &flags);
break;
+
+ next_bio:
+ bio_kunmap_irq(buffer, &flags);
+
+ /*
+ * Ok, we've completed that BIO, move on to next
+ * BIO in the chain. Note: this doesn't actually
+ * complete the BIO!
+ */
+ if (!process_that_request_first(req, req->current_nr_sectors))
+ break;
+
+ host->offset = 0;
+ status = readl(base + MMCISTATUS);
} while (1);
return ret;
mmc->f_max = min(host->mclk, fmax);
mmc->ocr_avail = plat->ocr_mask;
+ /*
+ * We can do SGIO
+ */
+ mmc->max_hw_segs = 16;
+ mmc->max_phys_segs = 16;
+
+ /*
+ * Since we only have a 16-bit data length register, we must
+ * ensure that we don't exceed 2^16-1 bytes in a single request.
+ * Choose 64 (512-byte) sectors as the limit.
+ */
+ mmc->max_sectors = 64;
+
+ /*
+ * Set the maximum segment size. Since we aren't doing DMA
+ * (yet) we are only limited by the data length register.
+ */
+ mmc->max_seg_size = mmc->max_sectors << 9;
+
spin_lock_init(&host->lock);
writel(0, host->base + MMCIMASK0);