doubao_chat/apps/common/system/device_mount.c

522 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "device/device.h"
#include "event/event.h"
#include "event/device_event.h"
#include "asm/sfc_norflash_api.h"
#include "fs/fs.h"
#include "system/init.h"
#include "sdio/sdmmc.h"
#include "generic/ascii.h"
#include "app_config.h"
#if TCFG_USB_SLAVE_ENABLE || TCFG_USB_HOST_ENABLE
#include "usb_stack.h"
#include "msd.h"
#include "device/hid.h"
#include "uac_audio.h"
#include "usb_host.h"
#include "audio.h"
#include "hid.h"
#include "adb.h"
#include "usbnet.h"
#endif
#ifdef CONFIG_JLFAT_ENABLE
#define FAT_FILE_SYSTEM_NAME "jlfat"
#else
#define FAT_FILE_SYSTEM_NAME "fat"
#endif
#ifndef FAT_CACHE_NUM
#define FAT_CACHE_NUM 32
#endif
enum {
SD_UNMOUNT = 0,
SD_MOUNT_SUSS,
SD_MOUNT_FAILD,
};
static u8 sd_mount[2];
static OS_MUTEX sd_mutex;
static int __sd_mutex_init()
{
return os_mutex_create(&sd_mutex);
}
early_initcall(__sd_mutex_init);
static int mount_sd_to_fs(const char *sd_name)
{
int err = 0;
u32 class = 0, capacity = 0, block_size = 0;
struct imount *mt;
int id = sd_name[2] - '0';
const char *dev = sd_name;
void *fd = NULL;
err = os_mutex_pend(&sd_mutex, 0);
if (err) {
return -EFAULT;
}
if (sd_mount[id] == SD_MOUNT_SUSS) {
goto __exit;
}
if (sd_mount[id] == SD_MOUNT_FAILD) {
err = -EFAULT;
goto __exit;
}
if (!dev_online(dev)) {
err = -EFAULT;
goto __exit;
}
#ifdef CONFIG_DMSDX_ENABLE
u8 i = 0;
char sub_dev_name[7] = {0};
char mount_path_name[16] = {0};
strcpy(sub_dev_name, dev);
strcpy(mount_path_name, id ? "storage/sd1" : "storage/sd0");
do {
sub_dev_name[strlen(dev)] = '.';
sub_dev_name[strlen(dev) + 1] = '0' + i;
fd = dev_open(sub_dev_name, 0);
if (fd) {
dev_close(fd);
mount_path_name[11] = '.';
mount_path_name[12] = '0' + i;
++i;
mt = mount(sub_dev_name, mount_path_name, FAT_FILE_SYSTEM_NAME, FAT_CACHE_NUM, NULL);
if (!mt) {
printf("%s mount %s %s fail, format...", sub_dev_name, mount_path_name, FAT_FILE_SYSTEM_NAME);
f_format(sub_dev_name, FAT_FILE_SYSTEM_NAME, 32 * 1024);
mt = mount(sub_dev_name, id ? "storage/sd1" : "storage/sd0", FAT_FILE_SYSTEM_NAME, FAT_CACHE_NUM, NULL);
} else {
printf("%s mount %s %s suss", sub_dev_name, mount_path_name, FAT_FILE_SYSTEM_NAME);
}
}
} while (fd != NULL && i < 10);
if (i == 0)
#endif
{
mt = mount(dev, id ? "storage/sd1" : "storage/sd0", FAT_FILE_SYSTEM_NAME, FAT_CACHE_NUM, NULL);
if (!mt) {
printf("mount %s fail\n", sd_name);
err = -EFAULT;
goto __err;
} else {
printf("mount %s suss\n", sd_name);
}
}
#if RCSP_MODE
if (mt) {
set_rcsp_mount_mt(&mt);
}
#endif
fd = dev_open(dev, 0);
if (!fd) {
err = -EFAULT;
goto __err;
}
dev_ioctl(fd, SD_IOCTL_GET_CLASS, (u32)&class);
if (class == SD_CLASS_10) {
log_i("%s card class: 10\n", sd_name);
} else {
log_w("%s card class: %d\n", sd_name, class * 2);
}
dev_close(fd);
__err:
sd_mount[id] = err ? SD_MOUNT_FAILD : SD_MOUNT_SUSS;
__exit:
os_mutex_post(&sd_mutex);
return err;
}
static void unmount_sd_to_fs(const char *sd_name)
{
int id = sd_name[2] - '0';
os_mutex_pend(&sd_mutex, 0);
#ifdef CONFIG_DMSDX_ENABLE
u8 i = 0;
char mount_path_name[16] = {0};
strcpy(mount_path_name, id ? "storage/sd1" : "storage/sd0");
mount_path_name[11] = '.';
while (1) {
mount_path_name[12] = '0' + i;
if (!fmount_exist(mount_path_name)) {
break;
}
unmount(mount_path_name);
printf("unmount %s", mount_path_name);
++i;
}
if (i == 0)
#endif
{
unmount(id ? "storage/sd1" : "storage/sd0");
}
sd_mount[id] = SD_UNMOUNT;
printf("unmount %s\n", sd_name);
os_mutex_post(&sd_mutex);
}
int storage_device_ready(void)
{
if (!dev_online(SDX_DEV)) {
return false;
}
if (SDX_DEV[2] - '0' < 2 && sd_mount[SDX_DEV[2] - '0'] == SD_UNMOUNT) {
mount_sd_to_fs(SDX_DEV);
}
return fmount_exist(CONFIG_STORAGE_PATH);
}
int sdcard_storage_device_ready(const char *sd_name)
{
int id = sd_name[2] - '0';
if (!dev_online(sd_name)) {
return false;
}
if (sd_mount[id] == SD_UNMOUNT) {
mount_sd_to_fs(sd_name);
}
return fmount_exist(id ? "storage/sd1" : "storage/sd0");
}
int sdcard_storage_device_format(const char *sd_name)
{
int err;
if (!sd_name || strlen(sd_name) != 3) {
return -EPERM;
}
unmount_sd_to_fs(sd_name);
err = f_format(sd_name, FAT_FILE_SYSTEM_NAME, 32 * 1024);
if (err == 0) {
mount_sd_to_fs(sd_name);
}
return err;
}
#ifdef CONFIG_DMSDX_ENABLE
int sdcard_storage_subdevice_format(const char *dev_name)
{
int err;
char sd_name[6] = {0};
if (!dev_name || strlen(dev_name) != 5) {
return -EPERM;
}
memcpy(sd_name, dev_name, 3);
unmount_sd_to_fs(sd_name);
err = f_format(dev_name, FAT_FILE_SYSTEM_NAME, 32 * 1024);
if (err == 0) {
mount_sd_to_fs(sd_name);
}
return err;
}
#endif
/*
* sd卡插拔事件处理
*/
static void sd_event_handler(struct device_event *event)
{
switch (event->event) {
case DEVICE_EVENT_IN:
printf("%s: in\n", (const char *)event->arg);
mount_sd_to_fs(event->arg);
break;
case DEVICE_EVENT_OUT:
printf("%s: out\n", (const char *)event->arg);
unmount_sd_to_fs(event->arg);
break;
}
}
#if TCFG_UDISK_ENABLE
enum {
UDISK_UNMOUNT = 0,
UDISK_MOUNT_SUSS,
UDISK_MOUNT_FAILD,
};
static OS_MUTEX udisk_mutex;
static u8 udisk_mount[2];
static u8 udisk_online[2];
static int __udisk_mutex_init()
{
return os_mutex_create(&udisk_mutex);
}
early_initcall(__udisk_mutex_init);
static int mount_udisk_to_fs(int id)
{
int err = 0;
struct imount *mt;
u32 sta = 0;
const char *name = id ? "udisk1" : "udisk0";
err = os_mutex_pend(&udisk_mutex, 0);
if (err) {
return -EFAULT;
}
if (udisk_mount[id] == UDISK_MOUNT_SUSS) {
goto __exit;
}
if (udisk_mount[id] == UDISK_MOUNT_FAILD) {
err = -EFAULT;
goto __exit;
}
sta = dev_online(name);
if (!sta) {
err = -EFAULT;
goto __exit;
}
mt = mount(name, id ? "storage/udisk1" : "storage/udisk0", FAT_FILE_SYSTEM_NAME, FAT_CACHE_NUM, NULL);
if (!mt) {
printf("mount %s fail\n", name);
err = -EFAULT;
} else {
printf("mount %s suss\n", name);
}
__err:
udisk_mount[id] = err ? UDISK_MOUNT_FAILD : UDISK_MOUNT_SUSS;
__exit:
os_mutex_post(&udisk_mutex);
return err;
}
static void unmount_udisk_to_fs(int id)
{
os_mutex_pend(&udisk_mutex, 0);
unmount(id ? "storage/udisk1" : "storage/udisk0");
udisk_mount[id] = UDISK_UNMOUNT;
printf("unmount udisk%d\n", id);
os_mutex_post(&udisk_mutex);
}
int udisk_storage_device_ready(int id)
{
u32 sta = 0;
sta = dev_online(id ? "udisk1" : "udisk0");
if (!sta) {
return false;
}
if (udisk_mount[id] == UDISK_UNMOUNT) {
mount_udisk_to_fs(id);
}
return fmount_exist(id ? "storage/udisk1" : "storage/udisk0");
}
int udisk_storage_device_format(int id)
{
int err;
unmount_udisk_to_fs(id);
err = f_format(id ? "udisk1" : "udisk0", FAT_FILE_SYSTEM_NAME, 32 * 1024);
if (err == 0) {
mount_udisk_to_fs(id);
}
return err;
}
#endif
static u8 incharge;
int sys_power_is_charging(void)
{
return incharge;
}
static void otg_event_handler(struct device_event *event)
{
if (event->event == DEVICE_EVENT_IN) {
if (((const char *)event->value)[0] == 'h') {
int usb_id = ((const char *)event->value)[2] - '0';
log_i("usb%d connect, host mode\n", usb_id);
#if TCFG_UDISK_ENABLE || TCFG_HOST_AUDIO_ENABLE || TCFG_HOST_UVC_ENABLE || TCFG_HOST_WIRELESS_ENABLE || TCFG_HID_HOST_ENABLE || TCFG_ADB_ENABLE
usb_host_mount(usb_id, MOUNT_RETRY, MOUNT_RESET, MOUNT_TIMEOUT);
#endif
} else if (((const char *)event->value)[0] == 'c') {
incharge = 1;
//插入充电,插入检测会有2秒延迟
}
} else if (event->event == DEVICE_EVENT_OUT) {
if (((const char *)event->value)[0] == 'h') {
int usb_id = ((const char *)event->value)[2] - '0';
log_i("usb%d disconnect, host mode\n", usb_id);
#if TCFG_UDISK_ENABLE || TCFG_HOST_AUDIO_ENABLE || TCFG_HOST_UVC_ENABLE || TCFG_HOST_WIRELESS_ENABLE || TCFG_HID_HOST_ENABLE || TCFG_ADB_ENABLE
usb_host_unmount(usb_id);
#endif
} else if (((const char *)event->value)[0] == 'c') {
incharge = 0;
//拔出充电,拔出检测会有5秒延迟
}
}
}
#if TCFG_USB_HOST_ENABLE
static void usb_host_event_handler(struct device_event *event)
{
int usb_id;
if (event->event == DEVICE_EVENT_IN) {
usb_id = ((const char *)event->arg)[8] - '0';
log_i("usb host%d mount succ\n", usb_id);
#if TCFG_UDISK_ENABLE
if (!strncmp((const char *)event->value, "udisk", 5)) {
//上电发现U盘原本挂在USB则出现不进中断,无法挂载文件系统,U盘断电就解决
mount_udisk_to_fs(usb_id);
}
#endif
#if TCFG_HOST_UVC_ENABLE
extern int usb_host_video_init(const usb_dev usb_id, const u8 sub_id);
if (!strncmp((const char *)event->value, "uvc", 3)) {
usb_host_video_init(usb_id, usb_id);
}
#endif
#if TCFG_HOST_AUDIO_ENABLE
if (!strncmp((const char *)event->value, "audio", 5)) {
usb_audio_start_process(usb_id);
}
#endif
#if TCFG_HID_HOST_ENABLE
if (!strncmp((const char *)event->value, "hid", 3)) {
hid_process(usb_id);
}
#endif
} else if (event->event == DEVICE_EVENT_OUT) {
usb_id = ((const char *)event->arg)[8] - '0';
log_i("usb host%d unmount\n", usb_id);
#if TCFG_UDISK_ENABLE
if (!strncmp((const char *)event->value, "udisk", 5)) {
unmount_udisk_to_fs(usb_id);
}
#endif
#if TCFG_HOST_UVC_ENABLE
extern int uvc_host_camera_out(u8 usb_id);
if (!strncmp((const char *)event->value, "uvc", 3)) {
uvc_host_camera_out(usb_id);
}
#endif
#if TCFG_HOST_AUDIO_ENABLE
if (!strncmp((const char *)event->value, "audio", 5)) {
usb_audio_stop_process(usb_id);
}
#endif
#if TCFG_HID_HOST_ENABLE
if (!strncmp((const char *)event->value, "hid", 3)) {
hid_stop_process(usb_id);
}
#endif
#if TCFG_ADB_ENABLE
if (!strncmp((const char *)event->value, "adb", 3)) {
adb_stop_process(usb_id);
}
#endif
#if TCFG_HOST_WIRELESS_ENABLE
if (!strncmp((const char *)event->value, "wireless", 8)) {
usb_net_stop_process(usb_id);
}
if (!strncmp((const char *)event->value, "at_port", 7)) {
usb_net_at_port_stop_process(usb_id);
}
#endif
}
}
#endif
static int device_event_handler(struct sys_event *e)
{
struct device_event *event = (struct device_event *)e->payload;
if (e->from == DEVICE_EVENT_FROM_OTG) {
#if TCFG_USB_SLAVE_ENABLE
extern int pc_device_event_handler(struct sys_event * e);
if (pc_device_event_handler(e)) {
return 1;
}
#endif
otg_event_handler(event);
} else if (e->from == DEVICE_EVENT_FROM_SD) {
sd_event_handler(event);
#if TCFG_USB_SLAVE_AUDIO_ENABLE
} else if (e->from == DEVICE_EVENT_FROM_UAC) {
extern int usb_audio_event_handler(struct device_event * event);
return usb_audio_event_handler(event);
#endif
#if TCFG_USB_HOST_ENABLE
} else if (e->from == DEVICE_EVENT_FROM_USB_HOST) {
usb_host_event_handler(event);
#endif
#if TCFG_EQ_ENABLE && TCFG_EQ_ONLINE_ENABLE && defined TCFG_COMM_TYPE && (TCFG_COMM_TYPE == TCFG_USB_COMM)
} else if (e->from == DEVICE_EVENT_FROM_CFG_TOOL) {
extern void usb_cdc_read_data_handler(struct device_event * event);
usb_cdc_read_data_handler(event);
#endif
}
return 0;
}
/*
* 静态注册设备事件回调函数,优先级为0
*/
SYS_EVENT_STATIC_HANDLER_REGISTER(device_event) = {
.event_type = SYS_DEVICE_EVENT,
.prob_handler = device_event_handler,
.post_handler = NULL,
};
extern int sdfile_ext_init(const char *dev_name, u32 sdfile_ext_base_addr, u32 sdfile_ext_end_addr);
extern u32 boot_info_get_sfc_base_addr(void);
extern u32 ex_app_info_get_base_addr(void);
#ifdef CONFIG_SDFILE_EXT_ENABLE
void sdfile_ext_mount_init(void)
{
while (!dev_online(SDX_DEV)) {
os_time_dly(1);
}
/* sdfile_ext_init(SDX_DEV, boot_info_get_sfc_base_addr(), __FLASH_SIZE__); */
sdfile_ext_init(SDX_DEV, ex_app_info_get_base_addr(), CONFIG_SDNAND_HFS_LEN);
}
#endif