mblog.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 385 行

C
385
字号
/* * linux/arch/arm/mach-omap/dsp/mblog.c * * OMAP DSP driver Mailbox log module * * Copyright (C) 2003,2004 Nokia Corporation * * Written by Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: mblog.c * $Revision: 3.0.1 * $Date: 2004/10/04 * */#include <linux/module.h>#include <linux/sched.h>#include <linux/proc_fs.h>#include <linux/init.h>#include <asm/irq.h>#include <asm/arch/dsp.h>#include "dsp.h"#define CMD_L_TYPE_NULL		0#define CMD_L_TYPE_TID		1#define CMD_L_TYPE_SUBCMD	2struct cmdinfo {	char *name;	char cmd_l_type;};static const struct cmdinfo	cif_null     = { "Unknown",  CMD_L_TYPE_NULL   },	cif_wdsnd    = { "WDSND",    CMD_L_TYPE_TID    },	cif_wdreq    = { "WDREQ",    CMD_L_TYPE_TID    },	cif_bksnd    = { "BKSND",    CMD_L_TYPE_TID    },	cif_bkreq    = { "BKREQ",    CMD_L_TYPE_TID    },	cif_bkyld    = { "BKYLD",    CMD_L_TYPE_NULL   },	cif_bksndp   = { "BKSNDP",   CMD_L_TYPE_TID    },	cif_bkreqp   = { "BKREQP",   CMD_L_TYPE_TID    },	cif_tctl     = { "TCTL",     CMD_L_TYPE_TID    },	cif_mmap     = { "MMAP",     CMD_L_TYPE_TID    },	cif_wdt      = { "WDT",      CMD_L_TYPE_NULL   },	cif_runlevel = { "RUNLEVEL", CMD_L_TYPE_SUBCMD },	cif_pm       = { "PM",       CMD_L_TYPE_SUBCMD },	cif_tcfg     = { "TCFG",     CMD_L_TYPE_TID    },	cif_tadd     = { "TADD",     CMD_L_TYPE_TID    },	cif_tdel     = { "TDEL",     CMD_L_TYPE_TID    },	cif_tstop    = { "TSTOP",    CMD_L_TYPE_TID    },	cif_dspcfg   = { "DSPCFG",   CMD_L_TYPE_SUBCMD },	cif_regrw    = { "REGRW",    CMD_L_TYPE_SUBCMD },	cif_getvar   = { "GETVAR",   CMD_L_TYPE_SUBCMD },	cif_setvar   = { "SETVAR",   CMD_L_TYPE_SUBCMD },	cif_err      = { "ERR",      CMD_L_TYPE_SUBCMD },	cif_dbg      = { "DBG",      CMD_L_TYPE_NULL   };static const struct cmdinfo	*cmdinfo[128] = {/*00*/	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*10*/	&cif_wdsnd, &cif_wdreq, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*20*/	&cif_bksnd, &cif_bkreq, &cif_null, &cif_bkyld,	&cif_bksndp, &cif_bkreqp, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*30*/	&cif_tctl, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*40*/	&cif_mmap, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*50*/	&cif_wdt, &cif_runlevel, &cif_pm, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*60*/	&cif_tcfg, &cif_null, &cif_tadd, &cif_tdel,	&cif_null, &cif_tstop, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null,/*70*/	&cif_dspcfg, &cif_null, &cif_regrw, &cif_null,	&cif_getvar, &cif_setvar, &cif_null, &cif_null,	&cif_err, &cif_dbg, &cif_null, &cif_null,	&cif_null, &cif_null, &cif_null, &cif_null};/* * */char *cmd_name(unsigned char cmd_h){	return cmdinfo[cmd_h]->name;}#define RLCMD(nm)	OMAP_DSP_MBCMD_RUNLEVEL_##nm#define PMCMD(nm)	OMAP_DSP_MBCMD_PM_##nm#define CFGCMD(nm)	OMAP_DSP_MBCMD_DSPCFG_##nm#define REGCMD(nm)	OMAP_DSP_MBCMD_REGRW_##nm#define VICMD(nm)	OMAP_DSP_MBCMD_VARID_##nm#define EID(nm)		OMAP_DSP_EID_##nmchar *subcmd_name(unsigned char cmd_h, unsigned char cmd_l){	char *s;	switch (cmd_h) {	case MBCMD(RUNLEVEL):		s = (cmd_l == RLCMD(USER))     ? "USER":		    (cmd_l == RLCMD(SUPER))    ? "SUPER":		    (cmd_l == RLCMD(RECOVERY)) ? "RECOVERY":		    NULL;		break;	case MBCMD(PM):		s = (cmd_l == PMCMD(DISABLE)) ? "DISABLE":		    (cmd_l == PMCMD(ENABLE))  ? "ENABLE":		    NULL;		break;	case MBCMD(DSPCFG):		{			unsigned char cfgc = cmd_l & 0x7f;			s = (cfgc == CFGCMD(REQ))     ? "REQ":			    (cfgc == CFGCMD(SYSADRH)) ? "SYSADRH":			    (cfgc == CFGCMD(SYSADRL)) ? "SYSADRL":			    (cfgc == CFGCMD(PROTREV)) ? "PROTREV":			    NULL;			break;		}	case MBCMD(REGRW):		s = (cmd_l == REGCMD(MEMR)) ? "MEMR":		    (cmd_l == REGCMD(MEMW)) ? "MEMW":		    (cmd_l == REGCMD(IOR))  ? "IOR":		    (cmd_l == REGCMD(IOW))  ? "IOW":		    (cmd_l == REGCMD(DATA)) ? "DATA":		    NULL;		break;	case MBCMD(GETVAR):	case MBCMD(SETVAR):		s = (cmd_l == VICMD(ICRMASK)) ? "ICRMASK":		    NULL;		break;	case MBCMD(ERR):		s = (cmd_l == EID(BADTID))     ? "BADTID":		    (cmd_l == EID(BADTCN))     ? "BADTCN":		    (cmd_l == EID(BADBID))     ? "BADBID":		    (cmd_l == EID(BADCNT))     ? "BADCNT":		    (cmd_l == EID(NOTLOCKED))  ? "NOTLOCKED":		    (cmd_l == EID(STVBUF))     ? "STVBUF":		    (cmd_l == EID(BADADR))     ? "BADADR":		    (cmd_l == EID(BADTCTL))    ? "BADTCTL":		    (cmd_l == EID(BADPARAM))   ? "BADPARAM":		    (cmd_l == EID(FATAL))      ? "FATAL":		    (cmd_l == EID(NOMEM))      ? "NOMEM":		    (cmd_l == EID(NORES))      ? "NORES":		    (cmd_l == EID(IPBFULL))    ? "IPBFULL":		    (cmd_l == EID(TASKNOTRDY)) ? "TASKNOTRDY":		    (cmd_l == EID(TASKBSY))    ? "TASKBSY":		    (cmd_l == EID(TASKERR))    ? "TASKERR":		    (cmd_l == EID(BADCFGTYP))  ? "BADCFGTYP":		    (cmd_l == EID(DEBUG))      ? "DEBUG":		    (cmd_l == EID(BADSEQ))     ? "BADSEQ":		    (cmd_l == EID(BADCMD))     ? "BADCMD":		    NULL;		break;	default:		s = NULL;	}	return s;}#ifdef CONFIG_OMAP_DSP_MBLOG#define MBLOG_DEPTH	256struct mblogent {	unsigned long jiffies;	unsigned short cmd;	unsigned short data;	char dir;};static struct {	int wp;	unsigned long cnt, cnt_ad, cnt_da;	struct mblogent ent[MBLOG_DEPTH];} mblog = {	.wp = 0,	.cnt = 0,	.cnt_ad = 0,	.cnt_da = 0,};void omap_dsp_mblog_add(unsigned short cmd, unsigned short data, char dir){	struct mblogent *ent;	disable_irq(INT_D2A_MB1);	ent = &mblog.ent[mblog.wp];	ent->jiffies = jiffies;	ent->cmd     = cmd;	ent->data    = data;	ent->dir     = dir;	if (mblog.cnt < 0xffffffff)		mblog.cnt++;	switch (dir) {	case MBLOG_DIR_AD:		if (mblog.cnt_ad < 0xffffffff)			mblog.cnt_ad++;		break;	case MBLOG_DIR_DA:		if (mblog.cnt_da < 0xffffffff)			mblog.cnt_da++;		break;	}	if (++mblog.wp == MBLOG_DEPTH)		mblog.wp = 0;	enable_irq(INT_D2A_MB1);}#ifdef CONFIG_PROC_FSstatic int omap_dsp_proc_mblog_read(char *page, char **start, off_t off,				    int count, int *eof, void *data){	char *out;	int len;	int wp;	int i;	disable_irq(INT_D2A_MB1);	wp = mblog.wp;	out = page;	out += sprintf(out,		       "log count:%ld / ARM->DSP:%ld, DSP->ARM:%ld\n",		       mblog.cnt, mblog.cnt_ad, mblog.cnt_da);	if (mblog.cnt == 0)		goto done;	out += sprintf(out, "         ARM->DSP  ARM<-DSP\n");	out += sprintf(out, "jiffies  cmd  data cmd  data\n");	i = (mblog.cnt >= MBLOG_DEPTH) ? wp : 0;	do {		struct mblogent *ent = &mblog.ent[i];		unsigned char seq   = mb_sqbit(ent->cmd);		unsigned char cmd_h = mb_cmd_h(ent->cmd);		unsigned char cmd_l = mb_cmd_l(ent->cmd);		const struct cmdinfo *ci = cmdinfo[cmd_h];		out += sprintf(out,			       (ent->dir == MBLOG_DIR_AD)?				"%08lx %04x %04x           seq=%d":				"%08lx           %04x %04x seq=%d",			       ent->jiffies, ent->cmd, ent->data, seq);		switch (ci->cmd_l_type) {		case CMD_L_TYPE_SUBCMD:			{				char *subname;				subname = subcmd_name(cmd_h, cmd_l);				out += sprintf(out, " %s:%s\n",					       ci->name,					       subname ? subname : "Unknown");				break;			}		case CMD_L_TYPE_TID:			out += sprintf(out, " %s:task %d\n", ci->name, cmd_l);			break;		case CMD_L_TYPE_NULL:			out += sprintf(out, " %s\n", ci->name);			break;		}		if (++i == MBLOG_DEPTH)			i = 0;	} while (i != wp);done:	enable_irq(INT_D2A_MB1);	len = out - page;	len -= off;	if (len < count) {		*eof = 1;		if (len <= 0)			return 0;	} else {		len = count;	}	*start = page + off;	return len;}void __init omap_dsp_create_mblog_proc(void){	struct proc_dir_entry *ent;	ent = create_proc_read_entry("mblog", 0, procdir_dsp,				     omap_dsp_proc_mblog_read, NULL);	if (ent == NULL) {		printk(KERN_ERR		       "omapdsp: failed to register proc device: mblog\n");	}}void omap_dsp_remove_mblog_proc(void){	remove_proc_entry("mblog", procdir_dsp);}#endif /* CONFIG_PROC_FS */#endif /* CONFIG_OMAP_DSP_MBLOG */#ifdef CONFIG_OMAP_DSP_MBCMD_VERBOSEvoid omap_dsp_mblog_printcmd(unsigned short cmd, unsigned short data, char dir){	unsigned char seq   = mb_sqbit(cmd);	unsigned char cmd_h = mb_cmd_h(cmd);	unsigned char cmd_l = mb_cmd_l(cmd);	const struct cmdinfo *ci = cmdinfo[cmd_h];	char *dir_str;	char *subname;	dir_str = (dir == MBLOG_DIR_AD) ? "sending" : "receiving";	switch (ci->cmd_l_type) {	case CMD_L_TYPE_SUBCMD:		if ((subname = subcmd_name(cmd_h, cmd_l)) == NULL)			subname = "Unknown";		printk(KERN_DEBUG		       "mailbox: %s seq=%d, cmd=0x%04x(%s:%s), data=0x%04x\n",		       dir_str, seq, cmd, ci->name, subname, data);		break;	case CMD_L_TYPE_TID:		printk(KERN_DEBUG		       "mailbox: %s seq=%d, cmd=0x%04x(%s:task %d), data=0x%04x\n",		       dir_str, seq, cmd, ci->name, cmd_l, data);		break;	case CMD_L_TYPE_NULL:		printk(KERN_DEBUG		       "mailbox: %s seq=%d, cmd=0x%04x(%s), data=0x%04x\n",		       dir_str, seq, cmd, ci->name, data);		break;	}}#endif /* CONFIG_OMAP_DSP_MBCMD_VERBOSE */void __init omap_dsp_mblog_init(void){#ifdef CONFIG_OMAP_DSP_MBLOG#ifdef CONFIG_PROC_FS	omap_dsp_create_mblog_proc();#endif#endif}void omap_dsp_mblog_exit(void){#ifdef CONFIG_OMAP_DSP_MBLOG#ifdef CONFIG_PROC_FS	omap_dsp_remove_mblog_proc();#endif#endif}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?