00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00098 #include <fs/fs.h>
00099
00100 #include <dirent.h>
00101
00102 #include <dev/blockdev.h>
00103
00104 #include <sys/event.h>
00105
00106 #include <fs/phatfs.h>
00107 #include <fs/phatvol.h>
00108 #include <fs/phatio.h>
00109 #include <fs/phatutil.h>
00110 #include <fs/phatdir.h>
00111
00112 #include <stdlib.h>
00113 #include <errno.h>
00114 #include <string.h>
00115 #include <fcntl.h>
00116
00117 #if 0
00118
00119 #define NUTDEBUG
00120 #include <stdio.h>
00121 #include <fs/phatdbg.h>
00122 #endif
00123
00124 #ifndef SEEK_SET
00125 # define SEEK_SET 0
00126 # define SEEK_CUR 1
00127 # define SEEK_END 2
00128 #endif
00129
00134
00145 static u_long SearchFreeCluster(NUTDEVICE * dev, u_long first, u_long last)
00146 {
00147 int rc = -1;
00148 u_long clust;
00149 u_long link = 1;
00150 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00151
00152 if (vol->vol_type == 32) {
00153 for (clust = first; clust < last; clust++) {
00154 if ((rc = Phat32GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00155 break;
00156 }
00157 }
00158 } else if (vol->vol_type == 16) {
00159 for (clust = first; clust < last; clust++) {
00160 if ((rc = Phat16GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00161 break;
00162 }
00163 }
00164 } else {
00165 for (clust = first; clust < last; clust++) {
00166 if ((rc = Phat12GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00167 break;
00168 }
00169 }
00170 }
00171
00172 if (rc || link) {
00173 return 0;
00174 }
00175 return clust;
00176 }
00177
00186 static u_long AllocCluster(NUTDEVICE * dev)
00187 {
00188 u_long clust;
00189 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00190
00191
00192
00193
00194 if (vol->vol_nxtfree < 2 || vol->vol_nxtfree >= vol->vol_last_clust) {
00195 vol->vol_nxtfree = 2;
00196 }
00197 if ((clust = SearchFreeCluster(dev, vol->vol_nxtfree, vol->vol_last_clust)) < 2) {
00198 if ((clust = SearchFreeCluster(dev, 2, vol->vol_nxtfree)) < 2) {
00199 vol->vol_nxtfree = 0;
00200 errno = ENOSPC;
00201 return 0;
00202 }
00203 }
00204 vol->vol_nxtfree = clust;
00205
00206 return clust;
00207 }
00208
00217 u_long AllocFirstCluster(NUTFILE * nfp)
00218 {
00219 u_long clust;
00220 NUTDEVICE *dev = nfp->nf_dev;
00221 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00222 PHATFILE *fcb = nfp->nf_fcb;
00223
00224 if ((clust = AllocCluster(dev)) < 2) {
00225 return 0;
00226 }
00227
00228
00229 fcb->f_dirent.dent_clusthi = (u_short) (clust >> 16);
00230 fcb->f_dirent.dent_clust = (u_short) clust;
00231 fcb->f_de_dirty = 1;
00232
00233
00234 if (vol->vol_type == 32) {
00235 if (Phat32SetClusterLink(dev, clust, PHAT32CMASK)) {
00236 return 0;
00237 }
00238 } else if (vol->vol_type == 16) {
00239 if (Phat16SetClusterLink(dev, clust, PHAT16CMASK)) {
00240 return 0;
00241 }
00242 } else if (Phat12SetClusterLink(dev, clust, PHAT12CMASK)) {
00243 return 0;
00244 }
00245 vol->vol_numfree--;
00246
00247 return clust;
00248 }
00249
00258 static u_long AllocNextCluster(NUTFILE * nfp)
00259 {
00260 u_long clust;
00261 NUTDEVICE *dev = nfp->nf_dev;
00262 PHATFILE *fcb = nfp->nf_fcb;
00263 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00264
00265
00266 if ((clust = AllocCluster(dev)) < 2) {
00267 return 0;
00268 }
00269
00270
00271
00272
00273 if (vol->vol_type == 32) {
00274 if (Phat32SetClusterLink(dev, fcb->f_clust, clust)) {
00275 return 0;
00276 }
00277 if (Phat32SetClusterLink(dev, clust, PHAT32CMASK)) {
00278 return 0;
00279 }
00280 } else if (vol->vol_type == 16) {
00281 if (Phat16SetClusterLink(dev, fcb->f_clust, clust)) {
00282 return 0;
00283 }
00284 if (Phat16SetClusterLink(dev, clust, PHAT16CMASK)) {
00285 return 0;
00286 }
00287 } else if (Phat12SetClusterLink(dev, fcb->f_clust, clust)) {
00288 return 0;
00289 } else if (Phat12SetClusterLink(dev, clust, PHAT12CMASK)) {
00290 return 0;
00291 }
00292 vol->vol_numfree--;
00293
00294 return clust;
00295 }
00296
00304 static int PhatFileFlush(NUTFILE * nfp)
00305 {
00306 int rc;
00307 NUTDEVICE *dev = nfp->nf_dev;
00308 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00309
00310
00311 if ((rc = PhatDirEntryUpdate(nfp)) == 0) {
00312
00313 NutEventWait(&vol->vol_iomutex, 0);
00314
00315 rc = PhatSectorFlush(nfp->nf_dev, -1);
00316
00317 NutEventPost(&vol->vol_iomutex);
00318 }
00319 return rc;
00320 }
00321
00329 int PhatFileClose(NUTFILE * nfp)
00330 {
00331 int rc;
00332
00333 if (nfp == NULL || nfp == NUTFILE_EOF) {
00334 errno = EBADF;
00335 return -1;
00336 }
00337 #ifdef NUTDEBUG
00338 PhatDbgFileInfo(stdout, "Close file", (PHATFILE *) nfp->nf_fcb);
00339 #endif
00340 rc = PhatFileFlush(nfp);
00341 if (nfp->nf_fcb) {
00342 free(nfp->nf_fcb);
00343 }
00344 free(nfp);
00345
00346 return rc;
00347 }
00348
00365 NUTFILE *PhatFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc)
00366 {
00367 NUTFILE *nfp = NUTFILE_EOF;
00368 NUTFILE *ndp = NUTFILE_EOF;
00369 PHATFILE *ffcb;
00370 PHATFILE *dfcb;
00371 PHATFIND *srch;
00372 CONST char *fname;
00373
00374
00375 if ((ndp = PhatDirOpenParent(dev, path, &fname)) == NUTFILE_EOF) {
00376 return NUTFILE_EOF;
00377 }
00378
00379
00380
00381
00382
00383
00384 dfcb = ndp->nf_fcb;
00385 if (*fname == 0) {
00386 dfcb->f_mode = mode;
00387 return ndp;
00388 }
00389
00390
00391
00392
00393 nfp = malloc(sizeof(NUTFILE));
00394 ffcb = malloc(sizeof(PHATFILE));
00395 srch = malloc(sizeof(PHATFIND));
00396 if (nfp == NULL || ffcb == NULL || srch == NULL) {
00397 PhatFileClose(ndp);
00398 if (nfp) {
00399 free(nfp);
00400 }
00401 if (ffcb) {
00402 free(ffcb);
00403 }
00404 if (srch) {
00405 free(srch);
00406 }
00407 return NUTFILE_EOF;
00408 }
00409
00410 memset(ffcb, 0, sizeof(PHATFILE));
00411 nfp->nf_next = 0;
00412 nfp->nf_dev = dev;
00413 nfp->nf_fcb = ffcb;
00414
00415
00416
00417
00418
00419
00420
00421 if (PhatDirEntryFind(ndp, fname, PHAT_FATTR_FILEMASK, srch)) {
00422
00423
00424
00425
00426 if ((mode & _O_CREAT) == 0) {
00427 free(srch);
00428 PhatFileClose(ndp);
00429 PhatFileClose(nfp);
00430 errno = ENOENT;
00431 return NUTFILE_EOF;
00432 }
00433
00434 if (PhatDirEntryCreate(ndp, fname, acc, &ffcb->f_dirent)) {
00435 free(srch);
00436 PhatFileClose(ndp);
00437 PhatFileClose(nfp);
00438 return NUTFILE_EOF;
00439 }
00440 ffcb->f_de_dirty = 1;
00441 #ifdef NUTDEBUG
00442 PhatDbgFileInfo(stdout, "New entry", ffcb);
00443 #endif
00444 } else {
00445
00446
00447
00448
00449 if ((mode & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) {
00450 free(srch);
00451 PhatFileClose(ndp);
00452 PhatFileClose(nfp);
00453 errno = EEXIST;
00454 return NUTFILE_EOF;
00455 }
00456 #ifdef NUTDEBUG
00457 PhatDbgFileInfo(stdout, "Existing entry", ffcb);
00458 #endif
00459
00460
00461
00462 if (mode & _O_TRUNC) {
00463
00464
00465
00466 if (PhatDirReleaseChain(dev, &srch->phfind_ent)) {
00467 PhatFileClose(ndp);
00468 PhatFileClose(nfp);
00469 free(srch);
00470 return NUTFILE_EOF;
00471 }
00472 memset(ffcb, 0, sizeof(PHATFILE));
00473 memcpy(ffcb->f_dirent.dent_name, srch->phfind_ent.dent_name, sizeof(ffcb->f_dirent.dent_name));
00474 ffcb->f_dirent.dent_attr = srch->phfind_ent.dent_attr;
00475 ffcb->f_dirent.dent_rsvdnt = srch->phfind_ent.dent_rsvdnt;
00476 ffcb->f_dirent.dent_ctsecs = srch->phfind_ent.dent_ctsecs;
00477 ffcb->f_dirent.dent_ctime = srch->phfind_ent.dent_ctime;
00478 ffcb->f_dirent.dent_cdate = srch->phfind_ent.dent_cdate;
00479 ffcb->f_de_dirty = 1;
00480 }
00481 else {
00482 ffcb->f_dirent = srch->phfind_ent;
00483 }
00484 }
00485 free(srch);
00486
00487
00488 ffcb->f_de_sect = PhatClusterSector(ndp, dfcb->f_clust) + dfcb->f_clust_pos;
00489 ffcb->f_de_offs = dfcb->f_sect_pos - 32;
00490
00491 ffcb->f_pde_clusthi = dfcb->f_dirent.dent_clusthi;
00492 ffcb->f_pde_clust = dfcb->f_dirent.dent_clust;
00493
00494 ffcb->f_clust = ffcb->f_dirent.dent_clusthi;
00495 ffcb->f_clust <<= 16;
00496 ffcb->f_clust += ffcb->f_dirent.dent_clust;
00497
00498 ffcb->f_mode = mode;
00499
00500
00501 PhatFileClose(ndp);
00502
00503
00504
00505
00506 if ((mode & _O_APPEND) != 0 && ffcb->f_dirent.dent_fsize) {
00507 if (PhatFilePosSet(nfp, ffcb->f_dirent.dent_fsize)) {
00508 PhatFileClose(nfp);
00509 return NUTFILE_EOF;
00510 }
00511 }
00512
00513 #ifdef NUTDEBUG
00514 PhatDbgFileInfo(stdout, "File opened", ffcb);
00515 #endif
00516 return nfp;
00517 }
00518
00531 int PhatFileWrite(NUTFILE * nfp, CONST void *buffer, int len)
00532 {
00533 int rc;
00534 int step;
00535 u_long clust;
00536 int sbn;
00537 u_char *buf = (u_char *) buffer;
00538 NUTDEVICE *dev = nfp->nf_dev;
00539 PHATFILE *fcb = nfp->nf_fcb;
00540 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00541
00542
00543
00544
00545 if (fcb->f_dirent.dent_attr & PHAT_FATTR_RDONLY) {
00546 errno = EACCES;
00547 return -1;
00548 }
00549
00550
00551
00552
00553 if (buf == NULL || len == 0) {
00554 return PhatFileFlush(nfp);
00555 }
00556
00557
00558
00559
00560 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00561
00562 u_long num = vol->vol_sectsz * vol->vol_clustsz;
00563
00564 u_long cur = (fcb->f_dirent.dent_fsize + num - 1) / num;
00565
00566
00567 num = (fcb->f_pos + len + num - 1) / num;
00568
00569 if (num > cur && num - cur > vol->vol_numfree) {
00570 errno = ENOSPC;
00571 return -1;
00572 }
00573
00574
00575 if (fcb->f_dirent.dent_fsize == 0) {
00576 if ((clust = AllocFirstCluster(nfp)) < 2) {
00577 return -1;
00578 }
00579 fcb->f_clust_prv = clust;
00580 fcb->f_clust = clust;
00581 }
00582 }
00583
00584
00585
00586
00587
00588 for (rc = 0, step = 0; rc < len; rc += step) {
00589
00590 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00591
00592 if (IsFixedRootDir(nfp)) {
00593 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00594
00595 break;
00596 }
00597 fcb->f_clust_pos++;
00598 }
00599 else {
00600
00601 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00602
00603 if (vol->vol_type == 32) {
00604 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00605 rc = -1;
00606 break;
00607 }
00608 if (clust >= (PHATEOC & PHAT32CMASK)) {
00609 if ((clust = AllocNextCluster(nfp)) < 2) {
00610 rc = -1;
00611 break;
00612 }
00613 }
00614 } else if (vol->vol_type == 16) {
00615 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00616 rc = -1;
00617 break;
00618 }
00619 if (clust >= (PHATEOC & PHAT16CMASK)) {
00620 if ((clust = AllocNextCluster(nfp)) < 2) {
00621 rc = -1;
00622 break;
00623 }
00624 }
00625 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00626 rc = -1;
00627 break;
00628 } else if (clust >= (PHATEOC & PHAT12CMASK)) {
00629 if ((clust = AllocNextCluster(nfp)) < 2) {
00630 rc = -1;
00631 break;
00632 }
00633 }
00634 fcb->f_clust_pos = 0;
00635 fcb->f_clust_prv = fcb->f_clust;
00636 fcb->f_clust = clust;
00637 }
00638 else {
00639 fcb->f_clust_pos++;
00640 }
00641 }
00642 fcb->f_sect_pos = 0;
00643 }
00644
00645
00646 if ((sbn = PhatSectorLoad(nfp->nf_dev, PhatClusterSector(nfp, fcb->f_clust) + fcb->f_clust_pos)) < 0) {
00647 rc = -1;
00648 break;
00649 }
00650
00651 step = (int) (vol->vol_sectsz - fcb->f_sect_pos);
00652 if (step > len - rc) {
00653 step = len - rc;
00654 }
00655
00656 memcpy(&vol->vol_buf[sbn].sect_data[fcb->f_sect_pos], &buf[rc], step);
00657 vol->vol_buf[sbn].sect_dirty = 1;
00658
00659 fcb->f_pos += step;
00660 fcb->f_sect_pos += step;
00661 }
00662
00663 if (rc > 0) {
00664
00665
00666
00667
00668 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00669 GetDosTimeStamp(&fcb->f_dirent.dent_mtime, &fcb->f_dirent.dent_mdate);
00670 fcb->f_dirent.dent_adate = fcb->f_dirent.dent_mdate;
00671 fcb->f_dirent.dent_attr |= PHAT_FATTR_ARCHIV;
00672 if(fcb->f_dirent.dent_fsize < fcb->f_pos) {
00673 fcb->f_dirent.dent_fsize = fcb->f_pos;
00674 }
00675 fcb->f_de_dirty = 1;
00676 }
00677 }
00678 return rc;
00679 }
00680
00681 #ifdef __HARVARD_ARCH__
00682
00699 int PhatFileWrite_P(NUTFILE * nfp, PGM_P buffer, int len)
00700 {
00701 return -1;
00702 }
00703 #endif
00704
00716 int PhatFileRead(NUTFILE * nfp, void *buffer, int size)
00717 {
00718 int rc;
00719 int step;
00720 int sbn;
00721 u_char *buf = (u_char *) buffer;
00722 NUTDEVICE *dev = nfp->nf_dev;
00723 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00724 PHATFILE *fcb = nfp->nf_fcb;
00725
00726
00727
00728
00729 if (buf == NULL || size == 0) {
00730 return 0;
00731 }
00732
00733
00734 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00735 if (fcb->f_pos + size >= fcb->f_dirent.dent_fsize) {
00736 size = fcb->f_dirent.dent_fsize - fcb->f_pos;
00737 }
00738 }
00739 for (rc = 0, step = 0; rc < size; rc += step) {
00740
00741 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00742
00743 if (IsFixedRootDir(nfp)) {
00744 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00745
00746 break;
00747 }
00748 fcb->f_clust_pos++;
00749 }
00750 else {
00751
00752 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00753
00754 u_long clust;
00755
00756 if (vol->vol_type == 32) {
00757 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00758 break;
00759 }
00760 if (clust >= (PHATEOC & PHAT32CMASK)) {
00761 break;
00762 }
00763 } else if (vol->vol_type == 16) {
00764 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00765 break;
00766 }
00767 if (clust >= (PHATEOC & PHAT16CMASK)) {
00768 break;
00769 }
00770 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00771 break;
00772 }
00773 else if (clust >= (PHATEOC & PHAT12CMASK)) {
00774 break;
00775 }
00776 fcb->f_clust_pos = 0;
00777 fcb->f_clust_prv = fcb->f_clust;
00778 fcb->f_clust = clust;
00779 }
00780 else {
00781 fcb->f_clust_pos++;
00782 }
00783 }
00784 fcb->f_sect_pos = 0;
00785 }
00786
00787
00788 if ((sbn = PhatSectorLoad(nfp->nf_dev, PhatClusterSector(nfp, fcb->f_clust) + fcb->f_clust_pos)) < 0) {
00789 rc = -1;
00790 break;
00791 }
00792 step = (int) (vol->vol_sectsz - fcb->f_sect_pos);
00793 if (step > size - rc) {
00794 step = size - rc;
00795 }
00796 memcpy(&buf[rc], &vol->vol_buf[sbn].sect_data[fcb->f_sect_pos], step);
00797 fcb->f_pos += step;
00798 fcb->f_sect_pos += step;
00799 }
00800 return rc;
00801 }
00802
00814 static long PhatFileSize(NUTFILE *nfp)
00815 {
00816 PHATFILE *fcb = nfp->nf_fcb;
00817
00818 return fcb->f_dirent.dent_fsize;
00819 }
00820
00821 static int PhatFileSeek(NUTFILE * nfp, long *pos, int whence)
00822 {
00823 int rc = 0;
00824 long npos = *pos;
00825 PHATFILE *fcb = nfp->nf_fcb;
00826
00827 switch (whence) {
00828 case SEEK_CUR:
00829 npos += fcb->f_pos;
00830 break;
00831 case SEEK_END:
00832 npos += PhatFileSize(nfp);
00833 break;
00834 }
00835
00836 if (npos < 0 || npos > PhatFileSize(nfp)) {
00837 rc = EINVAL;
00838 } else {
00839 rc = PhatFilePosSet(nfp, npos);
00840 *pos = fcb->f_pos;
00841 }
00842 return rc;
00843 }
00844
00849 static int PhatIOCtl(NUTDEVICE * dev, int req, void *conf)
00850 {
00851 int rc = -1;
00852
00853 switch (req) {
00854 case FS_STATUS:
00855 {
00856 FSCP_STATUS *par = (FSCP_STATUS *) conf;
00857
00858 rc = PhatDirEntryStatus(dev, par->par_path, par->par_stp);
00859 }
00860 break;
00861 case FS_DIR_CREATE:
00862 rc = PhatDirCreate(dev, (char *) conf);
00863 break;
00864 case FS_DIR_REMOVE:
00865 rc = PhatDirRemove(dev, (char *) conf);
00866 break;
00867 case FS_DIR_OPEN:
00868
00869 {
00870 DIR *dir = (DIR *) conf;
00871
00872 if ((dir->dd_fd = PhatDirOpen(dev, dir->dd_buf)) != NUTFILE_EOF) {
00873 rc = 0;
00874 }
00875 }
00876 break;
00877 case FS_DIR_CLOSE:
00878 rc = PhatFileClose(((DIR *) conf)->dd_fd);
00879 break;
00880 case FS_DIR_READ:
00881 rc = PhatDirRead((DIR *) conf);
00882 break;
00883 case FS_FILE_STATUS:
00884
00885 break;
00886 case FS_FILE_DELETE:
00887 rc = PhatDirDelEntry(dev, (char *) conf, PHAT_FATTR_FILEMASK & ~PHAT_FATTR_DIR);
00888 break;
00889 case FS_FILE_SEEK:
00890 PhatFileSeek((NUTFILE *) ((IOCTL_ARG3 *) conf)->arg1,
00891 (long *) ((IOCTL_ARG3 *) conf)->arg2,
00892 (int) ((IOCTL_ARG3 *) conf)->arg3);
00893 break;
00894 case FS_RENAME:
00895
00896 {
00897 FSCP_RENAME *par = (FSCP_RENAME *) conf;
00898
00899 rc = PhatDirRenameEntry(dev, par->par_old, par->par_new);
00900 }
00901 break;
00902
00903 case FS_VOL_MOUNT:
00904 {
00905
00906 FSCP_VOL_MOUNT *par = (FSCP_VOL_MOUNT *) conf;
00907
00908 rc = PhatVolMount(dev, par->fscp_bmnt, par->fscp_part_type);
00909 if (rc) {
00910
00911 PhatVolUnmount(dev);
00912 }
00913 }
00914 break;
00915 case FS_VOL_UNMOUNT:
00916
00917 rc = PhatVolUnmount(dev);
00918 break;
00919 }
00920 return rc;
00921 }
00922
00932 static int PhatInit(NUTDEVICE * dev)
00933 {
00934
00935 return 0;
00936 }
00937
00941 static NUTFILE *PhatApiFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc)
00942 {
00943 NUTFILE *rc;
00944 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00945
00946
00947 if (vol == NULL) {
00948 errno = ENOENT;
00949 return NUTFILE_EOF;
00950 }
00951
00952
00953 NutEventWait(&vol->vol_fsmutex, 0);
00954
00955 rc = PhatFileOpen(dev, path, mode, acc);
00956
00957 NutEventPost(&vol->vol_fsmutex);
00958
00959 return rc;
00960 }
00961
00965 static int PhatApiFileClose(NUTFILE * nfp)
00966 {
00967 int rc;
00968 NUTDEVICE *dev = nfp->nf_dev;
00969 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00970
00971
00972 NutEventWait(&vol->vol_fsmutex, 0);
00973
00974 rc = PhatFileClose(nfp);
00975
00976 NutEventPost(&vol->vol_fsmutex);
00977
00978 return rc;
00979 }
00980
00984 static int PhatApiFileWrite(NUTFILE * nfp, CONST void *buffer, int len)
00985 {
00986 int rc;
00987 NUTDEVICE *dev = nfp->nf_dev;
00988 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00989
00990
00991 NutEventWait(&vol->vol_fsmutex, 0);
00992
00993 rc = PhatFileWrite(nfp, buffer, len);
00994
00995 NutEventPost(&vol->vol_fsmutex);
00996
00997 return rc;
00998 }
00999
01000 #ifdef __HARVARD_ARCH__
01001
01004 static int PhatApiFileWrite_P(NUTFILE * nfp, PGM_P buffer, int len)
01005 {
01006 int rc;
01007 NUTDEVICE *dev = nfp->nf_dev;
01008 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
01009
01010
01011 NutEventWait(&vol->vol_fsmutex, 0);
01012
01013 rc = PhatFileWrite_P(nfp, buffer, len);
01014
01015 NutEventPost(&vol->vol_fsmutex);
01016
01017 return rc;
01018 }
01019 #endif
01020
01024 static int PhatApiFileRead(NUTFILE * nfp, void *buffer, int size)
01025 {
01026 int rc;
01027 NUTDEVICE *dev = nfp->nf_dev;
01028 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
01029
01030
01031 NutEventWait(&vol->vol_fsmutex, 0);
01032
01033 rc = PhatFileRead(nfp, buffer, size);
01034
01035 NutEventPost(&vol->vol_fsmutex);
01036
01037 return rc;
01038 }
01039
01043 static int PhatApiIOCtl(NUTDEVICE * dev, int req, void *conf)
01044 {
01045 int rc;
01046 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
01047
01048
01049 if (req != FS_VOL_MOUNT && vol) {
01050 NutEventWait(&vol->vol_fsmutex, 0);
01051 }
01052
01053 rc = PhatIOCtl(dev, req, conf);
01054
01055 if (req != FS_VOL_MOUNT && req != FS_VOL_UNMOUNT && vol) {
01056 NutEventPost(&vol->vol_fsmutex);
01057 }
01058 return rc;
01059 }
01060
01073 NUTDEVICE devPhat0 = {
01074 0,
01075 {'P', 'H', 'A', 'T', '0', 0, 0, 0, 0}
01076 ,
01077 IFTYP_FS,
01078 0,
01079 0,
01080 0,
01081 0,
01082 PhatInit,
01083 PhatApiIOCtl,
01084 PhatApiFileRead,
01085 PhatApiFileWrite,
01086 #ifdef __HARVARD_ARCH__
01087 PhatApiFileWrite_P,
01088 #endif
01089 PhatApiFileOpen,
01090 PhatApiFileClose,
01091 PhatFileSize
01092 };
01093
01094 NUTDEVICE devPhat1 = {
01095 0,
01096 {'P', 'H', 'A', 'T', '1', 0, 0, 0, 0}
01097 ,
01098 IFTYP_FS,
01099 0,
01100 0,
01101 0,
01102 0,
01103 PhatInit,
01104 PhatApiIOCtl,
01105 PhatApiFileRead,
01106 PhatApiFileWrite,
01107 #ifdef __HARVARD_ARCH__
01108 PhatApiFileWrite_P,
01109 #endif
01110 PhatApiFileOpen,
01111 PhatApiFileClose,
01112 PhatFileSize
01113 };
01114