mmc: core: align max segment size with logical block size [Linux 5.0]

This Linux kernel change "mmc: core: align max segment size with logical block size" is included in the Linux 5.0 release. This change is authored by Ming Lei <ming.lei [at] redhat.com> on Thu Feb 28 00:02:11 2019 +0800. The commit for this change in Linux stable tree is c53336c (patch).

mmc: core: align max segment size with logical block size

Logical block size is the lowest possible block size that the storage
device can address. Max segment size is often related with controller's
DMA capability. And it is reasonable to align max segment size with
logical block size.

SDHCI sets un-aligned max segment size, and causes ADMA error, so
fix it by aligning max segment size with logical block size.

Reported-by: Naresh Kamboju <[email protected]>
Cc: Christoph Hellwig <[email protected]>
Cc: Naresh Kamboju <[email protected]>
Cc: Faiz Abbas <[email protected]>
Cc: [email protected]
Signed-off-by: Ming Lei <[email protected]>
Signed-off-by: Ulf Hansson <[email protected]>

There are 15 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/mmc/core/block.c | 6 ------
 drivers/mmc/core/queue.c | 9 ++++++++-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 14f3fdb..9ce8eb5 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -2380,12 +2380,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
    snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
         "mmcblk%u%s", card->host->index, subname ? subname : "");

-   if (mmc_card_mmc(card))
-       blk_queue_logical_block_size(md->queue.queue,
-                        card->ext_csd.data_sector_size);
-   else
-       blk_queue_logical_block_size(md->queue.queue, 512);
-
    set_capacity(md->disk, size);

    if (mmc_host_cmd23(card->host)) {
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
index 35cc138..15a45ec 100644
--- a/drivers/mmc/core/queue.c
+++ b/drivers/mmc/core/queue.c
@@ -355,6 +355,7 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
 {
    struct mmc_host *host = card->host;
    u64 limit = BLK_BOUNCE_HIGH;
+   unsigned block_size = 512;

    if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
        limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
@@ -368,7 +369,13 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card)
    blk_queue_max_hw_sectors(mq->queue,
        min(host->max_blk_count, host->max_req_size / 512));
    blk_queue_max_segments(mq->queue, host->max_segs);
-   blk_queue_max_segment_size(mq->queue, host->max_seg_size);
+
+   if (mmc_card_mmc(card))
+       block_size = card->ext_csd.data_sector_size;
+
+   blk_queue_logical_block_size(mq->queue, block_size);
+   blk_queue_max_segment_size(mq->queue,
+           round_down(host->max_seg_size, block_size));

    INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler);
    INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work);

Leave a Reply

Your email address will not be published. Required fields are marked *