|
@@ -48,6 +48,13 @@ MODULE_ALIAS("mmc:block");
|
|
|
#endif
|
|
|
#define MODULE_PARAM_PREFIX "mmcblk."
|
|
|
|
|
|
+#define INAND_CMD38_ARG_EXT_CSD 113
|
|
|
+#define INAND_CMD38_ARG_ERASE 0x00
|
|
|
+#define INAND_CMD38_ARG_TRIM 0x01
|
|
|
+#define INAND_CMD38_ARG_SECERASE 0x80
|
|
|
+#define INAND_CMD38_ARG_SECTRIM1 0x81
|
|
|
+#define INAND_CMD38_ARG_SECTRIM2 0x88
|
|
|
+
|
|
|
#define REL_WRITES_SUPPORTED(card) (mmc_card_mmc((card)) && \
|
|
|
(((card)->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || \
|
|
|
((card)->ext_csd.rel_sectors)))
|
|
@@ -356,6 +363,16 @@ static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
|
|
|
else
|
|
|
arg = MMC_ERASE_ARG;
|
|
|
|
|
|
+ if (card->quirks & MMC_QUIRK_INAND_CMD38) {
|
|
|
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
|
|
+ INAND_CMD38_ARG_EXT_CSD,
|
|
|
+ arg == MMC_TRIM_ARG ?
|
|
|
+ INAND_CMD38_ARG_TRIM :
|
|
|
+ INAND_CMD38_ARG_ERASE,
|
|
|
+ 0);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
err = mmc_erase(card, from, nr, arg);
|
|
|
out:
|
|
|
spin_lock_irq(&md->lock);
|
|
@@ -386,9 +403,28 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq,
|
|
|
else
|
|
|
arg = MMC_SECURE_ERASE_ARG;
|
|
|
|
|
|
+ if (card->quirks & MMC_QUIRK_INAND_CMD38) {
|
|
|
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
|
|
+ INAND_CMD38_ARG_EXT_CSD,
|
|
|
+ arg == MMC_SECURE_TRIM1_ARG ?
|
|
|
+ INAND_CMD38_ARG_SECTRIM1 :
|
|
|
+ INAND_CMD38_ARG_SECERASE,
|
|
|
+ 0);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
err = mmc_erase(card, from, nr, arg);
|
|
|
- if (!err && arg == MMC_SECURE_TRIM1_ARG)
|
|
|
+ if (!err && arg == MMC_SECURE_TRIM1_ARG) {
|
|
|
+ if (card->quirks & MMC_QUIRK_INAND_CMD38) {
|
|
|
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
|
|
|
+ INAND_CMD38_ARG_EXT_CSD,
|
|
|
+ INAND_CMD38_ARG_SECTRIM2,
|
|
|
+ 0);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
|
|
|
+ }
|
|
|
out:
|
|
|
spin_lock_irq(&md->lock);
|
|
|
__blk_end_request(req, err, blk_rq_bytes(req));
|
|
@@ -941,6 +977,11 @@ static int mmc_add_disk(struct mmc_blk_data *md)
|
|
|
|
|
|
static const struct mmc_fixup blk_fixups[] =
|
|
|
{
|
|
|
+ MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
|
|
|
+ MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
|
|
|
+ MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
|
|
|
+ MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
|
|
|
+ MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
|
|
|
END_FIXUP
|
|
|
};
|
|
|
|