Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 39a63bd9 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mmc: block: workaround for timeout issue with some vendor devices"

parents 473b8a2d 7ecbbe01
Loading
Loading
Loading
Loading
+36 −14
Original line number Diff line number Diff line
@@ -2823,6 +2823,15 @@ static int mmc_blk_cmdq_issue_rw_rq(struct mmc_queue *mq, struct request *req)
	mc_rq = mmc_blk_cmdq_rw_prep(active_mqrq, mq);

	ret = mmc_blk_cmdq_start_req(card->host, mc_rq);

	if (!ret && (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD)) {
		unsigned int sectors = blk_rq_sectors(req);

		if (((sectors > 0) && (sectors < 8))
		    && (rq_data_dir(req) == READ))
			host->cmdq_ctx.active_small_sector_read_reqs++;
	}

	return ret;
}

@@ -3396,26 +3405,39 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
	}

	if (req) {
		if (cmd_flags & REQ_DISCARD) {
			if (cmd_flags & REQ_SECURE &&
			   !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN))
				ret = mmc_blk_cmdq_issue_secdiscard_rq(mq, req);
			else
				ret = mmc_blk_cmdq_issue_discard_rq(mq, req);
		} else if (cmd_flags & REQ_FLUSH) {
			if (card->quirks &
			    MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH) {
				ret = wait_event_interruptible(
					card->host->cmdq_ctx.queue_empty_wq,
					(!card->host->cmdq_ctx.active_reqs));
		struct mmc_host *host = card->host;
		struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx;

		if ((cmd_flags & (REQ_FLUSH | REQ_DISCARD)) &&
		    (card->quirks & MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD) &&
		    ctx->active_small_sector_read_reqs) {
			ret = wait_event_interruptible(ctx->queue_empty_wq,
						      !ctx->active_reqs);
			if (ret) {
				pr_err("%s: failed while waiting for the CMDQ to be empty %s err (%d)\n",
						mmc_hostname(card->host),
					mmc_hostname(host),
					__func__, ret);
				BUG_ON(1);
			}
			/* clear the counter now */
			ctx->active_small_sector_read_reqs = 0;
			/*
			 * If there were small sector (less than 8 sectors) read
			 * operations in progress then we have to wait for the
			 * outstanding requests to finish and should also have
			 * atleast 6 microseconds delay before queuing the DCMD
			 * request.
			 */
			udelay(MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD);
		}

		if (cmd_flags & REQ_DISCARD) {
			if (cmd_flags & REQ_SECURE &&
			   !(card->quirks & MMC_QUIRK_SEC_ERASE_TRIM_BROKEN))
				ret = mmc_blk_cmdq_issue_secdiscard_rq(mq, req);
			else
				ret = mmc_blk_cmdq_issue_discard_rq(mq, req);
		} else if (cmd_flags & REQ_FLUSH) {
			ret = mmc_blk_cmdq_issue_flush_rq(mq, req);
		} else {
			ret = mmc_blk_cmdq_issue_rw_rq(mq, req);
@@ -3874,7 +3896,7 @@ static const struct mmc_fixup blk_fixups[] =
	MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
		  MMC_QUIRK_BLK_NO_CMD23),
	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_TOSHIBA, CID_OEMID_ANY,
		  add_quirk_mmc, MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH),
		  add_quirk_mmc, MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD),

	/*
	 * Some Micron MMC cards needs longer data read timeout than
+4 −2
Original line number Diff line number Diff line
@@ -332,6 +332,8 @@ enum mmc_pon_type {
	MMC_SHRT_PON,
};

#define MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD 6 /* microseconds */

/*
 * MMC device
 */
@@ -383,8 +385,8 @@ struct mmc_card {
#define MMC_QUIRK_QCA6574_SETTINGS (1 << 15)	/* QCA6574 card settings*/
#define MMC_QUIRK_QCA9377_SETTINGS (1 << 16)	/* QCA9377 card settings*/

/* Make sure CMDQ is empty before queuing cache flush */
#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH (1 << 17)
/* Make sure CMDQ is empty before queuing DCMD */
#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD (1 << 17)

	unsigned int		erase_size;	/* erase size in sectors */
 	unsigned int		erase_shift;	/* if erase unit is power 2 */
+1 −0
Original line number Diff line number Diff line
@@ -258,6 +258,7 @@ struct mmc_cmdq_context_info {
#define	CMDQ_STATE_HALT 2
	wait_queue_head_t	queue_empty_wq;
	wait_queue_head_t	wait;
	int active_small_sector_read_reqs;
};

/**