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
00082 #include <fs/fs.h>
00083
00084 #include <dirent.h>
00085
00086 #include <dev/blockdev.h>
00087
00088 #include <sys/event.h>
00089
00090 #include <fs/phatfs.h>
00091 #include <fs/phatvol.h>
00092 #include <fs/phatio.h>
00093 #include <fs/phatutil.h>
00094 #include <fs/phatdir.h>
00095
00096 #include <stdlib.h>
00097 #include <errno.h>
00098 #include <string.h>
00099 #include <fcntl.h>
00100
00101 #if 0
00102
00103 #define NUTDEBUG
00104 #include <stdio.h>
00105 #include <fs/phatdbg.h>
00106 #endif
00107
00108 #ifndef SEEK_SET
00109 # define SEEK_SET 0
00110 # define SEEK_CUR 1
00111 # define SEEK_END 2
00112 #endif
00113
00118
00129 static u_long SearchFreeCluster(NUTDEVICE * dev, u_long first, u_long last)
00130 {
00131 int rc = -1;
00132 u_long clust;
00133 u_long link = 1;
00134 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00135
00136 if (vol->vol_type == 32) {
00137 for (clust = first; clust < last; clust++) {
00138 if ((rc = Phat32GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00139 break;
00140 }
00141 }
00142 } else if (vol->vol_type == 16) {
00143 for (clust = first; clust < last; clust++) {
00144 if ((rc = Phat16GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00145 break;
00146 }
00147 }
00148 } else {
00149 for (clust = first; clust < last; clust++) {
00150 if ((rc = Phat12GetClusterLink(dev, clust, &link)) < 0 || link == 0) {
00151 break;
00152 }
00153 }
00154 }
00155
00156 if (rc || link) {
00157 return 0;
00158 }
00159 return clust;
00160 }
00161
00170 static u_long AllocCluster(NUTDEVICE * dev)
00171 {
00172 u_long clust;
00173 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00174
00175
00176
00177
00178 if (vol->vol_nxtfree < 2 || vol->vol_nxtfree >= vol->vol_last_clust) {
00179 vol->vol_nxtfree = 2;
00180 }
00181 if ((clust = SearchFreeCluster(dev, vol->vol_nxtfree, vol->vol_last_clust)) < 2) {
00182 if ((clust = SearchFreeCluster(dev, 2, vol->vol_nxtfree)) < 2) {
00183 vol->vol_nxtfree = 0;
00184 errno = ENOSPC;
00185 return 0;
00186 }
00187 }
00188 vol->vol_nxtfree = clust;
00189
00190 return clust;
00191 }
00192
00201 u_long AllocFirstCluster(NUTFILE * nfp)
00202 {
00203 u_long clust;
00204 NUTDEVICE *dev = nfp->nf_dev;
00205 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00206 PHATFILE *fcb = nfp->nf_fcb;
00207
00208 if ((clust = AllocCluster(dev)) < 2) {
00209 return 0;
00210 }
00211
00212
00213 fcb->f_dirent.dent_clusthi = (u_short) (clust >> 16);
00214 fcb->f_dirent.dent_clust = (u_short) clust;
00215 fcb->f_de_dirty = 1;
00216
00217
00218 if (vol->vol_type == 32) {
00219 if (Phat32SetClusterLink(dev, clust, PHAT32CMASK)) {
00220 return 0;
00221 }
00222 } else if (vol->vol_type == 16) {
00223 if (Phat16SetClusterLink(dev, clust, PHAT16CMASK)) {
00224 return 0;
00225 }
00226 } else if (Phat12SetClusterLink(dev, clust, PHAT12CMASK)) {
00227 return 0;
00228 }
00229 vol->vol_numfree--;
00230
00231 return clust;
00232 }
00233
00242 static u_long AllocNextCluster(NUTFILE * nfp)
00243 {
00244 u_long clust;
00245 NUTDEVICE *dev = nfp->nf_dev;
00246 PHATFILE *fcb = nfp->nf_fcb;
00247 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00248
00249
00250 if ((clust = AllocCluster(dev)) < 2) {
00251 return 0;
00252 }
00253
00254
00255
00256
00257 if (vol->vol_type == 32) {
00258 if (Phat32SetClusterLink(dev, fcb->f_clust, clust)) {
00259 return 0;
00260 }
00261 if (Phat32SetClusterLink(dev, clust, PHAT32CMASK)) {
00262 return 0;
00263 }
00264 } else if (vol->vol_type == 16) {
00265 if (Phat16SetClusterLink(dev, fcb->f_clust, clust)) {
00266 return 0;
00267 }
00268 if (Phat16SetClusterLink(dev, clust, PHAT16CMASK)) {
00269 return 0;
00270 }
00271 } else if (Phat12SetClusterLink(dev, fcb->f_clust, clust)) {
00272 return 0;
00273 } else if (Phat12SetClusterLink(dev, clust, PHAT12CMASK)) {
00274 return 0;
00275 }
00276 vol->vol_numfree--;
00277
00278 return clust;
00279 }
00280
00288 static int PhatFileFlush(NUTFILE * nfp)
00289 {
00290 int rc;
00291 NUTDEVICE *dev = nfp->nf_dev;
00292 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00293
00294
00295 if ((rc = PhatDirEntryUpdate(nfp)) == 0) {
00296
00297 NutEventWait(&vol->vol_iomutex, 0);
00298
00299 rc = PhatSectorFlush(nfp->nf_dev, -1);
00300
00301 NutEventPost(&vol->vol_iomutex);
00302 }
00303 return rc;
00304 }
00305
00313 int PhatFileClose(NUTFILE * nfp)
00314 {
00315 int rc;
00316
00317 if (nfp == NULL || nfp == NUTFILE_EOF) {
00318 errno = EBADF;
00319 return -1;
00320 }
00321 #ifdef NUTDEBUG
00322 PhatDbgFileInfo(stdout, "Close file", (PHATFILE *) nfp->nf_fcb);
00323 #endif
00324 rc = PhatFileFlush(nfp);
00325 if (nfp->nf_fcb) {
00326 free(nfp->nf_fcb);
00327 }
00328 free(nfp);
00329
00330 return rc;
00331 }
00332
00347 NUTFILE *PhatFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc)
00348 {
00349 NUTFILE *nfp = NUTFILE_EOF;
00350 NUTFILE *ndp = NUTFILE_EOF;
00351 PHATFILE *ffcb;
00352 PHATFILE *dfcb;
00353 PHATFIND *srch;
00354 CONST char *fname;
00355
00356
00357 if ((ndp = PhatDirOpenParent(dev, path, &fname)) == NUTFILE_EOF) {
00358 return NUTFILE_EOF;
00359 }
00360
00361
00362
00363
00364
00365
00366 dfcb = ndp->nf_fcb;
00367 if (*fname == 0) {
00368 dfcb->f_mode = mode;
00369 return ndp;
00370 }
00371
00372
00373
00374
00375 nfp = malloc(sizeof(NUTFILE));
00376 ffcb = malloc(sizeof(PHATFILE));
00377 srch = malloc(sizeof(PHATFIND));
00378 if (nfp == NULL || ffcb == NULL || srch == NULL) {
00379 PhatFileClose(ndp);
00380 if (nfp) {
00381 free(nfp);
00382 }
00383 if (ffcb) {
00384 free(ffcb);
00385 }
00386 if (srch) {
00387 free(srch);
00388 }
00389 return NUTFILE_EOF;
00390 }
00391
00392 memset(ffcb, 0, sizeof(PHATFILE));
00393 nfp->nf_next = 0;
00394 nfp->nf_dev = dev;
00395 nfp->nf_fcb = ffcb;
00396
00397
00398
00399
00400
00401
00402
00403 if (PhatDirEntryFind(ndp, fname, PHAT_FATTR_FILEMASK, srch)) {
00404
00405
00406
00407
00408 if ((mode & _O_CREAT) == 0) {
00409 free(srch);
00410 PhatFileClose(ndp);
00411 PhatFileClose(nfp);
00412 errno = ENOENT;
00413 return NUTFILE_EOF;
00414 }
00415
00416 if (PhatDirEntryCreate(ndp, fname, acc, &ffcb->f_dirent)) {
00417 free(srch);
00418 PhatFileClose(ndp);
00419 PhatFileClose(nfp);
00420 return NUTFILE_EOF;
00421 }
00422 ffcb->f_de_dirty = 1;
00423 #ifdef NUTDEBUG
00424 PhatDbgFileInfo(stdout, "New entry", ffcb);
00425 #endif
00426 } else {
00427
00428
00429
00430
00431 if ((mode & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL)) {
00432 free(srch);
00433 PhatFileClose(ndp);
00434 PhatFileClose(nfp);
00435 errno = EEXIST;
00436 return NUTFILE_EOF;
00437 }
00438 #ifdef NUTDEBUG
00439 PhatDbgFileInfo(stdout, "Existing entry", ffcb);
00440 #endif
00441
00442
00443
00444 if (mode & _O_TRUNC) {
00445
00446
00447
00448 if (PhatDirReleaseChain(dev, &srch->phfind_ent)) {
00449 PhatFileClose(ndp);
00450 PhatFileClose(nfp);
00451 free(srch);
00452 return NUTFILE_EOF;
00453 }
00454 memset(ffcb, 0, sizeof(PHATFILE));
00455 memcpy(ffcb->f_dirent.dent_name, srch->phfind_ent.dent_name, sizeof(ffcb->f_dirent.dent_name));
00456 ffcb->f_dirent.dent_attr = srch->phfind_ent.dent_attr;
00457 ffcb->f_dirent.dent_rsvdnt = srch->phfind_ent.dent_rsvdnt;
00458 ffcb->f_dirent.dent_ctsecs = srch->phfind_ent.dent_ctsecs;
00459 ffcb->f_dirent.dent_ctime = srch->phfind_ent.dent_ctime;
00460 ffcb->f_dirent.dent_cdate = srch->phfind_ent.dent_cdate;
00461 ffcb->f_de_dirty = 1;
00462 }
00463
00464
00465
00466 else {
00467 ffcb->f_dirent = srch->phfind_ent;
00468 if (ffcb->f_dirent.dent_fsize) {
00469 PhatFilePosSet(nfp, ffcb->f_dirent.dent_fsize + 1);
00470 }
00471 }
00472 }
00473 free(srch);
00474
00475
00476 ffcb->f_de_sect = PhatClusterSector(ndp, dfcb->f_clust) + dfcb->f_clust_pos;
00477 ffcb->f_de_offs = dfcb->f_sect_pos - 32;
00478
00479 ffcb->f_pde_clusthi = dfcb->f_dirent.dent_clusthi;
00480 ffcb->f_pde_clust = dfcb->f_dirent.dent_clust;
00481
00482 ffcb->f_clust = ffcb->f_dirent.dent_clusthi;
00483 ffcb->f_clust <<= 16;
00484 ffcb->f_clust += ffcb->f_dirent.dent_clust;
00485
00486 ffcb->f_mode = mode;
00487
00488
00489 PhatFileClose(ndp);
00490
00491 #ifdef NUTDEBUG
00492 PhatDbgFileInfo(stdout, "File opened", ffcb);
00493 #endif
00494 return nfp;
00495 }
00496
00509 int PhatFileWrite(NUTFILE * nfp, CONST void *buffer, int len)
00510 {
00511 int rc;
00512 int step;
00513 u_long clust;
00514 int sbn;
00515 u_char *buf = (u_char *) buffer;
00516 NUTDEVICE *dev = nfp->nf_dev;
00517 PHATFILE *fcb = nfp->nf_fcb;
00518 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00519
00520
00521
00522
00523 if (fcb->f_dirent.dent_attr & PHAT_FATTR_RDONLY) {
00524 errno = EACCES;
00525 return -1;
00526 }
00527
00528
00529
00530
00531 if (buf == NULL || len == 0) {
00532 return PhatFileFlush(nfp);
00533 }
00534
00535
00536
00537
00538 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00539
00540 u_long num = vol->vol_sectsz * vol->vol_clustsz;
00541
00542 u_long cur = (fcb->f_dirent.dent_fsize + num - 1) / num;
00543
00544
00545 num = (fcb->f_pos + len + num - 1) / num;
00546
00547 if (num > cur && num - cur > vol->vol_numfree) {
00548 errno = ENOSPC;
00549 return -1;
00550 }
00551
00552
00553 if (fcb->f_dirent.dent_fsize == 0) {
00554 if ((clust = AllocFirstCluster(nfp)) < 2) {
00555 return -1;
00556 }
00557 fcb->f_clust_prv = clust;
00558 fcb->f_clust = clust;
00559 }
00560 }
00561
00562
00563
00564
00565
00566 for (rc = 0, step = 0; rc < len; rc += step) {
00567
00568 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00569
00570 if (IsFixedRootDir(nfp)) {
00571 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00572
00573 break;
00574 }
00575 fcb->f_clust_pos++;
00576 }
00577 else {
00578
00579 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00580
00581 if (vol->vol_type == 32) {
00582 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00583 rc = -1;
00584 break;
00585 }
00586 if (clust >= (PHATEOC & PHAT32CMASK)) {
00587 if ((clust = AllocNextCluster(nfp)) < 2) {
00588 rc = -1;
00589 break;
00590 }
00591 }
00592 } else if (vol->vol_type == 16) {
00593 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00594 rc = -1;
00595 break;
00596 }
00597 if (clust >= (PHATEOC & PHAT16CMASK)) {
00598 if ((clust = AllocNextCluster(nfp)) < 2) {
00599 rc = -1;
00600 break;
00601 }
00602 }
00603 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00604 rc = -1;
00605 break;
00606 } else if (clust >= (PHATEOC & PHAT12CMASK)) {
00607 if ((clust = AllocNextCluster(nfp)) < 2) {
00608 rc = -1;
00609 break;
00610 }
00611 }
00612 fcb->f_clust_pos = 0;
00613 fcb->f_clust_prv = fcb->f_clust;
00614 fcb->f_clust = clust;
00615 }
00616 else {
00617 fcb->f_clust_pos++;
00618 }
00619 }
00620 fcb->f_sect_pos = 0;
00621 }
00622
00623
00624 if ((sbn = PhatSectorLoad(nfp->nf_dev, PhatClusterSector(nfp, fcb->f_clust) + fcb->f_clust_pos)) < 0) {
00625 rc = -1;
00626 break;
00627 }
00628
00629 step = (int) (vol->vol_sectsz - fcb->f_sect_pos);
00630 if (step > len - rc) {
00631 step = len - rc;
00632 }
00633
00634 memcpy(&vol->vol_buf[sbn].sect_data[fcb->f_sect_pos], &buf[rc], step);
00635 vol->vol_buf[sbn].sect_dirty = 1;
00636
00637 fcb->f_pos += step;
00638 fcb->f_sect_pos += step;
00639 }
00640
00641 if (rc > 0) {
00642
00643
00644
00645
00646 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00647 GetDosTimeStamp(&fcb->f_dirent.dent_mtime, &fcb->f_dirent.dent_mdate);
00648 fcb->f_dirent.dent_adate = fcb->f_dirent.dent_mdate;
00649 fcb->f_dirent.dent_attr |= PHAT_FATTR_ARCHIV;
00650 fcb->f_dirent.dent_fsize += rc;
00651 fcb->f_de_dirty = 1;
00652 }
00653 }
00654 return rc;
00655 }
00656
00657 #ifdef __HARVARD_ARCH__
00658
00675 int PhatFileWrite_P(NUTFILE * nfp, PGM_P buffer, int len)
00676 {
00677 return -1;
00678 }
00679 #endif
00680
00692 int PhatFileRead(NUTFILE * nfp, void *buffer, int size)
00693 {
00694 int rc;
00695 int step;
00696 int sbn;
00697 u_char *buf = (u_char *) buffer;
00698 NUTDEVICE *dev = nfp->nf_dev;
00699 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00700 PHATFILE *fcb = nfp->nf_fcb;
00701
00702
00703
00704
00705 if (buf == NULL || size == 0) {
00706 return 0;
00707 }
00708
00709
00710 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0) {
00711 if (fcb->f_pos + size >= fcb->f_dirent.dent_fsize) {
00712 size = fcb->f_dirent.dent_fsize - fcb->f_pos;
00713 }
00714 }
00715 for (rc = 0, step = 0; rc < size; rc += step) {
00716
00717 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00718
00719 if (IsFixedRootDir(nfp)) {
00720 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00721
00722 break;
00723 }
00724 fcb->f_clust_pos++;
00725 }
00726 else {
00727
00728 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00729
00730 u_long clust;
00731
00732 if (vol->vol_type == 32) {
00733 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00734 break;
00735 }
00736 if (clust >= (PHATEOC & PHAT32CMASK)) {
00737 break;
00738 }
00739 } else if (vol->vol_type == 16) {
00740 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00741 break;
00742 }
00743 if (clust >= (PHATEOC & PHAT16CMASK)) {
00744 break;
00745 }
00746 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00747 break;
00748 }
00749 else if (clust >= (PHATEOC & PHAT12CMASK)) {
00750 break;
00751 }
00752 fcb->f_clust_pos = 0;
00753 fcb->f_clust_prv = fcb->f_clust;
00754 fcb->f_clust = clust;
00755 }
00756 else {
00757 fcb->f_clust_pos++;
00758 }
00759 }
00760 fcb->f_sect_pos = 0;
00761 }
00762
00763
00764 if ((sbn = PhatSectorLoad(nfp->nf_dev, PhatClusterSector(nfp, fcb->f_clust) + fcb->f_clust_pos)) < 0) {
00765 rc = -1;
00766 break;
00767 }
00768 step = (int) (vol->vol_sectsz - fcb->f_sect_pos);
00769 if (step > size - rc) {
00770 step = size - rc;
00771 }
00772 memcpy(&buf[rc], &vol->vol_buf[sbn].sect_data[fcb->f_sect_pos], step);
00773 fcb->f_pos += step;
00774 fcb->f_sect_pos += step;
00775 }
00776 return rc;
00777 }
00778
00790 static long PhatFileSize(NUTFILE *nfp)
00791 {
00792 PHATFILE *fcb = nfp->nf_fcb;
00793
00794 return fcb->f_dirent.dent_fsize;
00795 }
00796
00797 static int PhatFileSeek(NUTFILE * nfp, long *pos, int whence)
00798 {
00799 int rc = 0;
00800 long npos = *pos;
00801 PHATFILE *fcb = nfp->nf_fcb;
00802
00803 switch (whence) {
00804 case SEEK_CUR:
00805 npos += fcb->f_pos;
00806 break;
00807 case SEEK_END:
00808 npos += PhatFileSize(nfp);
00809 break;
00810 }
00811
00812 if (npos < 0 || npos > PhatFileSize(nfp)) {
00813 rc = EINVAL;
00814 } else {
00815 rc = PhatFilePosSet(nfp, npos);
00816 *pos = fcb->f_pos;
00817 }
00818 return rc;
00819 }
00820
00825 static int PhatIOCtl(NUTDEVICE * dev, int req, void *conf)
00826 {
00827 int rc = -1;
00828
00829 switch (req) {
00830 case FS_STATUS:
00831 {
00832 FSCP_STATUS *par = (FSCP_STATUS *) conf;
00833
00834 rc = PhatDirEntryStatus(dev, par->par_path, par->par_stp);
00835 }
00836 break;
00837 case FS_DIR_CREATE:
00838 rc = PhatDirCreate(dev, (char *) conf);
00839 break;
00840 case FS_DIR_REMOVE:
00841 rc = PhatDirRemove(dev, (char *) conf);
00842 break;
00843 case FS_DIR_OPEN:
00844
00845 {
00846 DIR *dir = (DIR *) conf;
00847
00848 if ((dir->dd_fd = PhatDirOpen(dev, dir->dd_buf)) != NUTFILE_EOF) {
00849 rc = 0;
00850 }
00851 }
00852 break;
00853 case FS_DIR_CLOSE:
00854 rc = PhatFileClose(((DIR *) conf)->dd_fd);
00855 break;
00856 case FS_DIR_READ:
00857 rc = PhatDirRead((DIR *) conf);
00858 break;
00859 case FS_FILE_STATUS:
00860
00861 break;
00862 case FS_FILE_DELETE:
00863 rc = PhatDirDelEntry(dev, (char *) conf, PHAT_FATTR_FILEMASK & ~PHAT_FATTR_DIR);
00864 break;
00865 case FS_FILE_SEEK:
00866 PhatFileSeek((NUTFILE *) ((IOCTL_ARG3 *) conf)->arg1,
00867 (long *) ((IOCTL_ARG3 *) conf)->arg2,
00868 (int) ((IOCTL_ARG3 *) conf)->arg3);
00869 break;
00870 case FS_RENAME:
00871
00872 {
00873 FSCP_RENAME *par = (FSCP_RENAME *) conf;
00874
00875 rc = PhatDirRenameEntry(dev, par->par_old, par->par_new);
00876 }
00877 break;
00878
00879 case FS_VOL_MOUNT:
00880 {
00881
00882 FSCP_VOL_MOUNT *par = (FSCP_VOL_MOUNT *) conf;
00883
00884 rc = PhatVolMount(dev, par->fscp_bmnt, par->fscp_part_type);
00885 if (rc) {
00886
00887 PhatVolUnmount(dev);
00888 }
00889 }
00890 break;
00891 case FS_VOL_UNMOUNT:
00892
00893 rc = PhatVolUnmount(dev);
00894 break;
00895 }
00896 return rc;
00897 }
00898
00908 static int PhatInit(NUTDEVICE * dev)
00909 {
00910
00911 return 0;
00912 }
00913
00917 static NUTFILE *PhatApiFileOpen(NUTDEVICE * dev, CONST char *path, int mode, int acc)
00918 {
00919 NUTFILE *rc;
00920 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00921
00922
00923 NutEventWait(&vol->vol_fsmutex, 0);
00924
00925 rc = PhatFileOpen(dev, path, mode, acc);
00926
00927 NutEventPost(&vol->vol_fsmutex);
00928
00929 return rc;
00930 }
00931
00935 static int PhatApiFileClose(NUTFILE * nfp)
00936 {
00937 int rc;
00938 NUTDEVICE *dev = nfp->nf_dev;
00939 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00940
00941
00942 NutEventWait(&vol->vol_fsmutex, 0);
00943
00944 rc = PhatFileClose(nfp);
00945
00946 NutEventPost(&vol->vol_fsmutex);
00947
00948 return rc;
00949 }
00950
00954 static int PhatApiFileWrite(NUTFILE * nfp, CONST void *buffer, int len)
00955 {
00956 int rc;
00957 NUTDEVICE *dev = nfp->nf_dev;
00958 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00959
00960
00961 NutEventWait(&vol->vol_fsmutex, 0);
00962
00963 rc = PhatFileWrite(nfp, buffer, len);
00964
00965 NutEventPost(&vol->vol_fsmutex);
00966
00967 return rc;
00968 }
00969
00970 #ifdef __HARVARD_ARCH__
00971
00974 static int PhatApiFileWrite_P(NUTFILE * nfp, PGM_P buffer, int len)
00975 {
00976 int rc;
00977 NUTDEVICE *dev = nfp->nf_dev;
00978 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00979
00980
00981 NutEventWait(&vol->vol_fsmutex, 0);
00982
00983 rc = PhatFileWrite_P(nfp, buffer, len);
00984
00985 NutEventPost(&vol->vol_fsmutex);
00986
00987 return rc;
00988 }
00989 #endif
00990
00994 static int PhatApiFileRead(NUTFILE * nfp, void *buffer, int size)
00995 {
00996 int rc;
00997 NUTDEVICE *dev = nfp->nf_dev;
00998 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00999
01000
01001 NutEventWait(&vol->vol_fsmutex, 0);
01002
01003 rc = PhatFileRead(nfp, buffer, size);
01004
01005 NutEventPost(&vol->vol_fsmutex);
01006
01007 return rc;
01008 }
01009
01013 static int PhatApiIOCtl(NUTDEVICE * dev, int req, void *conf)
01014 {
01015 int rc;
01016 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
01017
01018
01019 if (req != FS_VOL_MOUNT && vol) {
01020 NutEventWait(&vol->vol_fsmutex, 0);
01021 }
01022
01023 rc = PhatIOCtl(dev, req, conf);
01024
01025 if (req != FS_VOL_MOUNT && req != FS_VOL_UNMOUNT && vol) {
01026 NutEventPost(&vol->vol_fsmutex);
01027 }
01028 return rc;
01029 }
01030
01043 NUTDEVICE devPhat0 = {
01044 0,
01045 {'P', 'H', 'A', 'T', '0', 0, 0, 0, 0}
01046 ,
01047 IFTYP_FS,
01048 0,
01049 0,
01050 0,
01051 0,
01052 PhatInit,
01053 PhatApiIOCtl,
01054 PhatApiFileRead,
01055 PhatApiFileWrite,
01056 #ifdef __HARVARD_ARCH__
01057 PhatApiFileWrite_P,
01058 #endif
01059 PhatApiFileOpen,
01060 PhatApiFileClose,
01061 PhatFileSize
01062 };
01063
01064 NUTDEVICE devPhat1 = {
01065 0,
01066 {'P', 'H', 'A', 'T', '1', 0, 0, 0, 0}
01067 ,
01068 IFTYP_FS,
01069 0,
01070 0,
01071 0,
01072 0,
01073 PhatInit,
01074 PhatApiIOCtl,
01075 PhatApiFileRead,
01076 PhatApiFileWrite,
01077 #ifdef __HARVARD_ARCH__
01078 PhatApiFileWrite_P,
01079 #endif
01080 PhatApiFileOpen,
01081 PhatApiFileClose,
01082 PhatFileSize
01083 };
01084