2005-04-16 22:20:36 +00:00
|
|
|
#ifndef MMC_QUEUE_H
|
|
|
|
#define MMC_QUEUE_H
|
|
|
|
|
2017-01-13 13:14:07 +00:00
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/blkdev.h>
|
mmc: core: Allocate per-request data using the block layer core
The mmc_queue_req is a per-request state container the MMC core uses
to carry bounce buffers, pointers to asynchronous requests and so on.
Currently allocated as a static array of objects, then as a request
comes in, a mmc_queue_req is assigned to it, and used during the
lifetime of the request.
This is backwards compared to how other block layer drivers work:
they usally let the block core provide a per-request struct that get
allocated right beind the struct request, and which can be obtained
using the blk_mq_rq_to_pdu() helper. (The _mq_ infix in this function
name is misleading: it is used by both the old and the MQ block
layer.)
The per-request struct gets allocated to the size stored in the queue
variable .cmd_size initialized using the .init_rq_fn() and
cleaned up using .exit_rq_fn().
The block layer code makes the MMC core rely on this mechanism to
allocate the per-request mmc_queue_req state container.
Doing this make a lot of complicated queue handling go away. We only
need to keep the .qnct that keeps count of how many request are
currently being processed by the MMC layer. The MQ block layer will
replace also this once we transition to it.
Doing this refactoring is necessary to move the ioctl() operations
into custom block layer requests tagged with REQ_OP_DRV_[IN|OUT]
instead of the custom code using the BigMMCHostLock that we have
today: those require that per-request data be obtainable easily from
a request after creating a custom request with e.g.:
struct request *rq = blk_get_request(q, REQ_OP_DRV_IN, __GFP_RECLAIM);
struct mmc_queue_req *mq_rq = req_to_mq_rq(rq);
And this is not possible with the current construction, as the request
is not immediately assigned the per-request state container, but
instead it gets assigned when the request finally enters the MMC
queue, which is way too late for custom requests.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[Ulf: Folded in the fix to drop a call to blk_cleanup_queue()]
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Heiner Kallweit <hkallweit1@gmail.com>
2017-05-18 09:29:32 +00:00
|
|
|
#include <linux/blk-mq.h>
|
2017-01-13 13:14:07 +00:00
|
|
|
#include <linux/mmc/core.h>
|
|
|
|
#include <linux/mmc/host.h>
|
|
|
|
|
mmc: core: Allocate per-request data using the block layer core
The mmc_queue_req is a per-request state container the MMC core uses
to carry bounce buffers, pointers to asynchronous requests and so on.
Currently allocated as a static array of objects, then as a request
comes in, a mmc_queue_req is assigned to it, and used during the
lifetime of the request.
This is backwards compared to how other block layer drivers work:
they usally let the block core provide a per-request struct that get
allocated right beind the struct request, and which can be obtained
using the blk_mq_rq_to_pdu() helper. (The _mq_ infix in this function
name is misleading: it is used by both the old and the MQ block
layer.)
The per-request struct gets allocated to the size stored in the queue
variable .cmd_size initialized using the .init_rq_fn() and
cleaned up using .exit_rq_fn().
The block layer code makes the MMC core rely on this mechanism to
allocate the per-request mmc_queue_req state container.
Doing this make a lot of complicated queue handling go away. We only
need to keep the .qnct that keeps count of how many request are
currently being processed by the MMC layer. The MQ block layer will
replace also this once we transition to it.
Doing this refactoring is necessary to move the ioctl() operations
into custom block layer requests tagged with REQ_OP_DRV_[IN|OUT]
instead of the custom code using the BigMMCHostLock that we have
today: those require that per-request data be obtainable easily from
a request after creating a custom request with e.g.:
struct request *rq = blk_get_request(q, REQ_OP_DRV_IN, __GFP_RECLAIM);
struct mmc_queue_req *mq_rq = req_to_mq_rq(rq);
And this is not possible with the current construction, as the request
is not immediately assigned the per-request state container, but
instead it gets assigned when the request finally enters the MMC
queue, which is way too late for custom requests.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[Ulf: Folded in the fix to drop a call to blk_cleanup_queue()]
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Heiner Kallweit <hkallweit1@gmail.com>
2017-05-18 09:29:32 +00:00
|
|
|
static inline struct mmc_queue_req *req_to_mmc_queue_req(struct request *rq)
|
|
|
|
{
|
|
|
|
return blk_mq_rq_to_pdu(rq);
|
|
|
|
}
|
|
|
|
|
2017-05-19 13:37:27 +00:00
|
|
|
struct mmc_queue_req;
|
|
|
|
|
|
|
|
static inline struct request *mmc_queue_req_to_req(struct mmc_queue_req *mqr)
|
|
|
|
{
|
|
|
|
return blk_mq_rq_from_pdu(mqr);
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct task_struct;
|
2016-11-18 12:36:15 +00:00
|
|
|
struct mmc_blk_data;
|
2017-05-18 09:29:34 +00:00
|
|
|
struct mmc_blk_ioc_data;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2011-07-09 21:12:36 +00:00
|
|
|
struct mmc_blk_request {
|
|
|
|
struct mmc_request mrq;
|
|
|
|
struct mmc_command sbc;
|
|
|
|
struct mmc_command cmd;
|
|
|
|
struct mmc_command stop;
|
|
|
|
struct mmc_data data;
|
2015-05-07 10:10:24 +00:00
|
|
|
int retune_retry_done;
|
2011-07-09 21:12:36 +00:00
|
|
|
};
|
|
|
|
|
2017-05-19 13:37:28 +00:00
|
|
|
/**
|
|
|
|
* enum mmc_drv_op - enumerates the operations in the mmc_queue_req
|
|
|
|
* @MMC_DRV_OP_IOCTL: ioctl operation
|
mmc: block: Convert RPMB to a character device
The RPMB partition on the eMMC devices is a special area used
for storing cryptographically safe information signed by a
special secret key. To write and read records from this special
area, authentication is needed.
The RPMB area is *only* and *exclusively* accessed using
ioctl():s from userspace. It is not really a block device,
as blocks cannot be read or written from the device, also
the signed chunks that can be stored on the RPMB are actually
256 bytes, not 512 making a block device a real bad fit.
Currently the RPMB partition spawns a separate block device
named /dev/mmcblkNrpmb for each device with an RPMB partition,
including the creation of a block queue with its own kernel
thread and all overhead associated with this. On the Ux500
HREFv60 platform, for example, the two eMMCs means that two
block queues with separate threads are created for no use
whatsoever.
I have concluded that this block device design for RPMB is
actually pretty wrong. The RPMB area should have been designed
to be accessed from /dev/mmcblkN directly, using ioctl()s on
the main block device. It is however way too late to change
that, since userspace expects to open an RPMB device in
/dev/mmcblkNrpmb and we cannot break userspace.
This patch tries to amend the situation using the following
strategy:
- Stop creating a block device for the RPMB partition/area
- Instead create a custom, dynamic character device with
the same name.
- Make this new character device support exactly the same
set of ioctl()s as the old block device.
- Wrap the requests back to the same ioctl() handlers, but
issue them on the block queue of the main partition/area,
i.e. /dev/mmcblkN
We need to create a special "rpmb" bus type in order to get
udev and/or busybox hot/coldplug to instantiate the device
node properly.
Before the patch, this appears in 'ps aux':
101 root 0:00 [mmcqd/2rpmb]
123 root 0:00 [mmcqd/3rpmb]
After applying the patch these surplus block queue threads
are gone, but RPMB is as usable as ever using the userspace
MMC tools, such as 'mmc rpmb read-counter'.
We get instead those dynamice devices in /dev:
brw-rw---- 1 root root 179, 0 Jan 1 2000 mmcblk0
brw-rw---- 1 root root 179, 1 Jan 1 2000 mmcblk0p1
brw-rw---- 1 root root 179, 2 Jan 1 2000 mmcblk0p2
brw-rw---- 1 root root 179, 5 Jan 1 2000 mmcblk0p5
brw-rw---- 1 root root 179, 8 Jan 1 2000 mmcblk2
brw-rw---- 1 root root 179, 16 Jan 1 2000 mmcblk2boot0
brw-rw---- 1 root root 179, 24 Jan 1 2000 mmcblk2boot1
crw-rw---- 1 root root 248, 0 Jan 1 2000 mmcblk2rpmb
brw-rw---- 1 root root 179, 32 Jan 1 2000 mmcblk3
brw-rw---- 1 root root 179, 40 Jan 1 2000 mmcblk3boot0
brw-rw---- 1 root root 179, 48 Jan 1 2000 mmcblk3boot1
brw-rw---- 1 root root 179, 33 Jan 1 2000 mmcblk3p1
crw-rw---- 1 root root 248, 1 Jan 1 2000 mmcblk3rpmb
Notice the (248,0) and (248,1) character devices for RPMB.
Cc: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-09-20 08:02:00 +00:00
|
|
|
* @MMC_DRV_OP_IOCTL_RPMB: RPMB-oriented ioctl operation
|
2017-05-19 13:37:30 +00:00
|
|
|
* @MMC_DRV_OP_BOOT_WP: write protect boot partitions
|
2017-08-20 21:39:08 +00:00
|
|
|
* @MMC_DRV_OP_GET_CARD_STATUS: get card status
|
|
|
|
* @MMC_DRV_OP_GET_EXT_CSD: get the EXT CSD from an eMMC card
|
2017-05-19 13:37:28 +00:00
|
|
|
*/
|
|
|
|
enum mmc_drv_op {
|
|
|
|
MMC_DRV_OP_IOCTL,
|
mmc: block: Convert RPMB to a character device
The RPMB partition on the eMMC devices is a special area used
for storing cryptographically safe information signed by a
special secret key. To write and read records from this special
area, authentication is needed.
The RPMB area is *only* and *exclusively* accessed using
ioctl():s from userspace. It is not really a block device,
as blocks cannot be read or written from the device, also
the signed chunks that can be stored on the RPMB are actually
256 bytes, not 512 making a block device a real bad fit.
Currently the RPMB partition spawns a separate block device
named /dev/mmcblkNrpmb for each device with an RPMB partition,
including the creation of a block queue with its own kernel
thread and all overhead associated with this. On the Ux500
HREFv60 platform, for example, the two eMMCs means that two
block queues with separate threads are created for no use
whatsoever.
I have concluded that this block device design for RPMB is
actually pretty wrong. The RPMB area should have been designed
to be accessed from /dev/mmcblkN directly, using ioctl()s on
the main block device. It is however way too late to change
that, since userspace expects to open an RPMB device in
/dev/mmcblkNrpmb and we cannot break userspace.
This patch tries to amend the situation using the following
strategy:
- Stop creating a block device for the RPMB partition/area
- Instead create a custom, dynamic character device with
the same name.
- Make this new character device support exactly the same
set of ioctl()s as the old block device.
- Wrap the requests back to the same ioctl() handlers, but
issue them on the block queue of the main partition/area,
i.e. /dev/mmcblkN
We need to create a special "rpmb" bus type in order to get
udev and/or busybox hot/coldplug to instantiate the device
node properly.
Before the patch, this appears in 'ps aux':
101 root 0:00 [mmcqd/2rpmb]
123 root 0:00 [mmcqd/3rpmb]
After applying the patch these surplus block queue threads
are gone, but RPMB is as usable as ever using the userspace
MMC tools, such as 'mmc rpmb read-counter'.
We get instead those dynamice devices in /dev:
brw-rw---- 1 root root 179, 0 Jan 1 2000 mmcblk0
brw-rw---- 1 root root 179, 1 Jan 1 2000 mmcblk0p1
brw-rw---- 1 root root 179, 2 Jan 1 2000 mmcblk0p2
brw-rw---- 1 root root 179, 5 Jan 1 2000 mmcblk0p5
brw-rw---- 1 root root 179, 8 Jan 1 2000 mmcblk2
brw-rw---- 1 root root 179, 16 Jan 1 2000 mmcblk2boot0
brw-rw---- 1 root root 179, 24 Jan 1 2000 mmcblk2boot1
crw-rw---- 1 root root 248, 0 Jan 1 2000 mmcblk2rpmb
brw-rw---- 1 root root 179, 32 Jan 1 2000 mmcblk3
brw-rw---- 1 root root 179, 40 Jan 1 2000 mmcblk3boot0
brw-rw---- 1 root root 179, 48 Jan 1 2000 mmcblk3boot1
brw-rw---- 1 root root 179, 33 Jan 1 2000 mmcblk3p1
crw-rw---- 1 root root 248, 1 Jan 1 2000 mmcblk3rpmb
Notice the (248,0) and (248,1) character devices for RPMB.
Cc: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
2017-09-20 08:02:00 +00:00
|
|
|
MMC_DRV_OP_IOCTL_RPMB,
|
2017-05-19 13:37:30 +00:00
|
|
|
MMC_DRV_OP_BOOT_WP,
|
2017-08-20 21:39:08 +00:00
|
|
|
MMC_DRV_OP_GET_CARD_STATUS,
|
|
|
|
MMC_DRV_OP_GET_EXT_CSD,
|
2017-05-19 13:37:28 +00:00
|
|
|
};
|
|
|
|
|
2011-07-09 21:12:36 +00:00
|
|
|
struct mmc_queue_req {
|
|
|
|
struct mmc_blk_request brq;
|
|
|
|
struct scatterlist *sg;
|
2017-02-01 12:47:55 +00:00
|
|
|
struct mmc_async_req areq;
|
2017-05-19 13:37:28 +00:00
|
|
|
enum mmc_drv_op drv_op;
|
2017-05-19 13:37:30 +00:00
|
|
|
int drv_op_result;
|
2017-08-20 21:39:06 +00:00
|
|
|
void *drv_op_data;
|
2017-05-18 09:29:35 +00:00
|
|
|
unsigned int ioc_count;
|
2011-07-09 21:12:36 +00:00
|
|
|
};
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
struct mmc_queue {
|
|
|
|
struct mmc_card *card;
|
2006-11-13 19:23:52 +00:00
|
|
|
struct task_struct *thread;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct semaphore thread_sem;
|
2017-02-01 12:47:56 +00:00
|
|
|
bool suspended;
|
2016-11-29 10:09:10 +00:00
|
|
|
bool asleep;
|
2016-11-18 12:36:15 +00:00
|
|
|
struct mmc_blk_data *blkdata;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct request_queue *queue;
|
mmc: core: Allocate per-request data using the block layer core
The mmc_queue_req is a per-request state container the MMC core uses
to carry bounce buffers, pointers to asynchronous requests and so on.
Currently allocated as a static array of objects, then as a request
comes in, a mmc_queue_req is assigned to it, and used during the
lifetime of the request.
This is backwards compared to how other block layer drivers work:
they usally let the block core provide a per-request struct that get
allocated right beind the struct request, and which can be obtained
using the blk_mq_rq_to_pdu() helper. (The _mq_ infix in this function
name is misleading: it is used by both the old and the MQ block
layer.)
The per-request struct gets allocated to the size stored in the queue
variable .cmd_size initialized using the .init_rq_fn() and
cleaned up using .exit_rq_fn().
The block layer code makes the MMC core rely on this mechanism to
allocate the per-request mmc_queue_req state container.
Doing this make a lot of complicated queue handling go away. We only
need to keep the .qnct that keeps count of how many request are
currently being processed by the MMC layer. The MQ block layer will
replace also this once we transition to it.
Doing this refactoring is necessary to move the ioctl() operations
into custom block layer requests tagged with REQ_OP_DRV_[IN|OUT]
instead of the custom code using the BigMMCHostLock that we have
today: those require that per-request data be obtainable easily from
a request after creating a custom request with e.g.:
struct request *rq = blk_get_request(q, REQ_OP_DRV_IN, __GFP_RECLAIM);
struct mmc_queue_req *mq_rq = req_to_mq_rq(rq);
And this is not possible with the current construction, as the request
is not immediately assigned the per-request state container, but
instead it gets assigned when the request finally enters the MMC
queue, which is way too late for custom requests.
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
[Ulf: Folded in the fix to drop a call to blk_cleanup_queue()]
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Tested-by: Heiner Kallweit <hkallweit1@gmail.com>
2017-05-18 09:29:32 +00:00
|
|
|
/*
|
|
|
|
* FIXME: this counter is not a very reliable way of keeping
|
|
|
|
* track of how many requests that are ongoing. Switch to just
|
|
|
|
* letting the block core keep track of requests and per-request
|
|
|
|
* associated mmc_queue_req data.
|
|
|
|
*/
|
2017-03-13 12:36:35 +00:00
|
|
|
int qcnt;
|
2005-04-16 22:20:36 +00:00
|
|
|
};
|
|
|
|
|
2011-06-23 10:40:28 +00:00
|
|
|
extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
|
|
|
|
const char *);
|
2005-04-16 22:20:36 +00:00
|
|
|
extern void mmc_cleanup_queue(struct mmc_queue *);
|
|
|
|
extern void mmc_queue_suspend(struct mmc_queue *);
|
|
|
|
extern void mmc_queue_resume(struct mmc_queue *);
|
2011-07-09 21:12:36 +00:00
|
|
|
extern unsigned int mmc_queue_map_sg(struct mmc_queue *,
|
|
|
|
struct mmc_queue_req *);
|
2007-05-11 22:26:16 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
#endif
|