fs/fdos: Remove

We have an unused FAT implementation in fs/fdos, remove.

Signed-off-by: Tom Rini <trini@ti.com>
master
Tom Rini 10 years ago
parent 4c89a369c7
commit 1530f6f51a
  1. 1
      README
  2. 3
      common/Makefile
  3. 67
      common/cmd_fdc.c
  4. 1
      fs/Makefile
  5. 13
      fs/fdos/Makefile
  6. 174
      fs/fdos/dev.c
  7. 159
      fs/fdos/dos.h
  8. 122
      fs/fdos/fat.c
  9. 156
      fs/fdos/fdos.c
  10. 100
      fs/fdos/fdos.h
  11. 98
      fs/fdos/fs.c
  12. 329
      fs/fdos/subdir.c
  13. 336
      fs/fdos/vfat.c
  14. 1
      include/config_cmd_all.h

@ -927,7 +927,6 @@ The following options need to be configured:
CONFIG_CMD_SAVEENV saveenv
CONFIG_CMD_FDC * Floppy Disk Support
CONFIG_CMD_FAT * FAT command support
CONFIG_CMD_FDOS * Dos diskette Support
CONFIG_CMD_FLASH flinfo, erase, protect
CONFIG_CMD_FPGA FPGA device initialization support
CONFIG_CMD_FUSE * Device fuse support

@ -81,9 +81,8 @@ obj-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o
obj-$(CONFIG_CMD_EXT4) += cmd_ext4.o
obj-$(CONFIG_CMD_EXT2) += cmd_ext2.o
obj-$(CONFIG_CMD_FAT) += cmd_fat.o
obj-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o
obj-$(CONFIG_CMD_FDC) += cmd_fdc.o
obj-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o
obj-$(CONFIG_CMD_FDOS) += cmd_fdos.o
obj-$(CONFIG_CMD_FITUPD) += cmd_fitupd.o
obj-$(CONFIG_CMD_FLASH) += cmd_flash.o
ifdef CONFIG_FPGA

@ -627,72 +627,6 @@ int fdc_setup(int drive, FDC_COMMAND_STRUCT *pCMD, FD_GEO_STRUCT *pFG)
return true;
}
#if defined(CONFIG_CMD_FDOS)
/* Low level functions for the Floppy-DOS layer */
/**************************************************************************
* int fdc_fdos_init
* initialize the FDC layer
*
*/
int fdc_fdos_init (int drive)
{
FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
FDC_COMMAND_STRUCT *pCMD = &cmd;
/* setup FDC and scan for drives */
if (fdc_setup(drive, pCMD, pFG) == false) {
printf("\n** Error in setup FDC **\n");
return false;
}
if (fdc_check_drive(pCMD, pFG) == false) {
printf("\n** Error in check_drives **\n");
return false;
}
if((pCMD->flags&(1<<drive))==0) {
/* drive not available */
printf("\n** Drive %d not available **\n",drive);
return false;
}
if((pCMD->flags&(0x10<<drive))==0) {
/* no disk inserted */
printf("\n** No disk inserted in drive %d **\n",drive);
return false;
}
/* ok, we have a valid source */
pCMD->drive=drive;
/* read first block */
pCMD->blnr=0;
return true;
}
/**************************************************************************
* int fdc_fdos_seek
* parameter is a block number
*/
int fdc_fdos_seek (int where)
{
FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
FDC_COMMAND_STRUCT *pCMD = &cmd;
pCMD -> blnr = where ;
return (fdc_seek (pCMD, pFG));
}
/**************************************************************************
* int fdc_fdos_read
* the length is in block number
*/
int fdc_fdos_read (void *buffer, int len)
{
FD_GEO_STRUCT *pFG = (FD_GEO_STRUCT *)floppy_type;
FDC_COMMAND_STRUCT *pCMD = &cmd;
return (fdc_read_data (buffer, len, pCMD, pFG));
}
#endif
#if defined(CONFIG_CMD_FDC)
/****************************************************************************
* main routine do_fdcboot
*/
@ -812,4 +746,3 @@ U_BOOT_CMD(
"boot from floppy device",
"loadAddr drive"
);
#endif

@ -15,7 +15,6 @@ obj-$(CONFIG_CMD_CBFS) += cbfs/
obj-$(CONFIG_CMD_CRAMFS) += cramfs/
obj-$(CONFIG_FS_EXT4) += ext4/
obj-y += fat/
obj-$(CONFIG_CMD_FDOS) += fdos/
obj-$(CONFIG_CMD_JFFS2) += jffs2/
obj-$(CONFIG_CMD_REISER) += reiserfs/
obj-$(CONFIG_SANDBOX) += sandbox/

@ -1,13 +0,0 @@
#
# (C) Copyright 2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2002
# Stäubli Faverges - <www.staubli.com>
# Pierre AUBERT p.aubert@staubli.com
#
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := fat.o vfat.o dev.o fdos.o fs.o subdir.o

