phatio.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2005 by egnite Software GmbH. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00021  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  */
00032 
00059 #include <errno.h>
00060 
00061 #include <fs/fs.h>
00062 
00063 #include <fs/phatfs.h>
00064 #include <fs/phatvol.h>
00065 #include <dev/blockdev.h>
00066 #include <fs/phatio.h>
00067 
00068 #include <sys/event.h>
00069 
00070 #if 0
00071 /* Use for local debugging. */
00072 #define NUTDEBUG
00073 #include <stdio.h>
00074 #endif
00075 
00080 
00091 int PhatSectorFlush(NUTDEVICE * dev, int bufnum)
00092 {
00093     BLKPAR_SEEK pars;
00094     int sbn;
00095     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00096     NUTFILE *blkmnt = dev->dev_icb;
00097     NUTDEVICE *blkdev = blkmnt->nf_dev;
00098 
00099     if (bufnum < 0) {
00100         sbn = 0;
00101 #if PHAT_SECTOR_BUFFERS
00102         bufnum = PHAT_SECTOR_BUFFERS - 1;
00103 #else
00104         bufnum = 0;
00105 #endif
00106     }
00107     else {
00108         sbn = bufnum;
00109     }
00110 
00111     while (sbn <= bufnum) {
00112         if (vol->vol_buf[sbn].sect_dirty) {
00113             pars.par_nfp = blkmnt;
00114             pars.par_blknum = vol->vol_buf[sbn].sect_num;
00115             if ((*blkdev->dev_ioctl) (blkdev, NUTBLKDEV_SEEK, &pars)) {
00116                 errno = EIO;
00117                 return -1;
00118             }
00119             if ((*blkdev->dev_write) (blkmnt, vol->vol_buf[sbn].sect_data, 1) != 1) {
00120                 errno = EIO;
00121                 return -1;
00122             }
00123             vol->vol_buf[sbn].sect_dirty = 0;
00124         }
00125         sbn++;
00126     }
00127     return 0;
00128 }
00129 
00141 int PhatSectorRead(NUTFILE * blkmnt, u_long sect, u_char * buf)
00142 {
00143     BLKPAR_SEEK pars;
00144     NUTDEVICE *blkdev = blkmnt->nf_dev;
00145 
00146     /* Set the block device's sector position. */
00147     pars.par_nfp = blkmnt;
00148     pars.par_blknum = sect;
00149     if ((*blkdev->dev_ioctl) (blkdev, NUTBLKDEV_SEEK, &pars)) {
00150         errno = EIO;
00151         return -1;
00152     }
00153 
00154     /* Read a single block from the device. */
00155     if ((*blkdev->dev_read) (blkmnt, buf, 1) != 1) {
00156         errno = EIO;
00157         return -1;
00158     }
00159     return 0;
00160 }
00161 
00162 /*
00163  * \param dev Specifies the file system device.
00164  * \return Buffer number on success, -1 on failures.
00165  */
00166 int PhatSectorLoad(NUTDEVICE * dev, u_long sect)
00167 {
00168     int sbn;
00169     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00170 
00171     /* Gain mutex access. */
00172     NutEventWait(&vol->vol_iomutex, 0);
00173 
00174 #if PHAT_SECTOR_BUFFERS
00175     for (sbn = 0; sbn < PHAT_SECTOR_BUFFERS; sbn++) {
00176         if (vol->vol_buf[sbn].sect_num == sect) {
00177             vol->vol_usenext = sbn;
00178             /* Release mutex access. */
00179             NutEventPostAsync(&vol->vol_iomutex);
00180             return sbn;
00181         }
00182     }
00183 
00184     /* Sector not loaded. Use round robin to select a buffer. */
00185     vol->vol_usenext++;
00186     if (vol->vol_usenext >= PHAT_SECTOR_BUFFERS) {
00187         vol->vol_usenext = 0;
00188     }
00189     sbn = vol->vol_usenext;
00190 #else
00191     sbn = 0;
00192     if (vol->vol_buf[sbn].sect_num == sect) {
00193         /* Release mutex access. */
00194         NutEventPostAsync(&vol->vol_iomutex);
00195         return sbn;
00196     }
00197 #endif
00198 
00199     if (PhatSectorFlush(dev, sbn)) {
00200         sbn = -1;
00201     }
00202     else if (PhatSectorRead(dev->dev_icb, sect, vol->vol_buf[sbn].sect_data)) {
00203         sbn = -1;
00204     }
00205     else {
00206         vol->vol_buf[sbn].sect_num = sect;
00207     }
00208 
00209     /* Release mutex access. */
00210     NutEventPostAsync(&vol->vol_iomutex);
00211 
00212     return sbn;
00213 }
00214 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/