blob: 80466724bc8d0d9c16d9ed7927b61d45bf298472 [file] [log] [blame]
/*
* Copyright (C) 2017 MediaTek Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#ifndef __MT_UFS_DEUBG__
#define __MT_UFS_DEUBG__
#include "ufs-mtk.h"
struct ufs_cmd_hlist_struct {
enum ufs_trace_event event;
u8 opcode;
u8 lun;
u8 crypted;
u8 keyslot;
pid_t pid;
u32 cpu;
u32 tag;
u32 transfer_len;
sector_t lba;
u64 time;
u64 duration;
struct request *rq;
unsigned long long ppn;
u32 region;
u32 subregion;
u32 resv;
};
/*
* snprintf may return a value of size or "more" to indicate
* that the output was truncated, thus be careful of "more"
* case.
*/
#define SPREAD_PRINTF(buff, size, evt, fmt, args...) \
do { \
if (buff && size && *(size)) { \
unsigned long var = snprintf(*(buff), *(size), fmt, ##args); \
if (var > 0) { \
if (var > *(size)) \
var = *(size); \
*(size) -= var; \
*(buff) += var; \
} \
} \
if (evt) \
seq_printf(evt, fmt, ##args); \
if (!buff && !evt) { \
pr_info(fmt, ##args); \
} \
} while (0)
#define SPREAD_DEV_PRINTF(buff, size, evt, dev, fmt, args...) \
do { \
if (buff && size && *(size)) { \
unsigned long var = snprintf(*(buff), *(size), fmt, ##args); \
if (var > 0) { \
*(size) -= var; \
*(buff) += var; \
} \
} \
if (evt) \
seq_printf(evt, fmt, ##args); \
if (!buff && !evt) { \
dev_info(dev, fmt, ##args); \
} \
} while (0)
enum {
UFS_CMDS_DUMP = 0,
UFS_GET_PWR_MODE = 1,
UFS_DUMP_HEALTH_DESCRIPTOR = 2,
UFS_CMD_HIST_BEGIN = 3,
UFS_CMD_HIST_STOP = 4,
UFS_CMD_UNKNOWN
};
#define UFS_PRINFO_PROC_MSG(evt, fmt, args...) \
do { \
if (evt == NULL) { \
pr_info(fmt, ##args); \
} \
else { \
seq_printf(evt, fmt, ##args); \
} \
} while (0)
#define UFS_DEVINFO_PROC_MSG(evt, dev, fmt, args...) \
do { \
if (evt == NULL) { \
dev_info(dev, fmt, ##args); \
} \
else { \
seq_printf(evt, fmt, ##args); \
} \
} while (0)
#define UFS_PRDBG_PROC_MSG(evt, fmt, args...) \
do { \
if (evt == NULL) { \
pr_dbg(fmt, ##args); \
} \
else { \
seq_printf(evt, fmt, ##args); \
} \
} while (0)
#define UFS_DEVDBG_PROC_MSG(evt, dev, fmt, args...) \
do { \
if (evt == NULL) { \
dev_dbg(dev, fmt, ##args); \
} \
else { \
seq_printf(evt, fmt, ##args); \
} \
} while (0)
int ufs_mtk_debug_proc_init(struct ufs_hba *hba);
void ufs_mtk_dbg_add_trace(struct ufs_hba *hba,
enum ufs_trace_event event, u32 tag,
u8 lun, u32 transfer_len, sector_t lba, u8 opcode,
unsigned long long ppn, u32 region, u32 subregion, u32 resv);
void ufs_mtk_dbg_stop_trace(struct ufs_hba *hba);
void ufs_mtk_dbg_start_trace(struct ufs_hba *hba);
void ufs_mtk_dbg_hang_detect_dump(void);
void ufs_mtk_dbg_proc_dump(struct seq_file *m);
void ufs_mtk_dme_cmd_log(struct ufs_hba *hba, struct uic_command *ucmd,
enum ufs_trace_event event);
void ufs_mtk_dbg_dump_trace(char **buff, unsigned long *size,
u32 latest_cnt, struct seq_file *m);
#endif