dosfstools: fix build on OS X
authorFelix Fietkau <nbd@openwrt.org>
Sun, 15 Mar 2015 05:18:45 +0000 (05:18 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Sun, 15 Mar 2015 05:18:45 +0000 (05:18 +0000)
Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
SVN-Revision: 44763

tools/dosfstools/patches/0001-Add-OSX-support.patch [new file with mode: 0644]

diff --git a/tools/dosfstools/patches/0001-Add-OSX-support.patch b/tools/dosfstools/patches/0001-Add-OSX-support.patch
new file mode 100644 (file)
index 0000000..71b8a95
--- /dev/null
@@ -0,0 +1,1849 @@
+From 92e55f1d1404e823b0a5fd6d0ea0b962de247e31 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= <noltari@gmail.com>
+Date: Wed, 25 Feb 2015 17:00:32 +0100
+Subject: [PATCH] Add OSX support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
+---
+ Makefile             |  16 +-
+ src/boot.c           |   1 +
+ src/common.h         |  54 ++++-
+ src/file.c           |   9 +-
+ src/file.h           |   2 +
+ src/fsck.fat.h       |  11 -
+ src/io.c             |   4 +-
+ src/linux/fd.h       | 383 ++++++++++++++++++++++++++++++
+ src/linux/fs.h       | 206 ++++++++++++++++
+ src/linux/hdreg.h    | 644 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/linux/magic.h    |  76 ++++++
+ src/linux/msdos_fs.h | 201 ++++++++++++++++
+ src/mkfs.fat.c       |  32 ++-
+ 13 files changed, 1603 insertions(+), 36 deletions(-)
+ create mode 100644 src/linux/fd.h
+ create mode 100644 src/linux/fs.h
+ create mode 100644 src/linux/hdreg.h
+ create mode 100644 src/linux/magic.h
+ create mode 100644 src/linux/msdos_fs.h
+
+diff --git a/Makefile b/Makefile
+index 3cbdb76..b86111d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -27,10 +27,16 @@ SBINDIR = $(PREFIX)/sbin
+ DOCDIR = $(PREFIX)/share/doc
+ MANDIR = $(PREFIX)/share/man
++UNAME_S := $(shell uname -s)
++ifeq ($(UNAME_S),Darwin)
++  CFLAGS += -D__osx__
++  LDLIBS += -liconv
++endif
++
+ #OPTFLAGS = -O2 -fomit-frame-pointer -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
+ OPTFLAGS = -O2 -fomit-frame-pointer -D_GNU_SOURCE $(shell getconf LFS_CFLAGS)
+ #WARNFLAGS = -Wall -pedantic -std=c99
+-WARNFLAGS = -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings
++WARNFLAGS = -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings -Wimplicit-function-declaration
+ DEBUGFLAGS = -g
+ CFLAGS += $(OPTFLAGS) $(WARNFLAGS) $(DEBUGFLAGS)
+@@ -62,7 +68,8 @@ install-man:
+       for MANPAGE in manpages/en/*; \
+       do \
+               SECTION="8"; \
+-              install -D -m 0644 $${MANPAGE} $(DESTDIR)/$(MANDIR)/man$${SECTION}/$$(basename $${MANPAGE}); \
++              mkdir -p $(DESTDIR)/$(MANDIR)/man$${SECTION}/; \
++              install -m 0644 $${MANPAGE} $(DESTDIR)/$(MANDIR)/man$${SECTION}/$$(basename $${MANPAGE}); \
+       done
+       for LANGUAGE in $(LANGUAGES); \
+@@ -70,7 +77,8 @@ install-man:
+               for MANPAGE in manpages/$${LANGUAGE}/*; \
+               do \
+                       SECTION="8"; \
+-                      install -D -m 0644 $${MANPAGE} $(DESTDIR)/$(MANDIR)/$${LANGUAGE}/man$${SECTION}/$$(basename $${MANPAGE} .$${LANGUAGE}.$${SECTION}).$${SECTION}; \
++                      mkdir -p $(DESTDIR)/$(MANDIR)/$${LANGUAGE}/man$${SECTION}/; \
++                      install -m 0644 $${MANPAGE} $(DESTDIR)/$(MANDIR)/$${LANGUAGE}/man$${SECTION}/$$(basename $${MANPAGE} .$${LANGUAGE}.$${SECTION}).$${SECTION}; \
+               done; \
+       done
+ install-symlinks: install-bin install-man
+@@ -127,7 +135,7 @@ uninstall-man:
+       for MANPAGE in manpages/en/*; \
+       do \
+               SECTION="8"; \
+-              rm -f $(DESTDIR)/$(MANDIR}/man$${SECTION}/$$(basename $${MANPAGE} .en.$${SECTION}).$${SECTION}; \
++              rm -f $(DESTDIR)/$(MANDIR)/man$${SECTION}/$$(basename $${MANPAGE} .en.$${SECTION}).$${SECTION}; \
+       done
+       for LANGUAGE in $(LANGUAGES); \
+diff --git a/src/boot.c b/src/boot.c
+index be7bfb7..0c8b273 100644
+--- a/src/boot.c
++++ b/src/boot.c
+@@ -31,6 +31,7 @@
+ #include <time.h>
+ #include "common.h"
++#include "linux/msdos_fs.h"
+ #include "fsck.fat.h"
+ #include "fat.h"
+ #include "io.h"
+diff --git a/src/common.h b/src/common.h
+index b127f63..e16c00c 100644
+--- a/src/common.h
++++ b/src/common.h
+@@ -20,11 +20,61 @@
+    can be found in /usr/share/common-licenses/GPL-3 file.
+ */
+-#include <asm/types.h>
+-
+ #ifndef _COMMON_H
+ #define _COMMON_H
++/* from linux/types.h */
++#if defined(__linux__)
++    #include <linux/types.h>
++#elif defined(__osx__)
++    #include <stdint.h>
++
++    typedef uint8_t __u8;
++    typedef uint16_t __u16;
++    typedef uint32_t __u32;
++    typedef uint64_t __u64;
++
++    typedef int16_t __le16;
++    typedef int32_t __le32;
++
++    /* from linux stdio.h */
++    #ifndef loff_t
++        typedef long long loff_t;
++    #endif /* loff_t */
++
++    #ifndef off64_t
++        #ifdef _LP64
++            typedef off_t off64_t;
++        #else
++            typedef __longlong_t off64_t;
++        #endif /* _LP64 */
++    #endif /* off64_t */
++
++    /* from endian.h */
++    #if defined(__APPLE__) && defined(__MACH__)
++        #include <libkern/OSByteOrder.h>
++
++        #define htobe16(x) OSSwapHostToBigInt16(x)
++        #define htole16(x) OSSwapHostToLittleInt16(x)
++        #define be16toh(x) OSSwapBigToHostInt16(x)
++        #define le16toh(x) OSSwapLittleToHostInt16(x)
++
++        #define htobe32(x) OSSwapHostToBigInt32(x)
++        #define htole32(x) OSSwapHostToLittleInt32(x)
++        #define be32toh(x) OSSwapBigToHostInt32(x)
++        #define le32toh(x) OSSwapLittleToHostInt32(x)
++
++        #define htobe64(x) OSSwapHostToBigInt64(x)
++        #define htole64(x) OSSwapHostToLittleInt64(x)
++        #define be64toh(x) OSSwapBigToHostInt64(x)
++        #define le64toh(x) OSSwapLittleToHostInt64(x)
++
++        #ifndef lseek64
++            #define lseek64 lseek
++        #endif /* lseek64 */
++    #endif /* __APPLE__ && __MACH__ */
++#endif
++
+ void die(const char *msg, ...) __attribute((noreturn));
+ /* Displays a prinf-style message and terminates the program. */
+diff --git a/src/file.c b/src/file.c
+index 30adcde..1c1a5f0 100644
+--- a/src/file.c
++++ b/src/file.c
+@@ -30,15 +30,8 @@
+ #include <ctype.h>
+ #include <unistd.h>
+-#define _LINUX_STAT_H         /* hack to avoid inclusion of <linux/stat.h> */
+-#define _LINUX_STRING_H_      /* hack to avoid inclusion of <linux/string.h> */
+-#define _LINUX_FS_H           /* hack to avoid inclusion of <linux/fs.h> */
+-
+-#include <asm/types.h>
+-
+-#include <linux/msdos_fs.h>
+-
+ #include "common.h"
++#include "linux/msdos_fs.h"
+ #include "file.h"
+ #include "charconv.h"
+diff --git a/src/file.h b/src/file.h
+index 3adfc96..f5dec16 100644
+--- a/src/file.h
++++ b/src/file.h
+@@ -23,6 +23,8 @@
+ #ifndef _FILE_H
+ #define _FILE_H
++#include "linux/msdos_fs.h"
++
+ typedef enum { fdt_none, fdt_drop, fdt_undelete } FD_TYPE;
+ typedef struct _fptr {
+diff --git a/src/fsck.fat.h b/src/fsck.fat.h
+index e5ade5b..274820a 100644
+--- a/src/fsck.fat.h
++++ b/src/fsck.fat.h
+@@ -28,19 +28,8 @@
+ #define _DOSFSCK_H
+ #include <fcntl.h>
+-#include <sys/types.h>
+-#define _LINUX_STAT_H         /* hack to avoid inclusion of <linux/stat.h> */
+-#define _LINUX_STRING_H_      /* hack to avoid inclusion of <linux/string.h> */
+-#define _LINUX_FS_H           /* hack to avoid inclusion of <linux/fs.h> */
+-
+-#include <asm/types.h>
+-#include <asm/byteorder.h>
+-
+-#include <linux/msdos_fs.h>
+-
+ #include <stddef.h>
+ #include <stdint.h>
+-#include <endian.h>
+ #define VFAT_LN_ATTR (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
+diff --git a/src/io.c b/src/io.c
+index 3755ba5..fa96b62 100644
+--- a/src/io.c
++++ b/src/io.c
+@@ -40,10 +40,10 @@
+ #include <sys/ioctl.h>
+ #include <errno.h>
+ #include <fcntl.h>
+-#include <linux/fd.h>
+-#include "fsck.fat.h"
++#include "linux/fd.h"
+ #include "common.h"
++#include "fsck.fat.h"
+ #include "io.h"
+ typedef struct _change {
+diff --git a/src/linux/fd.h b/src/linux/fd.h
+new file mode 100644
+index 0000000..ffe33a6
+--- /dev/null
++++ b/src/linux/fd.h
+@@ -0,0 +1,383 @@
++#ifndef _LINUX_FD_H
++#define _LINUX_FD_H
++
++#ifdef __linux__
++#include <linux/ioctl.h>
++#endif
++
++/* New file layout: Now the ioctl definitions immediately follow the
++ * definitions of the structures that they use */
++
++/*
++ * Geometry
++ */
++struct floppy_struct {
++      unsigned int    size,           /* nr of sectors total */
++                      sect,           /* sectors per track */
++                      head,           /* nr of heads */
++                      track,          /* nr of tracks */
++                      stretch;        /* bit 0 !=0 means double track steps */
++                                      /* bit 1 != 0 means swap sides */
++                                      /* bits 2..9 give the first sector */
++                                      /*  number (the LSB is flipped) */
++#define FD_STRETCH 1
++#define FD_SWAPSIDES 2
++#define FD_ZEROBASED 4
++#define FD_SECTBASEMASK 0x3FC
++#define FD_MKSECTBASE(s) (((s) ^ 1) << 2)
++#define FD_SECTBASE(floppy) ((((floppy)->stretch & FD_SECTBASEMASK) >> 2) ^ 1)
++
++      unsigned char   gap,            /* gap1 size */
++
++                      rate,           /* data rate. |= 0x40 for perpendicular */
++#define FD_2M 0x4
++#define FD_SIZECODEMASK 0x38
++#define FD_SIZECODE(floppy) (((((floppy)->rate&FD_SIZECODEMASK)>> 3)+ 2) %8)
++#define FD_SECTSIZE(floppy) ( (floppy)->rate & FD_2M ? \
++                           512 : 128 << FD_SIZECODE(floppy) )
++#define FD_PERP 0x40
++
++                      spec1,          /* stepping rate, head unload time */
++                      fmt_gap;        /* gap2 size */
++      const char      * name; /* used only for predefined formats */
++};
++
++
++/* commands needing write access have 0x40 set */
++/* commands needing super user access have 0x80 set */
++
++#define FDCLRPRM _IO(2, 0x41)
++/* clear user-defined parameters */
++
++#define FDSETPRM _IOW(2, 0x42, struct floppy_struct) 
++#define FDSETMEDIAPRM FDSETPRM
++/* set user-defined parameters for current media */
++
++#define FDDEFPRM _IOW(2, 0x43, struct floppy_struct) 
++#define FDGETPRM _IOR(2, 0x04, struct floppy_struct)
++#define FDDEFMEDIAPRM FDDEFPRM
++#define FDGETMEDIAPRM FDGETPRM
++/* set/get disk parameters */
++
++
++#define       FDMSGON  _IO(2,0x45)
++#define       FDMSGOFF _IO(2,0x46)
++/* issue/don't issue kernel messages on media type change */
++
++
++/* 
++ * Formatting (obsolete)
++ */
++#define FD_FILL_BYTE 0xF6 /* format fill byte. */
++
++struct format_descr {
++      unsigned int device,head,track;
++};
++
++#define FDFMTBEG _IO(2,0x47)
++/* begin formatting a disk */
++#define       FDFMTTRK _IOW(2,0x48, struct format_descr)
++/* format the specified track */
++#define FDFMTEND _IO(2,0x49)
++/* end formatting a disk */
++
++
++/*
++ * Error thresholds
++ */
++struct floppy_max_errors {
++      unsigned int
++        abort,      /* number of errors to be reached before aborting */
++        read_track, /* maximal number of errors permitted to read an
++                     * entire track at once */
++        reset,      /* maximal number of errors before a reset is tried */
++        recal,      /* maximal number of errors before a recalibrate is
++                     * tried */
++
++        /*
++         * Threshold for reporting FDC errors to the console.
++         * Setting this to zero may flood your screen when using
++         * ultra cheap floppies ;-)
++         */
++        reporting;
++
++};
++
++#define FDSETEMSGTRESH        _IO(2,0x4a)
++/* set fdc error reporting threshold */
++
++#define FDFLUSH  _IO(2,0x4b)
++/* flush buffers for media; either for verifying media, or for
++ * handling a media change without closing the file descriptor */
++
++#define FDSETMAXERRS _IOW(2, 0x4c, struct floppy_max_errors)
++#define FDGETMAXERRS _IOR(2, 0x0e, struct floppy_max_errors)
++/* set/get abortion and read_track threshold. See also floppy_drive_params
++ * structure */
++
++
++typedef char floppy_drive_name[16];
++#define FDGETDRVTYP _IOR(2, 0x0f, floppy_drive_name)
++/* get drive type: 5 1/4 or 3 1/2 */
++
++
++/*
++ * Drive parameters (user modifiable)
++ */
++struct floppy_drive_params {
++      signed char cmos;               /* CMOS type */
++      
++      /* Spec2 is (HLD<<1 | ND), where HLD is head load time (1=2ms, 2=4 ms 
++       * etc) and ND is set means no DMA. Hardcoded to 6 (HLD=6ms, use DMA).
++       */
++      unsigned long max_dtr;          /* Step rate, usec */
++      unsigned long hlt;              /* Head load/settle time, msec */
++      unsigned long hut;              /* Head unload time (remnant of 
++                                       * 8" drives) */
++      unsigned long srt;              /* Step rate, usec */
++
++      unsigned long spinup;           /* time needed for spinup (expressed
++                                       * in jiffies) */
++      unsigned long spindown;         /* timeout needed for spindown */
++      unsigned char spindown_offset;  /* decides in which position the disk
++                                       * will stop */
++      unsigned char select_delay;     /* delay to wait after select */
++      unsigned char rps;              /* rotations per second */
++      unsigned char tracks;           /* maximum number of tracks */
++      unsigned long timeout;          /* timeout for interrupt requests */
++      
++      unsigned char interleave_sect;  /* if there are more sectors, use 
++                                       * interleave */
++      
++      struct floppy_max_errors max_errors;
++      
++      char flags;                     /* various flags, including ftd_msg */
++/*
++ * Announce successful media type detection and media information loss after
++ * disk changes.
++ * Also used to enable/disable printing of overrun warnings.
++ */
++
++#define FTD_MSG 0x10
++#define FD_BROKEN_DCL 0x20
++#define FD_DEBUG 0x02
++#define FD_SILENT_DCL_CLEAR 0x4
++#define FD_INVERTED_DCL 0x80 /* must be 0x80, because of hardware 
++                              considerations */
++
++      char read_track;                /* use readtrack during probing? */
++
++/*
++ * Auto-detection. Each drive type has eight formats which are
++ * used in succession to try to read the disk. If the FDC cannot lock onto
++ * the disk, the next format is tried. This uses the variable 'probing'.
++ */
++      short autodetect[8];            /* autodetected formats */
++      
++      int checkfreq; /* how often should the drive be checked for disk 
++                      * changes */
++      int native_format; /* native format of this drive */
++};
++
++enum {
++      FD_NEED_TWADDLE_BIT,    /* more magic */
++      FD_VERIFY_BIT,          /* inquire for write protection */
++      FD_DISK_NEWCHANGE_BIT,  /* change detected, and no action undertaken yet
++                               * to clear media change status */
++      FD_UNUSED_BIT,
++      FD_DISK_CHANGED_BIT,    /* disk has been changed since last i/o */
++      FD_DISK_WRITABLE_BIT    /* disk is writable */
++};
++
++#define FDSETDRVPRM _IOW(2, 0x90, struct floppy_drive_params)
++#define FDGETDRVPRM _IOR(2, 0x11, struct floppy_drive_params)
++/* set/get drive parameters */
++
++
++/*
++ * Current drive state (not directly modifiable by user, readonly)
++ */
++struct floppy_drive_struct {
++      unsigned long flags;
++/* values for these flags */
++#define FD_NEED_TWADDLE (1 << FD_NEED_TWADDLE_BIT)
++#define FD_VERIFY (1 << FD_VERIFY_BIT)
++#define FD_DISK_NEWCHANGE (1 << FD_DISK_NEWCHANGE_BIT)
++#define FD_DISK_CHANGED (1 << FD_DISK_CHANGED_BIT)
++#define FD_DISK_WRITABLE (1 << FD_DISK_WRITABLE_BIT)
++
++      unsigned long spinup_date;
++      unsigned long select_date;
++      unsigned long first_read_date;
++      short probed_format;
++      short track; /* current track */
++      short maxblock; /* id of highest block read */
++      short maxtrack; /* id of highest half track read */
++      int generation; /* how many diskchanges? */
++
++/*
++ * (User-provided) media information is _not_ discarded after a media change
++ * if the corresponding keep_data flag is non-zero. Positive values are
++ * decremented after each probe.
++ */
++      int keep_data;
++      
++      /* Prevent "aliased" accesses. */
++      int fd_ref;
++      int fd_device;
++      unsigned long last_checked; /* when was the drive last checked for a disk 
++                         * change? */
++      
++      char *dmabuf;
++      int bufblocks;
++};
++
++#define FDGETDRVSTAT _IOR(2, 0x12, struct floppy_drive_struct)
++#define FDPOLLDRVSTAT _IOR(2, 0x13, struct floppy_drive_struct)
++/* get drive state: GET returns the cached state, POLL polls for new state */
++
++
++/*
++ * reset FDC
++ */
++enum reset_mode {
++      FD_RESET_IF_NEEDED,     /* reset only if the reset flags is set */
++      FD_RESET_IF_RAWCMD,     /* obsolete */
++      FD_RESET_ALWAYS         /* reset always */
++};
++#define FDRESET _IO(2, 0x54)
++
++
++/*
++ * FDC state
++ */
++struct floppy_fdc_state {     
++      int spec1;              /* spec1 value last used */
++      int spec2;              /* spec2 value last used */
++      int dtr;
++      unsigned char version;  /* FDC version code */
++      unsigned char dor;
++      unsigned long address;  /* io address */
++      unsigned int rawcmd:2;
++      unsigned int reset:1;
++      unsigned int need_configure:1;
++      unsigned int perp_mode:2;
++      unsigned int has_fifo:1;
++      unsigned int driver_version;    /* version code for floppy driver */
++#define FD_DRIVER_VERSION 0x100
++/* user programs using the floppy API should use floppy_fdc_state to
++ * get the version number of the floppy driver that they are running
++ * on. If this version number is bigger than the one compiled into the
++ * user program (the FD_DRIVER_VERSION define), it should be prepared
++ * to bigger structures
++ */
++
++      unsigned char track[4];
++      /* Position of the heads of the 4 units attached to this FDC,
++       * as stored on the FDC. In the future, the position as stored
++       * on the FDC might not agree with the actual physical
++       * position of these drive heads. By allowing such
++       * disagreement, it will be possible to reset the FDC without
++       * incurring the expensive cost of repositioning all heads.
++       * Right now, these positions are hard wired to 0. */
++
++};
++
++#define FDGETFDCSTAT _IOR(2, 0x15, struct floppy_fdc_state)
++
++
++/*
++ * Asynchronous Write error tracking
++ */
++struct floppy_write_errors {
++      /* Write error logging.
++       *
++       * These fields can be cleared with the FDWERRORCLR ioctl.
++       * Only writes that were attempted but failed due to a physical media
++       * error are logged.  write(2) calls that fail and return an error code
++       * to the user process are not counted.
++       */
++
++      unsigned int write_errors;  /* number of physical write errors 
++                                   * encountered */
++      
++      /* position of first and last write errors */
++      unsigned long first_error_sector;
++      int           first_error_generation;
++      unsigned long last_error_sector;
++      int           last_error_generation;
++      
++      unsigned int badness; /* highest retry count for a read or write 
++                             * operation */
++};
++
++#define FDWERRORCLR  _IO(2, 0x56)
++/* clear write error and badness information */
++#define FDWERRORGET  _IOR(2, 0x17, struct floppy_write_errors)
++/* get write error and badness information */
++
++
++/*
++ * Raw commands
++ */
++/* new interface flag: now we can do them in batches */
++#define FDHAVEBATCHEDRAWCMD
++
++struct floppy_raw_cmd {
++      unsigned int flags;
++#define FD_RAW_READ 1
++#define FD_RAW_WRITE 2
++#define FD_RAW_NO_MOTOR 4
++#define FD_RAW_DISK_CHANGE 4 /* out: disk change flag was set */
++#define FD_RAW_INTR 8    /* wait for an interrupt */
++#define FD_RAW_SPIN 0x10 /* spin up the disk for this command */
++#define FD_RAW_NO_MOTOR_AFTER 0x20 /* switch the motor off after command 
++                                  * completion */
++#define FD_RAW_NEED_DISK 0x40  /* this command needs a disk to be present */
++#define FD_RAW_NEED_SEEK 0x80  /* this command uses an implied seek (soft) */
++
++/* more "in" flags */
++#define FD_RAW_MORE 0x100  /* more records follow */
++#define FD_RAW_STOP_IF_FAILURE 0x200 /* stop if we encounter a failure */
++#define FD_RAW_STOP_IF_SUCCESS 0x400 /* stop if command successful */
++#define FD_RAW_SOFTFAILURE 0x800 /* consider the return value for failure
++                                * detection too */
++
++/* more "out" flags */
++#define FD_RAW_FAILURE 0x10000 /* command sent to fdc, fdc returned error */
++#define FD_RAW_HARDFAILURE 0x20000 /* fdc had to be reset, or timed out */
++
++      void *data;
++      char *kernel_data; /* location of data buffer in the kernel */
++      struct floppy_raw_cmd *next; /* used for chaining of raw cmd's 
++                                    * within the kernel */
++      long length; /* in: length of dma transfer. out: remaining bytes */
++      long phys_length; /* physical length, if different from dma length */
++      int buffer_length; /* length of allocated buffer */
++
++      unsigned char rate;
++      unsigned char cmd_count;
++      unsigned char cmd[16];
++      unsigned char reply_count;
++      unsigned char reply[16];
++      int track;
++      int resultcode;
++
++      int reserved1;
++      int reserved2;
++};
++
++#define FDRAWCMD _IO(2, 0x58)
++/* send a raw command to the fdc. Structure size not included, because of
++ * batches */
++
++#define FDTWADDLE _IO(2, 0x59)
++/* flicker motor-on bit before reading a sector. Experimental */
++
++
++#define FDEJECT _IO(2, 0x5a)
++/* eject the disk */
++
++
++
++#endif /* _LINUX_FD_H */
+diff --git a/src/linux/fs.h b/src/linux/fs.h
+new file mode 100644
+index 0000000..8639ce5
+--- /dev/null
++++ b/src/linux/fs.h
+@@ -0,0 +1,206 @@
++#ifndef _LINUX_FS_H
++#define _LINUX_FS_H
++
++/*
++ * This file has definitions for some important file table
++ * structures etc.
++ */
++
++#ifdef __linux__
++#include <linux/limits.h>
++#include <linux/ioctl.h>
++#include <linux/types.h>
++#endif
++
++/*
++ * It's silly to have NR_OPEN bigger than NR_FILE, but you can change
++ * the file limit at runtime and only root can increase the per-process
++ * nr_file rlimit, so it's safe to set up a ridiculously high absolute
++ * upper limit on files-per-process.
++ *
++ * Some programs (notably those using select()) may have to be 
++ * recompiled to take full advantage of the new limits..  
++ */
++
++/* Fixed constants first: */
++#undef NR_OPEN
++#define INR_OPEN_CUR 1024     /* Initial setting for nfile rlimits */
++#define INR_OPEN_MAX 4096     /* Hard limit for nfile rlimits */
++
++#define BLOCK_SIZE_BITS 10
++#define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
++
++#define SEEK_SET      0       /* seek relative to beginning of file */
++#define SEEK_CUR      1       /* seek relative to current file position */
++#define SEEK_END      2       /* seek relative to end of file */
++#define SEEK_DATA     3       /* seek to the next data */
++#define SEEK_HOLE     4       /* seek to the next hole */
++#define SEEK_MAX      SEEK_HOLE
++
++struct fstrim_range {
++      __u64 start;
++      __u64 len;
++      __u64 minlen;
++};
++
++/* And dynamically-tunable limits and defaults: */
++struct files_stat_struct {
++      unsigned long nr_files;         /* read only */
++      unsigned long nr_free_files;    /* read only */
++      unsigned long max_files;                /* tunable */
++};
++
++struct inodes_stat_t {
++      long nr_inodes;
++      long nr_unused;
++      long dummy[5];          /* padding for sysctl ABI compatibility */
++};
++
++
++#define NR_FILE  8192 /* this can well be larger on a larger system */
++
++
++/*
++ * These are the fs-independent mount-flags: up to 32 flags are supported
++ */
++#define MS_RDONLY      1      /* Mount read-only */
++#define MS_NOSUID      2      /* Ignore suid and sgid bits */
++#define MS_NODEV       4      /* Disallow access to device special files */
++#define MS_NOEXEC      8      /* Disallow program execution */
++#define MS_SYNCHRONOUS        16      /* Writes are synced at once */
++#define MS_REMOUNT    32      /* Alter flags of a mounted FS */
++#define MS_MANDLOCK   64      /* Allow mandatory locks on an FS */
++#define MS_DIRSYNC    128     /* Directory modifications are synchronous */
++#define MS_NOATIME    1024    /* Do not update access times. */
++#define MS_NODIRATIME 2048    /* Do not update directory access times */
++#define MS_BIND               4096
++#define MS_MOVE               8192
++#define MS_REC                16384
++#define MS_VERBOSE    32768   /* War is peace. Verbosity is silence.
++                                 MS_VERBOSE is deprecated. */
++#define MS_SILENT     32768
++#define MS_POSIXACL   (1<<16) /* VFS does not apply the umask */
++#define MS_UNBINDABLE (1<<17) /* change to unbindable */
++#define MS_PRIVATE    (1<<18) /* change to private */
++#define MS_SLAVE      (1<<19) /* change to slave */
++#define MS_SHARED     (1<<20) /* change to shared */
++#define MS_RELATIME   (1<<21) /* Update atime relative to mtime/ctime. */
++#define MS_KERNMOUNT  (1<<22) /* this is a kern_mount call */
++#define MS_I_VERSION  (1<<23) /* Update inode I_version field */
++#define MS_STRICTATIME        (1<<24) /* Always perform atime updates */
++
++/* These sb flags are internal to the kernel */
++#define MS_NOSEC      (1<<28)
++#define MS_BORN               (1<<29)
++#define MS_ACTIVE     (1<<30)
++#define MS_NOUSER     (1<<31)
++
++/*
++ * Superblock flags that can be altered by MS_REMOUNT
++ */
++#define MS_RMT_MASK   (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION)
++
++/*
++ * Old magic mount flag and mask
++ */
++#define MS_MGC_VAL 0xC0ED0000
++#define MS_MGC_MSK 0xffff0000
++
++/* the read-only stuff doesn't really belong here, but any other place is
++   probably as bad and I don't want to create yet another include file. */
++
++#define BLKROSET   _IO(0x12,93)       /* set device read-only (0 = read-write) */
++#define BLKROGET   _IO(0x12,94)       /* get read-only status (0 = read_write) */
++#define BLKRRPART  _IO(0x12,95)       /* re-read partition table */
++#define BLKGETSIZE _IO(0x12,96)       /* return device size /512 (long *arg) */
++#define BLKFLSBUF  _IO(0x12,97)       /* flush buffer cache */
++#define BLKRASET   _IO(0x12,98)       /* set read ahead for block device */
++#define BLKRAGET   _IO(0x12,99)       /* get current read ahead setting */
++#define BLKFRASET  _IO(0x12,100)/* set filesystem (mm/filemap.c) read-ahead */
++#define BLKFRAGET  _IO(0x12,101)/* get filesystem (mm/filemap.c) read-ahead */
++#define BLKSECTSET _IO(0x12,102)/* set max sectors per request (ll_rw_blk.c) */
++#define BLKSECTGET _IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
++#define BLKSSZGET  _IO(0x12,104)/* get block device sector size */
++#if 0
++#define BLKPG      _IO(0x12,105)/* See blkpg.h */
++
++/* Some people are morons.  Do not use sizeof! */
++
++#define BLKELVGET  _IOR(0x12,106,size_t)/* elevator get */
++#define BLKELVSET  _IOW(0x12,107,size_t)/* elevator set */
++/* This was here just to show that the number is taken -
++   probably all these _IO(0x12,*) ioctls should be moved to blkpg.h. */
++#endif
++/* A jump here: 108-111 have been used for various private purposes. */
++#define BLKBSZGET  _IOR(0x12,112,size_t)
++#define BLKBSZSET  _IOW(0x12,113,size_t)
++#define BLKGETSIZE64 _IOR(0x12,114,size_t)    /* return device size in bytes (u64 *arg) */
++#define BLKTRACESETUP _IOWR(0x12,115,struct blk_user_trace_setup)
++#define BLKTRACESTART _IO(0x12,116)
++#define BLKTRACESTOP _IO(0x12,117)
++#define BLKTRACETEARDOWN _IO(0x12,118)
++#define BLKDISCARD _IO(0x12,119)
++#define BLKIOMIN _IO(0x12,120)
++#define BLKIOOPT _IO(0x12,121)
++#define BLKALIGNOFF _IO(0x12,122)
++#define BLKPBSZGET _IO(0x12,123)
++#define BLKDISCARDZEROES _IO(0x12,124)
++#define BLKSECDISCARD _IO(0x12,125)
++#define BLKROTATIONAL _IO(0x12,126)
++#define BLKZEROOUT _IO(0x12,127)
++
++#define BMAP_IOCTL 1          /* obsolete - kept for compatibility */
++#define FIBMAP           _IO(0x00,1)  /* bmap access */
++#define FIGETBSZ   _IO(0x00,2)        /* get the block size used for bmap */
++#define FIFREEZE      _IOWR('X', 119, int)    /* Freeze */
++#define FITHAW                _IOWR('X', 120, int)    /* Thaw */
++#define FITRIM                _IOWR('X', 121, struct fstrim_range)    /* Trim */
++
++#define       FS_IOC_GETFLAGS                 _IOR('f', 1, long)
++#define       FS_IOC_SETFLAGS                 _IOW('f', 2, long)
++#define       FS_IOC_GETVERSION               _IOR('v', 1, long)
++#define       FS_IOC_SETVERSION               _IOW('v', 2, long)
++#define FS_IOC_FIEMAP                 _IOWR('f', 11, struct fiemap)
++#define FS_IOC32_GETFLAGS             _IOR('f', 1, int)
++#define FS_IOC32_SETFLAGS             _IOW('f', 2, int)
++#define FS_IOC32_GETVERSION           _IOR('v', 1, int)
++#define FS_IOC32_SETVERSION           _IOW('v', 2, int)
++
++/*
++ * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS)
++ */
++#define       FS_SECRM_FL                     0x00000001 /* Secure deletion */
++#define       FS_UNRM_FL                      0x00000002 /* Undelete */
++#define       FS_COMPR_FL                     0x00000004 /* Compress file */
++#define FS_SYNC_FL                    0x00000008 /* Synchronous updates */
++#define FS_IMMUTABLE_FL                       0x00000010 /* Immutable file */
++#define FS_APPEND_FL                  0x00000020 /* writes to file may only append */
++#define FS_NODUMP_FL                  0x00000040 /* do not dump file */
++#define FS_NOATIME_FL                 0x00000080 /* do not update atime */
++/* Reserved for compression usage... */
++#define FS_DIRTY_FL                   0x00000100
++#define FS_COMPRBLK_FL                        0x00000200 /* One or more compressed clusters */
++#define FS_NOCOMP_FL                  0x00000400 /* Don't compress */
++#define FS_ECOMPR_FL                  0x00000800 /* Compression error */
++/* End compression flags --- maybe not all used */
++#define FS_BTREE_FL                   0x00001000 /* btree format dir */
++#define FS_INDEX_FL                   0x00001000 /* hash-indexed directory */
++#define FS_IMAGIC_FL                  0x00002000 /* AFS directory */
++#define FS_JOURNAL_DATA_FL            0x00004000 /* Reserved for ext3 */
++#define FS_NOTAIL_FL                  0x00008000 /* file tail should not be merged */
++#define FS_DIRSYNC_FL                 0x00010000 /* dirsync behaviour (directories only) */
++#define FS_TOPDIR_FL                  0x00020000 /* Top of directory hierarchies*/
++#define FS_EXTENT_FL                  0x00080000 /* Extents */
++#define FS_DIRECTIO_FL                        0x00100000 /* Use direct i/o */
++#define FS_NOCOW_FL                   0x00800000 /* Do not cow file */
++#define FS_RESERVED_FL                        0x80000000 /* reserved for ext2 lib */
++
++#define FS_FL_USER_VISIBLE            0x0003DFFF /* User visible flags */
++#define FS_FL_USER_MODIFIABLE         0x000380FF /* User modifiable flags */
++
++
++#define SYNC_FILE_RANGE_WAIT_BEFORE   1
++#define SYNC_FILE_RANGE_WRITE         2
++#define SYNC_FILE_RANGE_WAIT_AFTER    4
++
++#endif /* _LINUX_FS_H */
+diff --git a/src/linux/hdreg.h b/src/linux/hdreg.h
+new file mode 100644
+index 0000000..5f23b03
+--- /dev/null
++++ b/src/linux/hdreg.h
+@@ -0,0 +1,644 @@
++#ifndef _LINUX_HDREG_H
++#define _LINUX_HDREG_H
++
++#ifdef __linux__
++#include <linux/types.h>
++#endif
++
++/*
++ * Command Header sizes for IOCTL commands
++ */
++
++#define HDIO_DRIVE_CMD_HDR_SIZE               (4 * sizeof(__u8))
++#define HDIO_DRIVE_HOB_HDR_SIZE               (8 * sizeof(__u8))
++#define HDIO_DRIVE_TASK_HDR_SIZE      (8 * sizeof(__u8))
++
++#define IDE_DRIVE_TASK_NO_DATA                0
++#define IDE_DRIVE_TASK_INVALID                -1
++#define IDE_DRIVE_TASK_SET_XFER               1
++#define IDE_DRIVE_TASK_IN             2
++#define IDE_DRIVE_TASK_OUT            3
++#define IDE_DRIVE_TASK_RAW_WRITE      4
++
++/*
++ * Define standard taskfile in/out register
++ */
++#define IDE_TASKFILE_STD_IN_FLAGS     0xFE
++#define IDE_HOB_STD_IN_FLAGS          0x3C
++#define IDE_TASKFILE_STD_OUT_FLAGS    0xFE
++#define IDE_HOB_STD_OUT_FLAGS         0x3C
++
++typedef unsigned char task_ioreg_t;
++typedef unsigned long sata_ioreg_t;
++
++typedef union ide_reg_valid_s {
++      unsigned all                            : 16;
++      struct {
++              unsigned data                   : 1;
++              unsigned error_feature          : 1;
++              unsigned sector                 : 1;
++              unsigned nsector                : 1;
++              unsigned lcyl                   : 1;
++              unsigned hcyl                   : 1;
++              unsigned select                 : 1;
++              unsigned status_command         : 1;
++
++              unsigned data_hob               : 1;
++              unsigned error_feature_hob      : 1;
++              unsigned sector_hob             : 1;
++              unsigned nsector_hob            : 1;
++              unsigned lcyl_hob               : 1;
++              unsigned hcyl_hob               : 1;
++              unsigned select_hob             : 1;
++              unsigned control_hob            : 1;
++      } b;
++} ide_reg_valid_t;
++
++typedef struct ide_task_request_s {
++      __u8            io_ports[8];
++      __u8            hob_ports[8]; /* bytes 6 and 7 are unused */
++      ide_reg_valid_t out_flags;
++      ide_reg_valid_t in_flags;
++      int             data_phase;
++      int             req_cmd;
++      unsigned long   out_size;
++      unsigned long   in_size;
++} ide_task_request_t;
++
++typedef struct ide_ioctl_request_s {
++      ide_task_request_t      *task_request;
++      unsigned char           *out_buffer;
++      unsigned char           *in_buffer;
++} ide_ioctl_request_t;
++
++struct hd_drive_cmd_hdr {
++      __u8 command;
++      __u8 sector_number;
++      __u8 feature;
++      __u8 sector_count;
++};
++
++typedef struct hd_drive_task_hdr {
++      __u8 data;
++      __u8 feature;
++      __u8 sector_count;
++      __u8 sector_number;
++      __u8 low_cylinder;
++      __u8 high_cylinder;
++      __u8 device_head;
++      __u8 command;
++} task_struct_t;
++
++typedef struct hd_drive_hob_hdr {
++      __u8 data;
++      __u8 feature;
++      __u8 sector_count;
++      __u8 sector_number;
++      __u8 low_cylinder;
++      __u8 high_cylinder;
++      __u8 device_head;
++      __u8 control;
++} hob_struct_t;
++
++#define TASKFILE_NO_DATA              0x0000
++
++#define TASKFILE_IN                   0x0001
++#define TASKFILE_MULTI_IN             0x0002
++
++#define TASKFILE_OUT                  0x0004
++#define TASKFILE_MULTI_OUT            0x0008
++#define TASKFILE_IN_OUT                       0x0010
++
++#define TASKFILE_IN_DMA                       0x0020
++#define TASKFILE_OUT_DMA              0x0040
++#define TASKFILE_IN_DMAQ              0x0080
++#define TASKFILE_OUT_DMAQ             0x0100
++
++#define TASKFILE_P_IN                 0x0200
++#define TASKFILE_P_OUT                        0x0400
++#define TASKFILE_P_IN_DMA             0x0800
++#define TASKFILE_P_OUT_DMA            0x1000
++#define TASKFILE_P_IN_DMAQ            0x2000
++#define TASKFILE_P_OUT_DMAQ           0x4000
++#define TASKFILE_48                   0x8000
++#define TASKFILE_INVALID              0x7fff
++
++/* ATA/ATAPI Commands pre T13 Spec */
++#define WIN_NOP                               0x00
++/*
++ *    0x01->0x02 Reserved
++ */
++#define CFA_REQ_EXT_ERROR_CODE                0x03 /* CFA Request Extended Error Code */
++/*
++ *    0x04->0x07 Reserved
++ */
++#define WIN_SRST                      0x08 /* ATAPI soft reset command */
++#define WIN_DEVICE_RESET              0x08
++/*
++ *    0x09->0x0F Reserved
++ */
++#define WIN_RECAL                     0x10
++#define WIN_RESTORE                   WIN_RECAL
++/*
++ *    0x10->0x1F Reserved
++ */
++#define WIN_READ                      0x20 /* 28-Bit */
++#define WIN_READ_ONCE                 0x21 /* 28-Bit without retries */
++#define WIN_READ_LONG                 0x22 /* 28-Bit */
++#define WIN_READ_LONG_ONCE            0x23 /* 28-Bit without retries */
++#define WIN_READ_EXT                  0x24 /* 48-Bit */
++#define WIN_READDMA_EXT                       0x25 /* 48-Bit */
++#define WIN_READDMA_QUEUED_EXT                0x26 /* 48-Bit */
++#define WIN_READ_NATIVE_MAX_EXT               0x27 /* 48-Bit */
++/*
++ *    0x28
++ */
++#define WIN_MULTREAD_EXT              0x29 /* 48-Bit */
++/*
++ *    0x2A->0x2F Reserved
++ */
++#define WIN_WRITE                     0x30 /* 28-Bit */
++#define WIN_WRITE_ONCE                        0x31 /* 28-Bit without retries */
++#define WIN_WRITE_LONG                        0x32 /* 28-Bit */
++#define WIN_WRITE_LONG_ONCE           0x33 /* 28-Bit without retries */
++#define WIN_WRITE_EXT                 0x34 /* 48-Bit */
++#define WIN_WRITEDMA_EXT              0x35 /* 48-Bit */
++#define WIN_WRITEDMA_QUEUED_EXT               0x36 /* 48-Bit */
++#define WIN_SET_MAX_EXT                       0x37 /* 48-Bit */
++#define CFA_WRITE_SECT_WO_ERASE               0x38 /* CFA Write Sectors without erase */
++#define WIN_MULTWRITE_EXT             0x39 /* 48-Bit */
++/*
++ *    0x3A->0x3B Reserved
++ */
++#define WIN_WRITE_VERIFY              0x3C /* 28-Bit */
++/*
++ *    0x3D->0x3F Reserved
++ */
++#define WIN_VERIFY                    0x40 /* 28-Bit - Read Verify Sectors */
++#define WIN_VERIFY_ONCE                       0x41 /* 28-Bit - without retries */
++#define WIN_VERIFY_EXT                        0x42 /* 48-Bit */
++/*
++ *    0x43->0x4F Reserved
++ */
++#define WIN_FORMAT                    0x50
++/*
++ *    0x51->0x5F Reserved
++ */
++#define WIN_INIT                      0x60
++/*
++ *    0x61->0x5F Reserved
++ */
++#define WIN_SEEK                      0x70 /* 0x70-0x7F Reserved */
++
++#define CFA_TRANSLATE_SECTOR          0x87 /* CFA Translate Sector */
++#define WIN_DIAGNOSE                  0x90
++#define WIN_SPECIFY                   0x91 /* set drive geometry translation */
++#define WIN_DOWNLOAD_MICROCODE                0x92
++#define WIN_STANDBYNOW2                       0x94
++#define WIN_STANDBY2                  0x96
++#define WIN_SETIDLE2                  0x97
++#define WIN_CHECKPOWERMODE2           0x98
++#define WIN_SLEEPNOW2                 0x99
++/*
++ *    0x9A VENDOR
++ */
++#define WIN_PACKETCMD                 0xA0 /* Send a packet command. */
++#define WIN_PIDENTIFY                 0xA1 /* identify ATAPI device   */
++#define WIN_QUEUED_SERVICE            0xA2
++#define WIN_SMART                     0xB0 /* self-monitoring and reporting */
++#define CFA_ERASE_SECTORS             0xC0
++#define WIN_MULTREAD                  0xC4 /* read sectors using multiple mode*/
++#define WIN_MULTWRITE                 0xC5 /* write sectors using multiple mode */
++#define WIN_SETMULT                   0xC6 /* enable/disable multiple mode */
++#define WIN_READDMA_QUEUED            0xC7 /* read sectors using Queued DMA transfers */
++#define WIN_READDMA                   0xC8 /* read sectors using DMA transfers */
++#define WIN_READDMA_ONCE              0xC9 /* 28-Bit - without retries */
++#define WIN_WRITEDMA                  0xCA /* write sectors using DMA transfers */
++#define WIN_WRITEDMA_ONCE             0xCB /* 28-Bit - without retries */
++#define WIN_WRITEDMA_QUEUED           0xCC /* write sectors using Queued DMA transfers */
++#define CFA_WRITE_MULTI_WO_ERASE      0xCD /* CFA Write multiple without erase */
++#define WIN_GETMEDIASTATUS            0xDA
++#define WIN_ACKMEDIACHANGE            0xDB /* ATA-1, ATA-2 vendor */
++#define WIN_POSTBOOT                  0xDC
++#define WIN_PREBOOT                   0xDD
++#define WIN_DOORLOCK                  0xDE /* lock door on removable drives */
++#define WIN_DOORUNLOCK                        0xDF /* unlock door on removable drives */
++#define WIN_STANDBYNOW1                       0xE0
++#define WIN_IDLEIMMEDIATE             0xE1 /* force drive to become "ready" */
++#define WIN_STANDBY                   0xE2 /* Set device in Standby Mode */
++#define WIN_SETIDLE1                  0xE3
++#define WIN_READ_BUFFER                       0xE4 /* force read only 1 sector */
++#define WIN_CHECKPOWERMODE1           0xE5
++#define WIN_SLEEPNOW1                 0xE6
++#define WIN_FLUSH_CACHE                       0xE7
++#define WIN_WRITE_BUFFER              0xE8 /* force write only 1 sector */
++#define WIN_WRITE_SAME                        0xE9 /* read ata-2 to use */
++      /* SET_FEATURES 0x22 or 0xDD */
++#define WIN_FLUSH_CACHE_EXT           0xEA /* 48-Bit */
++#define WIN_IDENTIFY                  0xEC /* ask drive to identify itself    */
++#define WIN_MEDIAEJECT                        0xED
++#define WIN_IDENTIFY_DMA              0xEE /* same as WIN_IDENTIFY, but DMA */
++#define WIN_SETFEATURES                       0xEF /* set special drive features */
++#define EXABYTE_ENABLE_NEST           0xF0
++#define WIN_SECURITY_SET_PASS         0xF1
++#define WIN_SECURITY_UNLOCK           0xF2
++#define WIN_SECURITY_ERASE_PREPARE    0xF3
++#define WIN_SECURITY_ERASE_UNIT               0xF4
++#define WIN_SECURITY_FREEZE_LOCK      0xF5
++#define WIN_SECURITY_DISABLE          0xF6
++#define WIN_READ_NATIVE_MAX           0xF8 /* return the native maximum address */
++#define WIN_SET_MAX                   0xF9
++#define DISABLE_SEAGATE                       0xFB
++
++/* WIN_SMART sub-commands */
++
++#define SMART_READ_VALUES             0xD0
++#define SMART_READ_THRESHOLDS         0xD1
++#define SMART_AUTOSAVE                        0xD2
++#define SMART_SAVE                    0xD3
++#define SMART_IMMEDIATE_OFFLINE               0xD4
++#define SMART_READ_LOG_SECTOR         0xD5
++#define SMART_WRITE_LOG_SECTOR                0xD6
++#define SMART_WRITE_THRESHOLDS                0xD7
++#define SMART_ENABLE                  0xD8
++#define SMART_DISABLE                 0xD9
++#define SMART_STATUS                  0xDA
++#define SMART_AUTO_OFFLINE            0xDB
++
++/* Password used in TF4 & TF5 executing SMART commands */
++
++#define SMART_LCYL_PASS                       0x4F
++#define SMART_HCYL_PASS                       0xC2
++
++/* WIN_SETFEATURES sub-commands */
++#define SETFEATURES_EN_8BIT   0x01    /* Enable 8-Bit Transfers */
++#define SETFEATURES_EN_WCACHE 0x02    /* Enable write cache */
++#define SETFEATURES_DIS_DEFECT        0x04    /* Disable Defect Management */
++#define SETFEATURES_EN_APM    0x05    /* Enable advanced power management */
++#define SETFEATURES_EN_SAME_R 0x22    /* for a region ATA-1 */
++#define SETFEATURES_DIS_MSN   0x31    /* Disable Media Status Notification */
++#define SETFEATURES_DIS_RETRY 0x33    /* Disable Retry */
++#define SETFEATURES_EN_AAM    0x42    /* Enable Automatic Acoustic Management */
++#define SETFEATURES_RW_LONG   0x44    /* Set Length of VS bytes */
++#define SETFEATURES_SET_CACHE 0x54    /* Set Cache segments to SC Reg. Val */
++#define SETFEATURES_DIS_RLA   0x55    /* Disable read look-ahead feature */
++#define SETFEATURES_EN_RI     0x5D    /* Enable release interrupt */
++#define SETFEATURES_EN_SI     0x5E    /* Enable SERVICE interrupt */
++#define SETFEATURES_DIS_RPOD  0x66    /* Disable reverting to power on defaults */
++#define SETFEATURES_DIS_ECC   0x77    /* Disable ECC byte count */
++#define SETFEATURES_DIS_8BIT  0x81    /* Disable 8-Bit Transfers */
++#define SETFEATURES_DIS_WCACHE        0x82    /* Disable write cache */
++#define SETFEATURES_EN_DEFECT 0x84    /* Enable Defect Management */
++#define SETFEATURES_DIS_APM   0x85    /* Disable advanced power management */
++#define SETFEATURES_EN_ECC    0x88    /* Enable ECC byte count */
++#define SETFEATURES_EN_MSN    0x95    /* Enable Media Status Notification */
++#define SETFEATURES_EN_RETRY  0x99    /* Enable Retry */
++#define SETFEATURES_EN_RLA    0xAA    /* Enable read look-ahead feature */
++#define SETFEATURES_PREFETCH  0xAB    /* Sets drive prefetch value */
++#define SETFEATURES_EN_REST   0xAC    /* ATA-1 */
++#define SETFEATURES_4B_RW_LONG        0xBB    /* Set Length of 4 bytes */
++#define SETFEATURES_DIS_AAM   0xC2    /* Disable Automatic Acoustic Management */
++#define SETFEATURES_EN_RPOD   0xCC    /* Enable reverting to power on defaults */
++#define SETFEATURES_DIS_RI    0xDD    /* Disable release interrupt ATAPI */
++#define SETFEATURES_EN_SAME_M 0xDD    /* for a entire device ATA-1 */
++#define SETFEATURES_DIS_SI    0xDE    /* Disable SERVICE interrupt ATAPI */
++
++/* WIN_SECURITY sub-commands */
++
++#define SECURITY_SET_PASSWORD         0xBA
++#define SECURITY_UNLOCK                       0xBB
++#define SECURITY_ERASE_PREPARE                0xBC
++#define SECURITY_ERASE_UNIT           0xBD
++#define SECURITY_FREEZE_LOCK          0xBE
++#define SECURITY_DISABLE_PASSWORD     0xBF
++
++struct hd_geometry {
++      unsigned char heads;
++      unsigned char sectors;
++      unsigned short cylinders;
++      unsigned long start;
++};
++
++/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
++#define HDIO_GETGEO           0x0301  /* get device geometry */
++#define HDIO_GET_UNMASKINTR   0x0302  /* get current unmask setting */
++#define HDIO_GET_MULTCOUNT    0x0304  /* get current IDE blockmode setting */
++#define HDIO_GET_QDMA         0x0305  /* get use-qdma flag */
++
++#define HDIO_SET_XFER         0x0306  /* set transfer rate via proc */
++
++#define HDIO_OBSOLETE_IDENTITY        0x0307  /* OBSOLETE, DO NOT USE: returns 142 bytes */
++#define HDIO_GET_KEEPSETTINGS 0x0308  /* get keep-settings-on-reset flag */
++#define HDIO_GET_32BIT                0x0309  /* get current io_32bit setting */
++#define HDIO_GET_NOWERR               0x030a  /* get ignore-write-error flag */
++#define HDIO_GET_DMA          0x030b  /* get use-dma flag */
++#define HDIO_GET_NICE         0x030c  /* get nice flags */
++#define HDIO_GET_IDENTITY     0x030d  /* get IDE identification info */
++#define HDIO_GET_WCACHE               0x030e  /* get write cache mode on|off */
++#define HDIO_GET_ACOUSTIC     0x030f  /* get acoustic value */
++#define       HDIO_GET_ADDRESS        0x0310  /* */
++
++#define HDIO_GET_BUSSTATE     0x031a  /* get the bus state of the hwif */
++#define HDIO_TRISTATE_HWIF    0x031b  /* execute a channel tristate */
++#define HDIO_DRIVE_RESET      0x031c  /* execute a device reset */
++#define HDIO_DRIVE_TASKFILE   0x031d  /* execute raw taskfile */
++#define HDIO_DRIVE_TASK               0x031e  /* execute task and special drive command */
++#define HDIO_DRIVE_CMD                0x031f  /* execute a special drive command */
++#define HDIO_DRIVE_CMD_AEB    HDIO_DRIVE_TASK
++
++/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
++#define HDIO_SET_MULTCOUNT    0x0321  /* change IDE blockmode */
++#define HDIO_SET_UNMASKINTR   0x0322  /* permit other irqs during I/O */
++#define HDIO_SET_KEEPSETTINGS 0x0323  /* keep ioctl settings on reset */
++#define HDIO_SET_32BIT                0x0324  /* change io_32bit flags */
++#define HDIO_SET_NOWERR               0x0325  /* change ignore-write-error flag */
++#define HDIO_SET_DMA          0x0326  /* change use-dma flag */
++#define HDIO_SET_PIO_MODE     0x0327  /* reconfig interface to new speed */
++#define HDIO_SCAN_HWIF                0x0328  /* register and (re)scan interface */
++#define HDIO_UNREGISTER_HWIF  0x032a  /* unregister interface */
++#define HDIO_SET_NICE         0x0329  /* set nice flags */
++#define HDIO_SET_WCACHE               0x032b  /* change write cache enable-disable */
++#define HDIO_SET_ACOUSTIC     0x032c  /* change acoustic behavior */
++#define HDIO_SET_BUSSTATE     0x032d  /* set the bus state of the hwif */
++#define HDIO_SET_QDMA         0x032e  /* change use-qdma flag */
++#define HDIO_SET_ADDRESS      0x032f  /* change lba addressing modes */
++
++/* bus states */
++enum {
++      BUSSTATE_OFF = 0,
++      BUSSTATE_ON,
++      BUSSTATE_TRISTATE
++};
++
++/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */
++/* 0x330 is reserved - used to be HDIO_GETGEO_BIG */
++/* 0x331 is reserved - used to be HDIO_GETGEO_BIG_RAW */
++/* 0x338 is reserved - used to be HDIO_SET_IDE_SCSI */
++/* 0x339 is reserved - used to be HDIO_SET_SCSI_IDE */
++
++#define __NEW_HD_DRIVE_ID
++
++/*
++ * Structure returned by HDIO_GET_IDENTITY, as per ANSI NCITS ATA6 rev.1b spec.
++ *
++ * If you change something here, please remember to update fix_driveid() in
++ * ide/probe.c.
++ */
++struct hd_driveid {
++      unsigned short  config;         /* lots of obsolete bit flags */
++      unsigned short  cyls;           /* Obsolete, "physical" cyls */
++      unsigned short  reserved2;      /* reserved (word 2) */
++      unsigned short  heads;          /* Obsolete, "physical" heads */
++      unsigned short  track_bytes;    /* unformatted bytes per track */
++      unsigned short  sector_bytes;   /* unformatted bytes per sector */
++      unsigned short  sectors;        /* Obsolete, "physical" sectors per track */
++      unsigned short  vendor0;        /* vendor unique */
++      unsigned short  vendor1;        /* vendor unique */
++      unsigned short  vendor2;        /* Retired vendor unique */
++      unsigned char   serial_no[20];  /* 0 = not_specified */
++      unsigned short  buf_type;       /* Retired */
++      unsigned short  buf_size;       /* Retired, 512 byte increments
++                                       * 0 = not_specified
++                                       */
++      unsigned short  ecc_bytes;      /* for r/w long cmds; 0 = not_specified */
++      unsigned char   fw_rev[8];      /* 0 = not_specified */
++      unsigned char   model[40];      /* 0 = not_specified */
++      unsigned char   max_multsect;   /* 0=not_implemented */
++      unsigned char   vendor3;        /* vendor unique */
++      unsigned short  dword_io;       /* 0=not_implemented; 1=implemented */
++      unsigned char   vendor4;        /* vendor unique */
++      unsigned char   capability;     /* (upper byte of word 49)
++                                       *  3:  IORDYsup
++                                       *  2:  IORDYsw
++                                       *  1:  LBA
++                                       *  0:  DMA
++                                       */
++      unsigned short  reserved50;     /* reserved (word 50) */
++      unsigned char   vendor5;        /* Obsolete, vendor unique */
++      unsigned char   tPIO;           /* Obsolete, 0=slow, 1=medium, 2=fast */
++      unsigned char   vendor6;        /* Obsolete, vendor unique */
++      unsigned char   tDMA;           /* Obsolete, 0=slow, 1=medium, 2=fast */
++      unsigned short  field_valid;    /* (word 53)
++                                       *  2:  ultra_ok        word  88
++                                       *  1:  eide_ok         words 64-70
++                                       *  0:  cur_ok          words 54-58
++                                       */
++      unsigned short  cur_cyls;       /* Obsolete, logical cylinders */
++      unsigned short  cur_heads;      /* Obsolete, l heads */
++      unsigned short  cur_sectors;    /* Obsolete, l sectors per track */
++      unsigned short  cur_capacity0;  /* Obsolete, l total sectors on drive */
++      unsigned short  cur_capacity1;  /* Obsolete, (2 words, misaligned int)     */
++      unsigned char   multsect;       /* current multiple sector count */
++      unsigned char   multsect_valid; /* when (bit0==1) multsect is ok */
++      unsigned int    lba_capacity;   /* Obsolete, total number of sectors */
++      unsigned short  dma_1word;      /* Obsolete, single-word dma info */
++      unsigned short  dma_mword;      /* multiple-word dma info */
++      unsigned short  eide_pio_modes; /* bits 0:mode3 1:mode4 */
++      unsigned short  eide_dma_min;   /* min mword dma cycle time (ns) */
++      unsigned short  eide_dma_time;  /* recommended mword dma cycle time (ns) */
++      unsigned short  eide_pio;       /* min cycle time (ns), no IORDY  */
++      unsigned short  eide_pio_iordy; /* min cycle time (ns), with IORDY */
++      unsigned short  words69_70[2];  /* reserved words 69-70
++                                       * future command overlap and queuing
++                                       */
++      unsigned short  words71_74[4];  /* reserved words 71-74
++                                       * for IDENTIFY PACKET DEVICE command
++                                       */
++      unsigned short  queue_depth;    /* (word 75)
++                                       * 15:5 reserved
++                                       *  4:0 Maximum queue depth -1
++                                       */
++      unsigned short  words76_79[4];  /* reserved words 76-79 */
++      unsigned short  major_rev_num;  /* (word 80) */
++      unsigned short  minor_rev_num;  /* (word 81) */
++      unsigned short  command_set_1;  /* (word 82) supported
++                                       * 15:  Obsolete
++                                       * 14:  NOP command
++                                       * 13:  READ_BUFFER
++                                       * 12:  WRITE_BUFFER
++                                       * 11:  Obsolete
++                                       * 10:  Host Protected Area
++                                       *  9:  DEVICE Reset
++                                       *  8:  SERVICE Interrupt
++                                       *  7:  Release Interrupt
++                                       *  6:  look-ahead
++                                       *  5:  write cache
++                                       *  4:  PACKET Command
++                                       *  3:  Power Management Feature Set
++                                       *  2:  Removable Feature Set
++                                       *  1:  Security Feature Set
++                                       *  0:  SMART Feature Set
++                                       */
++      unsigned short  command_set_2;  /* (word 83)
++                                       * 15:  Shall be ZERO
++                                       * 14:  Shall be ONE
++                                       * 13:  FLUSH CACHE EXT
++                                       * 12:  FLUSH CACHE
++                                       * 11:  Device Configuration Overlay
++                                       * 10:  48-bit Address Feature Set
++                                       *  9:  Automatic Acoustic Management
++                                       *  8:  SET MAX security
++                                       *  7:  reserved 1407DT PARTIES
++                                       *  6:  SetF sub-command Power-Up
++                                       *  5:  Power-Up in Standby Feature Set
++                                       *  4:  Removable Media Notification
++                                       *  3:  APM Feature Set
++                                       *  2:  CFA Feature Set
++                                       *  1:  READ/WRITE DMA QUEUED
++                                       *  0:  Download MicroCode
++                                       */
++      unsigned short  cfsse;          /* (word 84)
++                                       * cmd set-feature supported extensions
++                                       * 15:  Shall be ZERO
++                                       * 14:  Shall be ONE
++                                       * 13:6 reserved
++                                       *  5:  General Purpose Logging
++                                       *  4:  Streaming Feature Set
++                                       *  3:  Media Card Pass Through
++                                       *  2:  Media Serial Number Valid
++                                       *  1:  SMART selt-test supported
++                                       *  0:  SMART error logging
++                                       */
++      unsigned short  cfs_enable_1;   /* (word 85)
++                                       * command set-feature enabled
++                                       * 15:  Obsolete
++                                       * 14:  NOP command
++                                       * 13:  READ_BUFFER
++                                       * 12:  WRITE_BUFFER
++                                       * 11:  Obsolete
++                                       * 10:  Host Protected Area
++                                       *  9:  DEVICE Reset
++                                       *  8:  SERVICE Interrupt
++                                       *  7:  Release Interrupt
++                                       *  6:  look-ahead
++                                       *  5:  write cache
++                                       *  4:  PACKET Command
++                                       *  3:  Power Management Feature Set
++                                       *  2:  Removable Feature Set
++                                       *  1:  Security Feature Set
++                                       *  0:  SMART Feature Set
++                                       */
++      unsigned short  cfs_enable_2;   /* (word 86)
++                                       * command set-feature enabled
++                                       * 15:  Shall be ZERO
++                                       * 14:  Shall be ONE
++                                       * 13:  FLUSH CACHE EXT
++                                       * 12:  FLUSH CACHE
++                                       * 11:  Device Configuration Overlay
++                                       * 10:  48-bit Address Feature Set
++                                       *  9:  Automatic Acoustic Management
++                                       *  8:  SET MAX security
++                                       *  7:  reserved 1407DT PARTIES
++                                       *  6:  SetF sub-command Power-Up
++                                       *  5:  Power-Up in Standby Feature Set
++                                       *  4:  Removable Media Notification
++                                       *  3:  APM Feature Set
++                                       *  2:  CFA Feature Set
++                                       *  1:  READ/WRITE DMA QUEUED
++                                       *  0:  Download MicroCode
++                                       */
++      unsigned short  csf_default;    /* (word 87)
++                                       * command set-feature default
++                                       * 15:  Shall be ZERO
++                                       * 14:  Shall be ONE
++                                       * 13:6 reserved
++                                       *  5:  General Purpose Logging enabled
++                                       *  4:  Valid CONFIGURE STREAM executed
++                                       *  3:  Media Card Pass Through enabled
++                                       *  2:  Media Serial Number Valid
++                                       *  1:  SMART selt-test supported
++                                       *  0:  SMART error logging
++                                       */
++      unsigned short  dma_ultra;      /* (word 88) */
++      unsigned short  trseuc;         /* time required for security erase */
++      unsigned short  trsEuc;         /* time required for enhanced erase */
++      unsigned short  CurAPMvalues;   /* current APM values */
++      unsigned short  mprc;           /* master password revision code */
++      unsigned short  hw_config;      /* hardware config (word 93)
++                                       * 15:  Shall be ZERO
++                                       * 14:  Shall be ONE
++                                       * 13:
++                                       * 12:
++                                       * 11:
++                                       * 10:
++                                       *  9:
++                                       *  8:
++                                       *  7:
++                                       *  6:
++                                       *  5:
++                                       *  4:
++                                       *  3:
++                                       *  2:
++                                       *  1:
++                                       *  0:  Shall be ONE
++                                       */
++      unsigned short  acoustic;       /* (word 94)
++                                       * 15:8 Vendor's recommended value
++                                       *  7:0 current value
++                                       */
++      unsigned short  msrqs;          /* min stream request size */
++      unsigned short  sxfert;         /* stream transfer time */
++      unsigned short  sal;            /* stream access latency */
++      unsigned int    spg;            /* stream performance granularity */
++      unsigned long long lba_capacity_2;/* 48-bit total number of sectors */
++      unsigned short  words104_125[22];/* reserved words 104-125 */
++      unsigned short  last_lun;       /* (word 126) */
++      unsigned short  word127;        /* (word 127) Feature Set
++                                       * Removable Media Notification
++                                       * 15:2 reserved
++                                       *  1:0 00 = not supported
++                                       *      01 = supported
++                                       *      10 = reserved
++                                       *      11 = reserved
++                                       */
++      unsigned short  dlf;            /* (word 128)
++                                       * device lock function
++                                       * 15:9 reserved
++                                       *  8   security level 1:max 0:high
++                                       *  7:6 reserved
++                                       *  5   enhanced erase
++                                       *  4   expire
++                                       *  3   frozen
++                                       *  2   locked
++                                       *  1   en/disabled
++                                       *  0   capability
++                                       */
++      unsigned short  csfo;           /*  (word 129)
++                                       * current set features options
++                                       * 15:4 reserved
++                                       *  3:  auto reassign
++                                       *  2:  reverting
++                                       *  1:  read-look-ahead
++                                       *  0:  write cache
++                                       */
++      unsigned short  words130_155[26];/* reserved vendor words 130-155 */
++      unsigned short  word156;        /* reserved vendor word 156 */
++      unsigned short  words157_159[3];/* reserved vendor words 157-159 */
++      unsigned short  cfa_power;      /* (word 160) CFA Power Mode
++                                       * 15 word 160 supported
++                                       * 14 reserved
++                                       * 13
++                                       * 12
++                                       * 11:0
++                                       */
++      unsigned short  words161_175[15];/* Reserved for CFA */
++      unsigned short  words176_205[30];/* Current Media Serial Number */
++      unsigned short  words206_254[49];/* reserved words 206-254 */
++      unsigned short  integrity_word; /* (word 255)
++                                       * 15:8 Checksum
++                                       *  7:0 Signature
++                                       */
++};
++
++/*
++ * IDE "nice" flags. These are used on a per drive basis to determine
++ * when to be nice and give more bandwidth to the other devices which
++ * share the same IDE bus.
++ */
++#define IDE_NICE_DSC_OVERLAP  (0)     /* per the DSC overlap protocol */
++#define IDE_NICE_ATAPI_OVERLAP        (1)     /* not supported yet */
++#define IDE_NICE_1            (3)     /* when probably won't affect us much */
++#define IDE_NICE_0            (2)     /* when sure that it won't affect us */
++#define IDE_NICE_2            (4)     /* when we know it's on our expense */
++
++#endif        /* _LINUX_HDREG_H */
+diff --git a/src/linux/magic.h b/src/linux/magic.h
+new file mode 100644
+index 0000000..77c6031
+--- /dev/null
++++ b/src/linux/magic.h
+@@ -0,0 +1,76 @@
++#ifndef __LINUX_MAGIC_H__
++#define __LINUX_MAGIC_H__
++
++#define ADFS_SUPER_MAGIC      0xadf5
++#define AFFS_SUPER_MAGIC      0xadff
++#define AFS_SUPER_MAGIC                0x5346414F
++#define AUTOFS_SUPER_MAGIC    0x0187
++#define CODA_SUPER_MAGIC      0x73757245
++#define CRAMFS_MAGIC          0x28cd3d45      /* some random number */
++#define CRAMFS_MAGIC_WEND     0x453dcd28      /* magic number with the wrong endianess */
++#define DEBUGFS_MAGIC          0x64626720
++#define SECURITYFS_MAGIC      0x73636673
++#define SELINUX_MAGIC         0xf97cff8c
++#define SMACK_MAGIC           0x43415d53      /* "SMAC" */
++#define RAMFS_MAGIC           0x858458f6      /* some random number */
++#define TMPFS_MAGIC           0x01021994
++#define HUGETLBFS_MAGIC       0x958458f6      /* some random number */
++#define SQUASHFS_MAGIC                0x73717368
++#define ECRYPTFS_SUPER_MAGIC  0xf15f
++#define EFS_SUPER_MAGIC               0x414A53
++#define EXT2_SUPER_MAGIC      0xEF53
++#define EXT3_SUPER_MAGIC      0xEF53
++#define XENFS_SUPER_MAGIC     0xabba1974
++#define EXT4_SUPER_MAGIC      0xEF53
++#define BTRFS_SUPER_MAGIC     0x9123683E
++#define NILFS_SUPER_MAGIC     0x3434
++#define F2FS_SUPER_MAGIC      0xF2F52010
++#define HPFS_SUPER_MAGIC      0xf995e849
++#define ISOFS_SUPER_MAGIC     0x9660
++#define JFFS2_SUPER_MAGIC     0x72b6
++#define PSTOREFS_MAGIC                0x6165676C
++#define EFIVARFS_MAGIC                0xde5e81e4
++#define HOSTFS_SUPER_MAGIC    0x00c0ffee
++
++#define MINIX_SUPER_MAGIC     0x137F          /* minix v1 fs, 14 char names */
++#define MINIX_SUPER_MAGIC2    0x138F          /* minix v1 fs, 30 char names */
++#define MINIX2_SUPER_MAGIC    0x2468          /* minix v2 fs, 14 char names */
++#define MINIX2_SUPER_MAGIC2   0x2478          /* minix v2 fs, 30 char names */
++#define MINIX3_SUPER_MAGIC    0x4d5a          /* minix v3 fs, 60 char names */
++
++#define MSDOS_SUPER_MAGIC     0x4d44          /* MD */
++#define NCP_SUPER_MAGIC               0x564c          /* Guess, what 0x564c is :-) */
++#define NFS_SUPER_MAGIC               0x6969
++#define OPENPROM_SUPER_MAGIC  0x9fa1
++#define QNX4_SUPER_MAGIC      0x002f          /* qnx4 fs detection */
++#define QNX6_SUPER_MAGIC      0x68191122      /* qnx6 fs detection */
++
++#define REISERFS_SUPER_MAGIC  0x52654973      /* used by gcc */
++                                      /* used by file system utilities that
++                                         look at the superblock, etc.  */
++#define REISERFS_SUPER_MAGIC_STRING   "ReIsErFs"
++#define REISER2FS_SUPER_MAGIC_STRING  "ReIsEr2Fs"
++#define REISER2FS_JR_SUPER_MAGIC_STRING       "ReIsEr3Fs"
++
++#define SMB_SUPER_MAGIC               0x517B
++#define CGROUP_SUPER_MAGIC    0x27e0eb
++
++
++#define STACK_END_MAGIC               0x57AC6E9D
++
++#define V9FS_MAGIC            0x01021997
++
++#define BDEVFS_MAGIC            0x62646576
++#define BINFMTFS_MAGIC          0x42494e4d
++#define DEVPTS_SUPER_MAGIC    0x1cd1
++#define FUTEXFS_SUPER_MAGIC   0xBAD1DEA
++#define PIPEFS_MAGIC            0x50495045
++#define PROC_SUPER_MAGIC      0x9fa0
++#define SOCKFS_MAGIC          0x534F434B
++#define SYSFS_MAGIC           0x62656572
++#define USBDEVICE_SUPER_MAGIC 0x9fa2
++#define MTD_INODE_FS_MAGIC      0x11307854
++#define ANON_INODE_FS_MAGIC   0x09041934
++#define BTRFS_TEST_MAGIC      0x73727279
++
++#endif /* __LINUX_MAGIC_H__ */
+diff --git a/src/linux/msdos_fs.h b/src/linux/msdos_fs.h
+new file mode 100644
+index 0000000..635d905
+--- /dev/null
++++ b/src/linux/msdos_fs.h
+@@ -0,0 +1,201 @@
++#ifndef _LINUX_MSDOS_FS_H
++#define _LINUX_MSDOS_FS_H
++
++#ifdef __linux__
++#include <linux/types.h>
++#include <asm/byteorder.h>
++#endif
++#include "magic.h"
++
++/*
++ * The MS-DOS filesystem constants/structures
++ */
++
++#define SECTOR_SIZE   512             /* sector size (bytes) */
++#define SECTOR_BITS   9               /* log2(SECTOR_SIZE) */
++#define MSDOS_DPB     (MSDOS_DPS)     /* dir entries per block */
++#define MSDOS_DPB_BITS        4               /* log2(MSDOS_DPB) */
++#define MSDOS_DPS     (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
++#define MSDOS_DPS_BITS        4               /* log2(MSDOS_DPS) */
++#define MSDOS_LONGNAME        256             /* maximum name length */
++#define CF_LE_W(v)    le16_to_cpu(v)
++#define CF_LE_L(v)    le32_to_cpu(v)
++#define CT_LE_W(v)    cpu_to_le16(v)
++#define CT_LE_L(v)    cpu_to_le32(v)
++
++#define MSDOS_ROOT_INO         1      /* The root inode number */
++#define MSDOS_FSINFO_INO 2    /* Used for managing the FSINFO block */
++
++#define MSDOS_DIR_BITS        5       /* log2(sizeof(struct msdos_dir_entry)) */
++
++/* directory limit */
++#define FAT_MAX_DIR_ENTRIES   (65536)
++#define FAT_MAX_DIR_SIZE      (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
++
++#define ATTR_NONE     0       /* no attribute bits */
++#define ATTR_RO               1       /* read-only */
++#define ATTR_HIDDEN   2       /* hidden */
++#define ATTR_SYS      4       /* system */
++#define ATTR_VOLUME   8       /* volume label */
++#define ATTR_DIR      16      /* directory */
++#define ATTR_ARCH     32      /* archived */
++
++/* attribute bits that are copied "as is" */
++#define ATTR_UNUSED   (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
++/* bits that are used by the Windows 95/Windows NT extended FAT */
++#define ATTR_EXT      (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
++
++#define CASE_LOWER_BASE       8       /* base is lower case */
++#define CASE_LOWER_EXT        16      /* extension is lower case */
++
++#define DELETED_FLAG  0xe5    /* marks file as deleted when in name[0] */
++#define IS_FREE(n)    (!*(n) || *(n) == DELETED_FLAG)
++
++#define FAT_LFN_LEN   255     /* maximum long name length */
++#define MSDOS_NAME    11      /* maximum name length */
++#define MSDOS_SLOTS   21      /* max # of slots for short and long names */
++#define MSDOS_DOT     ".          "   /* ".", padded to MSDOS_NAME chars */
++#define MSDOS_DOTDOT  "..         "   /* "..", padded to MSDOS_NAME chars */
++
++#define FAT_FIRST_ENT(s, x)   ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
++      MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
++
++/* start of data cluster's entry (number of reserved clusters) */
++#define FAT_START_ENT 2
++
++/* maximum number of clusters */
++#define MAX_FAT12     0xFF4
++#define MAX_FAT16     0xFFF4
++#define MAX_FAT32     0x0FFFFFF6
++#define MAX_FAT(s)    (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
++      MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
++
++/* bad cluster mark */
++#define BAD_FAT12     0xFF7
++#define BAD_FAT16     0xFFF7
++#define BAD_FAT32     0x0FFFFFF7
++
++/* standard EOF */
++#define EOF_FAT12     0xFFF
++#define EOF_FAT16     0xFFFF
++#define EOF_FAT32     0x0FFFFFFF
++
++#define FAT_ENT_FREE  (0)
++#define FAT_ENT_BAD   (BAD_FAT32)
++#define FAT_ENT_EOF   (EOF_FAT32)
++
++#define FAT_FSINFO_SIG1       0x41615252
++#define FAT_FSINFO_SIG2       0x61417272
++#define IS_FSINFO(x)  (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \
++                       && le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)
++
++#define FAT_STATE_DIRTY 0x01
++
++struct __fat_dirent {
++      long            d_ino;
++      long    d_off;
++      unsigned short  d_reclen;
++      char            d_name[256]; /* We must not include limits.h! */
++};
++
++/*
++ * ioctl commands
++ */
++#define VFAT_IOCTL_READDIR_BOTH               _IOR('r', 1, struct __fat_dirent[2])
++#define VFAT_IOCTL_READDIR_SHORT      _IOR('r', 2, struct __fat_dirent[2])
++/* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */
++#define FAT_IOCTL_GET_ATTRIBUTES      _IOR('r', 0x10, __u32)
++#define FAT_IOCTL_SET_ATTRIBUTES      _IOW('r', 0x11, __u32)
++/*Android kernel has used 0x12, so we use 0x13*/
++#define FAT_IOCTL_GET_VOLUME_ID               _IOR('r', 0x13, __u32)
++
++struct fat_boot_sector {
++      __u8    ignored[3];     /* Boot strap short or near jump */
++      __u8    system_id[8];   /* Name - can be used to special case
++                                 partition manager volumes */
++      __u8    sector_size[2]; /* bytes per logical sector */
++      __u8    sec_per_clus;   /* sectors/cluster */
++      __le16  reserved;       /* reserved sectors */
++      __u8    fats;           /* number of FATs */
++      __u8    dir_entries[2]; /* root directory entries */
++      __u8    sectors[2];     /* number of sectors */
++      __u8    media;          /* media code */
++      __le16  fat_length;     /* sectors/FAT */
++      __le16  secs_track;     /* sectors per track */
++      __le16  heads;          /* number of heads */
++      __le32  hidden;         /* hidden sectors (unused) */
++      __le32  total_sect;     /* number of sectors (if sectors == 0) */
++
++      union {
++              struct {
++                      /*  Extended BPB Fields for FAT16 */
++                      __u8    drive_number;   /* Physical drive number */
++                      __u8    state;          /* undocumented, but used
++                                                 for mount state. */
++                      __u8    signature;  /* extended boot signature */
++                      __u8    vol_id[4];      /* volume ID */
++                      __u8    vol_label[11];  /* volume label */
++                      __u8    fs_type[8];             /* file system type */
++                      /* other fiealds are not added here */
++              } fat16;
++
++              struct {
++                      /* only used by FAT32 */
++                      __le32  length;         /* sectors/FAT */
++                      __le16  flags;          /* bit 8: fat mirroring,
++                                                 low 4: active fat */
++                      __u8    version[2];     /* major, minor filesystem
++                                                 version */
++                      __le32  root_cluster;   /* first cluster in
++                                                 root directory */
++                      __le16  info_sector;    /* filesystem info sector */
++                      __le16  backup_boot;    /* backup boot sector */
++                      __le16  reserved2[6];   /* Unused */
++                      /* Extended BPB Fields for FAT32 */
++                      __u8    drive_number;   /* Physical drive number */
++                      __u8    state;          /* undocumented, but used
++                                                 for mount state. */
++                      __u8    signature;  /* extended boot signature */
++                      __u8    vol_id[4];      /* volume ID */
++                      __u8    vol_label[11];  /* volume label */
++                      __u8    fs_type[8];             /* file system type */
++                      /* other fiealds are not added here */
++              } fat32;
++      };
++};
++
++struct fat_boot_fsinfo {
++      __le32   signature1;    /* 0x41615252L */
++      __le32   reserved1[120];        /* Nothing as far as I can tell */
++      __le32   signature2;    /* 0x61417272L */
++      __le32   free_clusters; /* Free cluster count.  -1 if unknown */
++      __le32   next_cluster;  /* Most recently allocated cluster */
++      __le32   reserved2[4];
++};
++
++struct msdos_dir_entry {
++      __u8    name[MSDOS_NAME];/* name and extension */
++      __u8    attr;           /* attribute bits */
++      __u8    lcase;          /* Case for base and extension */
++      __u8    ctime_cs;       /* Creation time, centiseconds (0-199) */
++      __le16  ctime;          /* Creation time */
++      __le16  cdate;          /* Creation date */
++      __le16  adate;          /* Last access date */
++      __le16  starthi;        /* High 16 bits of cluster in FAT32 */
++      __le16  time,date,start;/* time, date and first cluster */
++      __le32  size;           /* file size (in bytes) */
++};
++
++/* Up to 13 characters of the name */
++struct msdos_dir_slot {
++      __u8    id;             /* sequence number for slot */
++      __u8    name0_4[10];    /* first 5 characters in name */
++      __u8    attr;           /* attribute byte */
++      __u8    reserved;       /* always 0 */
++      __u8    alias_checksum; /* checksum for 8.3 alias */
++      __u8    name5_10[12];   /* 6 more characters in name */
++      __le16   start;         /* starting cluster number, 0 in long slots */
++      __u8    name11_12[4];   /* last 2 characters in name */
++};
++
++#endif /* _LINUX_MSDOS_FS_H */
+diff --git a/src/mkfs.fat.c b/src/mkfs.fat.c
+index e6f9390..ebdfdb5 100644
+--- a/src/mkfs.fat.c
++++ b/src/mkfs.fat.c
+@@ -47,12 +47,6 @@
+ #include "version.h"
+ #include <fcntl.h>
+-#include <linux/hdreg.h>
+-#include <sys/mount.h>
+-#include <linux/fs.h>
+-#include <linux/fd.h>
+-#include <endian.h>
+-#include <mntent.h>
+ #include <signal.h>
+ #include <string.h>
+ #include <stdio.h>
+@@ -60,15 +54,23 @@
+ #include <sys/ioctl.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
+-#include <sys/types.h>
+ #include <unistd.h>
+ #include <time.h>
+ #include <errno.h>
+ #include <ctype.h>
+ #include <stdint.h>
+-#include <endian.h>
+-#include <asm/types.h>
++#if defined(__linux__)
++    #include <mntent.h>
++#elif defined(__osx__)
++    #include <fstab.h>
++    #include <sys/mount.h>
++#endif
++
++#include "common.h"
++#include "linux/fs.h"
++#include "linux/fd.h"
++#include "linux/hdreg.h"
+ /* In earlier versions, an own llseek() was used, but glibc lseek() is
+  * sufficient (or even better :) for 64 bit offsets in the meantime */
+@@ -524,6 +526,7 @@ static uint64_t count_blocks(char *filename, int *remainder)
+ static void check_mount(char *device_name)
+ {
++#if defined(__linux__)
+     FILE *f;
+     struct mntent *mnt;
+@@ -533,6 +536,17 @@ static void check_mount(char *device_name)
+       if (strcmp(device_name, mnt->mnt_fsname) == 0)
+           die("%s contains a mounted filesystem.");
+     endmntent(f);
++#elif defined(__osx__)
++    struct statfs* mounts;
++    int num_mounts = getmntinfo(&mounts, MNT_WAIT);
++    if (num_mounts < 0) 
++        return;
++    for ( int i = 0; i < num_mounts; i++ )
++    {
++        if (strcmp(device_name, mounts[i].f_mntfromname) == 0)
++            die("%s contains a mounted filesystem.");
++    }
++#endif
+ }
+ /* Establish the geometry and media parameters for the device */
+-- 
+1.9.1
+