blk/mmc: add function blk_dread_prepare
This function prepares to read data without confirming completed. We can use it to prefetch data and run other process. Signed-off-by: Jason Zhu <jason.zhu@rock-chips.com> Change-Id: I76116c25dfdb7559b80a0216c414189e85409a3e
This commit is contained in:
parent
55eb094f8a
commit
47f7fd3a52
|
|
@ -22,6 +22,15 @@ config SPL_BLK
|
||||||
be partitioned into several areas, called 'partitions' in U-Boot.
|
be partitioned into several areas, called 'partitions' in U-Boot.
|
||||||
A filesystem can be placed in each partition.
|
A filesystem can be placed in each partition.
|
||||||
|
|
||||||
|
config SPL_BLK_READ_PREPARE
|
||||||
|
bool "Support block devices prepare to read data in SPL"
|
||||||
|
depends on SPL_BLK
|
||||||
|
help
|
||||||
|
Enable support for block devices to prefetch data. MMC and mtd_blk
|
||||||
|
devices can be attached to block devices. It is applied to prefetch
|
||||||
|
data in the background and the device run some other process in the
|
||||||
|
same time.
|
||||||
|
|
||||||
config BLOCK_CACHE
|
config BLOCK_CACHE
|
||||||
bool "Use block device cache"
|
bool "Use block device cache"
|
||||||
default n
|
default n
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,20 @@ unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
|
||||||
return blks_read;
|
return blks_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
unsigned long blk_dread_prepare(struct blk_desc *block_dev, lbaint_t start,
|
||||||
|
lbaint_t blkcnt, void *buffer)
|
||||||
|
{
|
||||||
|
struct udevice *dev = block_dev->bdev;
|
||||||
|
const struct blk_ops *ops = blk_get_ops(dev);
|
||||||
|
|
||||||
|
if (!ops->read)
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
return ops->read_prepare(dev, start, blkcnt, buffer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
|
unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
|
||||||
lbaint_t blkcnt, const void *buffer)
|
lbaint_t blkcnt, const void *buffer)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <bouncebuf.h>
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <bouncebuf.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <memalign.h>
|
#include <memalign.h>
|
||||||
|
|
@ -437,6 +437,135 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
#ifdef CONFIG_DM_MMC
|
||||||
|
static int dwmci_send_cmd_prepare(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data)
|
||||||
|
{
|
||||||
|
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||||
|
#else
|
||||||
|
static int dwmci_send_cmd_prepare(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
struct dwmci_host *host = mmc->priv;
|
||||||
|
struct dwmci_idmac *cur_idmac;
|
||||||
|
int ret = 0, flags = 0, i;
|
||||||
|
unsigned int timeout = 500;
|
||||||
|
u32 retry = 100000;
|
||||||
|
u32 mask;
|
||||||
|
ulong start = get_timer(0);
|
||||||
|
struct bounce_buffer bbstate;
|
||||||
|
|
||||||
|
cur_idmac = malloc(ROUND(DIV_ROUND_UP(data->blocks, 8) *
|
||||||
|
sizeof(struct dwmci_idmac),
|
||||||
|
ARCH_DMA_MINALIGN) + ARCH_DMA_MINALIGN - 1);
|
||||||
|
if (!cur_idmac)
|
||||||
|
return -ENODATA;
|
||||||
|
|
||||||
|
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
|
||||||
|
if (get_timer(start) > timeout) {
|
||||||
|
debug("%s: Timeout on data busy\n", __func__);
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dwmci_writel(host, DWMCI_RINTSTS, DWMCI_INTMSK_ALL);
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
if (host->fifo_mode) {
|
||||||
|
dwmci_writel(host, DWMCI_BLKSIZ, data->blocksize);
|
||||||
|
dwmci_writel(host, DWMCI_BYTCNT,
|
||||||
|
data->blocksize * data->blocks);
|
||||||
|
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
|
||||||
|
} else {
|
||||||
|
if (data->flags == MMC_DATA_READ) {
|
||||||
|
bounce_buffer_start(&bbstate, (void *)data->dest,
|
||||||
|
data->blocksize *
|
||||||
|
data->blocks, GEN_BB_WRITE);
|
||||||
|
} else {
|
||||||
|
bounce_buffer_start(&bbstate, (void *)data->src,
|
||||||
|
data->blocksize *
|
||||||
|
data->blocks, GEN_BB_READ);
|
||||||
|
}
|
||||||
|
dwmci_prepare_data(host, data, cur_idmac,
|
||||||
|
bbstate.bounce_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dwmci_writel(host, DWMCI_CMDARG, cmd->cmdarg);
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
flags = dwmci_set_transfer_mode(host, data);
|
||||||
|
|
||||||
|
if ((cmd->resp_type & MMC_RSP_136) && (cmd->resp_type & MMC_RSP_BUSY))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
|
||||||
|
flags |= DWMCI_CMD_ABORT_STOP;
|
||||||
|
else
|
||||||
|
flags |= DWMCI_CMD_PRV_DAT_WAIT;
|
||||||
|
|
||||||
|
if (cmd->resp_type & MMC_RSP_PRESENT) {
|
||||||
|
flags |= DWMCI_CMD_RESP_EXP;
|
||||||
|
if (cmd->resp_type & MMC_RSP_136)
|
||||||
|
flags |= DWMCI_CMD_RESP_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->resp_type & MMC_RSP_CRC)
|
||||||
|
flags |= DWMCI_CMD_CHECK_CRC;
|
||||||
|
|
||||||
|
flags |= (cmd->cmdidx | DWMCI_CMD_START | DWMCI_CMD_USE_HOLD_REG);
|
||||||
|
|
||||||
|
debug("Sending CMD%d\n", cmd->cmdidx);
|
||||||
|
|
||||||
|
dwmci_writel(host, DWMCI_CMD, flags);
|
||||||
|
|
||||||
|
for (i = 0; i < retry; i++) {
|
||||||
|
mask = dwmci_readl(host, DWMCI_RINTSTS);
|
||||||
|
if (mask & DWMCI_INTMSK_CDONE) {
|
||||||
|
if (!data)
|
||||||
|
dwmci_writel(host, DWMCI_RINTSTS, mask);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == retry) {
|
||||||
|
debug("%s: Timeout.\n", __func__);
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & DWMCI_INTMSK_RTO) {
|
||||||
|
/*
|
||||||
|
* Timeout here is not necessarily fatal. (e)MMC cards
|
||||||
|
* will splat here when they receive CMD55 as they do
|
||||||
|
* not support this command and that is exactly the way
|
||||||
|
* to tell them apart from SD cards. Thus, this output
|
||||||
|
* below shall be debug(). eMMC cards also do not favor
|
||||||
|
* CMD8, please keep that in mind.
|
||||||
|
*/
|
||||||
|
debug("%s: Response Timeout.\n", __func__);
|
||||||
|
return -ETIMEDOUT;
|
||||||
|
} else if (mask & DWMCI_INTMSK_RE) {
|
||||||
|
debug("%s: Response Error.\n", __func__);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd->resp_type & MMC_RSP_PRESENT) {
|
||||||
|
if (cmd->resp_type & MMC_RSP_136) {
|
||||||
|
cmd->response[0] = dwmci_readl(host, DWMCI_RESP3);
|
||||||
|
cmd->response[1] = dwmci_readl(host, DWMCI_RESP2);
|
||||||
|
cmd->response[2] = dwmci_readl(host, DWMCI_RESP1);
|
||||||
|
cmd->response[3] = dwmci_readl(host, DWMCI_RESP0);
|
||||||
|
} else {
|
||||||
|
cmd->response[0] = dwmci_readl(host, DWMCI_RESP0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
|
static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
|
||||||
{
|
{
|
||||||
u32 div, status;
|
u32 div, status;
|
||||||
|
|
@ -669,6 +798,9 @@ int dwmci_probe(struct udevice *dev)
|
||||||
const struct dm_mmc_ops dm_dwmci_ops = {
|
const struct dm_mmc_ops dm_dwmci_ops = {
|
||||||
.card_busy = dwmci_card_busy,
|
.card_busy = dwmci_card_busy,
|
||||||
.send_cmd = dwmci_send_cmd,
|
.send_cmd = dwmci_send_cmd,
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
.send_cmd_prepare = dwmci_send_cmd_prepare,
|
||||||
|
#endif
|
||||||
.set_ios = dwmci_set_ios,
|
.set_ios = dwmci_set_ios,
|
||||||
.get_cd = dwmci_get_cd,
|
.get_cd = dwmci_get_cd,
|
||||||
.execute_tuning = dwmci_execute_tuning,
|
.execute_tuning = dwmci_execute_tuning,
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,37 @@ int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
int dm_mmc_send_cmd_prepare(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data)
|
||||||
|
{
|
||||||
|
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
||||||
|
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mmmc_trace_before_send(mmc, cmd);
|
||||||
|
if (ops->send_cmd_prepare)
|
||||||
|
ret = ops->send_cmd_prepare(dev, cmd, data);
|
||||||
|
else
|
||||||
|
ret = -ENOSYS;
|
||||||
|
mmmc_trace_after_send(mmc, cmd, ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
{
|
{
|
||||||
return dm_mmc_send_cmd(mmc->dev, cmd, data);
|
return dm_mmc_send_cmd(mmc->dev, cmd, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
int mmc_send_cmd_prepare(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
|
{
|
||||||
|
return dm_mmc_send_cmd_prepare(mmc->dev, cmd, data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool mmc_card_busy(struct mmc *mmc)
|
bool mmc_card_busy(struct mmc *mmc)
|
||||||
{
|
{
|
||||||
struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev);
|
struct dm_mmc_ops *ops = mmc_get_ops(mmc->dev);
|
||||||
|
|
@ -289,6 +315,9 @@ static int mmc_blk_probe(struct udevice *dev)
|
||||||
|
|
||||||
static const struct blk_ops mmc_blk_ops = {
|
static const struct blk_ops mmc_blk_ops = {
|
||||||
.read = mmc_bread,
|
.read = mmc_bread,
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
.read_prepare = mmc_bread_prepare,
|
||||||
|
#endif
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#ifndef CONFIG_SPL_BUILD
|
||||||
.write = mmc_bwrite,
|
.write = mmc_bwrite,
|
||||||
.erase = mmc_berase,
|
.erase = mmc_berase,
|
||||||
|
|
|
||||||
|
|
@ -263,6 +263,37 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
|
||||||
return blkcnt;
|
return blkcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
static int mmc_read_blocks_prepare(struct mmc *mmc, void *dst, lbaint_t start,
|
||||||
|
lbaint_t blkcnt)
|
||||||
|
{
|
||||||
|
struct mmc_cmd cmd;
|
||||||
|
struct mmc_data data;
|
||||||
|
|
||||||
|
if (blkcnt > 1)
|
||||||
|
cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
|
||||||
|
else
|
||||||
|
cmd.cmdidx = MMC_CMD_READ_SINGLE_BLOCK;
|
||||||
|
|
||||||
|
if (mmc->high_capacity)
|
||||||
|
cmd.cmdarg = start;
|
||||||
|
else
|
||||||
|
cmd.cmdarg = start * mmc->read_bl_len;
|
||||||
|
|
||||||
|
cmd.resp_type = MMC_RSP_R1;
|
||||||
|
|
||||||
|
data.dest = dst;
|
||||||
|
data.blocks = blkcnt;
|
||||||
|
data.blocksize = mmc->read_bl_len;
|
||||||
|
data.flags = MMC_DATA_READ;
|
||||||
|
|
||||||
|
if (mmc_send_cmd_prepare(mmc, &cmd, &data))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return blkcnt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(BLK)
|
#if CONFIG_IS_ENABLED(BLK)
|
||||||
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
|
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
|
||||||
#else
|
#else
|
||||||
|
|
@ -339,6 +370,77 @@ re_init_retry:
|
||||||
return blkcnt;
|
return blkcnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
#if CONFIG_IS_ENABLED(BLK)
|
||||||
|
ulong mmc_bread_prepare(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst)
|
||||||
|
#else
|
||||||
|
ulong mmc_bread_prepare(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
|
void *dst)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if CONFIG_IS_ENABLED(BLK)
|
||||||
|
struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
|
||||||
|
#endif
|
||||||
|
int dev_num = block_dev->devnum;
|
||||||
|
int timeout = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (blkcnt == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
struct mmc *mmc = find_mmc_device(dev_num);
|
||||||
|
|
||||||
|
if (!mmc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (CONFIG_IS_ENABLED(MMC_TINY))
|
||||||
|
err = mmc_switch_part(mmc, block_dev->hwpart);
|
||||||
|
else
|
||||||
|
err = blk_dselect_hwpart(block_dev, block_dev->hwpart);
|
||||||
|
|
||||||
|
if (err < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ((start + blkcnt) > block_dev->lba) {
|
||||||
|
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
|
||||||
|
printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
|
||||||
|
start + blkcnt, block_dev->lba);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
|
||||||
|
debug("%s: Failed to set blocklen\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mmc_read_blocks_prepare(mmc, dst, start, blkcnt) != blkcnt) {
|
||||||
|
debug("%s: Failed to read blocks\n", __func__);
|
||||||
|
re_init_retry:
|
||||||
|
timeout++;
|
||||||
|
/*
|
||||||
|
* Try re-init seven times.
|
||||||
|
*/
|
||||||
|
if (timeout > 7) {
|
||||||
|
printf("Re-init retry timeout\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mmc->has_init = 0;
|
||||||
|
if (mmc_init(mmc))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (mmc_read_blocks_prepare(mmc, dst, start, blkcnt) != blkcnt) {
|
||||||
|
printf("%s: Re-init mmc_read_blocks_prepare error\n",
|
||||||
|
__func__);
|
||||||
|
goto re_init_retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blkcnt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void mmc_set_clock(struct mmc *mmc, uint clock)
|
void mmc_set_clock(struct mmc *mmc, uint clock)
|
||||||
{
|
{
|
||||||
if (clock > mmc->cfg->f_max)
|
if (clock > mmc->cfg->f_max)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
extern int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
extern int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
struct mmc_data *data);
|
struct mmc_data *data);
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
int mmc_send_cmd_prepare(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data);
|
||||||
|
#endif
|
||||||
extern int mmc_send_status(struct mmc *mmc, int timeout);
|
extern int mmc_send_status(struct mmc *mmc, int timeout);
|
||||||
extern int mmc_set_blocklen(struct mmc *mmc, int len);
|
extern int mmc_set_blocklen(struct mmc *mmc, int len);
|
||||||
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
|
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
|
||||||
|
|
@ -23,9 +27,17 @@ void mmc_adapter_card_type_ident(void);
|
||||||
#if CONFIG_IS_ENABLED(BLK)
|
#if CONFIG_IS_ENABLED(BLK)
|
||||||
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
|
ulong mmc_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
void *dst);
|
void *dst);
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
ulong mmc_bread_prepare(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
|
void *dst);
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
|
ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
void *dst);
|
void *dst);
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
ulong mmc_bread_prepare(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
|
void *dst);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
|
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
|
||||||
|
|
|
||||||
|
|
@ -224,6 +224,20 @@ struct blk_ops {
|
||||||
unsigned long (*read)(struct udevice *dev, lbaint_t start,
|
unsigned long (*read)(struct udevice *dev, lbaint_t start,
|
||||||
lbaint_t blkcnt, void *buffer);
|
lbaint_t blkcnt, void *buffer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* read_prepare() - read from a block device
|
||||||
|
*
|
||||||
|
* @dev: Device to read from
|
||||||
|
* @start: Start block number to read (0=first)
|
||||||
|
* @blkcnt: Number of blocks to read
|
||||||
|
* @buffer: Destination buffer for data read
|
||||||
|
* @return number of blocks read, or -ve error number (see the
|
||||||
|
* IS_ERR_VALUE() macro
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
unsigned long (*read_prepare)(struct udevice *dev, lbaint_t start,
|
||||||
|
lbaint_t blkcnt, void *buffer);
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* write() - write to a block device
|
* write() - write to a block device
|
||||||
*
|
*
|
||||||
|
|
@ -279,6 +293,10 @@ struct blk_ops {
|
||||||
*/
|
*/
|
||||||
unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
|
unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
|
||||||
lbaint_t blkcnt, void *buffer);
|
lbaint_t blkcnt, void *buffer);
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
unsigned long blk_dread_prepare(struct blk_desc *block_dev, lbaint_t start,
|
||||||
|
lbaint_t blkcnt, void *buffer);
|
||||||
|
#endif
|
||||||
unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
|
unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
|
||||||
lbaint_t blkcnt, const void *buffer);
|
lbaint_t blkcnt, const void *buffer);
|
||||||
unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
|
unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
|
||||||
|
|
|
||||||
|
|
@ -416,6 +416,18 @@ struct dm_mmc_ops {
|
||||||
int (*send_cmd)(struct udevice *dev, struct mmc_cmd *cmd,
|
int (*send_cmd)(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
struct mmc_data *data);
|
struct mmc_data *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send_cmd_prepare() - Send a command to the MMC device
|
||||||
|
*
|
||||||
|
* @dev: Device to receive the command
|
||||||
|
* @cmd: Command to send
|
||||||
|
* @data: Additional data to send/receive
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_SPL_BLK_READ_PREPARE
|
||||||
|
int (*send_cmd_prepare)(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data);
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* card_busy() - Query the card device status
|
* card_busy() - Query the card device status
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue