mirror of
https://gitee.com/Vancouver2017/luban-lite-t3e-pro.git
synced 2025-12-15 19:08:54 +00:00
v1.0.3
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user