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

Commit 7604c56f 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: Add error handling in mmc_blk_cmdq_part_switch"

parents 8df8a510 460e513c
Loading
Loading
Loading
Loading
+55 −13
Original line number Diff line number Diff line
@@ -3666,6 +3666,7 @@ static inline int mmc_blk_cmdq_part_switch(struct mmc_card *card,
	struct mmc_host *host = card->host;
	struct mmc_cmdq_context_info *ctx = &host->cmdq_ctx;
	u8 part_config = card->ext_csd.part_config;
	int ret = 0, err = 0;

	if ((main_md->part_curr == md->part_type) &&
	    (card->part_curr == md->part_type))
@@ -3675,40 +3676,70 @@ static inline int mmc_blk_cmdq_part_switch(struct mmc_card *card,
		 card->ext_csd.cmdq_support &&
		 (md->flags & MMC_BLK_CMD_QUEUE)));

	if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state))
		WARN_ON(mmc_cmdq_halt(host, true));
	if (!test_bit(CMDQ_STATE_HALT, &ctx->curr_state)) {
		ret = mmc_cmdq_halt(host, true);
		if (ret) {
			pr_err("%s: %s: halt: failed: %d\n",
				mmc_hostname(host), __func__,  ret);
			goto out;
		}
	}

	/* disable CQ mode in card */
	if (mmc_card_cmdq(card)) {
		WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
		ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
				 EXT_CSD_CMDQ, 0,
				  card->ext_csd.generic_cmd6_time));
				 card->ext_csd.generic_cmd6_time);
		if (ret) {
			pr_err("%s: %s: cmdq mode disable failed %d\n",
				mmc_hostname(host), __func__, ret);
			goto cmdq_unhalt;
		}
		mmc_card_clr_cmdq(card);
	}

	part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
	part_config |= md->part_type;

	WARN_ON(mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
	ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
			 EXT_CSD_PART_CONFIG, part_config,
			  card->ext_csd.part_time));
			 card->ext_csd.part_time);
	if (ret) {
		pr_err("%s: %s: mmc_switch failure, %d -> %d , err = %d\n",
			mmc_hostname(host), __func__, main_md->part_curr,
			md->part_type, ret);
		goto cmdq_switch;
	}

	card->ext_csd.part_config = part_config;
	card->part_curr = md->part_type;

	main_md->part_curr = md->part_type;

	WARN_ON(mmc_blk_cmdq_switch(card, md, true));
	WARN_ON(mmc_cmdq_halt(host, false));

	return 0;
cmdq_switch:
	err = mmc_blk_cmdq_switch(card, md, true);
	if (err) {
		pr_err("%s: %s: mmc_blk_cmdq_switch failed: %d\n",
			mmc_hostname(host), __func__,  err);
		ret = err;
	}
cmdq_unhalt:
	err = mmc_cmdq_halt(host, false);
	if (err) {
		pr_err("%s: %s: unhalt: failed: %d\n",
			mmc_hostname(host), __func__,  err);
		ret = err;
	}
out:
	return ret;
}

static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)
{
	int ret;
	int ret, err = 0;
	struct mmc_blk_data *md = mq->data;
	struct mmc_card *card = md->queue.card;
	struct mmc_host *host = card->host;
	unsigned int cmd_flags = req ? req->cmd_flags : 0;

	mmc_get_card(card);
@@ -3730,10 +3761,21 @@ static int mmc_blk_cmdq_issue_rq(struct mmc_queue *mq, struct request *req)

	ret = mmc_blk_cmdq_part_switch(card, md);
	if (ret) {
		pr_err("%s: %s: partition switch failed %d\n",
		pr_err("%s: %s: partition switch failed %d, resetting cmdq\n",
				md->disk->disk_name, __func__, ret);

		mmc_blk_cmdq_reset(host, false);
		err = mmc_blk_cmdq_part_switch(card, md);
		if (!err) {
			pr_err("%s: %s: partition switch success err = %d\n",
				md->disk->disk_name, __func__, err);
		} else {
			pr_err("%s: %s: partition switch failed err = %d\n",
				md->disk->disk_name, __func__, err);
			ret = 0;
			goto out;
		}
	}

	if (req) {
		struct mmc_host *host = card->host;