@ -1,174 +0,0 @@
/*
* (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 "dos.h"
#include "fdos.h"
#define NB_HEADS 2
#define NB_TRACKS 80
#define NB_SECTORS 18
static int lastwhere;
/*-----------------------------------------------------------------------------
* dev_open --
*-----------------------------------------------------------------------------
*/
int dev_open (void)
{
lastwhere = 0;
return (0);
}
/*-----------------------------------------------------------------------------
* dev_read -- len and where are sectors number
*-----------------------------------------------------------------------------
*/
int dev_read (void *buffer, int where, int len)
{
PRINTF ("dev_read (len = %d, where = %d)\n", len, where);
/* Si on ne desire pas lire a la position courante, il faut un seek */
if (where != lastwhere) {
if (!fdc_fdos_seek (where)) {
PRINTF ("seek error in dev_read");
lastwhere = -1;
return (-1);
}
}
if (!fdc_fdos_read (buffer, len)) {
PRINTF ("read error\n");
lastwhere = -1;
return (-1);
}
lastwhere = where + len;
return (0);
}
/*-----------------------------------------------------------------------------
* check_dev -- verify the diskette format
*-----------------------------------------------------------------------------
*/
int check_dev (BootSector_t *boot, Fs_t *fs)
{
unsigned int heads, sectors, tracks;
int BootP, Infp0, InfpX, InfTm;
int sect_per_track;
/* Display Boot header */
PRINTF ("Jump to boot code 0x%02x 0x%02x 0x%02x\n",
boot -> jump [0], boot -> jump [1], boot -> jump[2]);
PRINTF ("OEM name & version '%*.*s'\n",
BANNER_LG, BANNER_LG, boot -> banner );
PRINTF ("Bytes per sector hopefully 512 %d\n",
__le16_to_cpu (boot -> secsiz));
PRINTF ("Cluster size in sectors %d\n",
boot -> clsiz);
PRINTF ("Number of reserved (boot) sectors %d\n",
__le16_to_cpu (boot -> nrsvsect));
PRINTF ("Number of FAT tables hopefully 2 %d\n",
boot -> nfat);
PRINTF ("Number of directory slots %d\n",
__le16_to_cpu (boot -> dirents));
PRINTF ("Total sectors on disk %d\n",
__le16_to_cpu (boot -> psect));
PRINTF ("Media descriptor=first byte of FAT %d\n",
boot -> descr);
PRINTF ("Sectors in FAT %d\n",
__le16_to_cpu (boot -> fatlen));
PRINTF ("Sectors/track %d\n",
__le16_to_cpu (boot -> nsect));
PRINTF ("Heads %d\n",
__le16_to_cpu (boot -> nheads));
PRINTF ("number of hidden sectors %d\n",
__le32_to_cpu (boot -> nhs));
PRINTF ("big total sectors %d\n",
__le32_to_cpu (boot -> bigsect));
PRINTF ("physical drive ? %d\n",
boot -> physdrive);
PRINTF ("reserved %d\n",
boot -> reserved);
PRINTF ("dos > 4.0 diskette %d\n",
boot -> dos4);
PRINTF ("serial number %d\n",
__le32_to_cpu (boot -> serial));
PRINTF ("disk label %*.*s\n",
LABEL_LG, LABEL_LG, boot -> label);
PRINTF ("FAT type %8.8s\n",
boot -> fat_type);
PRINTF ("reserved by 2M %d\n",
boot -> res_2m);
PRINTF ("2M checksum (not used) %d\n",
boot -> CheckSum);
PRINTF ("2MF format version %d\n",
boot -> fmt_2mf);
PRINTF ("1 if write track after format %d\n",
boot -> wt);
PRINTF ("data transfer rate on track 0 %d\n",
boot -> rate_0);
PRINTF ("data transfer rate on track<>0 %d\n",
boot -> rate_any);
PRINTF ("offset to boot program %d\n",
__le16_to_cpu (boot -> BootP));
PRINTF ("T1: information for track 0 %d\n",
__le16_to_cpu (boot -> Infp0));
PRINTF ("T2: information for track<>0 %d\n",
__le16_to_cpu (boot -> InfpX));
PRINTF ("T3: track sectors size table %d\n",
__le16_to_cpu (boot -> InfTm));
PRINTF ("Format date 0x%04x\n",
__le16_to_cpu (boot -> DateF));
PRINTF ("Format time 0x%04x\n",
__le16_to_cpu (boot -> TimeF));
/* information is extracted from boot sector */
heads = __le16_to_cpu (boot -> nheads);
sectors = __le16_to_cpu (boot -> nsect);
fs -> tot_sectors = __le32_to_cpu (boot -> bigsect);
if (__le16_to_cpu (boot -> psect) != 0) {
fs -> tot_sectors = __le16_to_cpu (boot -> psect);
}
sect_per_track = heads * sectors;
tracks = (fs -> tot_sectors + sect_per_track - 1) / sect_per_track;
BootP = __le16_to_cpu (boot -> BootP);
Infp0 = __le16_to_cpu (boot -> Infp0);
InfpX = __le16_to_cpu (boot -> InfpX);
InfTm = __le16_to_cpu (boot -> InfTm);
if (boot -> dos4 == EXTENDED_BOOT &&
strncmp( boot->banner,"2M", 2 ) == 0 &&
BootP < SZ_STD_SECTOR &&
Infp0 < SZ_STD_SECTOR &&
InfpX < SZ_STD_SECTOR &&
InfTm < SZ_STD_SECTOR &&
BootP >= InfTm + 2 &&
InfTm >= InfpX &&
InfpX >= Infp0 &&
Infp0 >= 76 ) {
return (-1);
}
if (heads != NB_HEADS ||
tracks != NB_TRACKS ||
sectors != NB_SECTORS ||
__le16_to_cpu (boot -> secsiz) != SZ_STD_SECTOR ||
fs -> tot_sectors == 0 ||
(fs -> tot_sectors % sectors) != 0) {
return (-1);
}
return (0);
}

