Nut/OS  4.10.3
API Reference
phat32.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 * 4;
00089 
00090     *sect = vol->vol_tab_sect[tabnum] + tabpos / vol->vol_sectsz;
00091     *pos = tabpos % vol->vol_sectsz;
00092 }
00093 
00103 int Phat32GetClusterLink(NUTDEVICE * dev, uint32_t clust, uint32_t * link)
00104 {
00105     uint32_t sect, pos;
00106     int sbn;
00107     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00108 
00109     /* Do not seek beyond the end of the chain. */
00110     if (clust >= (PHATEOC & PHAT32CMASK)) {
00111         return -1;
00112     }
00113 
00114     /* Load the sector that contains the table entry. */
00115     PhatTableLoc(vol, clust, 0, &sect, &pos);
00116     if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00117         return -1;
00118     }
00119 
00120     /* Get the 32 bit link value. */
00121     *link = vol->vol_buf[sbn].sect_data[pos];
00122     *link += (uint32_t)(vol->vol_buf[sbn].sect_data[pos + 1]) << 8;
00123     *link += (uint32_t)(vol->vol_buf[sbn].sect_data[pos + 2]) << 16;
00124     *link += (uint32_t)(vol->vol_buf[sbn].sect_data[pos + 3]) << 24;
00125 
00126     return 0;
00127 }
00128 
00138 int Phat32SetClusterLink(NUTDEVICE * dev, uint32_t clust, uint32_t link)
00139 {
00140     int tabnum;
00141     uint32_t sect;
00142     uint32_t pos;
00143     int sbn;
00144     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00145 
00146     for (tabnum = 0; tabnum < 2 && vol->vol_tab_sect[tabnum]; tabnum++) {
00147         link &= PHAT32CMASK;
00148 
00149         PhatTableLoc(vol, clust, tabnum, &sect, &pos);
00150         if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00151             return -1;
00152         }
00153         vol->vol_buf[sbn].sect_data[pos] = (uint8_t) link;
00154         vol->vol_buf[sbn].sect_data[pos + 1] = (uint8_t) (link >> 8);
00155         vol->vol_buf[sbn].sect_data[pos + 2] = (uint8_t) (link >> 16);
00156         vol->vol_buf[sbn].sect_data[pos + 3] = (uint8_t) (link >> 24);
00157         vol->vol_buf[sbn].sect_dirty = 1;
00158     }
00159     return 0;
00160 }
00161 
00170 int Phat32ReleaseChain(NUTDEVICE * dev, uint32_t first)
00171 {
00172     uint32_t next;
00173     PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00174 
00175     while (first < (PHATEOC & PHAT32CMASK)) {
00176         if (Phat32GetClusterLink(dev, first, &next)) {
00177             /* Read error. */
00178             return -1;
00179         }
00180         if (next < 2) {
00181             /* Incomplete chain, should not happen. */
00182             break;
00183         }
00184         if (Phat32SetClusterLink(dev, first, 0)) {
00185             /* Write error. */
00186             return -1;
00187         }
00188         vol->vol_numfree++;
00189         first = next;
00190     }
00191     return 0;
00192 }
00193