/*
 * (C) Copyright 2002
 * Stäubli Faverges - <www.staubli.com>
 * Pierre AUBERT  p.aubert@staubli.com
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <config.h>
#include <malloc.h>

#include "dos.h"
#include "fdos.h"


/*-----------------------------------------------------------------------------
 * fat_decode --
 *-----------------------------------------------------------------------------
 */
unsigned int fat_decode (Fs_t *fs, unsigned int num)
{
    unsigned int start = num * 3 / 2;
    unsigned char *address = fs -> fat_buf + start;

    if (num < 2 || start + 1 > (fs -> fat_len * SZ_STD_SECTOR))
	return 1;

    if (num & 1)
	return ((address [1] & 0xff) << 4) | ((address [0] & 0xf0 ) >> 4);
    else
	return ((address [1] & 0xf) << 8) | (address [0] & 0xff );
}
/*-----------------------------------------------------------------------------
 * check_fat --
 *-----------------------------------------------------------------------------
 */
static int check_fat (Fs_t *fs)
{
    int i, f;

    /* Cluster verification                                                  */
    for (i = 3 ; i < fs -> num_clus; i++){
	f = fat_decode (fs, i);
	if (f < FAT12_LAST && f > fs -> num_clus){
	    /* Wrong cluster number detected                                 */
	    return (-1);
	}
    }
    return (0);
}
/*-----------------------------------------------------------------------------
 * read_one_fat --
 *-----------------------------------------------------------------------------
 */
static int read_one_fat (BootSector_t *boot, Fs_t *fs, int nfat)
{
    if (dev_read (fs -> fat_buf,
		  (fs -> fat_start + nfat * fs -> fat_len),
		  fs -> fat_len) < 0) {
	return (-1);
    }

    if (fs -> fat_buf [0] || fs -> fat_buf [1] || fs -> fat_buf [2]) {
	if ((fs -> fat_buf [0] != boot -> descr &&
	     (fs -> fat_buf [0] != 0xf9 || boot -> descr != MEDIA_STD)) ||
	    fs -> fat_buf [0] < MEDIA_STD){
	    /* Unknown Media                                                 */
	    return (-1);
	}
	if (fs -> fat_buf [1] != 0xff || fs -> fat_buf [2] != 0xff){
	    /* FAT doesn't start with good values                            */
	    return (-1);
	}
    }

    if (fs -> num_clus >= FAT12_MAX_NB) {
	/* Too much clusters                                                 */
	return (-1);
    }

    return check_fat (fs);
}
/*-----------------------------------------------------------------------------
 * read_fat --
 *-----------------------------------------------------------------------------
 */
int read_fat (BootSector_t *boot, Fs_t *fs)
{
    unsigned int buflen;
    int i;

    /* Allocate Fat Buffer                                                   */
    buflen = fs -> fat_len * SZ_STD_SECTOR;
    if (fs -> fat_buf) {
	free (fs -> fat_buf);
    }

    if ((fs -> fat_buf = malloc (buflen)) == NULL) {
	return (-1);
    }

    /* Try to read each Fat                                                  */
    for (i = 0; i< fs -> nb_fat; i++){
	if (read_one_fat (boot, fs, i) == 0) {
	    /* Fat is OK                                                     */
	    fs -> num_fat = i;
	    break;
	}
    }

    if (i == fs -> nb_fat){
	return (-1);
    }

    if (fs -> fat_len > (((fs -> num_clus + 2) *
			  (FAT_BITS / 4) -1 ) / 2 /
			 SZ_STD_SECTOR + 1)) {
	return (-1);
    }
    return (0);
}
