1319349Sjkim/* SPDX-License-Identifier: GPL-2.0 */ 2319349Sjkim#ifndef MMC_QUEUE_H 3319349Sjkim#define MMC_QUEUE_H 4319349Sjkim 5319349Sjkim#include <linux/types.h> 6319349Sjkim#include <linux/blkdev.h> 7319349Sjkim#include <linux/blk-mq.h> 8319349Sjkim#include <linux/mmc/core.h> 9319349Sjkim#include <linux/mmc/host.h> 10319349Sjkim 11319349Sjkimenum mmc_issued { 12319349Sjkim MMC_REQ_STARTED, 13319349Sjkim MMC_REQ_BUSY, 14319349Sjkim MMC_REQ_FAILED_TO_START, 15319349Sjkim MMC_REQ_FINISHED, 16319349Sjkim}; 17319349Sjkim 18319349Sjkimenum mmc_issue_type { 19319349Sjkim MMC_ISSUE_SYNC, 20319349Sjkim MMC_ISSUE_DCMD, 21319349Sjkim MMC_ISSUE_ASYNC, 22319349Sjkim MMC_ISSUE_MAX, 23319349Sjkim}; 24319349Sjkim 25319349Sjkimstatic inline struct mmc_queue_req *req_to_mmc_queue_req(struct request *rq) 26319349Sjkim{ 27319349Sjkim return blk_mq_rq_to_pdu(rq); 28319349Sjkim} 29319349Sjkim 30319349Sjkimstruct mmc_queue_req; 31319297Sdelphij 32297276Sjkimstatic inline struct request *mmc_queue_req_to_req(struct mmc_queue_req *mqr) 33319297Sdelphij{ 34319297Sdelphij return blk_mq_rq_from_pdu(mqr); 35319297Sdelphij} 36319297Sdelphij 37319297Sdelphijstruct mmc_blk_data; 38319297Sdelphijstruct mmc_blk_ioc_data; 39319297Sdelphij 40319297Sdelphijstruct mmc_blk_request { 41319297Sdelphij struct mmc_request mrq; 42319297Sdelphij struct mmc_command sbc; 43319297Sdelphij struct mmc_command cmd; 44319297Sdelphij struct mmc_command stop; 45319297Sdelphij struct mmc_data data; 46319297Sdelphij}; 47319297Sdelphij 48319297Sdelphij/** 49319297Sdelphij * enum mmc_drv_op - enumerates the operations in the mmc_queue_req 50319297Sdelphij * @MMC_DRV_OP_IOCTL: ioctl operation 51319297Sdelphij * @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation 52319297Sdelphij * @MMC_DRV_OP_BOOT_WP: write protect boot partitions 53319297Sdelphij * @MMC_DRV_OP_GET_CARD_STATUS: get card status 54319297Sdelphij * @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card 55319297Sdelphij */ 56319297Sdelphijenum mmc_drv_op { 57319297Sdelphij MMC_DRV_OP_IOCTL, 58319297Sdelphij MMC_DRV_OP_IOCTL_RPMB, 59319297Sdelphij MMC_DRV_OP_BOOT_WP, 60319297Sdelphij MMC_DRV_OP_GET_CARD_STATUS, 61319297Sdelphij MMC_DRV_OP_GET_EXT_CSD, 62319297Sdelphij}; 63319297Sdelphij 64319297Sdelphijstruct mmc_queue_req { 65319297Sdelphij struct mmc_blk_request brq; 66319297Sdelphij struct scatterlist *sg; 67319297Sdelphij enum mmc_drv_op drv_op; 68319297Sdelphij int drv_op_result; 69319297Sdelphij void *drv_op_data; 70319297Sdelphij unsigned int ioc_count; 71319297Sdelphij int retries; 72319297Sdelphij}; 73319297Sdelphij 74319297Sdelphijstruct mmc_queue { 75319297Sdelphij struct mmc_card *card; 76319297Sdelphij struct mmc_ctx ctx; 77319297Sdelphij struct blk_mq_tag_set tag_set; 78319297Sdelphij struct mmc_blk_data *blkdata; 79319297Sdelphij struct request_queue *queue; 80319297Sdelphij spinlock_t lock; 81319297Sdelphij int in_flight[MMC_ISSUE_MAX]; 82319297Sdelphij unsigned int cqe_busy; 83319297Sdelphij#define MMC_CQE_DCMD_BUSY BIT(0) 84319297Sdelphij bool busy; 85319297Sdelphij bool recovery_needed; 86319297Sdelphij bool in_recovery; 87319297Sdelphij bool rw_wait; 88319297Sdelphij bool waiting; 89319297Sdelphij struct work_struct recovery_work; 90319297Sdelphij wait_queue_head_t wait; 91319297Sdelphij struct request *recovery_req; 92319297Sdelphij struct request *complete_req; 93319297Sdelphij struct mutex complete_lock; 94319297Sdelphij struct work_struct complete_work; 95319297Sdelphij}; 96319297Sdelphij 97319297Sdelphijstruct gendisk *mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card); 98319297Sdelphijextern void mmc_cleanup_queue(struct mmc_queue *); 99319297Sdelphijextern void mmc_queue_suspend(struct mmc_queue *); 100319297Sdelphijextern void mmc_queue_resume(struct mmc_queue *); 101319297Sdelphijextern unsigned int mmc_queue_map_sg(struct mmc_queue *, 102319297Sdelphij struct mmc_queue_req *); 103319297Sdelphij 104319297Sdelphijvoid mmc_cqe_check_busy(struct mmc_queue *mq); 105319297Sdelphijvoid mmc_cqe_recovery_notifier(struct mmc_request *mrq); 106319297Sdelphij 107319297Sdelphijenum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req); 108319297Sdelphij 109319297Sdelphijstatic inline int mmc_tot_in_flight(struct mmc_queue *mq) 110319297Sdelphij{ 111319297Sdelphij return mq->in_flight[MMC_ISSUE_SYNC] + 112319297Sdelphij mq->in_flight[MMC_ISSUE_DCMD] + 113319297Sdelphij mq->in_flight[MMC_ISSUE_ASYNC]; 114319297Sdelphij} 115319297Sdelphij 116319297Sdelphijstatic inline int mmc_cqe_qcnt(struct mmc_queue *mq) 117319297Sdelphij{ 118319297Sdelphij return mq->in_flight[MMC_ISSUE_DCMD] + 119319297Sdelphij mq->in_flight[MMC_ISSUE_ASYNC]; 120319297Sdelphij} 121319297Sdelphij 122319297Sdelphij#endif 123319297Sdelphij