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
00091 #include <fs/fs.h>
00092
00093 #include <dirent.h>
00094
00095 #include <dev/blockdev.h>
00096
00097 #include <sys/event.h>
00098
00099 #include <fs/phatfs.h>
00100 #include <fs/phatvol.h>
00101 #include <fs/phatio.h>
00102 #include <fs/phatutil.h>
00103 #include <fs/phatdir.h>
00104
00105 #include <stdlib.h>
00106 #include <errno.h>
00107 #include <string.h>
00108 #include <fcntl.h>
00109
00110 #if 0
00111
00112 #define NUTDEBUG
00113 #include <stdio.h>
00114 #include <fs/phatdbg.h>
00115 #endif
00116
00117 #ifndef SEEK_SET
00118 # define SEEK_SET 0
00119 # define SEEK_CUR 1
00120 # define SEEK_END 2
00121 #endif
00122
00127
00138 static u_long SearchFreeCluster(NUTDEVICE * dev, u_long first, u_long last)
00139 {
00140 int rc = -1;
00141 u_long clust;
00142 u_long link = 1;
00143 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00144
00145 if (vol->vol_type == 32) {
00146 for (clust = first; clust < last; clust++) {
00147 if ((rc = Phat32GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00148 break;
00149 }
00150 }
00151 } else if (vol->vol_type == 16) {
00152 for (clust = first; clust < last; clust++) {
00153 if ((rc = Phat16GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00154 break;
00155 }
00156 }
00157 } else {
00158 for (clust = first; clust < last; clust++) {
00159 if ((rc = Phat12GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00160 break;
00161 }
00162 }
00163 }
00164
00165 if (rc || link) {
00166 return 0;
00167 }
00168 return clust;
00169 }
00170
00179 static u_long AllocCluster(NUTDEVICE * dev)
00180 {
00181 u_long clust;
00182 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00183
00184
00185
00186
00187 if (vol->vol_nxtfree < 2 || vol->vol_nxtfree >= vol->vol_last_clust) {
00188 vol->vol_nxtfree = 2;
00189 }
00190 if ((clust = SearchFreeCluster(dev, vol->vol_nxtfree, vol->vol_last_clust)) < 2) {
00191 if ((clust = SearchFreeCluster(dev, 2, vol->vol_nxtfree)) < 2) {
00192 vol->vol_nxtfree = 0;
00193 errno = ENOSPC;
00194 return 0;
00195 }
00196 }
00197 vol->vol_nxtfree = clust;
00198
00199 return clust;
00200 }
00201
00210 u_long AllocFirstCluster(NUTFILE * nfp)
00211 {
00212 u_long clust;
00213 NUTDEVICE *dev = nfp->nf_dev;
00214 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00215 PHATFILE *fcb = nfp->nf_fcb;
00216
00217 if ((clust = AllocCluster(dev)) < 2) {
00218 return 0;
00219 }
00220
00221
00222 fcb->f_dirent.dent_clusthi = (u_short) (clust >> 16);
00223 fcb->f_dirent.dent_clust = (u_short) clust;
00224 fcb->f_de_dirty = 1;
00225
00226
00227 if (vol->vol_type == 32) {
00228 if (Phat32SetClusterLink(dev, clust, PHAT32CMASK)) {
00229 return 0;
00230 }
00231 } else if (vol->vol_type == 16) {
00232 if (Phat16SetClusterLink(dev, clust, PHAT16CMASK)) {
00233 return 0;
00234 }
00235 } else if (Phat12SetClusterLink(dev, clust, PHAT12CMASK)) {
00236 return 0;
00237 }
00238 vol->vol_numfree--;
00239
00240 return clust;
00241 }
00242
00251 static u_long AllocNextCluster(NUTFILE * nfp)
00252 {
00253 u_long clust;
00254 NUTDEVICE *dev = nfp->nf_dev;
00255 PHATFILE *fcb = nfp->nf_fcb;
00256 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00257
00258
00259 if ((clust = AllocCluster(dev)) < 2) {
00260 return 0;
00261 }
00262
00263
00264
00265
00266 if (vol->vol_type == 32) {
00267 if (Phat32SetClusterLink(dev, fcb->f_clust, clust)) {
00268 return 0;
00269 }
00270 if (Phat32SetClusterLink(dev, clust, PHAT32CMASK)) {
00271 return 0;
00272 }
00273 } else if (vol->vol_type == 16) {
00274 if (Phat16SetClusterLink(dev, fcb->f_clust, clust)) {
00275 return 0;
00276 }
00277 if (Phat16SetClusterLink(dev, clust, PHAT16CMASK)) {
00278 return 0;
00279 }
00280 } else if (Phat12SetClusterLink(dev, fcb->f_clust, clust)) {
00281 return 0;
00282 } else if (Phat12SetClusterLink(dev, clust, PHAT12CMASK)) {
00283 return 0;
00284 }
00285 vol->vol_numfree--;
00286
00287 return clust;
00288 }
00289
00297 static int PhatFileFlush(NUTFILE * nfp)
00298 {
00299 int rc;
00300 NUTDEVICE *dev = nfp->nf_dev;
00301 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00302
00303
00304 if ((rc = PhatDirEntryUpdate(nfp)) == 0) {
00305
00306 NutEventWait(&vol->vol_iomutex, 0);
00307
00308 rc = PhatSectorFlush(nfp->nf_dev, -1);
00309
00310 NutEventPost(&vol->vol_iomutex);
00311 }
00312 return rc;
00313 }
00314
00322 int PhatFileClose(NUTFILE * nfp)
00323 {
00324 int rc;
00325
00326 if (nfp == NULL || nfp == NUTFILE_EOF) {
00327 errno = EBADF;
00328 return -1;
00329 }
00330 #ifdef NUTDEBUG
00331 PhatDbgFileInfo(stdout, "Close file", (PHATFILE *) nfp->nf_fcb);
00332 #endif
00333 rc = PhatFileFlush(nfp);
00334 if (nfp->nf_fcb) {
00335 free(nfp->nf_fcb);
00336 }
00337 free(nfp);
00338
00339 return rc;
00340 }
00341
00358 NUTFILE *PhatFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc)
00359 {
00360 NUTFILE *nfp = NUTFILE_EOF;
00361 NUTFILE *ndp = NUTFILE_EOF;
00362 PHATFILE *ffcb;
00363 PHATFILE *dfcb;
00364 PHATFIND *srch;
00365 CONST char *fname;
00366
00367
00368 if ((ndp = PhatDirOpenParent(dev, path, &fname)) == NUTFILE_EOF) {
00369 return NUTFILE_EOF;
00370 }
00371
00372
00373
00374
00375
00376
00377 dfcb = ndp->nf_fcb;
00378 if (*fname == 0) {
00379 dfcb->f_mode = mode;
00380 return ndp;
00381 }
00382
00383
00384
00385
00386 nfp = malloc(sizeof(NUTFILE));
00387 ffcb = malloc(sizeof(PHATFILE));
00388 srch = malloc(sizeof(PHATFIND));
00389 if (nfp == NULL || ffcb == NULL || srch == NULL) {
00390 PhatFileClose(ndp);
00391 if (nfp) {
00392 free(nfp);
00393 }
00394 if (ffcb) {
00395 free(ffcb);
00396 }
00397 if (srch) {
00398 free(srch);
00399 }
00400 return NUTFILE_EOF;
00401 }
00402
00403 memset(ffcb, 0, sizeof(PHATFILE));
00404 nfp->nf_next = 0;
00405 nfp->nf_dev = dev;
00406 nfp->nf_fcb = ffcb;
00407
00408
00409
00410
00411
00412
00413
00414 if (PhatDirEntryFind(ndp, fname, PHAT_FATTR_FILEMASK, srch)) {
00415
00416
00417
00418
00419 if ((mode & _O_CREAT) == 0) {
00420 free(srch);
00421 PhatFileClose(ndp);
00422 PhatFileClose(nfp);
00423 errno = ENOENT;
00424 return NUTFILE_EOF;
00425 }
00426
00427 if (PhatDirEntryCreate(ndp, fname, acc, &ffcb->f_dirent)) {
00428 free(srch);
00429 PhatFileClose(ndp);
00430 PhatFileClose(nfp);
00431 return NUTFILE_EOF;
00432 }
00433 ffcb->f_de_dirty = 1;
00434 #ifdef NUTDEBUG
00435 PhatDbgFileInfo(stdout, "New entry", ffcb);
00436 #endif
00437 } else {
00438
00439
00440
00441
00442 if ((mode & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) {
00443 free(srch);
00444 PhatFileClose(ndp);
00445 PhatFileClose(nfp);
00446 errno = EEXIST;
00447 return NUTFILE_EOF;
00448 }
00449 #ifdef NUTDEBUG
00450 PhatDbgFileInfo(stdout, "Existing entry", ffcb);
00451 #endif
00452
00453
00454
00455 if (mode & _O_TRUNC) {
00456
00457
00458
00459 if (PhatDirReleaseChain(dev, &srch->phfind_ent)) {
00460 PhatFileClose(ndp);
00461 PhatFileClose(nfp);
00462 free(srch);
00463 return NUTFILE_EOF;
00464 }
00465 memset(ffcb, 0, sizeof(PHATFILE));
00466 memcpy(ffcb->f_dirent.dent_name, srch->phfind_ent.dent_name, sizeof(ffcb->f_dirent.dent_name));
00467 ffcb->f_dirent.dent_attr = srch->phfind_ent.dent_attr;
00468 ffcb->f_dirent.dent_rsvdnt = srch->phfind_ent.dent_rsvdnt;
00469 ffcb->f_dirent.dent_ctsecs = srch->phfind_ent.dent_ctsecs;
00470 ffcb->f_dirent.dent_ctime = srch->phfind_ent.dent_ctime;
00471 ffcb->f_dirent.dent_cdate = srch->phfind_ent.dent_cdate;
00472 ffcb->f_de_dirty = 1;
00473 }
00474 else {
00475 ffcb->f_dirent = srch->phfind_ent;
00476
00477
00478
00479 if ((mode & _O_APPEND) != 0 && ffcb->f_dirent.dent_fsize) {
00480 if (PhatFilePosSet(nfp, ffcb->f_dirent.dent_fsize)) {
00481 PhatFileClose(ndp);
00482 PhatFileClose(nfp);
00483 free(srch);
00484 return NUTFILE_EOF;
00485 }
00486 }
00487 }
00488 }
00489 free(srch);
00490
00491
00492 ffcb->f_de_sect = PhatClusterSector(ndp, dfcb->f_clust) + dfcb->f_clust_pos;
00493 ffcb->f_de_offs = dfcb->f_sect_pos - 32;
00494
00495 ffcb->f_pde_clusthi = dfcb->f_dirent.dent_clusthi;
00496 ffcb->f_pde_clust = dfcb->f_dirent.dent_clust;
00497
00498 ffcb->f_clust = ffcb->f_dirent.dent_clusthi;
00499 ffcb->f_clust <<= 16;
00500 ffcb->f_clust += ffcb->f_dirent.dent_clust;
00501
00502 ffcb->f_mode = mode;
00503
00504
00505 PhatFileClose(ndp);
00506
00507 #ifdef NUTDEBUG
00508 PhatDbgFileInfo(stdout, "File opened", ffcb);
00509 #endif
00510 return nfp;
00511 }
00512
00525 int PhatFileWrite(NUTFILE * nfp, CONST void *buffer, int len)
00526 {
00527 int rc;
00528 int step;
00529 u_long clust;
00530 int sbn;
00531 u_char *buf = (u_char *) buffer;
00532 NUTDEVICE *dev = nfp->nf_dev;
00533 PHATFILE *fcb = nfp->nf_fcb;
00534 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00535
00536
00537
00538
00539 if (fcb->f_dirent.dent_attr & PHAT_FATTR_RDONLY) {
00540 errno = EACCES;
00541 return -1;
00542 }
00543
00544
00545
00546
00547 if (buf == NULL || len == 0) {
00548 return PhatFileFlush(nfp);
00549 }
00550
00551
00552
00553
00554 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00555
00556 u_long num = vol->vol_sectsz * vol->vol_clustsz;
00557
00558 u_long cur = (fcb->f_dirent.dent_fsize + num - 1) / num;
00559
00560
00561 num = (fcb->f_pos + len + num - 1) / num;
00562
00563 if (num > cur && num - cur > vol->vol_numfree) {
00564 errno = ENOSPC;
00565 return -1;
00566 }
00567
00568
00569 if (fcb->f_dirent.dent_fsize == 0) {
00570 if ((clust = AllocFirstCluster(nfp)) < 2) {
00571 return -1;
00572 }
00573 fcb->f_clust_prv = clust;
00574 fcb->f_clust = clust;
00575 }
00576 }
00577
00578
00579
00580
00581
00582 for (rc = 0, step = 0; rc < len; rc += step) {
00583
00584 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00585
00586 if (IsFixedRootDir(nfp)) {
00587 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00588
00589 break;
00590 }
00591 fcb->f_clust_pos++;
00592 }
00593 else {
00594
00595 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00596
00597 if (vol->vol_type == 32) {
00598 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00599 rc = -1;
00600 break;
00601 }
00602 if (clust >= (PHATEOC & PHAT32CMASK)) {
00603 if ((clust = AllocNextCluster(nfp)) < 2) {
00604 rc = -1;
00605 break;
00606 }
00607 }
00608 } else if (vol->vol_type == 16) {
00609 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00610 rc = -1;
00611 break;
00612 }
00613 if (clust >= (PHATEOC & PHAT16CMASK)) {
00614 if ((clust = AllocNextCluster(nfp)) < 2) {
00615 rc = -1;
00616 break;
00617 }
00618 }
00619 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00620 rc = -1;
00621 break;
00622 } else if (clust >= (PHATEOC & PHAT12CMASK)) {
00623 if ((clust = AllocNextCluster(nfp)) < 2) {
00624 rc = -1;
00625 break;
00626 }
00627 }
00628 fcb->f_clust_pos = 0;
00629 fcb->f_clust_prv = fcb->f_clust;
00630 fcb->f_clust = clust;
00631 }
00632 else {
00633 fcb->f_clust_pos++;
00634 }
00635 }
00636 fcb->f_sect_pos = 0;
00637 }
00638
00639
00640 if ((sbn = PhatSectorLoad(nfp->nf_dev, PhatClusterSector(nfp, fcb->f_clust) + fcb->f_clust_pos)) < 0) {
00641 rc = -1;
00642 break;
00643 }
00644
00645 step = (int) (vol->vol_sectsz - fcb->f_sect_pos);
00646 if (step > len - rc) {
00647 step = len - rc;
00648 }
00649
00650 memcpy(&vol->vol_buf[sbn].sect_data[fcb->f_sect_pos], &buf[rc], step);
00651 vol->vol_buf[sbn].sect_dirty = 1;
00652
00653 fcb->f_pos += step;
00654 fcb->f_sect_pos += step;
00655 }
00656
00657 if (rc > 0) {
00658
00659
00660
00661
00662 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00663 GetDosTimeStamp(&fcb->f_dirent.dent_mtime, &fcb->f_dirent.dent_mdate);
00664 fcb->f_dirent.dent_adate = fcb->f_dirent.dent_mdate;
00665 fcb->f_dirent.dent_attr |= PHAT_FATTR_ARCHIV;
00666 if(fcb->f_dirent.dent_fsize < fcb->f_pos) {
00667 fcb->f_dirent.dent_fsize = fcb->f_pos;
00668 }
00669 fcb->f_de_dirty = 1;
00670 }
00671 }
00672 return rc;
00673 }
00674
00675 #ifdef __HARVARD_ARCH__
00676
00693 int PhatFileWrite_P(NUTFILE * nfp, PGM_P buffer, int len)
00694 {
00695 return -1;
00696 }
00697 #endif
00698
00710 int PhatFileRead(NUTFILE * nfp, void *buffer, int size)
00711 {
00712 int rc;
00713 int step;
00714 int sbn;
00715 u_char *buf = (u_char *) buffer;
00716 NUTDEVICE *dev = nfp->nf_dev;
00717 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00718 PHATFILE *fcb = nfp->nf_fcb;
00719
00720
00721
00722
00723 if (buf == NULL || size == 0) {
00724 return 0;
00725 }
00726
00727
00728 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00729 if (fcb->f_pos + size >= fcb->f_dirent.dent_fsize) {
00730 size = fcb->f_dirent.dent_fsize - fcb->f_pos;
00731 }
00732 }
00733 for (rc = 0, step = 0; rc < size; rc += step) {
00734
00735 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00736
00737 if (IsFixedRootDir(nfp)) {
00738 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00739
00740 break;
00741 }
00742 fcb->f_clust_pos++;
00743 }
00744 else {
00745
00746 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00747
00748 u_long clust;
00749
00750 if (vol->vol_type == 32) {
00751 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00752 break;
00753 }
00754 if (clust >= (PHATEOC & PHAT32CMASK)) {
00755 break;
00756 }
00757 } else if (vol->vol_type == 16) {
00758 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00759 break;
00760 }
00761 if (clust >= (PHATEOC & PHAT16CMASK)) {
00762 break;
00763 }
00764 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00765 break;
00766 }
00767 else if (clust >= (PHATEOC & PHAT12CMASK)) {
00768 break;
00769 }
00770 fcb->f_clust_pos = 0;
00771 fcb->f_clust_prv = fcb->f_clust;
00772 fcb->f_clust = clust;
00773 }
00774 else {
00775 fcb->f_clust_pos++;
00776 }
00777 }
00778 fcb->f_sect_pos = 0;
00779 }
00780
00781
00782 if ((sbn = PhatSectorLoad(nfp->nf_dev, PhatClusterSector(nfp, fcb->f_clust) + fcb->f_clust_pos)) < 0) {
00783 rc = -1;
00784 break;
00785 }
00786 step = (int) (vol->vol_sectsz - fcb->f_sect_pos);
00787 if (step > size - rc) {
00788 step = size - rc;
00789 }
00790 memcpy(&buf[rc], &vol->vol_buf[sbn].sect_data[fcb->f_sect_pos], step);
00791 fcb->f_pos += step;
00792 fcb->f_sect_pos += step;
00793 }
00794 return rc;
00795 }
00796
00808 static long PhatFileSize(NUTFILE *nfp)
00809 {
00810 PHATFILE *fcb = nfp->nf_fcb;
00811
00812 return fcb->f_dirent.dent_fsize;
00813 }
00814
00815 static int PhatFileSeek(NUTFILE * nfp, long *pos, int whence)
00816 {
00817 int rc = 0;
00818 long npos = *pos;
00819 PHATFILE *fcb = nfp->nf_fcb;
00820
00821 switch (whence) {
00822 case SEEK_CUR:
00823 npos += fcb->f_pos;
00824 break;
00825 case SEEK_END:
00826 npos += PhatFileSize(nfp);
00827 break;
00828 }
00829
00830 if (npos < 0 || npos > PhatFileSize(nfp)) {
00831 rc = EINVAL;
00832 } else {
00833 rc = PhatFilePosSet(nfp, npos);
00834 *pos = fcb->f_pos;
00835 }
00836 return rc;
00837 }
00838
00843 static int PhatIOCtl(NUTDEVICE * dev, int req, void *conf)
00844 {
00845 int rc = -1;
00846
00847 switch (req) {
00848 case FS_STATUS:
00849 {
00850 FSCP_STATUS *par = (FSCP_STATUS *) conf;
00851
00852 rc = PhatDirEntryStatus(dev, par->par_path, par->par_stp);
00853 }
00854 break;
00855 case FS_DIR_CREATE:
00856 rc = PhatDirCreate(dev, (char *) conf);
00857 break;
00858 case FS_DIR_REMOVE:
00859 rc = PhatDirRemove(dev, (char *) conf);
00860 break;
00861 case FS_DIR_OPEN:
00862
00863 {
00864 DIR *dir = (DIR *) conf;
00865
00866 if ((dir->dd_fd = PhatDirOpen(dev, dir->dd_buf)) != NUTFILE_EOF) {
00867 rc = 0;
00868 }
00869 }
00870 break;
00871 case FS_DIR_CLOSE:
00872 rc = PhatFileClose(((DIR *) conf)->dd_fd);
00873 break;
00874 case FS_DIR_READ:
00875 rc = PhatDirRead((DIR *) conf);
00876 break;
00877 case FS_FILE_STATUS:
00878
00879 break;
00880 case FS_FILE_DELETE:
00881 rc = PhatDirDelEntry(dev, (char *) conf, PHAT_FATTR_FILEMASK & ~PHAT_FATTR_DIR);
00882 break;
00883 case FS_FILE_SEEK:
00884 PhatFileSeek((NUTFILE *) ((IOCTL_ARG3 *) conf)->arg1,
00885 (long *) ((IOCTL_ARG3 *) conf)->arg2,
00886 (int) ((IOCTL_ARG3 *) conf)->arg3);
00887 break;
00888 case FS_RENAME:
00889
00890 {
00891 FSCP_RENAME *par = (FSCP_RENAME *) conf;
00892
00893 rc = PhatDirRenameEntry(dev, par->par_old, par->par_new);
00894 }
00895 break;
00896
00897 case FS_VOL_MOUNT:
00898 {
00899
00900 FSCP_VOL_MOUNT *par = (FSCP_VOL_MOUNT *) conf;
00901
00902 rc = PhatVolMount(dev, par->fscp_bmnt, par->fscp_part_type);
00903 if (rc) {
00904
00905 PhatVolUnmount(dev);
00906 }
00907 }
00908 break;
00909 case FS_VOL_UNMOUNT:
00910
00911 rc = PhatVolUnmount(dev);
00912 break;
00913 }
00914 return rc;
00915 }
00916
00926 static int PhatInit(NUTDEVICE * dev)
00927 {
00928
00929 return 0;
00930 }
00931
00935 static NUTFILE *PhatApiFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc)
00936 {
00937 NUTFILE *rc;
00938 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00939
00940
00941 NutEventWait(&vol->vol_fsmutex, 0);
00942
00943 rc = PhatFileOpen(dev, path, mode, acc);
00944
00945 NutEventPost(&vol->vol_fsmutex);
00946
00947 return rc;
00948 }
00949
00953 static int PhatApiFileClose(NUTFILE * nfp)
00954 {
00955 int rc;
00956 NUTDEVICE *dev = nfp->nf_dev;
00957 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00958
00959
00960 NutEventWait(&vol->vol_fsmutex, 0);
00961
00962 rc = PhatFileClose(nfp);
00963
00964 NutEventPost(&vol->vol_fsmutex);
00965
00966 return rc;
00967 }
00968
00972 static int PhatApiFileWrite(NUTFILE * nfp, CONST void *buffer, int len)
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 = PhatFileWrite(nfp, buffer, len);
00982
00983 NutEventPost(&vol->vol_fsmutex);
00984
00985 return rc;
00986 }
00987
00988 #ifdef __HARVARD_ARCH__
00989
00992 static int PhatApiFileWrite_P(NUTFILE * nfp, PGM_P buffer, int len)
00993 {
00994 int rc;
00995 NUTDEVICE *dev = nfp->nf_dev;
00996 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00997
00998
00999 NutEventWait(&vol->vol_fsmutex, 0);
01000
01001 rc = PhatFileWrite_P(nfp, buffer, len);
01002
01003 NutEventPost(&vol->vol_fsmutex);
01004
01005 return rc;
01006 }
01007 #endif
01008
01012 static int PhatApiFileRead(NUTFILE * nfp, void *buffer, int size)
01013 {
01014 int rc;
01015 NUTDEVICE *dev = nfp->nf_dev;
01016 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
01017
01018
01019 NutEventWait(&vol->vol_fsmutex, 0);
01020
01021 rc = PhatFileRead(nfp, buffer, size);
01022
01023 NutEventPost(&vol->vol_fsmutex);
01024
01025 return rc;
01026 }
01027
01031 static int PhatApiIOCtl(NUTDEVICE * dev, int req, void *conf)
01032 {
01033 int rc;
01034 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
01035
01036
01037 if (req != FS_VOL_MOUNT && vol) {
01038 NutEventWait(&vol->vol_fsmutex, 0);
01039 }
01040
01041 rc = PhatIOCtl(dev, req, conf);
01042
01043 if (req != FS_VOL_MOUNT && req != FS_VOL_UNMOUNT && vol) {
01044 NutEventPost(&vol->vol_fsmutex);
01045 }
01046 return rc;
01047 }
01048
01061 NUTDEVICE devPhat0 = {
01062 0,
01063 {'P', 'H', 'A', 'T', '0', 0, 0, 0, 0}
01064 ,
01065 IFTYP_FS,
01066 0,
01067 0,
01068 0,
01069 0,
01070 PhatInit,
01071 PhatApiIOCtl,
01072 PhatApiFileRead,
01073 PhatApiFileWrite,
01074 #ifdef __HARVARD_ARCH__
01075 PhatApiFileWrite_P,
01076 #endif
01077 PhatApiFileOpen,
01078 PhatApiFileClose,
01079 PhatFileSize
01080 };
01081
01082 NUTDEVICE devPhat1 = {
01083 0,
01084 {'P', 'H', 'A', 'T', '1', 0, 0, 0, 0}
01085 ,
01086 IFTYP_FS,
01087 0,
01088 0,
01089 0,
01090 0,
01091 PhatInit,
01092 PhatApiIOCtl,
01093 PhatApiFileRead,
01094 PhatApiFileWrite,
01095 #ifdef __HARVARD_ARCH__
01096 PhatApiFileWrite_P,
01097 #endif
01098 PhatApiFileOpen,
01099 PhatApiFileClose,
01100 PhatFileSize
01101 };
01102