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