/* * Prepare a MMC request. This just filters out odd stuff. */ static int mmc_prep_request(struct request_queue *q, struct request *req) { struct mmc_queue *mq = q->queuedata; if (mq && mmc_card_removed(mq->card)) return BLKPREP_KILL; req->rq_flags |= RQF_DONTPREP; return BLKPREP_OK; }
static int mmc_prep_request(struct request_queue *q, struct request *req) { struct mmc_queue *mq = q->queuedata; if (req->cmd_type != REQ_TYPE_FS && !(req->cmd_flags & REQ_DISCARD)) { blk_dump_rq_flags(req, "MMC bad request"); return BLKPREP_KILL; } if (mq && mmc_card_removed(mq->card)) return BLKPREP_KILL; req->cmd_flags |= REQ_DONTPREP; return BLKPREP_OK; }
/* * Prepare a MMC request. This just filters out odd stuff. */ static int mmc_prep_request(struct request_queue *q, struct request *req) { struct mmc_queue *mq = q->queuedata; /* * We only like normal block requests and discards. */ if (req->cmd_type != REQ_TYPE_FS && req_op(req) != REQ_OP_DISCARD && req_op(req) != REQ_OP_SECURE_ERASE) { blk_dump_rq_flags(req, "MMC bad request"); return BLKPREP_KILL; } if (mq && (mmc_card_removed(mq->card) || mmc_access_rpmb(mq))) return BLKPREP_KILL; req->rq_flags |= RQF_DONTPREP; return BLKPREP_OK; }
static blk_status_t mmc_mq_queue_rq(struct blk_mq_hw_ctx *hctx, const struct blk_mq_queue_data *bd) { struct request *req = bd->rq; struct request_queue *q = req->q; struct mmc_queue *mq = q->queuedata; struct mmc_card *card = mq->card; struct mmc_host *host = card->host; enum mmc_issue_type issue_type; enum mmc_issued issued; bool get_card, cqe_retune_ok; int ret; if (mmc_card_removed(mq->card)) { req->rq_flags |= RQF_QUIET; return BLK_STS_IOERR; } issue_type = mmc_issue_type(mq, req); spin_lock_irq(&mq->lock); if (mq->recovery_needed || mq->busy) { spin_unlock_irq(&mq->lock); return BLK_STS_RESOURCE; } switch (issue_type) { case MMC_ISSUE_DCMD: if (mmc_cqe_dcmd_busy(mq)) { mq->cqe_busy |= MMC_CQE_DCMD_BUSY; spin_unlock_irq(&mq->lock); return BLK_STS_RESOURCE; } break; case MMC_ISSUE_ASYNC: break; default: /* * Timeouts are handled by mmc core, and we don't have a host * API to abort requests, so we can't handle the timeout anyway. * However, when the timeout happens, blk_mq_complete_request() * no longer works (to stop the request disappearing under us). * To avoid racing with that, set a large timeout. */ req->timeout = 600 * HZ; break; } /* Parallel dispatch of requests is not supported at the moment */ mq->busy = true; mq->in_flight[issue_type] += 1; get_card = (mmc_tot_in_flight(mq) == 1); cqe_retune_ok = (mmc_cqe_qcnt(mq) == 1); spin_unlock_irq(&mq->lock); if (!(req->rq_flags & RQF_DONTPREP)) { req_to_mmc_queue_req(req)->retries = 0; req->rq_flags |= RQF_DONTPREP; } if (get_card) mmc_get_card(card, &mq->ctx); if (mq->use_cqe) { host->retune_now = host->need_retune && cqe_retune_ok && !host->hold_retune; } blk_mq_start_request(req); issued = mmc_blk_mq_issue_rq(mq, req); switch (issued) { case MMC_REQ_BUSY: ret = BLK_STS_RESOURCE; break; case MMC_REQ_FAILED_TO_START: ret = BLK_STS_IOERR; break; default: ret = BLK_STS_OK; break; } if (issued != MMC_REQ_STARTED) { bool put_card = false; spin_lock_irq(&mq->lock); mq->in_flight[issue_type] -= 1; if (mmc_tot_in_flight(mq) == 0) put_card = true; mq->busy = false; spin_unlock_irq(&mq->lock); if (put_card) mmc_put_card(card, &mq->ctx); } else { WRITE_ONCE(mq->busy, false); } return ret; }