diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-10-22 16:35:23 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-10-22 16:49:48 +0200 |
commit | ed78b8dbbc13eb70aa80dedee146edf2cb567c5b (patch) | |
tree | d79a98f6a8ef2207133c811944834b91f3dc5b1c /drivers/mci/mci-core.c | |
parent | cf9b0c6927126a4f6e520a242378b5166aaa87a4 (diff) | |
download | barebox-ed78b8dbbc13eb70aa80dedee146edf2cb567c5b.tar.gz barebox-ed78b8dbbc13eb70aa80dedee146edf2cb567c5b.tar.xz |
mci: add max_req_size support
Some controller such as the ARM AMBA pl181 can not handle more than 16bits
data length request.
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mci/mci-core.c')
-rw-r--r-- | drivers/mci/mci-core.c | 38 |
1 files changed, 30 insertions, 8 deletions
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c index 66ddb5b4ff..cfae91b2ea 100644 --- a/drivers/mci/mci-core.c +++ b/drivers/mci/mci-core.c @@ -1199,6 +1199,11 @@ static int __maybe_unused mci_sd_write(struct block_device *blk, struct mci *mci = part->mci; struct mci_host *host = mci->host; int rc; + unsigned max_req_block = num_blocks; + int write_block; + + if (mci->host->max_req_size) + max_req_block = mci->host->max_req_size / mci->write_bl_len; mci_blk_part_switch(part); @@ -1222,10 +1227,16 @@ static int __maybe_unused mci_sd_write(struct block_device *blk, return -EINVAL; } - rc = mci_block_write(mci, buffer, block, num_blocks); - if (rc != 0) { - dev_dbg(&mci->dev, "Writing block %d failed with %d\n", block, rc); - return rc; + while (num_blocks) { + write_block = min_t(int, num_blocks, max_req_block); + rc = mci_block_write(mci, buffer, block, write_block); + if (rc != 0) { + dev_dbg(&mci->dev, "Writing block %d failed with %d\n", block, rc); + return rc; + } + num_blocks -= write_block; + block += write_block; + buffer += write_block * mci->write_bl_len; } return 0; @@ -1246,8 +1257,13 @@ static int mci_sd_read(struct block_device *blk, void *buffer, int block, { struct mci_part *part = container_of(blk, struct mci_part, blk); struct mci *mci = part->mci; + unsigned max_req_block = num_blocks; + int read_block; int rc; + if (mci->host->max_req_size) + max_req_block = mci->host->max_req_size / mci->read_bl_len; + mci_blk_part_switch(part); dev_dbg(&mci->dev, "%s: Read %d block(s), starting at %d\n", @@ -1264,10 +1280,16 @@ static int mci_sd_read(struct block_device *blk, void *buffer, int block, return -EINVAL; } - rc = mci_read_block(mci, buffer, block, num_blocks); - if (rc != 0) { - dev_dbg(&mci->dev, "Reading block %d failed with %d\n", block, rc); - return rc; + while (num_blocks) { + read_block = min_t(int, num_blocks, max_req_block); + rc = mci_read_block(mci, buffer, block, read_block); + if (rc != 0) { + dev_dbg(&mci->dev, "Reading block %d failed with %d\n", block, rc); + return rc; + } + num_blocks -= read_block; + block += read_block; + buffer += read_block * mci->read_bl_len; } return 0; |