/*
 * (C) Copyright 2002
 * Stäubli Faverges - <www.staubli.com>
 * Pierre AUBERT  p.aubert@staubli.com
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#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);
}
