nt9856x/code/application/source/cardv/SrcCode/Gx/GxStrg/GxStrgLnx.c

278 lines
7.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <mntent.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include "GxStrg.h"
#include "GxStrgInt.h"
#include "DxStorage.h"
#include "DxApi.h"
#define GXSTRG_STRCPY(dst, src, dst_size) do { strncpy(dst, src, dst_size-1); dst[dst_size-1] = '\0'; } while(0)
extern GXSTRG_LINUX_STATUS g_LnxStrgStatus[GXSTRG_STRG_NUM];
static int GxStrgLnx_DetStrgCard(DX_HANDLE StrgDXH)
{
UINT32 uiDxState = 0;
if (Dx_GetState(StrgDXH, STORAGE_STATE_INSERT, &uiDxState) == DX_OK && uiDxState == TRUE) {
return 1;
}
return 0;
}
static int GxStrgLnx_IsPathExist(char *path)
{
int fd;
fd = open(path, O_RDONLY);
if(fd < 0) {
return 0;
}
close(fd);
return 1;
}
static int GxStrgLnx_FindEntryByPrefix(const char *root_pathp, const char *prefix_namep, char *out_namep, int out_size)
{
DIR *pDIR;
struct dirent *entry = NULL;
int prefix_len;
int bfound = 0;
*out_namep = '\0';//set empty first
prefix_len = strlen(prefix_namep);
pDIR = opendir(root_pathp);
if (NULL == pDIR) {
return -1;
}
while (!bfound) {
entry = readdir(pDIR);
if (NULL == entry) {//reach the end
break;
}
if (0 == strncmp(entry->d_name, prefix_namep, prefix_len)) {
GXSTRG_STRCPY(out_namep, entry->d_name, out_size);
bfound = 1;
}
}
closedir(pDIR);
if (bfound) {
DBG_IND("Found %s in %s\r\n", out_namep, root_pathp);
return 0;
} else {
DBG_IND("Prefix:%s in %s not found\r\n", prefix_namep, root_pathp);
return -1;
}
}
static int GxStrgLnx_GetSD1DevByBus(char *out_path, int out_size)
{
#define MMC_SYS_PATH "/sys/bus/mmc/devices"
#define MMC0BUS_PREFIX "mmc0"
#define MMC0BUS "mmc2"
#define MMCDEV "mmc"
char find_path[64] = {0};//e.g. /sys/devices/platform/nt96660_mmc.0/mmc_host/mmc0/mmc0:b368/block
char dev_path[32] = {0};//e.g. /dev/mmcblk0p1, /dev/mmcblk0, /dev/mmcblk1p1, /dev/mmcblk1
char mmc_bus_name[16] = {0}; //e.g. mmc0:b368
char mmc_dev_name[16] = {0};
int bFound = 0, beMMCFound = 0;;
out_path[0] = '\0';//set empty first
//1. find the mmc2 to check eMMC is existed or not.
if(0 == GxStrgLnx_FindEntryByPrefix(MMC_SYS_PATH, MMC0BUS, mmc_bus_name, sizeof(mmc_bus_name))) {
DBG_IND("mmc0 bus not found\r\n");
beMMCFound = 1;
//return -1;
} else if(0 != GxStrgLnx_FindEntryByPrefix(MMC_SYS_PATH, MMC0BUS_PREFIX, mmc_bus_name, sizeof(mmc_bus_name))) { // find the bus mmc0 to check the card is inserted or not
DBG_IND("mmc0 bus not found\r\n");
return -1;
}
//2. get the device name from mmc0 information
snprintf(find_path, sizeof(find_path), "%s/%s/block", MMC_SYS_PATH, mmc_bus_name);
if (!GxStrgLnx_IsPathExist(find_path)) {
DBG_ERR("%s not found\r\n", find_path);
return -1;
}
if(0 != GxStrgLnx_FindEntryByPrefix(find_path, MMCDEV, mmc_dev_name, sizeof(mmc_dev_name))) {
DBG_IND("device not found\r\n");
return -1;
}
//3. try the real device name is mmcblk0/mmcblk1 or mmcblk0p1/mmcblk1p1
//find dev name with p1 (e.g. mmcblk0p1)
if (beMMCFound) { // emmc is mmcblk2p5.
snprintf(dev_path, sizeof(dev_path), "/dev/%sp5", mmc_dev_name);
DBG_IND("GxStrgLnx_GetSD1DevByBus: found emmc\r\n");
}
else {
snprintf(dev_path, sizeof(dev_path), "/dev/%sp1", mmc_dev_name);
}
if (GxStrgLnx_IsPathExist(dev_path)) {
bFound = 1;
}
if(!bFound) {//find dev name without p1. (e.g. mmcblk0)
snprintf(dev_path, sizeof(dev_path), "/dev/%s", mmc_dev_name);
if(GxStrgLnx_IsPathExist(dev_path)) {
bFound = 1;
}
}
if(bFound) {
DBG_IND("SD1Dev = %s\r\n", out_path);
GXSTRG_STRCPY(out_path, dev_path, out_size);
return 0;
} else {
DBG_ERR("The dev partition name not found\r\n");
return -1;
}
}
static int GxStrgLnx_GetDevByMountPath(char *pDevPath, const char* pMountPath, int BufSize)
{
struct mntent *ent;
FILE *Linux_pFILE;
int PathLen;
PathLen = strlen(pMountPath);
if('/' == pMountPath[PathLen-1]) {
PathLen--;//exclude the last '/' for strncmp
}
Linux_pFILE = setmntent("/proc/mounts", "r");
if (NULL == Linux_pFILE) {
DBG_ERR("setmntent error\n");
return -1;
}
while (NULL != (ent = getmntent(Linux_pFILE))) {
DBG_IND("%s => %s\n", ent->mnt_fsname, ent->mnt_dir);
if(0 == strncmp(pMountPath, ent->mnt_dir, PathLen)) {
strncpy(pDevPath, ent->mnt_fsname, BufSize-1);
pDevPath[BufSize-1] = '\0';
endmntent(Linux_pFILE);
return 0;
}
}
*pDevPath = 0;//clean the result
endmntent(Linux_pFILE);
return -1;
}
static INT32 GxStrgLnx_ChkStatus(UINT32 DevId)
{
CHAR DevPath[132] = {0}; //e.g. /dev/mmcblk0p1
CHAR *pMountPath = (CHAR *)&g_FSInitParam[DevId].FSParam.szMountPath; //e.g. /mnt/sd
INT32 ret;
UINT32 StrgCbVal;
BOOL bIsReadOnly = FALSE;
BOOL bIsFormatted;
static UINT32 StrgCbValPrev = STRG_CB_UNKNOWN;
//1. get the device name from the mount list
ret = GxStrgLnx_GetDevByMountPath(DevPath, pMountPath, sizeof(DevPath));
if (ret == 0) {
//0. if the storage object is set, detect card insert
if (g_pCurStrgDXH[DevId]) {
if (GxStrgLnx_DetStrgCard(g_pCurStrgDXH[DevId])) {
DBG_IND("Found %s is mounted on %s\r\n", DevPath, pMountPath);
StrgCbVal = STRG_CB_INSERTED;
bIsFormatted = TRUE;
goto label_exit;
} else {
DBG_IND("Found %s is removed (mounted on %s)\r\n", DevPath, pMountPath);
StrgCbVal = STRG_CB_REMOVED;
bIsFormatted = FALSE;
goto label_exit;
}
}
DBG_IND("Found %s is mounted on %s\r\n", DevPath, pMountPath);
StrgCbVal = STRG_CB_INSERTED;
bIsFormatted = TRUE;
goto label_exit;
}
//2. if the device is not mounted, get the dev name from the mmc0 bus
ret = GxStrgLnx_GetSD1DevByBus(DevPath, sizeof(DevPath));
if (ret == 0) {
//0. if the storage object is set, detect card insert
if (g_pCurStrgDXH[DevId]) {
if (GxStrgLnx_DetStrgCard(g_pCurStrgDXH[DevId])) {
DBG_IND("Found %s is unmounted but inserted\r\n", DevPath);
StrgCbVal = STRG_CB_INSERTED;
bIsFormatted = FALSE;
goto label_exit;
} else {
DBG_IND("Found %s is unmounted and removed\r\n", DevPath);
StrgCbVal = STRG_CB_REMOVED;
bIsFormatted = FALSE;
goto label_exit;
}
}
DBG_IND("Found %s is unmounted\r\n", DevPath);
StrgCbVal = STRG_CB_INSERTED;
bIsFormatted = FALSE;
goto label_exit;
}
else {
//0. if the storage object is set, detect card insert
if (g_pCurStrgDXH[DevId]) {
if (GxStrgLnx_DetStrgCard(g_pCurStrgDXH[DevId])) {
DBG_IND("Found %s is inserted on %s\r\n", DevPath, pMountPath);
StrgCbVal = STRG_CB_INSERTED;
bIsFormatted = FALSE;
goto label_exit;
} else {
DBG_IND("Found %s is removed\r\n", DevPath);
StrgCbVal = STRG_CB_REMOVED;
bIsFormatted = FALSE;
goto label_exit;
}
}
DBG_IND("Found %s is removed\r\n", DevPath);
StrgCbVal = STRG_CB_REMOVED;
bIsFormatted = FALSE;
goto label_exit;
}
label_exit:
if (StrgCbValPrev != StrgCbVal) {
g_LnxStrgStatus[DevId].IsInserted = (StrgCbVal == STRG_CB_INSERTED);
g_LnxStrgStatus[DevId].IsReadOnly = bIsReadOnly;
g_LnxStrgStatus[DevId].IsFormatted = bIsFormatted;
DBG_IND("MntPath %s, IsInserted %d, IsReadOnly %d, bIsFormatted %d\r\n",
g_FSInitParam[DevId].FSParam.szMountPath,
g_LnxStrgStatus[DevId].IsInserted,
g_LnxStrgStatus[DevId].IsReadOnly,
g_LnxStrgStatus[DevId].IsFormatted);
StrgCbValPrev = StrgCbVal;
}
if(g_LnxStrgStatus[DevId].IsInserted && bIsFormatted && !g_LnxStrgStatus[DevId].IsFormatted){
g_LnxStrgStatus[DevId].IsFormatted = bIsFormatted;
}
return 0;
}
INT32 GxStrgLnx_Det(UINT32 DevId)
{
if (0 != GxStrgLnx_ChkStatus(DevId)) {
return DET_CARD_UNKNOWN;
}
if (g_LnxStrgStatus[DevId].IsInserted) {
return DET_CARD_INSERTED;
} else {
return DET_CARD_REMOVED;
}
}