Merge pull request #1166 from gsomlo/gls-fatfs-sd-sata

RFC: software/fatfs: allow sata, [spi]sdcard disk ops to co-exist
This commit is contained in:
enjoy-digital 2022-01-17 10:59:57 +01:00 committed by GitHub
commit 3d3229fb49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 118 additions and 78 deletions

View File

@ -812,9 +812,11 @@ void sdcardboot(void)
{
#ifdef CSR_SPISDCARD_BASE
printf("Booting from SDCard in SPI-Mode...\n");
fatfs_set_ops_spisdcard(); /* use spisdcard disk access ops */
#endif
#ifdef CSR_SDCORE_BASE
printf("Booting from SDCard in SD-Mode...\n");
fatfs_set_ops_sdcard(); /* use sdcard disk access ops */
#endif
/* Boot from boot.json */
@ -986,6 +988,7 @@ static void sataboot_from_bin(const char * filename)
void sataboot(void)
{
printf("Booting from SATA...\n");
fatfs_set_ops_sata(); /* use sata disk access ops */
/* Boot from boot.json */
printf("Booting from boot.json...\n");

View File

@ -26,13 +26,16 @@ typedef enum {
/*---------------------------------------*/
/* Prototypes for disk control functions */
typedef struct {
DSTATUS (*disk_initialize) (BYTE pdrv);
DSTATUS (*disk_status) (BYTE pdrv);
DRESULT (*disk_read) (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
DRESULT (*disk_write) (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
DRESULT (*disk_ioctl) (BYTE pdrv, BYTE cmd, void* buff);
} DISKOPS;
DSTATUS disk_initialize (BYTE pdrv);
DSTATUS disk_status (BYTE pdrv);
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
/* Global disk control ops pointer */
extern DISKOPS *FfDiskOps;
/* Disk Status Bits (DSTATUS) */
#define STA_NOINIT 0x01 /* Drive not initialized */

View File

@ -22,6 +22,7 @@
#include "ff.h" /* Declarations of FatFs API */
#include "diskio.h" /* Declarations of device I/O functions */
DISKOPS *FfDiskOps; /* Global pointer to disk control ops */
/*--------------------------------------------------------------------------
@ -1077,10 +1078,10 @@ static FRESULT sync_window ( /* Returns FR_OK or FR_DISK_ERR */
if (fs->wflag) { /* Is the disk access window dirty? */
if (disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */
if (FfDiskOps->disk_write(fs->pdrv, fs->win, fs->winsect, 1) == RES_OK) { /* Write it back into the volume */
fs->wflag = 0; /* Clear window dirty flag */
if (fs->winsect - fs->fatbase < fs->fsize) { /* Is it in the 1st FAT? */
if (fs->n_fats == 2) disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */
if (fs->n_fats == 2) FfDiskOps->disk_write(fs->pdrv, fs->win, fs->winsect + fs->fsize, 1); /* Reflect it to 2nd FAT if needed */
}
} else {
res = FR_DISK_ERR;
@ -1104,7 +1105,7 @@ static FRESULT move_window ( /* Returns FR_OK or FR_DISK_ERR */
res = sync_window(fs); /* Flush the window */
#endif
if (res == FR_OK) { /* Fill sector window with new data */
if (disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) {
if (FfDiskOps->disk_read(fs->pdrv, fs->win, sect, 1) != RES_OK) {
sect = (LBA_t)0 - 1; /* Invalidate window if read data is not valid */
res = FR_DISK_ERR;
}
@ -1141,11 +1142,11 @@ static FRESULT sync_fs ( /* Returns FR_OK or FR_DISK_ERR */
st_dword(fs->win + FSI_Nxt_Free, fs->last_clst);
/* Write it into the FSInfo sector */
fs->winsect = fs->volbase + 1;
disk_write(fs->pdrv, fs->win, fs->winsect, 1);
FfDiskOps->disk_write(fs->pdrv, fs->win, fs->winsect, 1);
fs->fsi_flag = 0;
}
/* Make sure that no pending write process in the lower layer */
if (disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR;
if (FfDiskOps->disk_ioctl(fs->pdrv, CTRL_SYNC, 0) != RES_OK) res = FR_DISK_ERR;
}
return res;
@ -1494,7 +1495,7 @@ static FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */
#if FF_USE_TRIM
rt[0] = clst2sect(fs, scl); /* Start of data area to be freed */
rt[1] = clst2sect(fs, ecl) + fs->csize - 1; /* End of data area to be freed */
disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be erased */
FfDiskOps->disk_ioctl(fs->pdrv, CTRL_TRIM, rt); /* Inform storage device that the data in the block may be erased */
#endif
scl = ecl = nxt;
}
@ -1691,13 +1692,13 @@ static FRESULT dir_clear ( /* Returns FR_OK or FR_DISK_ERR */
if (szb > SS(fs)) { /* Buffer allocated? */
mem_set(ibuf, 0, szb);
szb /= SS(fs); /* Bytes -> Sectors */
for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */
for (n = 0; n < fs->csize && FfDiskOps->disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */
ff_memfree(ibuf);
} else
#endif
{
ibuf = fs->win; szb = 1; /* Use window buffer (many single-sector writes may take a time) */
for (n = 0; n < fs->csize && disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */
for (n = 0; n < fs->csize && FfDiskOps->disk_write(fs->pdrv, ibuf, sect + n, szb) == RES_OK; n += szb) ; /* Fill the cluster with 0 */
}
return (n == fs->csize) ? FR_OK : FR_DISK_ERR;
}
@ -3397,7 +3398,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */
mode &= (BYTE)~FA_READ; /* Desired access mode, write access or not */
if (fs->fs_type != 0) { /* If the volume has been mounted */
stat = disk_status(fs->pdrv);
stat = FfDiskOps->disk_status(fs->pdrv);
if (!(stat & STA_NOINIT)) { /* and the physical drive is kept initialized */
if (!FF_FS_READONLY && mode && (stat & STA_PROTECT)) { /* Check write protection if needed */
return FR_WRITE_PROTECTED;
@ -3411,7 +3412,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */
fs->fs_type = 0; /* Clear the filesystem object */
fs->pdrv = LD2PD(vol); /* Volume hosting physical drive */
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
stat = FfDiskOps->disk_initialize(fs->pdrv); /* Initialize the physical drive */
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
return FR_NOT_READY; /* Failed to initialize due to no medium or hard error */
}
@ -3419,7 +3420,7 @@ static FRESULT mount_volume ( /* FR_OK(0): successful, !=0: an error occurred */
return FR_WRITE_PROTECTED;
}
#if FF_MAX_SS != FF_MIN_SS /* Get sector size (multiple sector size cfg only) */
if (disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;
if (FfDiskOps->disk_ioctl(fs->pdrv, GET_SECTOR_SIZE, &SS(fs)) != RES_OK) return FR_DISK_ERR;
if (SS(fs) > FF_MAX_SS || SS(fs) < FF_MIN_SS || (SS(fs) & (SS(fs) - 1))) return FR_DISK_ERR;
#endif
@ -3607,7 +3608,7 @@ static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */
if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */
#if FF_FS_REENTRANT
if (lock_fs(obj->fs)) { /* Obtain the filesystem object */
if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
if (!(FfDiskOps->disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
res = FR_OK;
} else {
unlock_fs(obj->fs, FR_OK);
@ -3616,7 +3617,7 @@ static FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */
res = FR_TIMEOUT;
}
#else
if (!(disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
if (!(FfDiskOps->disk_status(obj->fs->pdrv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
res = FR_OK;
}
#endif
@ -3857,7 +3858,7 @@ FRESULT f_open (
} else {
fp->sect = sc + (DWORD)(ofs / SS(fs));
#if !FF_FS_TINY
if (disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;
if (FfDiskOps->disk_read(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;
#endif
}
}
@ -3932,7 +3933,7 @@ FRESULT f_read (
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
cc = fs->csize - csect;
}
if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
#if FF_FS_TINY
if (fs->wflag && fs->winsect - sect < cc) {
@ -3951,11 +3952,11 @@ FRESULT f_read (
if (fp->sect != sect) { /* Load data sector if not in cache */
#if !FF_FS_READONLY
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
if (FfDiskOps->disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
}
#endif
fp->sect = sect;
@ -4036,7 +4037,7 @@ FRESULT f_write (
if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
#else
if (fp->flag & FA_DIRTY) { /* Write-back sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
@ -4048,7 +4049,7 @@ FRESULT f_write (
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
cc = fs->csize - csect;
}
if (disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
#if FF_FS_MINIMIZE <= 2
#if FF_FS_TINY
if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
@ -4073,7 +4074,7 @@ FRESULT f_write (
#else
if (fp->sect != sect && /* Fill sector cache with file data */
fp->fptr < fp->obj.objsize &&
disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
FfDiskOps->disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) {
ABORT(fs, FR_DISK_ERR);
}
#endif
@ -4118,7 +4119,7 @@ FRESULT f_sync (
if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */
#if !FF_FS_TINY
if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
@ -4462,11 +4463,11 @@ FRESULT f_lseek (
#if !FF_FS_TINY
#if !FF_FS_READONLY
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
if (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */
if (FfDiskOps->disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */
#endif
fp->sect = dsc;
}
@ -4542,11 +4543,11 @@ FRESULT f_lseek (
#if !FF_FS_TINY
#if !FF_FS_READONLY
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
if (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
if (FfDiskOps->disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
#endif
fp->sect = nsect;
}
@ -4901,7 +4902,7 @@ FRESULT f_truncate (
fp->flag |= FA_MODIFIED;
#if !FF_FS_TINY
if (res == FR_OK && (fp->flag & FA_DIRTY)) {
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) {
res = FR_DISK_ERR;
} else {
fp->flag &= (BYTE)~FA_DIRTY;
@ -5654,11 +5655,11 @@ FRESULT f_forward (
if (fp->sect != sect) { /* Fill sector cache with file data */
#if !FF_FS_READONLY
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
if (FfDiskOps->disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
}
dbuf = fp->buf;
#endif
@ -5700,7 +5701,7 @@ static FRESULT create_partition (
BYTE *pte, hd, n_hd, sc, n_sc;
/* Get drive size */
if (disk_ioctl(drv, GET_SECTOR_COUNT, &sz_drv) != RES_OK) return FR_DISK_ERR;
if (FfDiskOps->disk_ioctl(drv, GET_SECTOR_COUNT, &sz_drv) != RES_OK) return FR_DISK_ERR;
#if FF_LBA64
if (sz_drv >= FF_MIN_GPT) { /* Create partitions in GPT */
@ -5711,7 +5712,7 @@ static FRESULT create_partition (
static const BYTE gpt_mbr[16] = {0x00, 0x00, 0x02, 0x00, 0xEE, 0xFE, 0xFF, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF};
#if FF_MAX_SS != FF_MIN_SS
if (disk_ioctl(drv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; /* Get sector size */
if (FfDiskOps->disk_ioctl(drv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR; /* Get sector size */
if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR;
#else
ss = FF_MAX_SS;
@ -5747,8 +5748,8 @@ static FRESULT create_partition (
}
if ((pi + 1) * SZ_GPTE % ss == 0) { /* Write the buffer if it is filled up */
for (i = 0; i < ss; bcc = crc32(bcc, buf[i++])) ; /* Calculate table check sum */
if (disk_write(drv, buf, 2 + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Primary table */
if (disk_write(drv, buf, s_bpt + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Secondary table */
if (FfDiskOps->disk_write(drv, buf, 2 + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Primary table */
if (FfDiskOps->disk_write(drv, buf, s_bpt + pi * SZ_GPTE / ss, 1) != RES_OK) return FR_DISK_ERR; /* Secondary table */
}
} while (++pi < GPT_ITEMS);
@ -5766,7 +5767,7 @@ static FRESULT create_partition (
rnd = make_rand(rnd, buf + GPTH_DskGuid, 16); /* Disk GUID */
for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ; /* Calculate header check sum */
st_dword(buf + GPTH_Bcc, ~bcc); /* Header check sum */
if (disk_write(drv, buf, 1, 1) != RES_OK) return FR_DISK_ERR;
if (FfDiskOps->disk_write(drv, buf, 1, 1) != RES_OK) return FR_DISK_ERR;
/* Create secondary GPT header */
st_qword(buf + GPTH_CurLba, sz_drv - 1); /* LBA of this header */
@ -5775,13 +5776,13 @@ static FRESULT create_partition (
st_dword(buf + GPTH_Bcc, 0);
for (i = 0, bcc= 0xFFFFFFFF; i < 92; bcc = crc32(bcc, buf[i++])) ; /* Calculate header check sum */
st_dword(buf + GPTH_Bcc, ~bcc); /* Header check sum */
if (disk_write(drv, buf, sz_drv - 1, 1) != RES_OK) return FR_DISK_ERR;
if (FfDiskOps->disk_write(drv, buf, sz_drv - 1, 1) != RES_OK) return FR_DISK_ERR;
/* Create protective MBR */
mem_set(buf, 0, ss);
mem_cpy(buf + MBR_Table, gpt_mbr, 16); /* Create a GPT partition */
st_word(buf + BS_55AA, 0xAA55);
if (disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR;
if (FfDiskOps->disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR;
} else
#endif
@ -5821,7 +5822,7 @@ static FRESULT create_partition (
}
st_word(buf + BS_55AA, 0xAA55); /* MBR signature */
if (disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Write it to the MBR */
if (FfDiskOps->disk_write(drv, buf, 0, 1) != RES_OK) return FR_DISK_ERR; /* Write it to the MBR */
}
return FR_OK;
@ -5860,14 +5861,14 @@ FRESULT f_mkfs (
if (!opt) opt = &defopt; /* Use default parameter if it is not given */
/* Get physical drive status (sz_drv, sz_blk, ss) */
ds = disk_initialize(pdrv);
ds = FfDiskOps->disk_initialize(pdrv);
if (ds & STA_NOINIT) return FR_NOT_READY;
if (ds & STA_PROTECT) return FR_WRITE_PROTECTED;
sz_blk = opt->align;
if (sz_blk == 0 && disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK) sz_blk = 1;
if (sz_blk == 0 && FfDiskOps->disk_ioctl(pdrv, GET_BLOCK_SIZE, &sz_blk) != RES_OK) sz_blk = 1;
if (sz_blk == 0 || sz_blk > 0x8000 || (sz_blk & (sz_blk - 1))) sz_blk = 1;
#if FF_MAX_SS != FF_MIN_SS
if (disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR;
if (FfDiskOps->disk_ioctl(pdrv, GET_SECTOR_SIZE, &ss) != RES_OK) return FR_DISK_ERR;
if (ss > FF_MAX_SS || ss < FF_MIN_SS || (ss & (ss - 1))) return FR_DISK_ERR;
#else
ss = FF_MAX_SS;
@ -5892,7 +5893,7 @@ FRESULT f_mkfs (
b_vol = sz_vol = 0;
if (FF_MULTI_PARTITION && ipart != 0) { /* Is the volume associated with any specific partition? */
/* Get partition location from the existing partition table */
if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */
if (FfDiskOps->disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load MBR */
if (ld_word(buf + BS_55AA) != 0xAA55) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if MBR is valid */
#if FF_LBA64
if (buf[MBR_Table + PTE_System] == 0xEE) { /* GPT protective MBR? */
@ -5900,13 +5901,13 @@ FRESULT f_mkfs (
QWORD pt_lba;
/* Get the partition location from GPT */
if (disk_read(pdrv, buf, 1, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load GPT header sector (next to MBR) */
if (FfDiskOps->disk_read(pdrv, buf, 1, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Load GPT header sector (next to MBR) */
if (!test_gpt_header(buf)) LEAVE_MKFS(FR_MKFS_ABORTED); /* Check if GPT header is valid */
n_ent = ld_dword(buf + GPTH_PtNum); /* Number of entries */
pt_lba = ld_qword(buf + GPTH_PtOfs); /* Table start sector */
ofs = i = 0;
while (n_ent) { /* Find MS Basic partition with order of ipart */
if (ofs == 0 && disk_read(pdrv, buf, pt_lba++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Get PT sector */
if (ofs == 0 && FfDiskOps->disk_read(pdrv, buf, pt_lba++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Get PT sector */
if (!mem_cmp(buf + ofs + GPTE_PtGuid, GUID_MS_Basic, 16) && ++i == ipart) { /* MS basic data partition? */
b_vol = ld_qword(buf + ofs + GPTE_FstLba);
sz_vol = ld_qword(buf + ofs + GPTE_LstLba) - b_vol + 1;
@ -5925,7 +5926,7 @@ FRESULT f_mkfs (
sz_vol = ld_dword(pte + PTE_SizLba); /* Get volume size */
}
} else { /* The volume is associated with a physical drive */
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_vol) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (!(fsopt & FM_SFD)) { /* To be partitioned? */
/* Create a single-partition on the drive in this function */
#if FF_LBA64
@ -5974,7 +5975,7 @@ FRESULT f_mkfs (
if (sz_vol < 0x1000) LEAVE_MKFS(FR_MKFS_ABORTED); /* Too small volume for exFAT? */
#if FF_USE_TRIM
lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1; /* Inform storage device that the volume area may be erased */
disk_ioctl(pdrv, CTRL_TRIM, lba);
FfDiskOps->disk_ioctl(pdrv, CTRL_TRIM, lba);
#endif
/* Determine FAT location, data location and number of clusters */
if (sz_au == 0) { /* AU auto-selection */
@ -6024,7 +6025,7 @@ FRESULT f_mkfs (
i += 2; szb_case += 2;
if (si == 0 || i == sz_buf * ss) { /* Write buffered data when buffer full or end of process */
n = (i + ss - 1) / ss;
if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
sect += n; i = 0;
}
} while (si);
@ -6039,7 +6040,7 @@ FRESULT f_mkfs (
for (i = 0; nb >= 8 && i < sz_buf * ss; buf[i++] = 0xFF, nb -= 8) ;
for (b = 1; nb != 0 && i < sz_buf * ss; buf[i] |= b, b <<= 1, nb--) ;
n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */
if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
sect += n; nsect -= n;
} while (nsect);
@ -6060,7 +6061,7 @@ FRESULT f_mkfs (
if (nb == 0 && j < 3) nb = tbl[j++]; /* Next chain */
} while (nb != 0 && i < sz_buf * ss);
n = (nsect > sz_buf) ? sz_buf : nsect; /* Write the buffered data */
if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
sect += n; nsect -= n;
} while (nsect);
@ -6077,7 +6078,7 @@ FRESULT f_mkfs (
sect = b_data + sz_au * (tbl[0] + tbl[1]); nsect = sz_au; /* Start of the root directory and number of sectors */
do { /* Fill root directory sectors */
n = (nsect > sz_buf) ? sz_buf : nsect;
if (disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect, n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
mem_set(buf, 0, ss);
sect += n; nsect -= n;
} while (nsect);
@ -6106,23 +6107,23 @@ FRESULT f_mkfs (
for (i = sum = 0; i < ss; i++) { /* VBR checksum */
if (i != BPB_VolFlagEx && i != BPB_VolFlagEx + 1 && i != BPB_PercInUseEx) sum = xsum32(buf[i], sum);
}
if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
/* Extended bootstrap record (+1..+8) */
mem_set(buf, 0, ss);
st_word(buf + ss - 2, 0xAA55); /* Signature (placed at end of sector) */
for (j = 1; j < 9; j++) {
for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */
if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
}
/* OEM/Reserved record (+9..+10) */
mem_set(buf, 0, ss);
for ( ; j < 11; j++) {
for (i = 0; i < ss; sum = xsum32(buf[i++], sum)) ; /* VBR checksum */
if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
}
/* Sum record (+11) */
for (i = 0; i < ss; i += 4) st_dword(buf + i, sum); /* Fill with checksum value */
if (disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect++, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
}
} else
@ -6204,7 +6205,7 @@ FRESULT f_mkfs (
#if FF_USE_TRIM
lba[0] = b_vol; lba[1] = b_vol + sz_vol - 1; /* Inform storage device that the volume area may be erased */
disk_ioctl(pdrv, CTRL_TRIM, lba);
FfDiskOps->disk_ioctl(pdrv, CTRL_TRIM, lba);
#endif
/* Create FAT VBR */
mem_set(buf, 0, ss);
@ -6240,19 +6241,19 @@ FRESULT f_mkfs (
mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19); /* Volume label, FAT signature */
}
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
if (FfDiskOps->disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
/* Create FSINFO record if needed */
if (fsty == FS_FAT32) {
disk_write(pdrv, buf, b_vol + 6, 1); /* Write backup VBR (VBR + 6) */
FfDiskOps->disk_write(pdrv, buf, b_vol + 6, 1); /* Write backup VBR (VBR + 6) */
mem_set(buf, 0, ss);
st_dword(buf + FSI_LeadSig, 0x41615252);
st_dword(buf + FSI_StrucSig, 0x61417272);
st_dword(buf + FSI_Free_Count, n_clst - 1); /* Number of free clusters */
st_dword(buf + FSI_Nxt_Free, 2); /* Last allocated cluster# */
st_word(buf + BS_55AA, 0xAA55);
disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
FfDiskOps->disk_write(pdrv, buf, b_vol + 7, 1); /* Write backup FSINFO (VBR + 7) */
FfDiskOps->disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
}
/* Initialize FAT area */
@ -6269,7 +6270,7 @@ FRESULT f_mkfs (
nsect = sz_fat; /* Number of FAT sectors */
do { /* Fill FAT sectors */
n = (nsect > sz_buf) ? sz_buf : nsect;
if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
mem_set(buf, 0, ss); /* Rest of FAT all are cleared */
sect += n; nsect -= n;
} while (nsect);
@ -6279,7 +6280,7 @@ FRESULT f_mkfs (
nsect = (fsty == FS_FAT32) ? pau : sz_dir; /* Number of root directory sectors */
do {
n = (nsect > sz_buf) ? sz_buf : nsect;
if (disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_write(pdrv, buf, sect, (UINT)n) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
sect += n; nsect -= n;
} while (nsect);
}
@ -6305,9 +6306,9 @@ FRESULT f_mkfs (
if (FF_MULTI_PARTITION && ipart != 0) { /* Volume is in the existing partition */
if (!FF_LBA64 || !(fsopt & 0x80)) {
/* Update system ID in the partition table */
if (disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */
if (FfDiskOps->disk_read(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Read the MBR */
buf[MBR_Table + (ipart - 1) * SZ_PTE + PTE_System] = sys; /* Set system ID */
if (disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it back to the MBR */
if (FfDiskOps->disk_write(pdrv, buf, 0, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it back to the MBR */
}
} else { /* Volume as a new single partition */
if (!(fsopt & FM_SFD)) { /* Create partition table if not in SFD */
@ -6317,7 +6318,7 @@ FRESULT f_mkfs (
}
}
if (disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
if (FfDiskOps->disk_ioctl(pdrv, CTRL_SYNC, 0) != RES_OK) LEAVE_MKFS(FR_DISK_ERR);
LEAVE_MKFS(FR_OK);
}
@ -6340,7 +6341,7 @@ FRESULT f_fdisk (
DSTATUS stat;
stat = disk_initialize(pdrv);
stat = FfDiskOps->disk_initialize(pdrv);
if (stat & STA_NOINIT) return FR_NOT_READY;
if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
#if FF_USE_LFN == 3

View File

@ -101,21 +101,31 @@ void sata_write(uint32_t sector, uint32_t count, uint8_t* buf)
static DSTATUS satastatus = STA_NOINIT;
DSTATUS disk_status(BYTE drv) {
static DSTATUS sata_disk_status(BYTE drv) {
if (drv) return STA_NOINIT;
return satastatus;
}
DSTATUS disk_initialize(BYTE drv) {
static DSTATUS sata_disk_initialize(BYTE drv) {
if (drv) return STA_NOINIT;
if (satastatus)
satastatus = sata_init() ? 0 : STA_NOINIT;
return satastatus;
}
DRESULT disk_read(BYTE drv, BYTE *buf, LBA_t sector, UINT count) {
static DRESULT sata_disk_read(BYTE drv, BYTE *buf, LBA_t sector, UINT count) {
sata_read(sector, count, buf);
return RES_OK;
}
static DISKOPS SataDiskOps = {
.disk_initialize = sata_disk_initialize,
.disk_status = sata_disk_status,
.disk_read = sata_disk_read,
};
void fatfs_set_ops_sata(void) {
FfDiskOps = &SataDiskOps;
}
#endif /* CSR_SATA_SECTOR2MEM_BASE */

View File

@ -13,6 +13,7 @@
#ifdef CSR_SATA_PHY_BASE
int sata_init(void);
void fatfs_set_ops_sata(void);
#endif

View File

@ -565,21 +565,31 @@ void sdcard_write(uint32_t block, uint32_t count, uint8_t* buf)
static DSTATUS sdcardstatus = STA_NOINIT;
DSTATUS disk_status(BYTE drv) {
static DSTATUS sd_disk_status(BYTE drv) {
if (drv) return STA_NOINIT;
return sdcardstatus;
}
DSTATUS disk_initialize(BYTE drv) {
static DSTATUS sd_disk_initialize(BYTE drv) {
if (drv) return STA_NOINIT;
if (sdcardstatus)
sdcardstatus = sdcard_init() ? 0 : STA_NOINIT;
return sdcardstatus;
}
DRESULT disk_read(BYTE drv, BYTE *buf, LBA_t block, UINT count) {
static DRESULT sd_disk_read(BYTE drv, BYTE *buf, LBA_t block, UINT count) {
sdcard_read(block, count, buf);
return RES_OK;
}
static DISKOPS SdCardDiskOps = {
.disk_initialize = sd_disk_initialize,
.disk_status = sd_disk_status,
.disk_read = sd_disk_read,
};
void fatfs_set_ops_sdcard(void) {
FfDiskOps = &SdCardDiskOps;
}
#endif /* CSR_SDCORE_BASE */

View File

@ -103,6 +103,7 @@ void sdcard_decode_csd(void);
int sdcard_init(void);
void sdcard_read(uint32_t sector, uint32_t count, uint8_t* buf);
void sdcard_write(uint32_t sector, uint32_t count, uint8_t* buf);
void fatfs_set_ops_sdcard(void);
#endif /* CSR_SDCORE_BASE */

View File

@ -264,12 +264,12 @@ uint8_t spisdcard_init(void) {
static DSTATUS spisdcardstatus = STA_NOINIT;
DSTATUS disk_status(BYTE drv) {
static DSTATUS spisd_disk_status(BYTE drv) {
if (drv) return STA_NOINIT;
return spisdcardstatus;
}
DSTATUS disk_initialize(BYTE drv) {
static DSTATUS spisd_disk_initialize(BYTE drv) {
if (drv) return STA_NOINIT;
if (spisdcardstatus) {
spisdcardstatus = spisdcard_init() ? 0 : STA_NOINIT;
@ -278,7 +278,7 @@ DSTATUS disk_initialize(BYTE drv) {
return spisdcardstatus;
}
DRESULT disk_read(BYTE drv, BYTE *buf, LBA_t block, UINT count) {
static DRESULT spisd_disk_read(BYTE drv, BYTE *buf, LBA_t block, UINT count) {
uint8_t cmd;
if (count > 1)
cmd = CMD18; /* READ_MULTIPLE_BLOCK */
@ -302,4 +302,14 @@ DRESULT disk_read(BYTE drv, BYTE *buf, LBA_t block, UINT count) {
return RES_OK;
}
static DISKOPS SpiSdDiskOps = {
.disk_initialize = spisd_disk_initialize,
.disk_status = spisd_disk_status,
.disk_read = spisd_disk_read,
};
void fatfs_set_ops_spisdcard(void) {
FfDiskOps = &SpiSdDiskOps;
}
#endif

View File

@ -50,6 +50,7 @@
/*-----------------------------------------------------------------------*/
uint8_t spisdcard_init(void);
void fatfs_set_ops_spisdcard(void);
#endif /* CSR_SPISDCARD_BASE */