@ -1,159 +0,0 @@
/*
* (C) Copyright 2002
* Stäubli Faverges - <www.staubli.com>
* Pierre AUBERT p.aubert@staubli.com
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _DOS_H_
#define _DOS_H_
/* Definitions for Dos diskettes */
/* General definitions */
#define SZ_STD_SECTOR 512 /* Standard sector size */
#define MDIR_SIZE 32 /* Direntry size */
#define FAT_BITS 12 /* Diskette use 12 bits fat */
#define MAX_PATH 128 /* Max size of the MSDOS PATH */
#define MAX_DIR_SECS 64 /* Taille max d'un repertoire (en */
/* secteurs) */
/* Misc. definitions */
#define DELMARK '\xe5'
#define EXTENDED_BOOT (0x29)
#define MEDIA_STD (0xf0)
#define JUMP_0_1 (0xe9)
#define JUMP_0_2 (0xeb)
/* Boot size is 256 bytes, but we need to read almost a sector, then
assume bootsize is 512 */
#define BOOTSIZE 512
/* Fat definitions for 12 bits fat */
#define FAT12_MAX_NB 4086
#define FAT12_LAST 0x0ff6
#define FAT12_END 0x0fff
/* file attributes */
#define ATTR_READONLY 0x01
#define ATTR_HIDDEN 0x02
#define ATTR_SYSTEM 0x04
#define ATTR_VOLUME 0x08
#define ATTR_DIRECTORY 0x10
#define ATTR_ARCHIVE 0x20
#define ATTR_VSE 0x0f
/* Name format */
#define EXTCASE 0x10
#define BASECASE 0x8
/* Definition of the boot sector */
#define BANNER_LG 8
#define LABEL_LG 11
typedef struct bootsector
{
unsigned char jump [3]; /* 0 Jump to boot code */
char banner [BANNER_LG]; /* 3 OEM name & version */
unsigned short secsiz; /* 11 Bytes per sector hopefully 512 */
unsigned char clsiz; /* 13 Cluster size in sectors */
unsigned short nrsvsect; /* 14 Number of reserved (boot) sectors */
unsigned char nfat; /* 16 Number of FAT tables hopefully 2 */
unsigned short dirents; /* 17 Number of directory slots */
unsigned short psect; /* 19 Total sectors on disk */
unsigned char descr; /* 21 Media descriptor=first byte of FAT */
unsigned short fatlen; /* 22 Sectors in FAT */
unsigned short nsect; /* 24 Sectors/track */
unsigned short nheads; /* 26 Heads */
unsigned int nhs; /* 28 number of hidden sectors */
unsigned int bigsect; /* 32 big total sectors */
unsigned char physdrive; /* 36 physical drive ? */
unsigned char reserved; /* 37 reserved */
unsigned char dos4; /* 38 dos > 4.0 diskette */
unsigned int serial; /* 39 serial number */
char label [LABEL_LG]; /* 43 disk label */
char fat_type [8]; /* 54 FAT type */
unsigned char res_2m; /* 62 reserved by 2M */
unsigned char CheckSum; /* 63 2M checksum (not used) */
unsigned char fmt_2mf; /* 64 2MF format version */
unsigned char wt; /* 65 1 if write track after format */
unsigned char rate_0; /* 66 data transfer rate on track 0 */
unsigned char rate_any; /* 67 data transfer rate on track<>0 */
unsigned short BootP; /* 68 offset to boot program */
unsigned short Infp0; /* 70 T1: information for track 0 */
unsigned short InfpX; /* 72 T2: information for track<>0 */
unsigned short InfTm; /* 74 T3: track sectors size table */
unsigned short DateF; /* 76 Format date */
unsigned short TimeF; /* 78 Format time */
unsigned char junk [BOOTSIZE - 80]; /* 80 remaining data */
} __attribute__ ((packed)) BootSector_t;
/* Structure d'une entree de repertoire */
typedef struct directory {
char name [8]; /* file name */
char ext [3]; /* file extension */
unsigned char attr; /* attribute byte */
unsigned char Case; /* case of short filename */
unsigned char reserved [9]; /* ?? */
unsigned char time [2]; /* time stamp */
unsigned char date [2]; /* date stamp */
unsigned short start; /* starting cluster number */
unsigned int size; /* size of the file */
} __attribute__ ((packed)) Directory_t;
#define MAX_VFAT_SUBENTRIES 20
#define VSE_NAMELEN 13
#define VSE1SIZE 5
#define VSE2SIZE 6
#define VSE3SIZE 2
#define VBUFSIZE ((MAX_VFAT_SUBENTRIES * VSE_NAMELEN) + 1)
#define MAX_VNAMELEN (255)
#define VSE_PRESENT 0x01
#define VSE_LAST 0x40
#define VSE_MASK 0x1f
/* Flag used by vfat_lookup */
#define DO_OPEN 1
#define ACCEPT_PLAIN 0x20
#define ACCEPT_DIR 0x10
#define ACCEPT_LABEL 0x08
#define SINGLE 2
#define MATCH_ANY 0x40
struct vfat_subentry {
unsigned char id; /* VSE_LAST pour la fin, VSE_MASK */
/* pour un VSE */
char text1 [VSE1SIZE * 2]; /* Caracteres encodes sur 16 bits */
unsigned char attribute; /* 0x0f pour les VFAT */
unsigned char hash1; /* toujours 0 */
unsigned char sum; /* Checksum du nom court */
char text2 [VSE2SIZE * 2]; /* Caracteres encodes sur 16 bits */
unsigned char sector_l; /* 0 pour les VFAT */
unsigned char sector_u; /* 0 pour les VFAT */
char text3 [VSE3SIZE * 2]; /* Caracteres encodes sur 16 bits */
} __attribute__ ((packed)) ;
struct vfat_state {
char name [VBUFSIZE];
int status; /* is now a bit map of 32 bits */
int subentries;
unsigned char sum; /* no need to remember the sum for each */
/* entry, it is the same anyways */
} __attribute__ ((packed)) ;
/* Conversion macros */
#define DOS_YEAR(dir) (((dir)->date[1] >> 1) + 1980)
#define DOS_MONTH(dir) (((((dir)->date[1]&0x1) << 3) + ((dir)->date[0] >> 5)))
#define DOS_DAY(dir) ((dir)->date[0] & 0x1f)
#define DOS_HOUR(dir) ((dir)->time[1] >> 3)
#define DOS_MINUTE(dir) (((((dir)->time[1]&0x7) << 3) + ((dir)->time[0] >> 5)))
#define DOS_SEC(dir) (((dir)->time[0] & 0x1f) * 2)
#endif

