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