blob: 1d7d3b0afff88d4a841d19a809177f42f62e945e [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002#ifndef MMC_QUEUE_H
3#define MMC_QUEUE_H
4
Ulf Hansson066185d2017-01-13 14:14:07 +01005#include <linux/types.h>
6#include <linux/blkdev.h>
Linus Walleij304419d2017-05-18 11:29:32 +02007#include <linux/blk-mq.h>
Ulf Hansson066185d2017-01-13 14:14:07 +01008#include <linux/mmc/core.h>
9#include <linux/mmc/host.h>
10
Adrian Hunter81196972017-11-29 15:41:03 +020011enum 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,
Adrian Hunter1e8e55b2017-11-29 15:41:04 +020020 MMC_ISSUE_DCMD,
Adrian Hunter81196972017-11-29 15:41:03 +020021 MMC_ISSUE_ASYNC,
22 MMC_ISSUE_MAX,
23};
24
Linus Walleij304419d2017-05-18 11:29:32 +020025static inline struct mmc_queue_req *req_to_mmc_queue_req(struct request *rq)
26{
27 return blk_mq_rq_to_pdu(rq);
28}
29
Linus Walleij67e69d52017-05-19 15:37:27 +020030struct 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070037struct task_struct;
Linus Walleij7db30282016-11-18 13:36:15 +010038struct mmc_blk_data;
Linus Walleij614f0382017-05-18 11:29:34 +020039struct mmc_blk_ioc_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Per Forlin97868a22011-07-09 17:12:36 -040041struct mmc_blk_request {
42 struct mmc_request mrq;
43 struct mmc_command sbc;
44 struct mmc_command cmd;
45 struct mmc_command stop;
46 struct mmc_data data;
Adrian Hunterb8360a42015-05-07 13:10:24 +030047 int retune_retry_done;
Per Forlin97868a22011-07-09 17:12:36 -040048};
49
Linus Walleij02166a02017-05-19 15:37:28 +020050/**
51 * enum mmc_drv_op - enumerates the operations in the mmc_queue_req
52 * @MMC_DRV_OP_IOCTL: ioctl operation
Linus Walleij97548572017-09-20 10:02:00 +020053 * @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation
Linus Walleij0493f6f2017-05-19 15:37:30 +020054 * @MMC_DRV_OP_BOOT_WP: write protect boot partitions
Linus Walleij627c3cc2017-08-20 23:39:08 +020055 * @MMC_DRV_OP_GET_CARD_STATUS: get card status
56 * @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card
Linus Walleij02166a02017-05-19 15:37:28 +020057 */
58enum mmc_drv_op {
59 MMC_DRV_OP_IOCTL,
Linus Walleij97548572017-09-20 10:02:00 +020060 MMC_DRV_OP_IOCTL_RPMB,
Linus Walleij0493f6f2017-05-19 15:37:30 +020061 MMC_DRV_OP_BOOT_WP,
Linus Walleij627c3cc2017-08-20 23:39:08 +020062 MMC_DRV_OP_GET_CARD_STATUS,
63 MMC_DRV_OP_GET_EXT_CSD,
Linus Walleij02166a02017-05-19 15:37:28 +020064};
65
Per Forlin97868a22011-07-09 17:12:36 -040066struct mmc_queue_req {
Per Forlin97868a22011-07-09 17:12:36 -040067 struct mmc_blk_request brq;
68 struct scatterlist *sg;
Linus Walleij74f5ba32017-02-01 13:47:55 +010069 struct mmc_async_req areq;
Linus Walleij02166a02017-05-19 15:37:28 +020070 enum mmc_drv_op drv_op;
Linus Walleij0493f6f2017-05-19 15:37:30 +020071 int drv_op_result;
Linus Walleij69f75992017-08-20 23:39:06 +020072 void *drv_op_data;
Linus Walleij3ecd8cf2017-05-18 11:29:35 +020073 unsigned int ioc_count;
Adrian Hunter81196972017-11-29 15:41:03 +020074 int retries;
Per Forlin97868a22011-07-09 17:12:36 -040075};
76
Linus Torvalds1da177e2005-04-16 15:20:36 -070077struct mmc_queue {
78 struct mmc_card *card;
Christoph Hellwig87598a22006-11-13 20:23:52 +010079 struct task_struct *thread;
Linus Torvalds1da177e2005-04-16 15:20:36 -070080 struct semaphore thread_sem;
Adrian Hunter81196972017-11-29 15:41:03 +020081 struct mmc_ctx ctx;
82 struct blk_mq_tag_set tag_set;
Linus Walleij9491be52017-02-01 13:47:56 +010083 bool suspended;
Adrian Huntere0097cf2016-11-29 12:09:10 +020084 bool asleep;
Linus Walleij7db30282016-11-18 13:36:15 +010085 struct mmc_blk_data *blkdata;
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 struct request_queue *queue;
Linus Walleij304419d2017-05-18 11:29:32 +020087 /*
88 * FIXME: this counter is not a very reliable way of keeping
89 * track of how many requests that are ongoing. Switch to just
90 * letting the block core keep track of requests and per-request
91 * associated mmc_queue_req data.
92 */
Adrian Huntercdf8a6f2017-03-13 14:36:35 +020093 int qcnt;
Adrian Hunter81196972017-11-29 15:41:03 +020094
95 int in_flight[MMC_ISSUE_MAX];
Adrian Hunter1e8e55b2017-11-29 15:41:04 +020096 unsigned int cqe_busy;
97#define MMC_CQE_DCMD_BUSY BIT(0)
98#define MMC_CQE_QUEUE_FULL BIT(1)
99 bool use_cqe;
100 bool recovery_needed;
101 bool in_recovery;
Adrian Hunter81196972017-11-29 15:41:03 +0200102 bool rw_wait;
103 bool waiting;
Adrian Hunter1e8e55b2017-11-29 15:41:04 +0200104 struct work_struct recovery_work;
Adrian Hunter81196972017-11-29 15:41:03 +0200105 wait_queue_head_t wait;
106 struct request *complete_req;
107 struct mutex complete_lock;
108 struct work_struct complete_work;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109};
110
Adrian Hunterd09408a2011-06-23 13:40:28 +0300111extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
112 const char *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113extern void mmc_cleanup_queue(struct mmc_queue *);
114extern void mmc_queue_suspend(struct mmc_queue *);
115extern void mmc_queue_resume(struct mmc_queue *);
Per Forlin97868a22011-07-09 17:12:36 -0400116extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
117 struct mmc_queue_req *);
Pierre Ossman98ccf142007-05-12 00:26:16 +0200118
Adrian Hunter1e8e55b2017-11-29 15:41:04 +0200119void mmc_cqe_check_busy(struct mmc_queue *mq);
120void mmc_cqe_recovery_notifier(struct mmc_request *mrq);
121
Adrian Hunter81196972017-11-29 15:41:03 +0200122enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req);
123
124static inline int mmc_tot_in_flight(struct mmc_queue *mq)
125{
126 return mq->in_flight[MMC_ISSUE_SYNC] +
Adrian Hunter1e8e55b2017-11-29 15:41:04 +0200127 mq->in_flight[MMC_ISSUE_DCMD] +
128 mq->in_flight[MMC_ISSUE_ASYNC];
129}
130
131static inline int mmc_cqe_qcnt(struct mmc_queue *mq)
132{
133 return mq->in_flight[MMC_ISSUE_DCMD] +
Adrian Hunter81196972017-11-29 15:41:03 +0200134 mq->in_flight[MMC_ISSUE_ASYNC];
135}
136
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137#endif