linux/drivers/mmc/core/queue.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef MMC_QUEUE_H
   3#define MMC_QUEUE_H
   4
   5#include <linux/types.h>
   6#include <linux/blkdev.h>
   7#include <linux/blk-mq.h>
   8#include <linux/mmc/core.h>
   9#include <linux/mmc/host.h>
  10
  11enum mmc_issued {
  12        MMC_REQ_STARTED,
  13        MMC_REQ_BUSY,
  14        MMC_REQ_FAILED_TO_START,
  15        MMC_REQ_FINISHED,
  16};
  17
  18enum mmc_issue_type {
  19        MMC_ISSUE_SYNC,
  20        MMC_ISSUE_DCMD,
  21        MMC_ISSUE_ASYNC,
  22        MMC_ISSUE_MAX,
  23};
  24
  25static inline struct mmc_queue_req *req_to_mmc_queue_req(struct request *rq)
  26{
  27        return blk_mq_rq_to_pdu(rq);
  28}
  29
  30struct mmc_queue_req;
  31
  32static inline struct request *mmc_queue_req_to_req(struct mmc_queue_req *mqr)
  33{
  34        return blk_mq_rq_from_pdu(mqr);
  35}
  36
  37struct mmc_blk_data;
  38struct mmc_blk_ioc_data;
  39
  40struct mmc_blk_request {
  41        struct mmc_request      mrq;
  42        struct mmc_command      sbc;
  43        struct mmc_command      cmd;
  44        struct mmc_command      stop;
  45        struct mmc_data         data;
  46};
  47
  48/**
  49 * enum mmc_drv_op - enumerates the operations in the mmc_queue_req
  50 * @MMC_DRV_OP_IOCTL: ioctl operation
  51 * @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation
  52 * @MMC_DRV_OP_BOOT_WP: write protect boot partitions
  53 * @MMC_DRV_OP_GET_CARD_STATUS: get card status
  54 * @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card
  55 */
  56enum mmc_drv_op {
  57        MMC_DRV_OP_IOCTL,
  58        MMC_DRV_OP_IOCTL_RPMB,
  59        MMC_DRV_OP_BOOT_WP,
  60        MMC_DRV_OP_GET_CARD_STATUS,
  61        MMC_DRV_OP_GET_EXT_CSD,
  62};
  63
  64struct mmc_queue_req {
  65        struct mmc_blk_request  brq;
  66        struct scatterlist      *sg;
  67        enum mmc_drv_op         drv_op;
  68        int                     drv_op_result;
  69        void                    *drv_op_data;
  70        unsigned int            ioc_count;
  71        int                     retries;
  72};
  73
  74struct mmc_queue {
  75        struct mmc_card         *card;
  76        struct mmc_ctx          ctx;
  77        struct blk_mq_tag_set   tag_set;
  78        struct mmc_blk_data     *blkdata;
  79        struct request_queue    *queue;
  80        spinlock_t              lock;
  81        int                     in_flight[MMC_ISSUE_MAX];
  82        unsigned int            cqe_busy;
  83#define MMC_CQE_DCMD_BUSY       BIT(0)
  84#define MMC_CQE_QUEUE_FULL      BIT(1)
  85        bool                    busy;
  86        bool                    use_cqe;
  87        bool                    recovery_needed;
  88        bool                    in_recovery;
  89        bool                    rw_wait;
  90        bool                    waiting;
  91        struct work_struct      recovery_work;
  92        wait_queue_head_t       wait;
  93        struct request          *recovery_req;
  94        struct request          *complete_req;
  95        struct mutex            complete_lock;
  96        struct work_struct      complete_work;
  97};
  98
  99extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *);
 100extern void mmc_cleanup_queue(struct mmc_queue *);
 101extern void mmc_queue_suspend(struct mmc_queue *);
 102extern void mmc_queue_resume(struct mmc_queue *);
 103extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
 104                                     struct mmc_queue_req *);
 105
 106void mmc_cqe_check_busy(struct mmc_queue *mq);
 107void mmc_cqe_recovery_notifier(struct mmc_request *mrq);
 108
 109enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req);
 110
 111static inline int mmc_tot_in_flight(struct mmc_queue *mq)
 112{
 113        return mq->in_flight[MMC_ISSUE_SYNC] +
 114               mq->in_flight[MMC_ISSUE_DCMD] +
 115               mq->in_flight[MMC_ISSUE_ASYNC];
 116}
 117
 118static inline int mmc_cqe_qcnt(struct mmc_queue *mq)
 119{
 120        return mq->in_flight[MMC_ISSUE_DCMD] +
 121               mq->in_flight[MMC_ISSUE_ASYNC];
 122}
 123
 124#endif
 125