修改上传所有文件
This commit is contained in:
656
e3_176_ref/middleware/disk/disk_mmc.c
Normal file
656
e3_176_ref/middleware/disk/disk_mmc.c
Normal file
@@ -0,0 +1,656 @@
|
||||
/**
|
||||
* @file disk_mmm.c
|
||||
*
|
||||
* Copyright (c) 2021 Semidrive Semiconductor.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* Revision History:
|
||||
* -----------------
|
||||
*/
|
||||
|
||||
#include <debug.h>
|
||||
#include <disk.h>
|
||||
#include <disk_mmc.h>
|
||||
#include <param.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
|
||||
/* Maximum value of a single transmission */
|
||||
#define MMC_MAX_XFER_SIZE (0x1000000)
|
||||
|
||||
/* mmc erase value */
|
||||
#define MMC_DEFAULT_FLAG(flag) \
|
||||
((flag == DISK_ERASE_DEFAULT) || (flag == DISK_ERASE_ZERO))
|
||||
|
||||
/* MMC physical layer API */
|
||||
static int mmc_dev_read(struct disk_mmc_info *mmc_info, uint8_t *dst,
|
||||
block_t sector, block_count_t count)
|
||||
{
|
||||
if (mmc_info->config.mmc_read)
|
||||
return mmc_info->config.mmc_read(mmc_info->config.mmc_dev, dst, sector,
|
||||
count);
|
||||
else
|
||||
return -DISK_ERROR_READ_ACCESS;
|
||||
}
|
||||
static int mmc_dev_write(struct disk_mmc_info *mmc_info, const uint8_t *src,
|
||||
block_t sector, block_count_t count)
|
||||
{
|
||||
if (mmc_info->config.mmc_write)
|
||||
return mmc_info->config.mmc_write(mmc_info->config.mmc_dev, src, sector,
|
||||
count);
|
||||
else
|
||||
return -DISK_ERROR_WRITE_ACCESS;
|
||||
}
|
||||
|
||||
static int mmc_dev_erase(struct disk_mmc_info *mmc_info, block_t block,
|
||||
block_count_t count)
|
||||
{
|
||||
if (mmc_info->config.mmc_erase)
|
||||
return mmc_info->config.mmc_erase(mmc_info->config.mmc_dev, block,
|
||||
count);
|
||||
else
|
||||
return -DISK_ERROR_ERASE_ACCESS;
|
||||
}
|
||||
|
||||
/* MMC buff reads */
|
||||
static int mmc_buff_read(struct disk_mmc_info *mmc_info, uint8_t *buff_dst,
|
||||
block_t sector, block_count_t sector_count,
|
||||
uint8_t *dst, disk_addr_t addr, disk_size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
/* Protect the buffer */
|
||||
xSemaphoreTake(mmc_info->disk_mmc_mutex, portMAX_DELAY);
|
||||
ret = mmc_dev_read(mmc_info, buff_dst, sector, sector_count);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
memcpy(dst, buff_dst + addr - ROUNDDOWN(addr, sector_size), size);
|
||||
xSemaphoreGive(mmc_info->disk_mmc_mutex);
|
||||
return 0;
|
||||
error:
|
||||
xSemaphoreGive(mmc_info->disk_mmc_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int disk_mmc_read(struct disk_info *info, uint8_t *dst, disk_addr_t addr,
|
||||
disk_size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
|
||||
uint8_t *buf = NULL;
|
||||
disk_size_t remaining = size;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
uint32_t buff_size = mmc_info->buff_size;
|
||||
|
||||
disk_addr_t sector_addr = 0;
|
||||
disk_size_t sector_count = 0;
|
||||
disk_size_t read_len = 0;
|
||||
disk_size_t max_read_length = 0;
|
||||
|
||||
while (remaining) {
|
||||
/* Process the unaligned portion of the address */
|
||||
if (!IS_ALIGNED(addr, sector_size)) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk read %s address sector unaligned portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
sector_count = 1;
|
||||
read_len = MIN(ROUNDUP(addr, sector_size) - addr, remaining);
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk read addr:%llx read_len:%lld\n",
|
||||
addr, read_len);
|
||||
}
|
||||
/* Address & size aligned portion of sector,Memory CACHE_LINE alignment
|
||||
*/
|
||||
else if ((remaining > sector_size) &&
|
||||
IS_ALIGNED(dst, CONFIG_ARCH_CACHE_LINE)) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk read %s address sector aligned & dst "
|
||||
"CACHE_LINE aligned portion\n",
|
||||
info->disk_name);
|
||||
buf = dst;
|
||||
sector_addr = addr / sector_size;
|
||||
max_read_length = MIN(mmc_info->mmc_max_xfer_size, remaining);
|
||||
sector_count = max_read_length / sector_size;
|
||||
read_len = sector_count * sector_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk read addr:%llx read_len:%lld\n",
|
||||
addr, read_len);
|
||||
}
|
||||
/* Address & size aligned portion of sector,Memory CACHE_LINE is not
|
||||
aligned */
|
||||
else {
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk read %s remaining portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
read_len = MIN(buff_size, remaining);
|
||||
sector_count = ROUNDUP(read_len, sector_size) / sector_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk read addr:%llx read_len:%lld\n",
|
||||
addr, read_len);
|
||||
}
|
||||
|
||||
if (buf == dst) {
|
||||
ret = mmc_dev_read(mmc_info, buf, sector_addr, sector_count);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
ret = mmc_buff_read(mmc_info, buf, sector_addr, sector_count, dst,
|
||||
addr, read_len);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Address & size offset */
|
||||
dst += read_len;
|
||||
addr += read_len;
|
||||
remaining -= read_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmc_buff_write(struct disk_mmc_info *mmc_info, uint8_t *buff_src,
|
||||
block_t sector, block_count_t sector_count,
|
||||
uint8_t *src, disk_addr_t addr, disk_size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
/* Protect the buffer */
|
||||
xSemaphoreTake(mmc_info->disk_mmc_mutex, portMAX_DELAY);
|
||||
|
||||
if (IS_ALIGNED(addr, sector_size) && IS_ALIGNED(size, sector_size)) {
|
||||
memcpy(buff_src, src, size);
|
||||
}
|
||||
else {
|
||||
ret = mmc_dev_read(mmc_info, buff_src, sector, sector_count);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
memcpy(buff_src + addr - ROUNDDOWN(addr, sector_size), src, size);
|
||||
}
|
||||
|
||||
ret = mmc_dev_write(mmc_info, buff_src, sector, sector_count);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
xSemaphoreGive(mmc_info->disk_mmc_mutex);
|
||||
return 0;
|
||||
error:
|
||||
xSemaphoreGive(mmc_info->disk_mmc_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int disk_mmc_write(struct disk_info *info, const uint8_t *src,
|
||||
disk_addr_t addr, disk_size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
|
||||
uint8_t *buf = NULL;
|
||||
disk_size_t remaining = size;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
uint32_t buff_size = mmc_info->buff_size;
|
||||
|
||||
disk_addr_t sector_addr = 0;
|
||||
disk_size_t sector_count = 0;
|
||||
disk_size_t write_len = 0;
|
||||
disk_size_t max_read_length = 0;
|
||||
|
||||
while (remaining) {
|
||||
/* Process the unaligned portion of the address */
|
||||
if (!IS_ALIGNED(addr, sector_size)) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk write %s address sector unaligned portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
sector_count = 1;
|
||||
write_len = MIN(ROUNDUP(addr, sector_size) - addr, remaining);
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk write addr:%llx write_len:%lld\n",
|
||||
addr, write_len);
|
||||
}
|
||||
/* Address & size aligned portion of sector,Memory CACHE_LINE alignment
|
||||
*/
|
||||
else if ((remaining > sector_size) &&
|
||||
IS_ALIGNED(src, CONFIG_ARCH_CACHE_LINE)) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk write %s address sector aligned & dst "
|
||||
"CACHE_LINE aligned portion\n",
|
||||
info->disk_name);
|
||||
buf = (uint8_t *)src;
|
||||
sector_addr = addr / sector_size;
|
||||
max_read_length = MIN(mmc_info->mmc_max_xfer_size, remaining);
|
||||
sector_count = max_read_length / sector_size;
|
||||
write_len = sector_count * sector_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk write addr:%llx write_len:%lld\n",
|
||||
addr, write_len);
|
||||
}
|
||||
else {
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk write %s remaining portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
write_len = MIN(buff_size, remaining);
|
||||
|
||||
if (!IS_ALIGNED(write_len, sector_size) &&
|
||||
(write_len > sector_size))
|
||||
write_len = ROUNDDOWN(write_len, sector_size);
|
||||
|
||||
sector_count = ROUNDUP(write_len, sector_size) / sector_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk write addr:%llx write_len:%lld\n",
|
||||
addr, write_len);
|
||||
}
|
||||
|
||||
if (buf == src) {
|
||||
ret = mmc_dev_write(mmc_info, buf, sector_addr, sector_count);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
ret = mmc_buff_write(mmc_info, buf, sector_addr, sector_count,
|
||||
(uint8_t *)src, addr, write_len);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Address & size offset */
|
||||
src += write_len;
|
||||
addr += write_len;
|
||||
remaining -= write_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disk_mmc_read_block(struct disk_info *info, uint8_t *dst,
|
||||
block_t block, block_count_t count,
|
||||
block_size_t blk_sz)
|
||||
{
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
uint32_t blk_to_sector = blk_sz / sector_size;
|
||||
return mmc_dev_read(mmc_info, dst, block * blk_to_sector,
|
||||
count * blk_to_sector);
|
||||
}
|
||||
|
||||
static int disk_mmc_write_block(struct disk_info *info, const uint8_t *src,
|
||||
block_t block, block_count_t count,
|
||||
block_size_t blk_sz)
|
||||
{
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
uint32_t blk_to_sector = blk_sz / sector_size;
|
||||
return mmc_dev_write(mmc_info, src, block * blk_to_sector,
|
||||
count * blk_to_sector);
|
||||
}
|
||||
|
||||
static int mmc_buff_erase(struct disk_mmc_info *mmc_info, uint8_t *buff,
|
||||
block_t sector, block_count_t sector_count,
|
||||
disk_addr_t addr, disk_size_t size, char flag)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
/* Protect the buff_sector buffer */
|
||||
xSemaphoreTake(mmc_info->disk_mmc_mutex, portMAX_DELAY);
|
||||
|
||||
if (IS_ALIGNED(addr, sector_size) && IS_ALIGNED(size, sector_size)) {
|
||||
memset(buff, flag, size);
|
||||
}
|
||||
else {
|
||||
ret = mmc_dev_read(mmc_info, buff, sector, sector_count);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
memset(buff + addr - ROUNDDOWN(addr, sector_size), flag, size);
|
||||
}
|
||||
|
||||
ret = mmc_dev_write(mmc_info, buff, sector, sector_count);
|
||||
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
xSemaphoreGive(mmc_info->disk_mmc_mutex);
|
||||
return 0;
|
||||
error:
|
||||
xSemaphoreGive(mmc_info->disk_mmc_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int disk_mmc_erase(struct disk_info *info, disk_addr_t addr,
|
||||
disk_size_t size, uint32_t flag)
|
||||
{
|
||||
int ret = 0;
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
|
||||
uint8_t *buf = NULL;
|
||||
disk_size_t remaining = size;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
uint32_t buff_size = mmc_info->buff_size;
|
||||
uint32_t scr_data_erase = mmc_info->config.scr_data_erase;
|
||||
uint32_t erase_size = info->erase_size;
|
||||
|
||||
disk_addr_t sector_addr = 0;
|
||||
disk_size_t sector_count = 0;
|
||||
disk_size_t erase_count = 0;
|
||||
disk_size_t erase_len = 0;
|
||||
|
||||
/* configure c_flag */
|
||||
char c_flag = 0;
|
||||
|
||||
if (MMC_DEFAULT_FLAG(flag))
|
||||
c_flag = 0x0;
|
||||
else
|
||||
c_flag = 0xff;
|
||||
|
||||
while (remaining) {
|
||||
/* Process the sector unaligned portion of the address */
|
||||
if (!IS_ALIGNED(addr, sector_size)) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk erase %s address sector unaligned portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
sector_count = 1;
|
||||
erase_len = MIN(ROUNDUP(addr, sector_size) - addr, remaining);
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk erase addr:%llx erase_len:%lld\n",
|
||||
addr, erase_len);
|
||||
}
|
||||
/* Process the erase_size unaligned portion of the address */
|
||||
else if (!IS_ALIGNED(addr, erase_size) && (remaining > erase_size)) {
|
||||
ssdk_printf(
|
||||
SSDK_DEBUG,
|
||||
"mmc disk erase %s address erase_size unaligned portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
erase_len = MIN(buff_size, remaining);
|
||||
erase_len = MIN(ROUNDUP(addr, erase_size) - addr, erase_len);
|
||||
sector_count = erase_len / sector_size;
|
||||
erase_len = sector_count * sector_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk erase addr:%llx erase_len:%lld\n",
|
||||
addr, erase_len);
|
||||
}
|
||||
/* Address & size aligned portion of sector,Memory CACHE_LINE alignment
|
||||
*/
|
||||
else if ((remaining > erase_size) && MMC_DEFAULT_FLAG(flag)
|
||||
&& !scr_data_erase) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk erase %s address erase_size aligned & size "
|
||||
"erase_size aligned portion\n",
|
||||
info->disk_name);
|
||||
buf = NULL;
|
||||
sector_addr = addr / sector_size;
|
||||
erase_count = remaining / erase_size;
|
||||
erase_len = erase_count * erase_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk erase addr:%llx erase_len:%lld\n",
|
||||
addr, erase_len);
|
||||
}
|
||||
else if ((remaining > erase_size) && !MMC_DEFAULT_FLAG(flag)
|
||||
&& scr_data_erase) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk erase %s address erase_size aligned & size "
|
||||
"erase_size aligned portion\n",
|
||||
info->disk_name);
|
||||
buf = NULL;
|
||||
sector_addr = addr / sector_size;
|
||||
erase_count = remaining / erase_size;
|
||||
erase_len = erase_count * erase_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk erase addr:%llx erase_len:%lld\n",
|
||||
addr, erase_len);
|
||||
}
|
||||
/* Address & size aligned portion of sector,Memory CACHE_LINE is not
|
||||
aligned */
|
||||
else {
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk erase %s remaining portion\n",
|
||||
info->disk_name);
|
||||
buf = mmc_info->buff_sector;
|
||||
sector_addr = addr / sector_size;
|
||||
erase_len = MIN(buff_size, remaining);
|
||||
|
||||
if (!IS_ALIGNED(erase_len, sector_size) &&
|
||||
(erase_len > sector_size))
|
||||
erase_len = ROUNDDOWN(erase_len, sector_size);
|
||||
|
||||
sector_count = ROUNDUP(erase_len, sector_size) / sector_size;
|
||||
ssdk_printf(SSDK_DEBUG, "mmc disk erase addr:%llx erase_len:%lld\n",
|
||||
addr, erase_len);
|
||||
}
|
||||
|
||||
if (NULL == buf) {
|
||||
ret = mmc_dev_erase(mmc_info, sector_addr, erase_len / sector_size);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
ret = mmc_buff_erase(mmc_info, buf, sector_addr, sector_count, addr,
|
||||
erase_len, c_flag);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Address & size offset */
|
||||
addr += erase_len;
|
||||
remaining -= erase_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int disk_mmc_erase_group(struct disk_info *info, uint32_t erase_block,
|
||||
uint32_t count, uint32_t erase_sz,
|
||||
uint32_t flag)
|
||||
{
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
uint32_t sector_size = mmc_info->config.sector_size;
|
||||
uint32_t scr_data_erase = mmc_info->config.scr_data_erase;
|
||||
|
||||
if (erase_sz != info->erase_size) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk %s erase group erase_sz error,erase_sz:0x%x "
|
||||
"erase_size:0x%x \n",
|
||||
info->disk_name, erase_sz, info->erase_size);
|
||||
return -DISK_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(erase_sz, sector_size)) {
|
||||
ssdk_printf(SSDK_DEBUG,
|
||||
"mmc disk %s erase group erase_sz error,erase_sz:0x%x "
|
||||
"sector_size:0x%x \n",
|
||||
info->disk_name, erase_sz, sector_size);
|
||||
return -DISK_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
uint32_t sector_addr = erase_block * erase_sz / sector_size;
|
||||
|
||||
switch (flag) {
|
||||
case DISK_ERASE_DEFAULT:
|
||||
case DISK_ERASE_ZERO:
|
||||
if (!scr_data_erase) {
|
||||
return mmc_dev_erase(mmc_info, sector_addr, count * erase_sz / sector_size);
|
||||
}
|
||||
else {
|
||||
return disk_mmc_erase(info, (disk_addr_t)erase_block * erase_sz,
|
||||
(disk_size_t)count * erase_sz, flag);
|
||||
}
|
||||
|
||||
case DISK_ERASE_ONE:
|
||||
if (scr_data_erase) {
|
||||
return mmc_dev_erase(mmc_info, sector_addr, count * erase_sz / sector_size);
|
||||
}
|
||||
else {
|
||||
return disk_mmc_erase(info, (disk_addr_t)erase_block * erase_sz,
|
||||
(disk_size_t)count * erase_sz, flag);
|
||||
}
|
||||
|
||||
default:
|
||||
ssdk_printf(SSDK_ERR, "disk mmc erase flag error\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int disk_mmc_status(struct disk_info *info) { return DISK_STATUS_OK; }
|
||||
|
||||
static int disk_mmc_ioctl(struct disk_info *info, uint32_t cmd, void *buff)
|
||||
{
|
||||
struct disk_mmc_info *mmc_info = info->private_data;
|
||||
|
||||
switch (cmd) {
|
||||
case MMC_IOCTL_PON:
|
||||
uint32_t pon_type = 0;
|
||||
memcpy(&pon_type, buff, sizeof(pon_type));
|
||||
|
||||
if (mmc_info->config.mmc_pon)
|
||||
return mmc_info->config.mmc_pon(mmc_info->config.mmc_dev, pon_type);
|
||||
else
|
||||
return DISK_ERROR_INVALID_PARAMETER;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ssdk_printf(SSDK_ERR, "disk mmc ioctl cmd error:%d\n", cmd);
|
||||
return DISK_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct disk_operations disk_mmc_ops = {
|
||||
.disk_read = disk_mmc_read,
|
||||
.disk_write = disk_mmc_write,
|
||||
.disk_read_block = disk_mmc_read_block,
|
||||
.disk_write_block = disk_mmc_write_block,
|
||||
.disk_erase = disk_mmc_erase,
|
||||
.disk_erase_group = disk_mmc_erase_group,
|
||||
.disk_status = disk_mmc_status,
|
||||
.disk_ioctl = disk_mmc_ioctl,
|
||||
};
|
||||
|
||||
int register_mmc_disk(struct disk_mmc_info *mmc_info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
struct disk_info *info = &mmc_info->info;
|
||||
struct disk_mmc_config *mmc_config = &mmc_info->config;
|
||||
|
||||
/* init mmc_info */
|
||||
mmc_info->buff_size = 4 * 1024;
|
||||
|
||||
if (!IS_ALIGNED(mmc_info->buff_size, mmc_config->sector_size)) {
|
||||
ssdk_printf(
|
||||
SSDK_ERR,
|
||||
"mmc disk %s mmc_max_xfer_size not aligned to sector_size\n",
|
||||
mmc_config->disk_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmc_info->buff_sector = (uint8_t *)pvPortMallocAligned(
|
||||
mmc_info->buff_size, CONFIG_ARCH_CACHE_LINE);
|
||||
|
||||
if (NULL == mmc_info->buff_sector) {
|
||||
ssdk_printf(SSDK_ERR, "mmc disk %s buff malloc error\n",
|
||||
mmc_config->disk_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mmc_info->disk_mmc_mutex = xSemaphoreCreateMutex();
|
||||
mmc_info->mmc_max_xfer_size = MMC_MAX_XFER_SIZE;
|
||||
|
||||
if (!IS_ALIGNED(mmc_info->mmc_max_xfer_size, mmc_config->sector_size)) {
|
||||
ssdk_printf(
|
||||
SSDK_ERR,
|
||||
"mmc disk %s mmc_max_xfer_size not aligned to sector_size\n",
|
||||
mmc_config->disk_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* base on config init info */
|
||||
info->disk_name = mmc_config->disk_name;
|
||||
info->disk_size = mmc_config->disk_size;
|
||||
info->disk_offset = 0;
|
||||
info->erase_size = mmc_config->erase_size;
|
||||
info->mem_align_size = CONFIG_ARCH_CACHE_LINE;
|
||||
info->block_align_size = mmc_config->sector_size;
|
||||
info->private_data = mmc_info;
|
||||
info->disk_ops = &disk_mmc_ops;
|
||||
|
||||
#ifdef CONFIG_DISK_CACHE_NOOP
|
||||
struct disk_cache_noop *cache_noop = &mmc_info->cache_noop;
|
||||
/* base on config cache,cache in disk dev layer??? */
|
||||
cache_noop->cache_align_size = 4u * 1024u;
|
||||
cache_noop->cache.private_data = cache_noop;
|
||||
ret = register_disk_cache_noop(cache_noop);
|
||||
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_ERR, "mmc disk register cache noop:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ssdk_printf(SSDK_INFO,
|
||||
"register mmc disk:%s disk_size:%lld erase_size:0x%x "
|
||||
"sector_size:0x%x\n",
|
||||
info->disk_name, info->disk_size, info->erase_size,
|
||||
mmc_config->sector_size);
|
||||
|
||||
xSemaphoreTake(g_disk_mutex, portMAX_DELAY);
|
||||
list_add_tail(&g_disk_list, &info->node);
|
||||
info->use_count = 0;
|
||||
xSemaphoreGive(g_disk_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
int unregister_mmc_disk(struct disk_mmc_info *mmc_info)
|
||||
{
|
||||
int ret = 0;
|
||||
struct disk_info *info = &mmc_info->info;
|
||||
|
||||
ssdk_printf(SSDK_INFO, "unregister mmc disk:%s\n", info->disk_name);
|
||||
|
||||
#ifdef CONFIG_DISK_CACHE_NOOP
|
||||
struct disk_cache_noop *cache_noop = &mmc_info->cache_noop;
|
||||
/* unregister disk cache noop */
|
||||
ret = unregister_disk_cache_noop(cache_noop);
|
||||
|
||||
if (ret < 0) {
|
||||
ssdk_printf(SSDK_ERR, "mmc disk unregister cache noop:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
vPortFree(mmc_info->buff_sector);
|
||||
vSemaphoreDelete(mmc_info->disk_mmc_mutex);
|
||||
|
||||
xSemaphoreTake(g_disk_mutex, portMAX_DELAY);
|
||||
|
||||
if (info->use_count) {
|
||||
xSemaphoreGive(g_disk_mutex);
|
||||
ret = -DISK_ERROR_BUSY;
|
||||
ssdk_printf(SSDK_ERR, "mmc disk unregister:%d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (list_in_list(&info->node))
|
||||
list_delete(&info->node);
|
||||
|
||||
xSemaphoreGive(g_disk_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user