2022-10-28 22:51:22 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018-2021 Zephyr contributors
|
|
|
|
* Copyright (c) 2022 Nordic Semiconductor ASA
|
2024-05-15 03:46:20 +08:00
|
|
|
* Copyright 2024 NXP
|
2022-10-28 22:51:22 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*/
|
|
|
|
/* The file is based on template file by (C)ChaN, 2019, as
|
|
|
|
* available from FAT FS module source:
|
|
|
|
* https://github.com/zephyrproject-rtos/fatfs/blob/master/diskio.c
|
|
|
|
* and has been previously avaialble from directory for that module
|
|
|
|
* under name zfs_diskio.c.
|
|
|
|
*/
|
|
|
|
#include <ff.h>
|
|
|
|
#include <diskio.h> /* FatFs lower layer API */
|
2024-05-15 03:46:20 +08:00
|
|
|
#include <zfs_diskio.h> /* Zephyr specific FatFS API */
|
2022-10-28 22:51:22 +08:00
|
|
|
#include <zephyr/storage/disk_access.h>
|
|
|
|
|
|
|
|
static const char * const pdrv_str[] = {FF_VOLUME_STRS};
|
|
|
|
|
|
|
|
/* Get Drive Status */
|
|
|
|
DSTATUS disk_status(BYTE pdrv)
|
|
|
|
{
|
|
|
|
__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
|
|
|
|
|
|
|
|
if (disk_access_status(pdrv_str[pdrv]) != 0) {
|
|
|
|
return STA_NOINIT;
|
|
|
|
} else {
|
|
|
|
return RES_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize a Drive */
|
|
|
|
DSTATUS disk_initialize(BYTE pdrv)
|
|
|
|
{
|
2024-05-15 03:46:20 +08:00
|
|
|
uint8_t param = DISK_IOCTL_POWER_ON;
|
2022-10-28 22:51:22 +08:00
|
|
|
|
2024-05-15 03:46:20 +08:00
|
|
|
return disk_ioctl(pdrv, CTRL_POWER, ¶m);
|
2022-10-28 22:51:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Read Sector(s) */
|
2022-11-23 22:27:38 +08:00
|
|
|
DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count)
|
2022-10-28 22:51:22 +08:00
|
|
|
{
|
|
|
|
__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
|
|
|
|
|
|
|
|
if (disk_access_read(pdrv_str[pdrv], buff, sector, count) != 0) {
|
|
|
|
return RES_ERROR;
|
|
|
|
} else {
|
|
|
|
return RES_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write Sector(s) */
|
2022-11-23 22:27:38 +08:00
|
|
|
DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count)
|
2022-10-28 22:51:22 +08:00
|
|
|
{
|
|
|
|
__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
|
|
|
|
|
|
|
|
if (disk_access_write(pdrv_str[pdrv], buff, sector, count) != 0) {
|
|
|
|
return RES_ERROR;
|
|
|
|
} else {
|
|
|
|
return RES_OK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Miscellaneous Functions */
|
|
|
|
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
|
|
|
|
{
|
|
|
|
int ret = RES_OK;
|
|
|
|
uint32_t sector_size = 0;
|
|
|
|
|
|
|
|
__ASSERT(pdrv < ARRAY_SIZE(pdrv_str), "pdrv out-of-range\n");
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case CTRL_SYNC:
|
|
|
|
if (disk_access_ioctl(pdrv_str[pdrv],
|
|
|
|
DISK_IOCTL_CTRL_SYNC, buff) != 0) {
|
|
|
|
ret = RES_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GET_SECTOR_COUNT:
|
|
|
|
if (disk_access_ioctl(pdrv_str[pdrv],
|
|
|
|
DISK_IOCTL_GET_SECTOR_COUNT, buff) != 0) {
|
|
|
|
ret = RES_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GET_SECTOR_SIZE:
|
|
|
|
/* Zephyr's DISK_IOCTL_GET_SECTOR_SIZE returns sector size as a
|
|
|
|
* 32-bit number while FatFS's GET_SECTOR_SIZE is supposed to
|
|
|
|
* return a 16-bit number.
|
|
|
|
*/
|
|
|
|
if ((disk_access_ioctl(pdrv_str[pdrv],
|
|
|
|
DISK_IOCTL_GET_SECTOR_SIZE, §or_size) == 0) &&
|
|
|
|
(sector_size == (uint16_t)sector_size)) {
|
|
|
|
*(uint16_t *)buff = (uint16_t)sector_size;
|
|
|
|
} else {
|
|
|
|
ret = RES_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GET_BLOCK_SIZE:
|
|
|
|
if (disk_access_ioctl(pdrv_str[pdrv],
|
|
|
|
DISK_IOCTL_GET_ERASE_BLOCK_SZ, buff) != 0) {
|
|
|
|
ret = RES_ERROR;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2024-05-15 03:46:20 +08:00
|
|
|
/* Optional IOCTL command used by Zephyr fs_unmount implementation,
|
|
|
|
* not called by FATFS
|
|
|
|
*/
|
|
|
|
case CTRL_POWER:
|
|
|
|
if (((*(uint8_t *)buff)) == DISK_IOCTL_POWER_OFF) {
|
|
|
|
/* Power disk off */
|
|
|
|
if (disk_access_ioctl(pdrv_str[pdrv],
|
|
|
|
DISK_IOCTL_CTRL_DEINIT,
|
|
|
|
NULL) != 0) {
|
|
|
|
ret = RES_ERROR;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Power disk on */
|
|
|
|
if (disk_access_ioctl(pdrv_str[pdrv],
|
|
|
|
DISK_IOCTL_CTRL_INIT,
|
|
|
|
NULL) != 0) {
|
|
|
|
ret = STA_NOINIT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2022-10-28 22:51:22 +08:00
|
|
|
default:
|
|
|
|
ret = RES_PARERR;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|