@ -1,122 +0,0 @@
/*
* (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);
}

@ -1,156 +0,0 @@
/*
* (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"
const char *month [] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
Fs_t fs;
File_t file;
/*-----------------------------------------------------------------------------
* dos_open --
*-----------------------------------------------------------------------------
*/
int dos_open(char *name)
{
int lg;
int entry;
char *fname;
/* We need to suppress the " char around the name */
if (name [0] == '"') {
name ++;
}
lg = strlen (name);
if (name [lg - 1] == '"') {
name [lg - 1] = '\0';
}
/* Open file system */
if (fs_init (&fs) < 0) {
return -1;
}
/* Init the file descriptor */
file.name = name;
file.fs = &fs;
/* find the subdirectory containing the file */
if (open_subdir (&file) < 0) {
return (-1);
}
fname = basename (name);
/* if we try to open root directory */
if (*fname == '\0') {
file.file = file.subdir;
return (0);
}
/* find the file in the subdir */
entry = 0;
if (vfat_lookup (&file.subdir,
file.fs,
&file.file.dir,
&entry,
0,
fname,
ACCEPT_DIR | ACCEPT_PLAIN | SINGLE | DO_OPEN,
0,
&file.file) != 0) {
/* File not found */
printf ("File not found\n");
return (-1);
}
return 0;
}
/*-----------------------------------------------------------------------------
* dos_read --
*-----------------------------------------------------------------------------
*/
int dos_read (ulong addr)
{
int read = 0, nb;
/* Try to boot a directory ? */
if (file.file.dir.attr & (ATTR_DIRECTORY | ATTR_VOLUME)) {
printf ("Unable to boot %s !!\n", file.name);
return (-1);
}
while (read < file.file.FileSize) {
PRINTF ("read_file (%ld)\n", (file.file.FileSize - read));
nb = read_file (&fs,
&file.file,
(char *)addr + read,
read,
(file.file.FileSize - read));
PRINTF ("read_file -> %d\n", nb);
if (nb < 0) {
printf ("read error\n");
return (-1);
}
read += nb;
}
return (read);
}
/*-----------------------------------------------------------------------------
* dos_dir --
*-----------------------------------------------------------------------------
*/
int dos_dir (void)
{
int entry;
Directory_t dir;
char *name;
if ((file.file.dir.attr & ATTR_DIRECTORY) == 0) {
printf ("%s: not a directory !!\n", file.name);
return (1);
}
entry = 0;
if ((name = malloc (MAX_VNAMELEN + 1)) == NULL) {
PRINTF ("Allcation error\n");
return (1);
}
while (vfat_lookup (&file.file,
file.fs,
&dir,
&entry,
0,
NULL,
ACCEPT_DIR | ACCEPT_PLAIN | MATCH_ANY,
name,
NULL) == 0) {
/* Display file info */
printf ("%3.3s %9d %s %02d %04d %02d:%02d:%02d %s\n",
(dir.attr & ATTR_DIRECTORY) ? "dir" : " ",
__le32_to_cpu (dir.size),
month [DOS_MONTH (&dir) - 1],
DOS_DAY (&dir),
DOS_YEAR (&dir),
DOS_HOUR (&dir),
DOS_MINUTE (&dir),
DOS_SEC (&dir),
name);
}
free (name);
return (0);
}

