Nut/OS  4.10.3
API Reference
phat16.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 
00064 #include <errno.h>
00065 
00066 #include <fs/phatfs.h>
00067 #include <fs/phatvol.h>
00068 #include <fs/phatio.h>
00069 
00074 
00086 static void PhatTableLoc(PHATVOL * vol, uint32_t clust, int tabnum, uint32_t * sect, uint32_t * pos)
00087 {
00088     uint32_t tabpos = clust * 2;
00089 
00090     *sect = vol->vol_tab_sect[tabnum] + tabpos / vol->vol_sectsz;
00091     *pos = tabpos % vol->vol_sectsz;
00092 }
00093 
00103 int Phat16GetClusterLink(NUTDEVICE * dev, uint32_t clust, uint32_t * link)
00104 {
00105     uint32_t sect;
00106     uint32_t pos;
00107     int sbn;
00108     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00109 
00110     /* Do not seek beyond the end of the chain. */
00111     if (clust >= (PHATEOC & PHAT16CMASK)) {
00112         return -1;
00113     }
00114 
00115     /* Load the sector that contains the table entry. */
00116     PhatTableLoc(vol, clust, 0, &sect, &pos);
00117     if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00118         return -1;
00119     }
00120 
00121     /* Get the 16 bit link value. */
00122     *link = vol->vol_buf[sbn].sect_data[pos];
00123     *link += (uint32_t)(vol->vol_buf[sbn].sect_data[pos + 1]) << 8;
00124 
00125     return 0;
00126 }
00127 
00137 int Phat16SetClusterLink(NUTDEVICE * dev, uint32_t clust, uint32_t link)
00138 {
00139     int tabnum;
00140     uint32_t sect;
00141     uint32_t pos;
00142     int sbn;
00143     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00144 
00145     for (tabnum = 0; tabnum < 2 && vol->vol_tab_sect[tabnum]; tabnum++) {
00146         PhatTableLoc(vol, clust, tabnum, &sect, &pos);
00147         if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00148             return -1;
00149         }
00150         vol->vol_buf[sbn].sect_data[pos] = (uint8_t) link;
00151         vol->vol_buf[sbn].sect_data[pos + 1] = (uint8_t) (link >> 8);
00152         vol->vol_buf[sbn].sect_dirty = 1;
00153     }
00154     return 0;
00155 }
00156 
00165 int Phat16ReleaseChain(NUTDEVICE * dev, uint32_t first)
00166 {
00167     uint32_t next;
00168     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00169 
00170     while (first < (PHATEOC & PHAT16CMASK)) {
00171         if (Phat16GetClusterLink(dev, first, &next)) {
00172             /* Read error. */
00173             return -1;
00174         }
00175         if (next < 2) {
00176             /* Incomplete chain, should not happen. */
00177             break;
00178         }
00179         if (Phat16SetClusterLink(dev, first, 0)) {
00180             /* Write error. */
00181             return -1;
00182         }
00183         vol->vol_numfree++;
00184         first = next;
00185     }
00186     return 0;
00187 }
00188