diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 7bbf0cda51c3..f1783c4516d8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -35,6 +35,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + #include #include #include @@ -1002,9 +1005,12 @@ retry: goto out; } - if (mmc_can_sanitize(card)) + if (mmc_can_sanitize(card)) { + trace_mmc_blk_erase_start(EXT_CSD_SANITIZE_START, 0, 0); err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_SANITIZE_START, 1, 0); + trace_mmc_blk_erase_end(EXT_CSD_SANITIZE_START, 0, 0); + } out_retry: if (err && !mmc_blk_reset(md, card->host, type)) goto retry; diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 812f3d98bfc8..6a83f4ccc108 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -173,6 +175,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) pr_debug("%s: %d bytes transferred: %d\n", mmc_hostname(host), mrq->data->bytes_xfered, mrq->data->error); + trace_mmc_blk_rw_end(cmd->opcode, cmd->arg, mrq->data); } if (mrq->stop) { @@ -537,8 +540,12 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, mmc_start_bkops(host->card, true); } - if (!err && areq) + if (!err && areq) { + trace_mmc_blk_rw_start(areq->mrq->cmd->opcode, + areq->mrq->cmd->arg, + areq->mrq->data); start_err = __mmc_start_data_req(host, areq->mrq); + } if (host->areq) mmc_post_req(host, host->areq->mrq, 0); @@ -1848,8 +1855,13 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, struct mmc_command cmd = {0}; unsigned int qty = 0; unsigned long timeout; + unsigned int fr, nr; int err; + fr = from; + nr = to - from + 1; + trace_mmc_blk_erase_start(arg, fr, nr); + /* * qty is used to calculate the erase timeout which depends on how many * erase groups (or allocation units in SD terminology) are affected. @@ -1953,6 +1965,8 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, } while (!(cmd.resp[0] & R1_READY_FOR_DATA) || (R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG)); out: + + trace_mmc_blk_erase_end(arg, fr, nr); return err; } diff --git a/include/trace/events/mmc.h b/include/trace/events/mmc.h new file mode 100644 index 000000000000..82b368dbcefc --- /dev/null +++ b/include/trace/events/mmc.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2013 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM mmc + +#if !defined(_TRACE_MMC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MMC_H + +#include +#include +#include + +/* + * Unconditional logging of mmc block erase operations, + * including cmd, address, size + */ +DECLARE_EVENT_CLASS(mmc_blk_erase_class, + TP_PROTO(unsigned int cmd, unsigned int addr, unsigned int size), + TP_ARGS(cmd, addr, size), + TP_STRUCT__entry( + __field(unsigned int, cmd) + __field(unsigned int, addr) + __field(unsigned int, size) + ), + TP_fast_assign( + __entry->cmd = cmd; + __entry->addr = addr; + __entry->size = size; + ), + TP_printk("cmd=%u,addr=0x%08x,size=0x%08x", + __entry->cmd, __entry->addr, __entry->size) +); + +DEFINE_EVENT(mmc_blk_erase_class, mmc_blk_erase_start, + TP_PROTO(unsigned int cmd, unsigned int addr, unsigned int size), + TP_ARGS(cmd, addr, size)); + +DEFINE_EVENT(mmc_blk_erase_class, mmc_blk_erase_end, + TP_PROTO(unsigned int cmd, unsigned int addr, unsigned int size), + TP_ARGS(cmd, addr, size)); + +/* + * Logging of start of read or write mmc block operation, + * including cmd, address, size + */ +DECLARE_EVENT_CLASS(mmc_blk_rw_class, + TP_PROTO(unsigned int cmd, unsigned int addr, struct mmc_data *data), + TP_ARGS(cmd, addr, data), + TP_STRUCT__entry( + __field(unsigned int, cmd) + __field(unsigned int, addr) + __field(unsigned int, size) + ), + TP_fast_assign( + __entry->cmd = cmd; + __entry->addr = addr; + __entry->size = data->blocks; + ), + TP_printk("cmd=%u,addr=0x%08x,size=0x%08x", + __entry->cmd, __entry->addr, __entry->size) +); + +DEFINE_EVENT_CONDITION(mmc_blk_rw_class, mmc_blk_rw_start, + TP_PROTO(unsigned int cmd, unsigned int addr, struct mmc_data *data), + TP_ARGS(cmd, addr, data), + TP_CONDITION(((cmd == MMC_READ_MULTIPLE_BLOCK) || + (cmd == MMC_WRITE_MULTIPLE_BLOCK)) && + data)); + +DEFINE_EVENT_CONDITION(mmc_blk_rw_class, mmc_blk_rw_end, + TP_PROTO(unsigned int cmd, unsigned int addr, struct mmc_data *data), + TP_ARGS(cmd, addr, data), + TP_CONDITION(((cmd == MMC_READ_MULTIPLE_BLOCK) || + (cmd == MMC_WRITE_MULTIPLE_BLOCK)) && + data)); +#endif /* _TRACE_MMC_H */ + +/* This part must be outside protection */ +#include