Merge remote-tracking branch 'stable/linux-5.15.y' into rpi-5.15.y
[platform/kernel/linux-rpi.git] / drivers / mmc / core / block.c
index a196116..7818437 100644 (file)
@@ -171,6 +171,13 @@ static DEFINE_MUTEX(open_lock);
 module_param(perdev_minors, int, 0444);
 MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device");
 
+/*
+ * Allow quirks to be overridden for the current card
+ */
+static char *card_quirks;
+module_param(card_quirks, charp, 0644);
+MODULE_PARM_DESC(card_quirks, "Force the use of the indicated quirks (a bitfield)");
+
 static inline int mmc_blk_part_switch(struct mmc_card *card,
                                      unsigned int part_type);
 static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
@@ -1863,7 +1870,11 @@ static void mmc_blk_mq_rw_recovery(struct mmc_queue *mq, struct request *req)
        }
 
        /* FIXME: Missing single sector read for large sector size */
-       if (!mmc_large_sector(card) && rq_data_dir(req) == READ &&
+       /*
+        * XXX: don't do single-sector reads, as it leaks a SG DMA
+        * mapping when reusing the still-pending req.
+        */
+       if (0 && !mmc_large_sector(card) && rq_data_dir(req) == READ &&
            brq->data.blocks > 1) {
                /* Read one sector at a time */
                mmc_blk_read_single(mq, req);
@@ -2923,6 +2934,8 @@ static int mmc_blk_probe(struct mmc_card *card)
 {
        struct mmc_blk_data *md;
        int ret = 0;
+       char quirk_str[24];
+       char cap_str[10];
 
        /*
         * Check that the card supports the command class(es) we need.
@@ -2930,7 +2943,16 @@ static int mmc_blk_probe(struct mmc_card *card)
        if (!(card->csd.cmdclass & CCC_BLOCK_READ))
                return -ENODEV;
 
-       mmc_fixup_device(card, mmc_blk_fixups);
+       if (card_quirks) {
+               unsigned long quirks;
+               if (kstrtoul(card_quirks, 0, &quirks) == 0)
+                       card->quirks = (unsigned int)quirks;
+               else
+                       pr_err("mmc_block: Invalid card_quirks parameter '%s'\n",
+                              card_quirks);
+       }
+       else
+               mmc_fixup_device(card, mmc_blk_fixups);
 
        card->complete_wq = alloc_workqueue("mmc_complete",
                                        WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
@@ -2945,6 +2967,17 @@ static int mmc_blk_probe(struct mmc_card *card)
                goto out_free;
        }
 
+       string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2,
+                       cap_str, sizeof(cap_str));
+       if (card->quirks)
+               snprintf(quirk_str, sizeof(quirk_str),
+                        " (quirks 0x%08x)", card->quirks);
+       else
+               quirk_str[0] = '\0';
+       pr_info("%s: %s %s %s%s%s\n",
+               md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
+               cap_str, md->read_only ? " (ro)" : "", quirk_str);
+
        ret = mmc_blk_alloc_parts(card, md);
        if (ret)
                goto out;