@ -1,100 +0,0 @@
/*
* (C) Copyright 2002
* Stäubli Faverges - <www.staubli.com>
* Pierre AUBERT p.aubert@staubli.com
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _FDOS_H_
#define _FDOS_H_
#undef FDOS_DEBUG
#ifdef FDOS_DEBUG
#define PRINTF(fmt,args...) printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/* Data structure describing media */
typedef struct fs
{
unsigned long tot_sectors;
int cluster_size;
int num_clus;
int fat_start;
int fat_len;
int nb_fat;
int num_fat;
int dir_start;
int dir_len;
unsigned char *fat_buf;
} Fs_t;
/* Data structure describing one file system slot */
typedef struct slot {
int (*map) (struct fs *fs,
struct slot *file,
int where,
int *len);
unsigned long FileSize;
unsigned short int FirstAbsCluNr;
unsigned short int PreviousAbsCluNr;
unsigned short int PreviousRelCluNr;
Directory_t dir;
} Slot_t;
typedef struct file {
char *name;
int Case;
Fs_t *fs;
Slot_t subdir;
Slot_t file;
} File_t;
/* dev.c */
int dev_read (void *buffer, int where, int len);
int dev_open (void);
int check_dev (BootSector_t *boot, Fs_t *fs);
/* fat.c */
unsigned int fat_decode (Fs_t *fs, unsigned int num);
int read_fat (BootSector_t *boot, Fs_t *fs);
/* vfat.c */
int vfat_lookup (Slot_t *dir,
Fs_t *fs,
Directory_t *dirent,
int *entry,
int *vfat_start,
char *filename,
int flags,
char *outname,
Slot_t *file);
/* subdir.c */
char *basename (char *name);
int open_subdir (File_t *desc);
int open_file (Slot_t *file, Directory_t *dir);
int read_file (Fs_t *fs,
Slot_t *file,
char *buf,
int where,
int len);
void init_subdir (void);
/* fs.c */
int fs_init (Fs_t *fs);
#endif

@ -1,98 +0,0 @@
/*
* (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"
/*-----------------------------------------------------------------------------
* fill_fs -- Read info on file system
*-----------------------------------------------------------------------------
*/
static int fill_fs (BootSector_t *boot, Fs_t *fs)
{
fs -> fat_start = __le16_to_cpu (boot -> nrsvsect);
fs -> fat_len = __le16_to_cpu (boot -> fatlen);
fs -> nb_fat = boot -> nfat;
fs -> dir_start = fs -> fat_start + fs -> nb_fat * fs -> fat_len;
fs -> dir_len = __le16_to_cpu (boot -> dirents) * MDIR_SIZE / SZ_STD_SECTOR;
fs -> cluster_size = boot -> clsiz;
fs -> num_clus = (fs -> tot_sectors - fs -> dir_start - fs -> dir_len) / fs -> cluster_size;
return (0);
}
/*-----------------------------------------------------------------------------
* fs_init --
*-----------------------------------------------------------------------------
*/
int fs_init (Fs_t *fs)
{
BootSector_t *boot;
/* Initialize physical device */
if (dev_open () < 0) {
PRINTF ("Unable to initialize the fdc\n");
return (-1);
}
init_subdir ();
/* Allocate space for read the boot sector */
if ((boot = (BootSector_t *)malloc (sizeof (BootSector_t))) == NULL) {
PRINTF ("Unable to allocate space for boot sector\n");
return (-1);
}
/* read boot sector */
if (dev_read (boot, 0, 1)){
PRINTF ("Error during boot sector read\n");
free (boot);
return (-1);
}
/* we verify it'a a DOS diskette */
if (boot -> jump [0] != JUMP_0_1 && boot -> jump [0] != JUMP_0_2) {
PRINTF ("Not a DOS diskette\n");
free (boot);
return (-1);
}
if (boot -> descr < MEDIA_STD) {
/* We handle only recent medias (type F0) */
PRINTF ("unrecognized diskette type\n");
free (boot);
return (-1);
}
if (check_dev (boot, fs) < 0) {
PRINTF ("Bad diskette\n");
free (boot);
return (-1);
}
if (fill_fs (boot, fs) < 0) {
free (boot);
return (-1);
}
/* Read FAT */
if (read_fat (boot, fs) < 0) {
free (boot);
return (-1);
}
free (boot);
return (0);
}

