diff options
-rw-r--r-- | drivers/mmc/card/block.c | 4 | ||||
-rwxr-xr-x | drivers/mmc/core/core.c | 16 | ||||
-rw-r--r-- | include/trace/events/mmc.h | 91 |
3 files changed, 110 insertions, 1 deletions
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 586b4ca4725e..dcdc948fbddb 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -35,6 +35,10 @@ #include <linux/capability.h> #include <linux/compat.h> +#include <linux/interrupt.h> +#define CREATE_TRACE_POINTS +#include <trace/events/mmc.h> + #include <linux/mmc/ioctl.h> #include <linux/mmc/card.h> #include <linux/mmc/host.h> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 58a38153db63..cd4f5ffc76ca 100755 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -27,6 +27,8 @@ #include <linux/suspend.h> #include <linux/wakelock.h> +#include <trace/events/mmc.h> + #include <linux/mmc/card.h> #include <linux/mmc/host.h> #include <linux/mmc/mmc.h> @@ -123,6 +125,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) { @@ -322,8 +325,12 @@ struct mmc_async_req *mmc_start_req(struct mmc_host *host, } } - if (areq) + if (areq) { + trace_mmc_blk_rw_start(areq->mrq->cmd->opcode, + areq->mrq->cmd->arg, + areq->mrq->data); __mmc_start_req(host, areq->mrq); + } if (host->areq) mmc_post_req(host, host->areq->mrq, 0); @@ -1678,8 +1685,13 @@ static int mmc_do_erase(struct mmc_card *card, unsigned int from, { struct mmc_command cmd = {0}; unsigned int qty = 0; + 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. @@ -1771,6 +1783,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 <linux/tracepoint.h> +#include <linux/mmc/mmc.h> +#include <linux/mmc/core.h> + +/* + * 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 <trace/define_trace.h> |