Greg Kroah-Hartman | b244131 | 2017-11-01 15:07:57 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | #ifndef MMC_QUEUE_H |
| 3 | #define MMC_QUEUE_H |
| 4 | |
Ulf Hansson | 066185d | 2017-01-13 14:14:07 +0100 | [diff] [blame] | 5 | #include <linux/types.h> |
| 6 | #include <linux/blkdev.h> |
Linus Walleij | 304419d | 2017-05-18 11:29:32 +0200 | [diff] [blame] | 7 | #include <linux/blk-mq.h> |
Ulf Hansson | 066185d | 2017-01-13 14:14:07 +0100 | [diff] [blame] | 8 | #include <linux/mmc/core.h> |
| 9 | #include <linux/mmc/host.h> |
| 10 | |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 11 | enum mmc_issued { |
| 12 | MMC_REQ_STARTED, |
| 13 | MMC_REQ_BUSY, |
| 14 | MMC_REQ_FAILED_TO_START, |
| 15 | MMC_REQ_FINISHED, |
| 16 | }; |
| 17 | |
| 18 | enum mmc_issue_type { |
| 19 | MMC_ISSUE_SYNC, |
Adrian Hunter | 1e8e55b | 2017-11-29 15:41:04 +0200 | [diff] [blame] | 20 | MMC_ISSUE_DCMD, |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 21 | MMC_ISSUE_ASYNC, |
| 22 | MMC_ISSUE_MAX, |
| 23 | }; |
| 24 | |
Linus Walleij | 304419d | 2017-05-18 11:29:32 +0200 | [diff] [blame] | 25 | static 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 Walleij | 67e69d5 | 2017-05-19 15:37:27 +0200 | [diff] [blame] | 30 | struct mmc_queue_req; |
| 31 | |
| 32 | static 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 Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 37 | struct task_struct; |
Linus Walleij | 7db3028 | 2016-11-18 13:36:15 +0100 | [diff] [blame] | 38 | struct mmc_blk_data; |
Linus Walleij | 614f038 | 2017-05-18 11:29:34 +0200 | [diff] [blame] | 39 | struct mmc_blk_ioc_data; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 40 | |
Per Forlin | 97868a2 | 2011-07-09 17:12:36 -0400 | [diff] [blame] | 41 | struct 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 Hunter | b8360a4 | 2015-05-07 13:10:24 +0300 | [diff] [blame] | 47 | int retune_retry_done; |
Per Forlin | 97868a2 | 2011-07-09 17:12:36 -0400 | [diff] [blame] | 48 | }; |
| 49 | |
Linus Walleij | 02166a0 | 2017-05-19 15:37:28 +0200 | [diff] [blame] | 50 | /** |
| 51 | * enum mmc_drv_op - enumerates the operations in the mmc_queue_req |
| 52 | * @MMC_DRV_OP_IOCTL: ioctl operation |
Linus Walleij | 9754857 | 2017-09-20 10:02:00 +0200 | [diff] [blame] | 53 | * @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation |
Linus Walleij | 0493f6f | 2017-05-19 15:37:30 +0200 | [diff] [blame] | 54 | * @MMC_DRV_OP_BOOT_WP: write protect boot partitions |
Linus Walleij | 627c3cc | 2017-08-20 23:39:08 +0200 | [diff] [blame] | 55 | * @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 Walleij | 02166a0 | 2017-05-19 15:37:28 +0200 | [diff] [blame] | 57 | */ |
| 58 | enum mmc_drv_op { |
| 59 | MMC_DRV_OP_IOCTL, |
Linus Walleij | 9754857 | 2017-09-20 10:02:00 +0200 | [diff] [blame] | 60 | MMC_DRV_OP_IOCTL_RPMB, |
Linus Walleij | 0493f6f | 2017-05-19 15:37:30 +0200 | [diff] [blame] | 61 | MMC_DRV_OP_BOOT_WP, |
Linus Walleij | 627c3cc | 2017-08-20 23:39:08 +0200 | [diff] [blame] | 62 | MMC_DRV_OP_GET_CARD_STATUS, |
| 63 | MMC_DRV_OP_GET_EXT_CSD, |
Linus Walleij | 02166a0 | 2017-05-19 15:37:28 +0200 | [diff] [blame] | 64 | }; |
| 65 | |
Per Forlin | 97868a2 | 2011-07-09 17:12:36 -0400 | [diff] [blame] | 66 | struct mmc_queue_req { |
Per Forlin | 97868a2 | 2011-07-09 17:12:36 -0400 | [diff] [blame] | 67 | struct mmc_blk_request brq; |
| 68 | struct scatterlist *sg; |
Linus Walleij | 74f5ba3 | 2017-02-01 13:47:55 +0100 | [diff] [blame] | 69 | struct mmc_async_req areq; |
Linus Walleij | 02166a0 | 2017-05-19 15:37:28 +0200 | [diff] [blame] | 70 | enum mmc_drv_op drv_op; |
Linus Walleij | 0493f6f | 2017-05-19 15:37:30 +0200 | [diff] [blame] | 71 | int drv_op_result; |
Linus Walleij | 69f7599 | 2017-08-20 23:39:06 +0200 | [diff] [blame] | 72 | void *drv_op_data; |
Linus Walleij | 3ecd8cf | 2017-05-18 11:29:35 +0200 | [diff] [blame] | 73 | unsigned int ioc_count; |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 74 | int retries; |
Per Forlin | 97868a2 | 2011-07-09 17:12:36 -0400 | [diff] [blame] | 75 | }; |
| 76 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 77 | struct mmc_queue { |
| 78 | struct mmc_card *card; |
Christoph Hellwig | 87598a2 | 2006-11-13 20:23:52 +0100 | [diff] [blame] | 79 | struct task_struct *thread; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 80 | struct semaphore thread_sem; |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 81 | struct mmc_ctx ctx; |
| 82 | struct blk_mq_tag_set tag_set; |
Linus Walleij | 9491be5 | 2017-02-01 13:47:56 +0100 | [diff] [blame] | 83 | bool suspended; |
Adrian Hunter | e0097cf | 2016-11-29 12:09:10 +0200 | [diff] [blame] | 84 | bool asleep; |
Linus Walleij | 7db3028 | 2016-11-18 13:36:15 +0100 | [diff] [blame] | 85 | struct mmc_blk_data *blkdata; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | struct request_queue *queue; |
Linus Walleij | 304419d | 2017-05-18 11:29:32 +0200 | [diff] [blame] | 87 | /* |
| 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 Hunter | cdf8a6f | 2017-03-13 14:36:35 +0200 | [diff] [blame] | 93 | int qcnt; |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 94 | |
| 95 | int in_flight[MMC_ISSUE_MAX]; |
Adrian Hunter | 1e8e55b | 2017-11-29 15:41:04 +0200 | [diff] [blame] | 96 | 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 Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 102 | bool rw_wait; |
| 103 | bool waiting; |
Adrian Hunter | 1e8e55b | 2017-11-29 15:41:04 +0200 | [diff] [blame] | 104 | struct work_struct recovery_work; |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 105 | wait_queue_head_t wait; |
| 106 | struct request *complete_req; |
| 107 | struct mutex complete_lock; |
| 108 | struct work_struct complete_work; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 109 | }; |
| 110 | |
Adrian Hunter | d09408a | 2011-06-23 13:40:28 +0300 | [diff] [blame] | 111 | extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *, |
| 112 | const char *); |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 113 | extern void mmc_cleanup_queue(struct mmc_queue *); |
| 114 | extern void mmc_queue_suspend(struct mmc_queue *); |
| 115 | extern void mmc_queue_resume(struct mmc_queue *); |
Per Forlin | 97868a2 | 2011-07-09 17:12:36 -0400 | [diff] [blame] | 116 | extern unsigned int mmc_queue_map_sg(struct mmc_queue *, |
| 117 | struct mmc_queue_req *); |
Pierre Ossman | 98ccf14 | 2007-05-12 00:26:16 +0200 | [diff] [blame] | 118 | |
Adrian Hunter | 1e8e55b | 2017-11-29 15:41:04 +0200 | [diff] [blame] | 119 | void mmc_cqe_check_busy(struct mmc_queue *mq); |
| 120 | void mmc_cqe_recovery_notifier(struct mmc_request *mrq); |
| 121 | |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 122 | enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req); |
| 123 | |
| 124 | static inline int mmc_tot_in_flight(struct mmc_queue *mq) |
| 125 | { |
| 126 | return mq->in_flight[MMC_ISSUE_SYNC] + |
Adrian Hunter | 1e8e55b | 2017-11-29 15:41:04 +0200 | [diff] [blame] | 127 | mq->in_flight[MMC_ISSUE_DCMD] + |
| 128 | mq->in_flight[MMC_ISSUE_ASYNC]; |
| 129 | } |
| 130 | |
| 131 | static inline int mmc_cqe_qcnt(struct mmc_queue *mq) |
| 132 | { |
| 133 | return mq->in_flight[MMC_ISSUE_DCMD] + |
Adrian Hunter | 8119697 | 2017-11-29 15:41:03 +0200 | [diff] [blame] | 134 | mq->in_flight[MMC_ISSUE_ASYNC]; |
| 135 | } |
| 136 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 137 | #endif |