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
00058 #include <errno.h>
00059
00060 #include <fs/phatfs.h>
00061 #include <fs/phatvol.h>
00062 #include <fs/phatio.h>
00063
00068
00080 static void PhatTableLoc(PHATVOL * vol, u_long clust, int tabnum, u_long * sect, u_long * pos)
00081 {
00082 u_long tabpos = clust + (clust / 2);
00083
00084 *sect = vol->vol_tab_sect[tabnum] + tabpos / vol->vol_sectsz;
00085 *pos = tabpos % vol->vol_sectsz;
00086 }
00087
00097 int Phat12GetClusterLink(NUTDEVICE * dev, u_long clust, u_long * link)
00098 {
00099 u_long sect;
00100 u_long pos;
00101 int sbn;
00102 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00103
00104
00105 if (clust >= (PHATEOC & PHAT12CMASK)) {
00106 return -1;
00107 }
00108
00109
00110 PhatTableLoc(vol, clust, 0, §, &pos);
00111 if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00112 return -1;
00113 }
00114
00115
00116 *link = vol->vol_buf[sbn].sect_data[pos++];
00117 if (pos >= vol->vol_sectsz) {
00118 if ((sbn = PhatSectorLoad(dev, sect + 1)) < 0) {
00119 return -1;
00120 }
00121 pos = 0;
00122 }
00123 *link += (u_long)(vol->vol_buf[sbn].sect_data[pos]) << 8;
00124
00125
00126 if (clust & 1) {
00127 *link >>= 4;
00128 }
00129 *link &= PHAT12CMASK;
00130
00131 return 0;
00132 }
00133
00143 int Phat12SetClusterLink(NUTDEVICE * dev, u_long clust, u_long link)
00144 {
00145 int tabnum;
00146 u_long sect;
00147 u_long pos;
00148 u_long tval;
00149 int sbn;
00150 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00151
00152 for (tabnum = 0; tabnum < 2 && vol->vol_tab_sect[tabnum]; tabnum++) {
00153
00154
00155 PhatTableLoc(vol, clust, tabnum, §, &pos);
00156 if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00157 return -1;
00158 }
00159
00160
00161
00162 tval = vol->vol_buf[sbn].sect_data[pos];
00163 if (pos + 1 < vol->vol_sectsz) {
00164 tval += (u_long)(vol->vol_buf[sbn].sect_data[pos + 1]) << 8;
00165 } else {
00166 if ((sbn = PhatSectorLoad(dev, sect + 1)) < 0) {
00167 return -1;
00168 }
00169 tval += (u_long)(vol->vol_buf[sbn].sect_data[0]) << 8;
00170 }
00171
00172 link &= PHAT12CMASK;
00173 if (clust & 1) {
00174 tval &= 0x000F;
00175 link <<= 4;
00176 } else {
00177 tval &= 0xF000;
00178 }
00179 tval |= link;
00180
00181
00182 if (pos + 1 < vol->vol_sectsz) {
00183 vol->vol_buf[sbn].sect_data[pos + 1] = (u_char) (tval >> 8);
00184 } else {
00185 vol->vol_buf[sbn].sect_data[0] = (u_char) (tval >> 8);
00186 vol->vol_buf[sbn].sect_dirty = 1;
00187 if ((sbn = PhatSectorLoad(dev, sect)) < 0) {
00188 return -1;
00189 }
00190 }
00191 vol->vol_buf[sbn].sect_data[pos] = (u_char) tval;
00192 vol->vol_buf[sbn].sect_dirty = 1;
00193 }
00194
00195 return 0;
00196 }
00197
00206 int Phat12ReleaseChain(NUTDEVICE * dev, u_long first)
00207 {
00208 u_long next;
00209 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00210
00211 while (first < (PHATEOC & PHAT12CMASK)) {
00212 if (Phat12GetClusterLink(dev, first, &next)) {
00213
00214 return -1;
00215 }
00216 if (next < 2) {
00217
00218 break;
00219 }
00220 if (Phat12SetClusterLink(dev, first, 0)) {
00221
00222 return -1;
00223 }
00224 vol->vol_numfree++;
00225 first = next;
00226 }
00227 return 0;
00228 }
00229