@ -1,329 +0,0 @@
/*
* (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"
static int cache_sect;
static unsigned char cache [SZ_STD_SECTOR];
#define min(x,y) ((x)<(y)?(x):(y))
static int descend (Slot_t *parent,
Fs_t *fs,
char *path);
/*-----------------------------------------------------------------------------
* init_subdir --
*-----------------------------------------------------------------------------
*/
void init_subdir (void)
{
cache_sect = -1;
}
/*-----------------------------------------------------------------------------
* basename --
*-----------------------------------------------------------------------------
*/
char *basename (char *name)
{
register char *cptr;
if (!name || !*name) {
return ("");
}
for (cptr= name; *cptr++; );
while (--cptr >= name) {
if (*cptr == '/') {
return (cptr + 1);
}
}
return(name);
}
/*-----------------------------------------------------------------------------
* root_map --
*-----------------------------------------------------------------------------
*/
static int root_map (Fs_t *fs, Slot_t *file, int where, int *len)
{
*len = min (*len, fs -> dir_len * SZ_STD_SECTOR - where);
if (*len < 0 ) {
*len = 0;
return (-1);
}
return fs -> dir_start * SZ_STD_SECTOR + where;
}
/*-----------------------------------------------------------------------------
* normal_map --
*-----------------------------------------------------------------------------
*/
static int normal_map (Fs_t *fs, Slot_t *file, int where, int *len)
{
int offset;
int NrClu;
unsigned short RelCluNr;
unsigned short CurCluNr;
unsigned short NewCluNr;
unsigned short AbsCluNr;
int clus_size;
clus_size = fs -> cluster_size * SZ_STD_SECTOR;
offset = where % clus_size;
*len = min (*len, file -> FileSize - where);
if (*len < 0 ) {
*len = 0;
return (0);
}
if (file -> FirstAbsCluNr < 2){
*len = 0;
return (0);
}
RelCluNr = where / clus_size;
if (RelCluNr >= file -> PreviousRelCluNr){
CurCluNr = file -> PreviousRelCluNr;
AbsCluNr = file -> PreviousAbsCluNr;
} else {
CurCluNr = 0;
AbsCluNr = file -> FirstAbsCluNr;
}
NrClu = (offset + *len - 1) / clus_size;
while (CurCluNr <= RelCluNr + NrClu) {
if (CurCluNr == RelCluNr){
/* we have reached the beginning of our zone. Save
* coordinates */
file -> PreviousRelCluNr = RelCluNr;
file -> PreviousAbsCluNr = AbsCluNr;
}
NewCluNr = fat_decode (fs, AbsCluNr);
if (NewCluNr == 1 || NewCluNr == 0) {
PRINTF("Fat problem while decoding %d %x\n",
AbsCluNr, NewCluNr);
return (-1);
}
if (CurCluNr == RelCluNr + NrClu) {
break;
}
if (CurCluNr < RelCluNr && NewCluNr == FAT12_END) {
*len = 0;
return 0;
}
if (CurCluNr >= RelCluNr && NewCluNr != AbsCluNr + 1)
break;
CurCluNr++;
AbsCluNr = NewCluNr;
}
*len = min (*len, (1 + CurCluNr - RelCluNr) * clus_size - offset);
return (((file -> PreviousAbsCluNr - 2) * fs -> cluster_size +
fs -> dir_start + fs -> dir_len) *
SZ_STD_SECTOR + offset);
}
/*-----------------------------------------------------------------------------
* open_subdir -- open the subdir containing the file
*-----------------------------------------------------------------------------
*/
int open_subdir (File_t *desc)
{
char *pathname;
char *tmp, *s, *path;
char terminator;
if ((pathname = (char *)malloc (MAX_PATH)) == NULL) {
return (-1);
}
strcpy (pathname, desc -> name);
/* Suppress file name */
tmp = basename (pathname);
*tmp = '\0';
/* root directory init */
desc -> subdir.FirstAbsCluNr = 0;
desc -> subdir.FileSize = -1;
desc -> subdir.map = root_map;
desc -> subdir.dir.attr = ATTR_DIRECTORY;
tmp = pathname;
for (s = tmp; ; ++s) {
if (*s == '/' || *s == '\0') {
path = tmp;
terminator = *s;
*s = '\0';
if (s != tmp && strcmp (path,".")) {
if (descend (&desc -> subdir, desc -> fs, path) < 0) {
free (pathname);
return (-1);
}
}
if (terminator == 0) {
break;
}
tmp = s + 1;
}
}
free (pathname);
return (0);
}
/*-----------------------------------------------------------------------------
* descend --
*-----------------------------------------------------------------------------
*/
static int descend (Slot_t *parent,
Fs_t *fs,
char *path)
{
int entry;
Slot_t SubDir;
if(path[0] == '\0' || strcmp (path, ".") == 0) {
return (0);
}
entry = 0;
if (vfat_lookup (parent,
fs,
&(SubDir.dir),
&entry,
0,
path,
ACCEPT_DIR | SINGLE | DO_OPEN,
0,
&SubDir) == 0) {
*parent = SubDir;
return (0);
}
if (strcmp(path, "..") == 0) {
parent -> FileSize = -1;
parent -> FirstAbsCluNr = 0;
parent -> map = root_map;
return (0);
}
return (-1);
}
/*-----------------------------------------------------------------------------
* open_file --
*-----------------------------------------------------------------------------
*/
int open_file (Slot_t *file, Directory_t *dir)
{
int first;
unsigned long size;
first = __le16_to_cpu (dir -> start);
if(first == 0 &&
(dir -> attr & ATTR_DIRECTORY) != 0) {
file -> FirstAbsCluNr = 0;
file -> FileSize = -1;
file -> map = root_map;
return (0);
}
if ((dir -> attr & ATTR_DIRECTORY) != 0) {
size = (1UL << 31) - 1;
}
else {
size = __le32_to_cpu (dir -> size);
}
file -> map = normal_map;
file -> FirstAbsCluNr = first;
file -> PreviousRelCluNr = 0xffff;
file -> FileSize = size;
return (0);
}
/*-----------------------------------------------------------------------------
* read_file --
*-----------------------------------------------------------------------------
*/
int read_file (Fs_t *fs,
Slot_t *file,
char *buf,
int where,
int len)
{
int pos;
int read, nb, sect, offset;
pos = file -> map (fs, file, where, &len);
if (pos < 0) {
return -1;
}
if (len == 0) {
return (0);
}
/* Compute sector number */
sect = pos / SZ_STD_SECTOR;
offset = pos % SZ_STD_SECTOR;
read = 0;
if (offset) {
/* Read doesn't start at the sector beginning. We need to use our */
/* cache */
if (sect != cache_sect) {
if (dev_read (cache, sect, 1) < 0) {
return (-1);
}
cache_sect = sect;
}
nb = min (len, SZ_STD_SECTOR - offset);
memcpy (buf, cache + offset, nb);
read += nb;
len -= nb;
sect += 1;
}
if (len > SZ_STD_SECTOR) {
nb = (len - 1) / SZ_STD_SECTOR;
if (dev_read (buf + read, sect, nb) < 0) {
return ((read) ? read : -1);
}
/* update sector position */
sect += nb;
/* Update byte position */
nb *= SZ_STD_SECTOR;
read += nb;
len -= nb;
}
if (len) {
if (sect != cache_sect) {
if (dev_read (cache, sect, 1) < 0) {
return ((read) ? read : -1);
cache_sect = -1;
}
cache_sect = sect;
}
memcpy (buf + read, cache, len);
read += len;
}
return (read);
}

