#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*)¶mValue)) { 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