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

@@ -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;
}