@ -1,336 +0,0 @@
/*
* (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 <linux/ctype.h>
#include "dos.h"
#include "fdos.h"
static int dir_read (Fs_t *fs,
Slot_t *dir,
Directory_t *dirent,
int num,
struct vfat_state *v);
static int unicode_read (char *in, char *out, int num);
static int match (const char *s, const char *p);
static unsigned char sum_shortname (char *name);
static int check_vfat (struct vfat_state *v, Directory_t *dir);
static char *conv_name (char *name, char *ext, char Case, char *ans);
/*-----------------------------------------------------------------------------
* clear_vfat --
*-----------------------------------------------------------------------------
*/
static void clear_vfat (struct vfat_state *v)
{
v -> subentries = 0;
v -> status = 0;
}
/*-----------------------------------------------------------------------------
* vfat_lookup --
*-----------------------------------------------------------------------------
*/
int vfat_lookup (Slot_t *dir,
Fs_t *fs,
Directory_t *dirent,
int *entry,
int *vfat_start,
char *filename,
int flags,
char *outname,
Slot_t *file)
{
int found;
struct vfat_state vfat;
char newfile [VSE_NAMELEN];
int vfat_present = 0;
if (*entry == -1) {
return -1;
}
found = 0;
clear_vfat (&vfat);
while (1) {
if (dir_read (fs, dir, dirent, *entry, &vfat) < 0) {
if (vfat_start) {
*vfat_start = *entry;
}
break;
}
(*entry)++;
/* Empty slot */
if (dirent -> name[0] == '\0'){
if (vfat_start == 0) {
break;
}
continue;
}
if (dirent -> attr == ATTR_VSE) {
/* VSE entry, continue */
continue;
}
if ( (dirent -> name [0] == DELMARK) ||
((dirent -> attr & ATTR_DIRECTORY) != 0 &&
(flags & ACCEPT_DIR) == 0) ||
((dirent -> attr & ATTR_VOLUME) != 0 &&
(flags & ACCEPT_LABEL) == 0) ||
(((dirent -> attr & (ATTR_DIRECTORY | ATTR_VOLUME)) == 0) &&
(flags & ACCEPT_PLAIN) == 0)) {
clear_vfat (&vfat);
continue;
}
vfat_present = check_vfat (&vfat, dirent);
if (vfat_start) {
*vfat_start = *entry - 1;
if (vfat_present) {
*vfat_start -= vfat.subentries;
}
}
if (dirent -> attr & ATTR_VOLUME) {
strncpy (newfile, dirent -> name, 8);
newfile [8] = '\0';
strncat (newfile, dirent -> ext, 3);
newfile [11] = '\0';
}
else {
conv_name (dirent -> name, dirent -> ext, dirent -> Case, newfile);
}
if (flags & MATCH_ANY) {
found = 1;
break;
}
if ((vfat_present && match (vfat.name, filename)) ||
(match (newfile, filename))) {
found = 1;
break;
}
clear_vfat (&vfat);
}
if (found) {
if ((flags & DO_OPEN) && file) {
if (open_file (file, dirent) < 0) {
return (-1);
}
}
if (outname) {
if (vfat_present) {
strcpy (outname, vfat.name);
}
else {
strcpy (outname, newfile);
}
}
return (0); /* File found */
} else {
*entry = -1;
return -1; /* File not found */
}
}
/*-----------------------------------------------------------------------------
* dir_read -- Read one directory entry
*-----------------------------------------------------------------------------
*/
static int dir_read (Fs_t *fs,
Slot_t *dir,
Directory_t *dirent,
int num,
struct vfat_state *v)
{
/* read the directory entry */
if (read_file (fs,
dir,
(char *)dirent,
num * MDIR_SIZE,
MDIR_SIZE) != MDIR_SIZE) {
return (-1);
}
if (v && (dirent -> attr == ATTR_VSE)) {
struct vfat_subentry *vse;
unsigned char id, last_flag;
char *c;
vse = (struct vfat_subentry *) dirent;
id = vse -> id & VSE_MASK;
last_flag = (vse -> id & VSE_LAST);
if (id > MAX_VFAT_SUBENTRIES) {
/* Invalid VSE entry */
return (-1);
}
/* Decode VSE */
if(v -> sum != vse -> sum) {
clear_vfat (v);
v -> sum = vse -> sum;
}
v -> status |= 1 << (id - 1);
if (last_flag) {
v -> subentries = id;
}
c = &(v -> name [VSE_NAMELEN * (id - 1)]);
c += unicode_read (vse->text1, c, VSE1SIZE);
c += unicode_read (vse->text2, c, VSE2SIZE);
c += unicode_read (vse->text3, c, VSE3SIZE);
if (last_flag) {
*c = '\0'; /* Null terminate long name */
}
}
return (0);
}
/*-----------------------------------------------------------------------------
* unicode_read --
*-----------------------------------------------------------------------------
*/
static int unicode_read (char *in, char *out, int num)
{
int j;
for (j = 0; j < num; ++j) {
if (in [1])
*out = '_';
else
*out = in [0];
out ++;
in += 2;
}
return num;
}
/*-----------------------------------------------------------------------------
* match --
*-----------------------------------------------------------------------------
*/
static int match (const char *s, const char *p)
{
for (; *p != '\0'; ) {
if (toupper (*s) != toupper (*p)) {
return (0);
}
p++;
s++;
}
if (*s != '\0') {
return (0);
}
else {
return (1);
}
}
/*-----------------------------------------------------------------------------
* sum_shortname --
*-----------------------------------------------------------------------------
*/
static unsigned char sum_shortname (char *name)
{
unsigned char sum;
int j;
for (j = sum = 0; j < 11; ++j) {
sum = ((sum & 1) ? 0x80 : 0) + (sum >> 1) +
(name [j] ? name [j] : ' ');
}
return (sum);
}
/*-----------------------------------------------------------------------------
* check_vfat --
* Return 1 if long name is valid, 0 else
*-----------------------------------------------------------------------------
*/
static int check_vfat (struct vfat_state *v, Directory_t *dir)
{
char name[12];
if (v -> subentries == 0) {
return 0;
}
strncpy (name, dir -> name, 8);
strncpy (name + 8, dir -> ext, 3);
name [11] = '\0';
if (v -> sum != sum_shortname (name)) {
return 0;
}
if( (v -> status & ((1 << v -> subentries) - 1)) !=
(1 << v -> subentries) - 1) {
return 0;
}
v->name [VSE_NAMELEN * v -> subentries] = 0;
return 1;
}
/*-----------------------------------------------------------------------------
* conv_name --
*-----------------------------------------------------------------------------
*/
static char *conv_name (char *name, char *ext, char Case, char *ans)
{
char tname [9], text [4];
int i;
i = 0;
while (i < 8 && name [i] != ' ' && name [i] != '\0') {
tname [i] = name [i];
i++;
}
tname [i] = '\0';
if (Case & BASECASE) {
for (i = 0; i < 8 && tname [i]; i++) {
tname [i] = tolower (tname [i]);
}
}
i = 0;
while (i < 3 && ext [i] != ' ' && ext [i] != '\0') {
text [i] = ext [i];
i++;
}
text [i] = '\0';
if (Case & EXTCASE){
for (i = 0; i < 3 && text [i]; i++) {
text [i] = tolower (text [i]);
}
}
if (*text) {
strcpy (ans, tname);
strcat (ans, ".");
strcat (ans, text);
}
else {
strcpy(ans, tname);
}
return (ans);
}

@ -38,7 +38,6 @@
#define CONFIG_CMD_EXT2 /* EXT2 Support */
#define CONFIG_CMD_FAT /* FAT support */
#define CONFIG_CMD_FDC /* Floppy Disk Support */
#define CONFIG_CMD_FDOS /* Floppy DOS support */
#define CONFIG_CMD_FLASH /* flinfo, erase, protect */
#define CONFIG_CMD_FPGA /* FPGA configuration Support */
#define CONFIG_CMD_FUSE /* Device fuse support */

Loading…
Cancel
Save