spbx/roms/srcs/images/ethernet/common/debug_info.c

293 lines
5.9 KiB
C

#ifdef __KERNEL__
#include "debug_info.h"
#include "log.h"
#define TOLOWER(x) ((x) | 0x20)
static const struct file_operations g_DbgSeq_fops;
static struct proc_dir_entry* g_DebugProcFS;
int InitDebugInfoProc(const char* proc_dir_name)
{
if(proc_dir_name)
{
g_DebugProcFS = proc_mkdir(proc_dir_name, NULL);
if(g_DebugProcFS != NULL)
{
return ERR_DBGFS_NO_ERROR;
}
}
return ERR_DBGFS_INIT;
}
void DeInitDebugInfoProc(void)
{
remove_proc_entry(g_DebugProcFS->name, NULL);
}
int DebugFsRegister(PDBGFS_PRIV pv)
{
struct proc_dir_entry* file;
if(pv == NULL)
{
return ERR_PARA_OUTOFRANGE;
}
file = create_proc_entry(pv->name, 0, g_DebugProcFS);
if(!file)
{
return ERR_DBGFS_REGISTER;
}
else
{
file->proc_fops = &g_DbgSeq_fops;
file->data = pv;
}
return ERR_DBGFS_NO_ERROR;
}
int DebugFsUnRegister(PDBGFS_PRIV pv)
{
if(strlen(pv->name) > 0)
{
remove_proc_entry(pv->name, g_DebugProcFS);
return ERR_DBGFS_NO_ERROR;
}
return ERR_DBGFS_UNREGISTER;
}
static int DbgSeqOpen(struct inode* inode, struct file* file)
{
PDBGFS_PRIV priv = (PDBGFS_PRIV)(PDE(inode)->data);
return single_open(file, priv->show, priv);
}
static int DbgSeqRelease(struct inode* inode, struct file* file)
{
return single_release(inode, file);
}
static int GetValueBase(unsigned char* pBuf)
{
int i = 0;
int strLen = strlen(pBuf);
if(pBuf)
{
if(pBuf[0] == '0' && pBuf[1] == 'x')
{
return 16;
}
for(i = 0; i < strLen; i++)
{
if(TOLOWER(pBuf[i]) >= 'a' && TOLOWER(pBuf[i]) <= 'f')
{
return 16;
}
}
}
return 10;
}
int GetStringParamValue(unsigned char* pBuf, int index, unsigned char* pValue, unsigned int maxBytes)
{
char tmpBuf[128];
char* token;
char* s = tmpBuf;
int paramIndex = 0;
if(pBuf == NULL || index < 0 || pValue == NULL)
{
return ERR_PARA_OUTOFRANGE;
}
memset(pValue, 0, maxBytes);
strcpy(tmpBuf, pBuf);
for(token = strsep(&s, " ");
token != NULL;
token = strsep(&s, " "))
{
if(token != NULL)
{
if(index != paramIndex)
{
paramIndex += 1;
continue;
}
strcpy(pValue, token);
return ERR_DBGFS_NO_ERROR;
}
}
return ERR_DBGFS_WRITEOPTS;
}
int GetIntParamValue(unsigned char* pBuf, int index)
{
char tmpBuf[128];
char* token;
char* s = tmpBuf;
int paramIndex = 0;
int paramValue = -1;
if(pBuf == NULL || index < 0)
{
return -1;
}
strcpy(tmpBuf, pBuf);
for(token = strsep(&s, " ");
token != NULL;
token = strsep(&s, " "))
{
if(token != NULL)
{
if(index != paramIndex)
{
paramIndex += 1;
continue;
}
if(strict_strtol(token, GetValueBase(token), (long*)&paramValue))
{
LOG_EX(LOG_Error, "strict_strtol [%s] Error\n", token);
return -1;
}
else
{
return paramValue;
}
}
}
return -1;
}
static int ProcessInputContent(struct seq_file* seq, unsigned char* pBuf, PDBGFS_PRIV pv)
{
int strLen = strlen(pBuf) - 1;
char tmpBuf[MAX_CMD_LEN], cmdBuf[32], paramBuf[64];
int i = 0;
int bIsCmd = FALSE;
memset(tmpBuf, 0, MAX_CMD_LEN);
memset(cmdBuf, 0, 32);
memset(paramBuf, 0, 64);
strcpy(tmpBuf, pBuf);
if(pBuf == NULL && pv == NULL)
{
return ERR_PARA_OUTOFRANGE;
}
for(i = 0; i < strLen; i++)
{
if(tmpBuf[i] == ' ')
{
strncpy(cmdBuf, tmpBuf, i);
strncpy(paramBuf, &tmpBuf[i + 1], MAX(strLen - i - 1, 0));
bIsCmd = TRUE;
break;
}
}
if(!bIsCmd)
{
if(strict_strtoul(pBuf, GetValueBase(pBuf), (long unsigned int*)&pv->params))
{
LOG_EX(LOG_Error, "strict_strtoul [%s] base %d Error\n", pBuf, GetValueBase(pBuf));
return -ERR_DBGFS_WRITEOPTS;
}
}
else
{
if(pv->ioctl != NULL)
{
pv->ioctl(seq, cmdBuf, paramBuf);
}
}
return ERR_PARA_OUTOFRANGE;
}
static ssize_t DgbSeqOptionsWrite(struct file* file, const char __user* userbuf,
size_t count, loff_t* data)
{
char buf[64];
struct seq_file* seq = (struct seq_file*)file->private_data;
PDBGFS_PRIV pv = (PDBGFS_PRIV)seq->private;
if(count >= sizeof(buf))
{
LOG_EX(LOG_Error, "Input Params Error:count = %d, max size = %d\n", count,
sizeof(buf));
return -ERR_PARA_OUTOFRANGE;
}
if(copy_from_user(buf, userbuf, count))
{
LOG_EX(LOG_Error, "Copy Data To Kernel Error\n");
return -ERR_DBGFS_WRITEOPTS;
}
if(buf[0] == 'h' &&
buf[1] == 'e' &&
buf[2] == 'l' &&
buf[3] == 'p')
{
if(pv->help != NULL)
{
pv->help((struct seq_file*)file->private_data, pv);
}
return count;
}
buf[count] = 0x00;
if(ProcessInputContent(seq, buf, pv) == ERR_PARA_OUTOFRANGE)
{
// LOG_EX(LOG_Debug, "Process [%s] Options Cmd[%s] Params [%u(hex:%08X)]\n",
// pv->name,
// (strlen(pv->cmd) <= 0) ? "NA" : pv->cmd,
// pv->params, pv->params);
}
else
{
LOG_EX(LOG_Error, "Input [%s] Process Error\n", buf);
}
return count;
}
static const struct file_operations g_DbgSeq_fops =
{
.owner = THIS_MODULE,
.open = DbgSeqOpen,
.read = seq_read,
.write = DgbSeqOptionsWrite,
.llseek = seq_lseek,
.release = DbgSeqRelease,
};
#endif