31#ifdef BUILDING_USBHDFSD
36#include "usbhd_common.h"
37#include "fat_driver.h"
40#ifdef BUILDING_USBHDFSD
43#ifdef BUILDING_IEEE1394_DISK
49#include "mass_debug.h"
51#define FLUSH_SECTORS fat_flushSectors
54 FS_FILE_FLAG_FOLDER = 0,
74 unsigned int sfnSector;
87static fs_rec fsRec[MAX_FILES];
92 if (fatdir->attr & FAT_ATTR_DIRECTORY) {
97 if (!(fatdir->attr & FAT_ATTR_READONLY)) {
101 stat->size = fatdir->size;
104 stat->ctime[4] = fatdir->cdate[0];
105 stat->ctime[5] = fatdir->cdate[1];
106 stat->ctime[6] = fatdir->cdate[2];
107 stat->ctime[7] = fatdir->cdate[3];
110 stat->ctime[3] = fatdir->ctime[0];
111 stat->ctime[2] = fatdir->ctime[1];
112 stat->ctime[1] = fatdir->ctime[2];
115 stat->atime[4] = fatdir->adate[0];
116 stat->atime[5] = fatdir->adate[1];
117 stat->atime[6] = fatdir->adate[2];
118 stat->atime[7] = fatdir->adate[3];
121 stat->mtime[4] = fatdir->mdate[0];
122 stat->mtime[5] = fatdir->mdate[1];
123 stat->mtime[6] = fatdir->mdate[2];
124 stat->mtime[7] = fatdir->mdate[3];
127 stat->mtime[3] = fatdir->mtime[0];
128 stat->mtime[2] = fatdir->mtime[1];
129 stat->mtime[1] = fatdir->mtime[2];
137static fs_rec *fs_findFreeFileSlot(
void)
141 M_DEBUG(
"%s\n", __func__);
143 for (i = 0; i < MAX_FILES; i++) {
144 if (fsRec[i].dirent.file_flag < 0) {
152static fs_rec *fs_findFileSlotByCluster(
unsigned int startCluster)
156 M_DEBUG(
"%s\n", __func__);
158 for (i = 0; i < MAX_FILES; i++) {
159 if (fsRec[i].dirent.file_flag >= 0 && fsRec[i].dirent.fatdir.startCluster == startCluster) {
167static int _lock_sema_id = -1;
170static int _fs_init_lock(
void)
172 M_DEBUG(
"%s\n", __func__);
181 if ((_lock_sema_id = CreateSema(&sp)) < 0) {
190static void _fs_lock(
void)
192 M_DEBUG(
"%s\n", __func__);
195 WaitSema(_lock_sema_id);
200static void _fs_unlock(
void)
202 M_DEBUG(
"%s\n", __func__);
205 SignalSema(_lock_sema_id);
210static void fs_reset(
void)
214 M_DEBUG(
"%s\n", __func__);
216 for (i = 0; i < MAX_FILES; i++) {
217 fsRec[i].dirent.file_flag = -1;
220 if (_lock_sema_id >= 0) {
221 DeleteSema(_lock_sema_id);
228static int fs_inited = 0;
235 M_DEBUG(
"%s\n", __func__);
246static int fs_open(
iop_file_t *fd,
const char *name,
int flags,
int mode)
251 unsigned int cluster;
255 M_DEBUG(
"%s: %s flags=%X mode=%X\n", __func__, name, flags, mode);
259 XPRINTF(
"fs_open called: %s flags=%X mode=%X \n", name, flags, mode);
261 fatd = fat_getData(fd->unit);
268 rec = fs_findFreeFileSlot();
276 XPRINTF(
"Calling fat_getFileStartCluster from fs_open\n");
277 ret = fat_getFileStartCluster(fatd, name, &cluster, &rec->dirent.fatdir);
278 if (ret < 0 && ret != -
ENOENT) {
285 rec2 = fs_findFileSlotByCluster(rec->dirent.fatdir.startCluster);
287 if ((flags & O_WRONLY) ||
288 (rec2->mode & O_WRONLY)) {
295 if (flags & O_WRONLY) {
301 if (flags & O_CREAT) {
302 XPRINTF(
"FAT I: O_CREAT detected!\n");
308 ret = fat_createFile(fatd, name, 0, escapeNotExist, &cluster, &rec->sfnSector, &rec->sfnOffset);
315 if (ret ==
EEXIST && (flags & O_TRUNC)) {
316 XPRINTF(
"FAT I: O_TRUNC detected!\n");
317 ret = fat_truncateFile(fatd, cluster, rec->sfnSector, rec->sfnOffset);
320 XPRINTF(
"FAT E: failed to truncate!\n");
328 XPRINTF(
"Calling fat_getFileStartCluster from fs_open after file creation\n");
329 ret = fat_getFileStartCluster(fatd, name, &cluster, &rec->dirent.fatdir);
337 if ((rec->dirent.fatdir.attr & FAT_ATTR_DIRECTORY) == FAT_ATTR_DIRECTORY) {
343 rec->dirent.file_flag = FS_FILE_FLAG_FILE;
348 if ((flags & O_APPEND) && (flags & O_WRONLY)) {
349 XPRINTF(
"FAT I: O_APPEND detected!\n");
350 rec->filePos = rec->dirent.fatdir.size;
366 M_DEBUG(
"%s\n", __func__);
373 if (rec->dirent.file_flag != FS_FILE_FLAG_FILE) {
378 rec->dirent.file_flag = -1;
381 fatd = fat_getData(fd->unit);
387 if ((rec->mode & O_WRONLY)) {
389 if (rec->sizeChange) {
390 fat_updateSfn(fatd, rec->dirent.fatdir.size, rec->sfnSector, rec->sfnOffset);
401static int fs_lseek(
iop_file_t *fd,
int offset,
int whence)
406 M_DEBUG(
"%s\n", __func__);
413 fatd = fat_getData(fd->unit);
419 if (rec->dirent.file_flag != FS_FILE_FLAG_FILE) {
426 rec->filePos = offset;
429 rec->filePos += offset;
432 rec->filePos = rec->dirent.fatdir.size + offset;
438 if ((
int)(rec->filePos) < 0) {
441 if (rec->filePos > rec->dirent.fatdir.size) {
442 rec->filePos = rec->dirent.fatdir.size;
450static int fs_write(
iop_file_t *fd,
void *buffer,
int size)
455 int updateClusterIndices = 0;
457 M_DEBUG(
"%s\n", __func__);
464 fatd = fat_getData(fd->unit);
470 if (rec->dirent.file_flag != FS_FILE_FLAG_FILE) {
475 if (!(rec->mode & O_WRONLY)) {
485 result = fat_writeFile(fatd, &rec->dirent.fatdir, &updateClusterIndices, rec->filePos, (
unsigned char *)buffer, size);
487 rec->filePos += result;
488 if (rec->filePos > rec->dirent.fatdir.size) {
489 rec->dirent.fatdir.size = rec->filePos;
492 if (updateClusterIndices) {
493 fat_setFatDirChain(fatd, &rec->dirent.fatdir);
503static int fs_read(
iop_file_t *fd,
void *buffer,
int size)
509 M_DEBUG(
"%s\n", __func__);
516 fatd = fat_getData(fd->unit);
522 if (rec->dirent.file_flag != FS_FILE_FLAG_FILE) {
527 if (!(rec->mode & O_RDONLY)) {
537 if ((rec->filePos + size) > rec->dirent.fatdir.size) {
538 size = rec->dirent.fatdir.size - rec->filePos;
541 result = fat_readFile(fatd, &rec->dirent.fatdir, rec->filePos, (
unsigned char *)buffer, size);
543 rec->filePos += result;
551static int fs_remove(
iop_file_t *fd,
const char *name)
556 unsigned int cluster;
559 M_DEBUG(
"%s\n", __func__);
563 fatd = fat_getData(fd->unit);
571 XPRINTF(
"Calling fat_getFileStartCluster from fs_remove\n");
572 result = fat_getFileStartCluster(fatd, name, &cluster, &fatdir);
578 rec = fs_findFileSlotByCluster(fatdir.startCluster);
587 result = fat_deleteFile(fatd, name, 0);
595static int fs_mkdir(
iop_file_t *fd,
const char *name,
int mode)
600 unsigned int sfnSector;
601 unsigned int cluster;
603 M_DEBUG(
"%s\n", __func__);
609 fatd = fat_getData(fd->unit);
615 XPRINTF(
"fs_mkdir: name=%s \n", name);
616 ret = fat_createFile(fatd, name, 1, 0, &cluster, &sfnSector, &sfnOffset);
629static int fs_rmdir(
iop_file_t *fd,
const char *name)
634 M_DEBUG(
"%s\n", __func__);
638 fatd = fat_getData(fd->unit);
644 ret = fat_deleteFile(fatd, name, 1);
651static int fs_dopen(
iop_file_t *fd,
const char *name)
657 M_DEBUG(
"%s: unit %d name %s\n", __func__, fd->unit, name);
661 XPRINTF(
"fs_dopen called: unit %d name %s\n", fd->unit, name);
663 fatd = fat_getData(fd->unit);
669 if (((name[0] ==
'/') && (name[1] ==
'\0')) || ((name[0] ==
'/') && (name[1] ==
'.') && (name[2] ==
'\0'))) {
674 fd->privdata = malloc(
sizeof(
fs_dir));
675 memset(fd->privdata, 0,
sizeof(
fs_dir));
676 rec = (
fs_dir *)fd->privdata;
678 rec->status = fat_getFirstDirentry(fatd, name, &rec->fatdlist, &rec->dirent.fatdir, &rec->current_fatdir);
681 if (rec->status == 0 && !is_root)
696 M_DEBUG(
"%s\n", __func__);
698 if (fd->privdata == NULL)
702 XPRINTF(
"fs_dclose called: unit %d\n", fd->unit);
703 if (rec->dirent.file_flag != FS_FILE_FLAG_FOLDER) {
721 M_DEBUG(
"%s\n", __func__);
728 XPRINTF(
"fs_dread called: unit %d\n", fd->unit);
730 fatd = fat_getData(fd->unit);
736 if (rec->dirent.file_flag != FS_FILE_FLAG_FOLDER) {
741 while (rec->status > 0 && (rec->current_fatdir.attr & FAT_ATTR_VOLUME_LABEL || ((rec->current_fatdir.attr & (FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM)) == (FAT_ATTR_HIDDEN | FAT_ATTR_SYSTEM))))
742 rec->status = fat_getNextDirentry(fatd, &rec->fatdlist, &rec->current_fatdir);
745 if (rec->status >= 0) {
747 fillStat(&buffer->stat, &rec->current_fatdir);
748 strcpy(buffer->name, (
const char *)rec->current_fatdir.name);
752 rec->status = fat_getNextDirentry(fatd, &rec->fatdlist, &rec->current_fatdir);
763 unsigned int cluster = 0;
766 M_DEBUG(
"%s: unit %d name %s\n", __func__, fd->unit, name);
770 XPRINTF(
"fs_getstat called: unit %d name %s\n", fd->unit, name);
772 fatd = fat_getData(fd->unit);
778 XPRINTF(
"Calling fat_getFileStartCluster from fs_getstat\n");
779 ret = fat_getFileStartCluster(fatd, name, &cluster, &fatdir);
786 fillStat(stat, &fatdir);
793int fs_ioctl(
iop_file_t *fd,
int cmd,
void *data)
799 M_DEBUG(
"%s\n", __func__);
806 fatd = fat_getData(fd->unit);
814 ret = fat_renameFile(fatd, &dirent->fatdir, data);
817#ifdef BUILDING_USBHDFSD
819 ret = ((
fs_rec *)fd->privdata)->dirent.fatdir.startCluster;
822 ret = fat_cluster2sector(&fatd->partBpb, ((
fs_rec *)fd->privdata)->dirent.fatdir.startCluster);
825 ret = fat_CheckChain(fatd, ((
fs_rec *)fd->privdata)->dirent.fatdir.startCluster);
828#if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
830 ret = *(
int *)fatd->bd->name;
841int fs_rename(
iop_file_t *fd,
const char *path,
const char *newpath)
846 unsigned int cluster;
855 fatd = fat_getData(fd->unit);
863 XPRINTF(
"Calling fat_getFileStartCluster from fs_rename\n");
864 ret = fat_getFileStartCluster(fatd, path, &cluster, &fatdir);
865 if (ret < 0 && ret != -
ENOENT) {
870 rec = fs_findFileSlotByCluster(fatdir.startCluster);
877 ret = fat_renameFile(fatd, &fatdir, newpath);
884#ifndef BUILDING_IEEE1394_DISK
885static int fs_devctl(
iop_file_t *fd,
const char *name,
int cmd,
void *arg,
unsigned int arglen,
void *buf,
unsigned int buflen)
887#ifdef BUILDING_USBHDFSD
902#ifdef BUILDING_USBHDFSD
903 fatd = fat_getData(fd->unit);
904 ret = (fatd != NULL) ? mass_stor_stop_unit(fatd->dev) : -
ENODEV;
906 ret = fat_stopUnit(fd->unit);
910#ifdef BUILDING_USBHDFSD
911 mass_store_stop_all();
927#if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
928static int fs_ioctl2(
iop_file_t *fd,
int cmd,
void *data,
unsigned int datalen,
void *rdata,
unsigned int rdatalen)
938 M_DEBUG(
"%s\n", __func__);
945 fatd = fat_getData(fd->unit);
955 if (rdata == NULL || rdatalen <
sizeof(u64))
964 *(u64*)rdata = (u64)fat_cluster2sector(&fatd->partBpb, ((
fs_rec *)fd->privdata)->dirent.fatdir.startCluster) + bd->sectorOffset;
971 if (rdata == NULL || rdatalen <
sizeof(u32))
982 *(u32*)rdata = bd->devNr;
998IOMANX_RETURN_VALUE_IMPL(0);
999IOMANX_RETURN_VALUE_IMPL(
EIO);
1003 IOMANX_RETURN_VALUE(0),
1004 IOMANX_RETURN_VALUE(
EIO),
1018 IOMANX_RETURN_VALUE(
EIO),
1020 IOMANX_RETURN_VALUE(
EIO),
1021 IOMANX_RETURN_VALUE(
EIO),
1022 IOMANX_RETURN_VALUE(
EIO),
1023 IOMANX_RETURN_VALUE(
EIO),
1024 IOMANX_RETURN_VALUE_S64(
EIO),
1025#ifndef BUILDING_IEEE1394_DISK
1028 IOMANX_RETURN_VALUE(
EIO),
1030 IOMANX_RETURN_VALUE(
EIO),
1031 IOMANX_RETURN_VALUE(
EIO),
1032#if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1035 IOMANX_RETURN_VALUE(
EIO),
1039#ifdef BUILDING_IEEE1394_DISK
1046#ifdef BUILDING_USBHDFSD
1047 "USB mass storage driver",
1049#ifdef BUILDING_IEEE1394_DISK
1052#if !defined(BUILDING_IEEE1394_DISK) && !defined(BUILDING_USBHDFSD)
1061 M_DEBUG(
"%s\n", __func__);
1063 DelDrv(fs_driver.name);
1064 return (AddDrv(&fs_driver) == 0 ? 0 : -1);
#define USBMASS_IOCTL_GET_CLUSTER
#define USBMASS_IOCTL_GET_DRIVERNAME
#define USBMASS_DEVCTL_STOP_ALL
#define USBMASS_DEVCTL_STOP_UNIT
#define USBMASS_IOCTL_RENAME
#define USBMASS_IOCTL_GET_DEVICE_NUMBER
#define USBMASS_IOCTL_GET_LBA
#define USBMASS_IOCTL_CHECK_CHAIN