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