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