This commit is contained in:
刘可亮
2024-01-27 08:47:24 +08:00
parent d3bd993b5f
commit 9f7ba67007
2345 changed files with 74421 additions and 76616 deletions

View File

@@ -9,12 +9,15 @@ CPPPATH = [cwd]
if GetDepend('AIC_SDMC_DRV'):
src += Glob('sdmc_disk/*.c')
if GetDepend('AIC_USB_DRV'):
if GetDepend('AIC_USB_HOST_EHCI_DRV'):
src += Glob('usb_disk/*.c')
if GetDepend('AIC_SPINAND_DRV'):
src += Glob('spinand_disk/*.c')
if GetDepend('AIC_SPINOR_DRV'):
src += Glob('spinor_disk/*.c')
group = DefineGroup('Filesystem', src, depend = ['LPKG_USING_DFS', 'LPKG_USING_DFS_ELMFAT'], CPPPATH = CPPPATH)
Return('group')

View File

@@ -34,7 +34,7 @@
#include "boot_param.h"
static struct dev_info disk[FF_VOLUMES] = {0};
static struct elm_dev_info disk[FF_VOLUMES] = {0};
static int elm_result_to_dfs(FRESULT result)
{
@@ -100,43 +100,30 @@ static int get_disk(rt_device_t id)
return -1;
}
static void get_disk_info(struct rt_device_blk_geometry *g)
{
disk_ioctl(SDMC_DISK, GET_SECTOR_COUNT, &g->sector_count);
disk_ioctl(SDMC_DISK, GET_SECTOR_SIZE, &g->bytes_per_sector);
disk_ioctl(SDMC_DISK, GET_BLOCK_SIZE, &g->block_size);
}
int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *data)
{
FATFS *fat;
FRESULT result;
int index;
struct rt_device_blk_geometry geometry = {0};
char logic_nbr[3] = {'0',':', 0};
/* get an empty position */
index = get_disk(RT_NULL);
if (index == -1)
if (index == -1) {
pr_err("Failed to get empty disk position.\n");
return -ENOENT;
}
logic_nbr[0] = '0' + index;
/* save device */
disk[index].dev_name = fs->dev_id;
disk[index].dev_type = (long)data;
/* check sector size */
get_disk_info(&geometry);
if (geometry.bytes_per_sector > FF_MAX_SS)
{
rt_kprintf("The sector size of device is greater than the sector size of FAT.\n");
return -EINVAL;
}
fat = (FATFS *)rt_malloc_align(sizeof(FATFS), CACHE_LINE_SIZE);
if (fat == RT_NULL)
{
disk[index].dev_name = RT_NULL;
pr_err("Failed to allocate memory.\n");
return -ENOMEM;
}
@@ -154,17 +141,20 @@ int dfs_elm_mount(struct dfs_filesystem *fs, unsigned long rwflag, const void *d
f_mount(RT_NULL, (const TCHAR *)logic_nbr, 1);
disk[index].dev_name = RT_NULL;
rt_free_align(fat);
pr_err("Failed to allocate memory for %s\n", drive);
return -ENOMEM;
}
/* open the root directory to test whether the fatfs is valid */
result = f_opendir(dir, drive);
if (result != FR_OK)
rt_free(dir);
if (result != FR_OK) {
pr_err("Try to open the fatfs failure.\n");;
goto __err;
}
/* mount succeed! */
fs->data = fat;
rt_free_align(dir);
return 0;
}
@@ -861,7 +851,7 @@ INIT_COMPONENT_EXPORT(elm_init);
#include "ram_disk/ram_disk.h"
#endif
#ifdef USB_DISK_ENABLE
#ifdef AIC_USB_HOST_EHCI_DRV
#include "usb_disk/usb_disk.h"
#endif
@@ -873,38 +863,53 @@ INIT_COMPONENT_EXPORT(elm_init);
#include "spinand_disk/spinand_disk.h"
#endif
#ifdef AIC_SPINOR_DRV
#include "spinor_disk/spinor_disk.h"
#endif
/* Initialize a Drive */
DSTATUS disk_initialize(BYTE pdrv)
{
DSTATUS stat = STA_NOINIT;
int dev_type = disk[pdrv].dev_type;
long dev_type = disk[pdrv].dev_type;
const char *device_name = disk[pdrv].dev_name;
void *handle = NULL;
(void)handle;
switch (dev_type) {
#ifdef RAM_DISK_ENABLE
case RAM_DISK:
case DTL(DEVICE_TYPE_RAM_DISK):
stat = ram_disk_initialize(pdrv);
return stat;
#endif
#ifdef USB_DISK_ENABLE
case USB_DISK:
#ifdef AIC_USB_HOST_EHCI_DRV
case DTL(DEVICE_TYPE_USB_DISK):
stat = usb_disk_initialize(pdrv);
return stat;
#endif
#ifdef AIC_SDMC_DRV
case SDMC_DISK:
stat = sdmc_disk_initialize(1, device_name);
return stat;
case DTL(DEVICE_TYPE_SDMC_DISK):
handle = sdmc_disk_initialize(device_name);
stat = 0;
break;
#endif
#ifdef AIC_SPINAND_DRV
case SPINAND_DISK:
stat = spinand_disk_initialize(device_name);
return stat;
case DTL(DEVICE_TYPE_SPINAND_DISK):
handle = spinand_disk_initialize(device_name);
stat = 0;
break;
#endif
#ifdef AIC_SPINOR_DRV
case DTL(DEVICE_TYPE_SPINOR_DISK):
handle = spinor_disk_initialize(device_name);
stat = 0;
break;
#endif
default:
break;
}
disk[pdrv].priv = handle;
return stat;
}
@@ -918,28 +923,33 @@ DSTATUS disk_status(BYTE pdrv)
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_PARERR;
int dev_type = disk[pdrv].dev_type;
const char *device_name = disk[pdrv].dev_name;
long dev_type = disk[pdrv].dev_type;
void *handle = disk[pdrv].priv;
switch (dev_type) {
#ifdef RAM_DISK_ENABLE
case RAM_DISK:
case DTL(DEVICE_TYPE_RAM_DISK):
res = ram_disk_read(pdrv, buff, sector, count);
return res;
#endif
#ifdef USB_DISK_ENABLE
case USB_DISK:
#ifdef AIC_USB_HOST_EHCI_DRV
case DTL(DEVICE_TYPE_USB_DISK):
res = usb_disk_read(pdrv, buff, sector, count);
return res;
#endif
#ifdef AIC_SDMC_DRV
case SDMC_DISK:
res = sdmc_disk_read(pdrv, device_name, buff, sector, count);
case DTL(DEVICE_TYPE_SDMC_DISK):
res = sdmc_disk_read(handle, buff, sector, count);
return res;
#endif
#ifdef AIC_SPINAND_DRV
case SPINAND_DISK:
res = spinand_disk_read(device_name, buff, sector, count);
case DTL(DEVICE_TYPE_SPINAND_DISK):
res = spinand_disk_read(handle, buff, sector, count);
return res;
#endif
#ifdef AIC_SPINOR_DRV
case DTL(DEVICE_TYPE_SPINOR_DISK):
res = spinor_disk_read(handle, buff, sector, count);
return res;
#endif
default:
@@ -953,28 +963,33 @@ DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_PARERR;
int dev_type = disk[pdrv].dev_type;
const char *device_name = disk[pdrv].dev_name;
long dev_type = disk[pdrv].dev_type;
void *handle = disk[pdrv].priv;
switch (dev_type) {
#ifdef RAM_DISK_ENABLE
case RAM_DISK:
case DTL(DEVICE_TYPE_RAM_DISK):
res = ram_disk_write(pdrv, buff, sector, count);
return res;
#endif
#ifdef USB_DISK_ENABLE
case USB_DISK:
#ifdef AIC_USB_HOST_EHCI_DRV
case DTL(DEVICE_TYPE_USB_DISK):
res = usb_disk_write(pdrv, buff, sector, count);
return res;
#endif
#ifdef AIC_SDMC_DRV
case SDMC_DISK:
res = sdmc_disk_write(pdrv, device_name, buff, sector, count);
case DTL(DEVICE_TYPE_SDMC_DISK):
res = sdmc_disk_write(handle, buff, sector, count);
return res;
#endif
#ifdef AIC_SPINAND_DRV
case SPINAND_DISK:
res = spinand_disk_write(device_name, buff, sector, count);
case DTL(DEVICE_TYPE_SPINAND_DISK):
res = spinand_disk_write(handle, buff, sector, count);
return res;
#endif
#ifdef AIC_SPINOR_DRV
case DTL(DEVICE_TYPE_SPINOR_DISK):
res = spinor_disk_write(handle, buff, sector, count);
return res;
#endif
default:
@@ -987,29 +1002,34 @@ DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
/* Miscellaneous Functions */
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
{
DRESULT res = RES_PARERR;
int dev_type = disk[pdrv].dev_type;
const char *device_name = disk[pdrv].dev_name;
DRESULT res = RES_PARERR;
long dev_type = disk[pdrv].dev_type;
void *handle = disk[pdrv].priv;
switch (dev_type) {
#ifdef RAM_DISK_ENABLE
case RAM_DISK:
case DTL(DEVICE_TYPE_RAM_DISK):
res = ram_disk_ioctl(pdrv, cmd, buff);
return res;
#endif
#ifdef USB_DISK_ENABLE
case USB_DISK:
#ifdef AIC_USB_HOST_EHCI_DRV
case DTL(DEVICE_TYPE_USB_DISK):
res = usb_disk_ioctl(pdrv, cmd, buff);
return res;
#endif
#ifdef AIC_SDMC_DRV
case SDMC_DISK:
res = sdmc_disk_ioctl(pdrv, device_name, cmd, buff);
case DTL(DEVICE_TYPE_SDMC_DISK):
res = sdmc_disk_ioctl(handle, cmd, buff);
return res;
#endif
#ifdef AIC_SPINAND_DRV
case SPINAND_DISK:
res = spinand_disk_ioctl(device_name, cmd, buff);
case DTL(DEVICE_TYPE_SPINAND_DISK):
res = spinand_disk_ioctl(handle, cmd, buff);
return res;
#endif
#ifdef AIC_SPINOR_DRV
case DTL(DEVICE_TYPE_SPINOR_DISK):
res = spinor_disk_ioctl(handle, cmd, buff);
return res;
#endif
default:

View File

@@ -19,16 +19,17 @@ extern "C" {
#define CACHE_LINE_SIZE 64
#endif
/* Definitions of physical drive number for each drive */
#define SDMC_DISK 0
#define SPINAND_DISK 1 /* spinand disk */
#define USB_DISK 2 /* usb disk */
#define SPINOR_DISK 3 /* spinor disk */
#define RAM_DISK 4 /* Example: ram disk */
#define DEVICE_TYPE_SDMC_DISK ((const void *)0) /* eMMC/SD */
#define DEVICE_TYPE_SPINAND_DISK ((const void *)1) /* SPINAND */
#define DEVICE_TYPE_USB_DISK ((const void *)2) /* USB pendrive */
#define DEVICE_TYPE_SPINOR_DISK ((const void *)3) /* SPINOR */
#define DEVICE_TYPE_RAM_DISK ((const void *)4) /* RAM */
#define DTL(x) (long)(x)
struct dev_info {
struct elm_dev_info {
char *dev_name;
int dev_type;
long dev_type;
void *priv;
};
int elm_init(void);

View File

@@ -14,34 +14,19 @@
#include "aic_osal.h"
#include "sdmc_disk.h"
#include "block_dev.h"
#include "hexdump.h"
#include "mmc.h"
/*******************************************************************************
* Definitons
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
struct aic_sdmc *g_sdmc_host = NULL;
static struct rt_device_blk_geometry info = {0};
/*******************************************************************************
* Code
******************************************************************************/
DRESULT sdmc_disk_write(uint8_t pdrv, const char *device_name, const uint8_t *buf, uint32_t sector, uint8_t cnt)
DRESULT sdmc_disk_write(void *hdisk, const uint8_t *buf, uint32_t sector, uint8_t cnt)
{
struct block_dev *dev = hdisk;
rt_size_t size = 0;
if (!g_sdmc_host)
if (!dev)
return RES_NOTRDY;
size = mmc_bwrite(g_sdmc_host, sector, cnt, buf);
size = block_write(dev, sector, cnt, (u8 *)buf);
if (size != cnt) {
pr_err("write() return %d/%d\n", size, cnt);
return RES_ERROR;
@@ -50,14 +35,15 @@ DRESULT sdmc_disk_write(uint8_t pdrv, const char *device_name, const uint8_t *bu
return RES_OK;
}
DRESULT sdmc_disk_read(uint8_t pdrv, const char *device_name, uint8_t *buf, uint32_t sector, uint8_t cnt)
DRESULT sdmc_disk_read(void *hdisk, uint8_t *buf, uint32_t sector, uint8_t cnt)
{
struct block_dev *dev = hdisk;
rt_size_t size = 0;
if (!g_sdmc_host)
if (!dev)
return RES_NOTRDY;
size = mmc_bread(g_sdmc_host, sector, cnt, buf);
size = block_read(dev, sector, cnt, buf);
if (size != cnt) {
pr_err("read() return %d/%d\n", size, cnt);
return RES_ERROR;
@@ -66,14 +52,18 @@ DRESULT sdmc_disk_read(uint8_t pdrv, const char *device_name, uint8_t *buf, uint
return RES_OK;
}
DRESULT sdmc_disk_ioctl(uint8_t pdrv, const char *device_name, uint8_t command, void *buf)
DRESULT sdmc_disk_ioctl(void *hdisk, uint8_t command, void *buf)
{
struct block_dev *dev = hdisk;
DRESULT result = RES_OK;
if (!dev)
return RES_NOTRDY;
switch (command) {
case GET_SECTOR_COUNT:
if (buf) {
*(uint32_t *)buf = info.sector_count;
*(uint32_t *)buf = dev->blk_cnt;
} else {
result = RES_PARERR;
}
@@ -82,7 +72,7 @@ DRESULT sdmc_disk_ioctl(uint8_t pdrv, const char *device_name, uint8_t command,
case GET_SECTOR_SIZE:
if (buf) {
*(uint32_t *)buf = info.bytes_per_sector;
*(uint32_t *)buf = dev->blk_size;
} else {
result = RES_PARERR;
}
@@ -91,7 +81,7 @@ DRESULT sdmc_disk_ioctl(uint8_t pdrv, const char *device_name, uint8_t command,
case GET_BLOCK_SIZE:
if (buf) {
*(uint32_t *)buf = info.block_size;
*(uint32_t *)buf = dev->blk_size;
} else {
result = RES_PARERR;
}
@@ -110,20 +100,16 @@ DRESULT sdmc_disk_ioctl(uint8_t pdrv, const char *device_name, uint8_t command,
return result;
}
DSTATUS sdmc_disk_status(uint8_t pdrv, const char *device_name)
DSTATUS sdmc_disk_status(void *hdisk)
{
return RES_OK;
}
DSTATUS sdmc_disk_initialize(uint8_t pdrv, const char *device_name)
void *sdmc_disk_initialize(const char *device_name)
{
g_sdmc_host = find_mmc_dev_by_index(pdrv);
if (!g_sdmc_host)
return RES_NOTRDY;
struct block_dev *dev;
info.block_size = g_sdmc_host->dev->max_blk_size;
info.bytes_per_sector = info.block_size;
info.sector_count = g_sdmc_host->dev->card_capacity * 2; /* unit: block */
dev = block_get_device(device_name);
return RES_OK;
return dev;
}

View File

@@ -43,60 +43,54 @@ extern "C" {
/*!
* @brief Initializes SDMC disk.
*
* @param pdrv Physical drive number.
* @param device_name the name of device which includes a file system.
* @retval STA_NOINIT Failed.
* @retval RES_OK Success.
* @retval disk handle.
*/
DSTATUS sdmc_disk_initialize(uint8_t pdrv, const char *device_name);
void *sdmc_disk_initialize(const char *device_name);
/*!
* Gets SDMC disk status
*
* @param pdrv Physical drive number.
* @param device_name the name of device which includes a file system.
* @param hdisk disk handle.
* @retval STA_NOINIT Failed.
* @retval RES_OK Success.
*/
DSTATUS sdmc_disk_status(uint8_t pdrv, const char *device_name);
DSTATUS sdmc_disk_status(void *hdisk);
/*!
* @brief Reads SDMC disk.
*
* @param pdrv Physical drive number.
* @param device_name the name of device which includes a file system.
* @param hdisk disk handle.
* @param buf The data buffer pointer to store read content.
* @param sector The start sector number to be read.
* @param cnt The sector count to be read.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT sdmc_disk_read(uint8_t pdrv, const char *device_name, uint8_t *buf, uint32_t sector, uint8_t cnt);
DRESULT sdmc_disk_read(void *hdisk, uint8_t *buf, uint32_t sector, uint8_t cnt);
/*!
* @brief Writes SDMC disk.
*
* @param pdrv Physical drive number.
* @param device_name the name of device which includes a file system.
* @param hdisk disk handle.
* @param buf The data buffer pointer to store write content.
* @param sector The start sector number to be written.
* @param cnt The sector count to be written.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT sdmc_disk_write(uint8_t pdrv, const char *device_name, const uint8_t *buf, uint32_t sector, uint8_t cnt);
DRESULT sdmc_disk_write(void *hdisk, const uint8_t *buf, uint32_t sector, uint8_t cnt);
/*!
* @brief SDMC disk IO operation.
*
* @param pdrv Physical drive number.
* @param device_name the name of device which includes a file system.
* @param hdisk disk handle.
* @param command The command to be set.
* @param buf The buffer to store command result.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT sdmc_disk_ioctl(uint8_t pdrv, const char *device_name, uint8_t command, void *buf);
DRESULT sdmc_disk_ioctl(void *hdisk, uint8_t command, void *buf);
/* @} */
#if defined(__cplusplus)

View File

@@ -15,23 +15,9 @@
#include "spinand_disk.h"
#include "mtd.h"
static struct spinand_blk_device *blk_device = NULL;
static struct rt_device_blk_geometry info = { 0 };
/*******************************************************************************
* Code
******************************************************************************/
DRESULT spinand_disk_write(const char *device_name, const uint8_t *buf,
uint32_t sector, uint8_t cnt)
{
if (!blk_device->mtd_device)
return RES_NOTRDY;
return RES_OK;
}
DRESULT spinand_disk_read(const char *device_name, uint8_t *buf,
uint32_t sector, uint8_t cnt)
static DRESULT spinand_disk_nonftl_read(struct spinand_blk_device *blk_device,
uint8_t *buf, uint32_t sector,
uint8_t cnt)
{
rt_size_t sectors_per_page;
rt_size_t start_page, block, offset;
@@ -41,14 +27,16 @@ DRESULT spinand_disk_read(const char *device_name, uint8_t *buf,
rt_size_t pages_per_block;
rt_size_t ret = 0;
struct mtd_dev *mtd = blk_device->mtd_device;
struct rt_device_blk_geometry *info;
if (!blk_device->mtd_device)
if (!mtd)
return RES_NOTRDY;
info = &blk_device->info;
pages_per_block = mtd->erasesize / mtd->writesize;
sectors_per_page = mtd->writesize / info.bytes_per_sector;
sectors_per_page = mtd->writesize / info->bytes_per_sector;
block = sector * info.bytes_per_sector / mtd->erasesize;
block = sector * info->bytes_per_sector / mtd->erasesize;
offset = block * mtd->erasesize;
/* Search for the first good block after the given offset */
@@ -71,14 +59,14 @@ DRESULT spinand_disk_read(const char *device_name, uint8_t *buf,
return -RT_ERROR;
}
copybuf = blk_device->pagebuf +
(sector % sectors_per_page) * info.bytes_per_sector;
copybuf = blk_device->pagebuf;
copybuf += (sector % sectors_per_page) * info->bytes_per_sector;
if (cnt > (sectors_per_page - sector % sectors_per_page)) {
copysize = (sectors_per_page - sector % sectors_per_page) *
info.bytes_per_sector;
info->bytes_per_sector;
sectors_read += (sectors_per_page - sector % sectors_per_page);
} else {
copysize = cnt * info.bytes_per_sector;
copysize = cnt * info->bytes_per_sector;
sectors_read += cnt;
}
@@ -94,7 +82,7 @@ DRESULT spinand_disk_read(const char *device_name, uint8_t *buf,
#ifdef AIC_SPINAND_CONT_READ
if ((cnt - sectors_read) > sectors_per_page) {
uint8_t *data_ptr = RT_NULL;
uint32_t copydata = (cnt - sectors_read) * info.bytes_per_sector;
uint32_t copydata = (cnt - sectors_read) * info->bytes_per_sector;
data_ptr = (uint8_t *)aicos_malloc_align(0, copydata, CACHE_LINE_SIZE);
if (data_ptr == RT_NULL) {
@@ -148,10 +136,10 @@ exit_spinand_disk_read_malloc:
}
if ((cnt - sectors_read) > sectors_per_page) {
copysize = sectors_per_page * info.bytes_per_sector;
copysize = sectors_per_page * info->bytes_per_sector;
sectors_read += sectors_per_page;
} else {
copysize = (cnt - sectors_read) * info.bytes_per_sector;
copysize = (cnt - sectors_read) * info->bytes_per_sector;
sectors_read += (cnt - sectors_read);
}
@@ -164,14 +152,78 @@ exit_spinand_disk_read_malloc:
return RES_OK;
}
DRESULT spinand_disk_ioctl(const char *device_name, uint8_t command, void *buf)
#ifdef AIC_NFTL_SUPPORT
DRESULT spinand_disk_nftl_read(struct spinand_blk_device *blk_device,
uint8_t *buf, uint32_t sector, uint8_t cnt)
{
if (!blk_device->nftl_handler)
return RES_NOTRDY;
nftl_api_read(blk_device->nftl_handler, sector, cnt, buf);
return RES_OK;
}
static DRESULT spinand_disk_nftl_write(struct spinand_blk_device *blk_device,
const uint8_t *buf, uint32_t sector,
uint8_t cnt)
{
if (!blk_device->nftl_handler)
return RES_NOTRDY;
nftl_api_write(blk_device->nftl_handler, sector, cnt, (uint8_t *)buf);
return RES_OK;
}
#endif
DRESULT spinand_disk_write(void *hdisk, const uint8_t *buf, uint32_t sector,
uint8_t cnt)
{
struct spinand_blk_device *dev;
dev = hdisk;
if (!dev)
return RES_NOTRDY;
#ifdef AIC_NFTL_SUPPORT
if (dev->attr == PART_ATTR_NFTL) {
return spinand_disk_nftl_write(dev, buf, sector, cnt);
}
#endif
return RES_OK;
}
DRESULT spinand_disk_read(void *hdisk, uint8_t *buf, uint32_t sector,
uint8_t cnt)
{
struct spinand_blk_device *dev;
dev = hdisk;
if (!dev)
return RES_NOTRDY;
#ifdef AIC_NFTL_SUPPORT
if (dev->attr == PART_ATTR_NFTL)
return spinand_disk_nftl_read(dev, buf, sector, cnt);
#endif
return spinand_disk_nonftl_read(dev, buf, sector, cnt);
}
DRESULT spinand_disk_ioctl(void *hdisk, uint8_t command, void *buf)
{
struct spinand_blk_device *dev;
DRESULT result = RES_OK;
dev = hdisk;
if (!dev || !dev->mtd_device)
return RES_NOTRDY;
switch (command) {
case GET_SECTOR_COUNT:
if (buf) {
*(uint32_t *)buf = info.sector_count;
*(uint32_t *)buf = dev->info.sector_count;
} else {
result = RES_PARERR;
}
@@ -180,7 +232,7 @@ DRESULT spinand_disk_ioctl(const char *device_name, uint8_t command, void *buf)
case GET_SECTOR_SIZE:
if (buf) {
*(uint32_t *)buf = info.bytes_per_sector;
*(uint32_t *)buf = dev->info.bytes_per_sector;
} else {
result = RES_PARERR;
}
@@ -189,7 +241,7 @@ DRESULT spinand_disk_ioctl(const char *device_name, uint8_t command, void *buf)
case GET_BLOCK_SIZE:
if (buf) {
*(uint32_t *)buf = info.block_size;
*(uint32_t *)buf = dev->info.block_size;
} else {
result = RES_PARERR;
}
@@ -197,6 +249,11 @@ DRESULT spinand_disk_ioctl(const char *device_name, uint8_t command, void *buf)
break;
case CTRL_SYNC:
#ifdef AIC_NFTL_SUPPORT
if (dev->attr == PART_ATTR_NFTL) {
nftl_api_write_cache(dev->nftl_handler, 0xffff);
}
#endif
result = RES_OK;
break;
@@ -208,37 +265,83 @@ DRESULT spinand_disk_ioctl(const char *device_name, uint8_t command, void *buf)
return result;
}
DSTATUS spinand_disk_status(const char *device_name)
DSTATUS spinand_disk_status(void *hdisk)
{
return RES_OK;
}
DSTATUS spinand_disk_initialize(const char *device_name)
void *spinand_disk_initialize(const char *device_name)
{
blk_device = (struct spinand_blk_device *)aicos_malloc(
MEM_CMA, sizeof(struct spinand_blk_device));
struct spinand_blk_device *blk_device;
struct mtd_dev *mtd;
blk_device = (void *)malloc(sizeof(*blk_device));
if (!blk_device) {
pr_err("Error: no memory for create SPI NAND block device");
return RES_ERROR;
return NULL;
}
memset(blk_device, 0, sizeof(*blk_device));
/*Obtain devices by part name*/
blk_device->mtd_device = mtd_get_device(device_name);
if (!blk_device->mtd_device) {
mtd = mtd_get_device(device_name);
if (!mtd) {
pr_err("Failed to get mtd %s\n", device_name);
return RES_NOTRDY;
goto err;
}
blk_device->pagebuf = aicos_malloc_align(
0, blk_device->mtd_device->writesize, CACHE_LINE_SIZE);
blk_device->mtd_device = mtd;
#ifdef AIC_NFTL_SUPPORT
if (blk_device->mtd_device->attr == PART_ATTR_NFTL) {
struct nftl_api_handler_t *nftl_hdl;
nftl_hdl = malloc(sizeof(struct nftl_api_handler_t));
if (!nftl_hdl) {
pr_err("Failed to allocate memory for nftl_handler");
goto err;
}
blk_device->nftl_handler = nftl_hdl;
memset(nftl_hdl, 0, sizeof(struct nftl_api_handler_t));
nftl_hdl->priv_mtd = (void *)mtd;
nftl_hdl->nandt = malloc(sizeof(struct nftl_api_nand_t));
nftl_hdl->nandt->page_size = mtd->writesize;
nftl_hdl->nandt->oob_size = mtd->oobsize;
nftl_hdl->nandt->pages_per_block = mtd->erasesize / mtd->writesize;
nftl_hdl->nandt->block_total = mtd->size / mtd->erasesize;
nftl_hdl->nandt->block_start = mtd->start / mtd->erasesize;
nftl_hdl->nandt->block_end = (mtd->start + mtd->size) / mtd->erasesize;
if (nftl_api_init(nftl_hdl, 1)) {
pr_err("[NE]nftl_initialize failed\n");
goto err;
}
}
#endif
blk_device->attr = mtd->attr;
blk_device->pagebuf =
aicos_malloc_align(0, mtd->writesize, CACHE_LINE_SIZE);
if (!blk_device->pagebuf) {
pr_err("Malloc buf failed\n");
return RES_ERROR;
goto err;
}
info.bytes_per_sector = 512;
info.block_size = info.bytes_per_sector;
info.sector_count = blk_device->mtd_device->size / info.bytes_per_sector;
blk_device->info.bytes_per_sector = 512;
blk_device->info.block_size = blk_device->info.bytes_per_sector;
blk_device->info.sector_count =
mtd->size / blk_device->info.bytes_per_sector;
return RES_OK;
return blk_device;
err:
if (blk_device && blk_device->pagebuf)
aicos_free_align(0, blk_device->pagebuf);
#ifdef AIC_NFTL_SUPPORT
if (blk_device->nftl_handler && blk_device->nftl_handler->nandt)
free(blk_device->nftl_handler->nandt);
if (blk_device->nftl_handler)
free(blk_device->nftl_handler);
#endif
if (blk_device)
free(blk_device);
return NULL;
}

View File

@@ -14,13 +14,23 @@
#include "diskio.h"
#include "mtd.h"
#ifdef AIC_NFTL_SUPPORT
#include "nftl_api.h"
#endif
#if defined(__cplusplus)
extern "C" {
#endif
struct spinand_blk_device {
struct mtd_dev *mtd_device;
struct rt_device_blk_geometry info;
#ifdef AIC_NFTL_SUPPORT
struct nftl_api_handler_t *nftl_handler;
#endif
u8 *pagebuf;
enum part_attr attr;
};
/*!
@@ -32,54 +42,53 @@ struct spinand_blk_device {
* @brief Initializes SPINAND disk.
*
* @param device_name the name of device which includes a file system.
* @retval STA_NOINIT Failed.
* @retval RES_OK Success.
* @retval the handle of disk.
*/
DSTATUS spinand_disk_initialize(const char *device_name);
void *spinand_disk_initialize(const char *device_name);
/*!
* Gets SPINAND disk status
*
* @param device_name the name of device which includes a file system.
* @param hdisk the handle of device which includes a file system.
* @retval STA_NOINIT Failed.
* @retval RES_OK Success.
*/
DSTATUS spinand_disk_status(const char *device_name);
DSTATUS spinand_disk_status(void *hdisk);
/*!
* @brief Reads SPINAND disk.
*
* @param device_name the name of device which includes a file system.
* @param hdisk the handle of device which includes a file system.
* @param buf The data buffer pointer to store read content.
* @param sector The start sector number to be read.
* @param cnt The sector count to be read.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT spinand_disk_read(const char *device_name, uint8_t *buf, uint32_t sector, uint8_t cnt);
DRESULT spinand_disk_read(void *hdisk, uint8_t *buf, uint32_t sector, uint8_t cnt);
/*!
* @brief Writes SPINAND disk.
*
* @param device_name the name of device which includes a file system.
* @param hdisk the handle of device which includes a file system.
* @param buf The data buffer pointer to store write content.
* @param sector The start sector number to be written.
* @param cnt The sector count to be written.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT spinand_disk_write(const char *device_name, const uint8_t *buf, uint32_t sector, uint8_t cnt);
DRESULT spinand_disk_write(void *hdisk, const uint8_t *buf, uint32_t sector, uint8_t cnt);
/*!
* @brief SPINAND disk IO operation.
*
* @param device_name the name of device which includes a file system.
* @param hdisk the handle of device which includes a file system.
* @param command The command to be set.
* @param buf The buffer to store command result.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT spinand_disk_ioctl(const char *device_name, uint8_t command, void *buf);
DRESULT spinand_disk_ioctl(void *hdisk, uint8_t command, void *buf);
/* @} */
#if defined(__cplusplus)

View File

@@ -0,0 +1,193 @@
/*
* Copyright (c) 2023, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: xuan.wen <xuan.wen@artinchip.com>
*/
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <dfs_bare.h>
#include <rtconfig.h>
#include "aic_osal.h"
#include "spinor_disk.h"
#include "mtd.h"
/*******************************************************************************
* Code
******************************************************************************/
DRESULT spinor_disk_write(void *hdisk, const uint8_t *buf, uint32_t sector,
uint8_t cnt)
{
#ifndef AIC_FATFS_ENABLE_WRITE_IN_SPINOR
pr_warn("This config only supports read!\n");
return RES_OK;
#else
struct spinor_blk_device *dev = hdisk;
struct mtd_dev *mtd;
rt_size_t phy_pos, pos;
rt_size_t phy_size, size;
rt_size_t ret = 0;
uint32_t align_sector = 0;
uint8_t align_cnt = 0;
if (!dev)
return RES_NOTRDY;
mtd = dev->mtd_device;
if (!mtd)
return RES_NOTRDY;
align_sector = sector - sector % 8;
align_cnt = sector % 8 + cnt;
align_cnt = (align_cnt + 7) / 8 * 8;
pr_debug("sector = %ld cnt = %d!\n", sector, cnt);
pr_debug("align_sector = %ld align_cnt = %d!\n", align_sector, align_cnt);
phy_pos = align_sector * dev->info.bytes_per_sector;
phy_size = align_cnt * dev->info.bytes_per_sector;
memset(dev->buf, 0xFF, dev->length);
ret = mtd_read(mtd, phy_pos, dev->buf, phy_size);
if (ret) {
pr_err("Mtd read data failed!\n");
return -RT_ERROR;
}
pos = sector % 8 * dev->info.bytes_per_sector;
size = cnt * dev->info.bytes_per_sector;
memcpy(dev->buf + pos, buf, size);
mtd_erase(mtd, phy_pos, phy_size);
ret = mtd_write(mtd, phy_pos, dev->buf, phy_size);
if (ret) {
pr_err("Mtd write data failed!\n");
return -RT_ERROR;
}
return RES_OK;
#endif
}
DRESULT spinor_disk_read(void *hdisk, uint8_t *buf, uint32_t sector,
uint8_t cnt)
{
struct spinor_blk_device *dev = hdisk;
struct mtd_dev *mtd;
rt_size_t ret = 0;
rt_size_t phy_pos;
rt_size_t phy_size;
if (!dev)
return RES_NOTRDY;
mtd = dev->mtd_device;
if (!mtd)
return RES_NOTRDY;
/* change the block device's logic address to physical address */
phy_pos = sector * dev->info.bytes_per_sector;
phy_size = cnt * dev->info.bytes_per_sector;
ret = mtd_read(mtd, phy_pos, buf, phy_size);
if (ret) {
pr_err("Mtd read data failed!\n");
return -RT_ERROR;
}
return RES_OK;
}
DRESULT spinor_disk_ioctl(void *hdisk, uint8_t command, void *buf)
{
struct spinor_blk_device *dev = hdisk;
DRESULT result = RES_OK;
if (!dev)
return RES_NOTRDY;
switch (command) {
case GET_SECTOR_COUNT:
if (buf) {
*(uint32_t *)buf = dev->info.sector_count;
} else {
result = RES_PARERR;
}
break;
case GET_SECTOR_SIZE:
if (buf) {
*(uint32_t *)buf = dev->info.bytes_per_sector;
} else {
result = RES_PARERR;
}
break;
case GET_BLOCK_SIZE:
if (buf) {
*(uint32_t *)buf = dev->info.block_size;
} else {
result = RES_PARERR;
}
break;
case CTRL_SYNC:
result = RES_OK;
break;
default:
result = RES_PARERR;
break;
}
return result;
}
DSTATUS spinor_disk_status(void *hdisk)
{
return RES_OK;
}
void *spinor_disk_initialize(const char *device_name)
{
struct spinor_blk_device *dev;
dev = (void *)malloc(sizeof(*dev));
if (!dev) {
pr_err("Error: no memory for create SPI NOR block device");
return NULL;
}
/*Obtain devices by part name*/
dev->mtd_device = mtd_get_device(device_name);
if (!dev->mtd_device) {
pr_err("Failed to get mtd %s\n", device_name);
free(dev);
return NULL;
}
#ifdef AIC_FATFS_ENABLE_WRITE_IN_SPINOR
dev->length = AIC_USING_FS_IMAGE_TYPE_FATFS_CLUSTER_SIZE * 512 * 2;
dev->buf = (uint8_t *)aicos_malloc(MEM_CMA, dev->length);
if (!dev->buf) {
pr_err("Error: no memory for create SPI NOR block buf");
free(dev);
return NULL;
}
#endif
dev->info.bytes_per_sector = 512;
dev->info.block_size = dev->info.bytes_per_sector;
dev->info.sector_count = dev->mtd_device->size / dev->info.bytes_per_sector;
return dev;
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (c) 2023, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Authors: xuan.wen <xuan.wen@artinchip.com>
*/
#ifndef _SPINOR_DISKIO_H_
#define _SPINOR_DISKIO_H_
#include <stdint.h>
#include <ff.h>
#include <rtconfig.h>
#include "diskio.h"
#include "mtd.h"
#if defined(__cplusplus)
extern "C" {
#endif
struct spinor_blk_device {
struct mtd_dev *mtd_device;
struct rt_device_blk_geometry info;
#ifdef AIC_FATFS_ENABLE_WRITE_IN_SPINOR
uint32_t length;
uint8_t *buf;
#endif
};
/*!
* @name SPINOR Disk Function
* @{
*/
/*!
* @brief Initializes SPINOR disk.
*
* @param device_name the name of device which includes a file system.
* @retval the handle of disk.
*/
void *spinor_disk_initialize(const char *device_name);
/*!
* Gets SPINOR disk status
*
* @param hdisk the handle of device which includes a file system.
* @retval STA_NOINIT Failed.
* @retval RES_OK Success.
*/
DSTATUS spinor_disk_status(void *hdisk);
/*!
* @brief Reads SPINOR disk.
*
* @param hdisk the handle of device which includes a file system.
* @param buf The data buffer pointer to store read content.
* @param sector The start sector number to be read.
* @param cnt The sector count to be read.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT spinor_disk_read(void *hdisk, uint8_t *buf, uint32_t sector, uint8_t cnt);
/*!
* @brief Writes SPINOR disk.
*
* @param hdisk the handle of device which includes a file system.
* @param buf The data buffer pointer to store write content.
* @param sector The start sector number to be written.
* @param cnt The sector count to be written.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT spinor_disk_write(void *hdisk, const uint8_t *buf, uint32_t sector, uint8_t cnt);
/*!
* @brief SPINOR disk IO operation.
*
* @param hdisk the handle of device which includes a file system.
* @param command The command to be set.
* @param buf The buffer to store command result.
* @retval RES_PARERR Failed.
* @retval RES_OK Success.
*/
DRESULT spinor_disk_ioctl(void *hdisk, uint8_t command, void *buf);
/* @} */
#if defined(__cplusplus)
}
#endif
#endif /* _SPINOR_DISKIO_H_ */

View File

@@ -7,10 +7,7 @@
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <aos/kernel.h>
#include <aos/debug.h>
#include "ff.h"
#include "soc.h"
__WEAK int USB_disk_status(void)
{